summaryrefslogtreecommitdiff
path: root/ecos/packages/devs
diff options
context:
space:
mode:
authorMichael Gielda <mgielda@antmicro.com>2014-04-03 14:53:04 +0200
committerMichael Gielda <mgielda@antmicro.com>2014-04-03 14:53:04 +0200
commitae1e4e08a1005a0c487f03ba189d7536e7fdcba6 (patch)
treef1c296f8a966a9a39876b0e98e16d9c5da1776dd /ecos/packages/devs
parentf157da5337118d3c5cd464266796de4262ac9dbd (diff)
Added the OS files
Diffstat (limited to 'ecos/packages/devs')
-rw-r--r--ecos/packages/devs/adc/arm/at91/current/ChangeLog31
-rw-r--r--ecos/packages/devs/adc/arm/at91/current/cdl/adc_at91.cdl355
-rw-r--r--ecos/packages/devs/adc/arm/at91/current/include/adc_at91.inl200
-rw-r--r--ecos/packages/devs/adc/arm/at91/current/src/adc_at91.c457
-rw-r--r--ecos/packages/devs/adc/arm/at91/current/tests/at91_adc_test.c290
-rwxr-xr-xecos/packages/devs/adc/arm/lpc24xx/current/ChangeLog30
-rwxr-xr-xecos/packages/devs/adc/arm/lpc24xx/current/cdl/adc_lpc24xx.cdl160
-rwxr-xr-xecos/packages/devs/adc/arm/lpc24xx/current/src/adc_lpc24xx.c509
-rwxr-xr-xecos/packages/devs/adc/arm/lpc24xx/current/tests/lpc24xx_adc_test.c300
-rw-r--r--ecos/packages/devs/adc/cortexm/lm3s/current/ChangeLog31
-rw-r--r--ecos/packages/devs/adc/cortexm/lm3s/current/cdl/adc_lm3s.cdl217
-rw-r--r--ecos/packages/devs/adc/cortexm/lm3s/current/include/adc_lm3s.inl140
-rw-r--r--ecos/packages/devs/adc/cortexm/lm3s/current/src/adc_lm3s.c489
-rw-r--r--ecos/packages/devs/adc/cortexm/lm3s/current/tests/lm3s_adc_test.c256
-rw-r--r--ecos/packages/devs/adc/cortexm/stm32/current/ChangeLog53
-rw-r--r--ecos/packages/devs/adc/cortexm/stm32/current/cdl/adc_stm32.cdl242
-rw-r--r--ecos/packages/devs/adc/cortexm/stm32/current/src/adc1.inl163
-rw-r--r--ecos/packages/devs/adc/cortexm/stm32/current/src/adc3.inl155
-rw-r--r--ecos/packages/devs/adc/cortexm/stm32/current/src/adc_stm32.c631
-rw-r--r--ecos/packages/devs/adc/synth/current/ChangeLog35
-rw-r--r--ecos/packages/devs/adc/synth/current/cdl/adc_synth.cdl158
-rw-r--r--ecos/packages/devs/adc/synth/current/src/adc_synth.c482
-rw-r--r--ecos/packages/devs/can/arm/at91/at91sam7/current/ChangeLog36
-rw-r--r--ecos/packages/devs/can/arm/at91/at91sam7/current/cdl/can_at91sam7.cdl216
-rw-r--r--ecos/packages/devs/can/arm/at91/at91sam7/current/include/can_at91sam7.inl185
-rw-r--r--ecos/packages/devs/can/arm/at91/at91sam7/current/src/can_at91sam7.c1594
-rw-r--r--ecos/packages/devs/can/arm/at91/at91sam7/current/tests/can_test_aux.inl147
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/ChangeLog152
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/cdl/can_lpc2xxx.cdl424
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/include/can_lpc2xxx.h92
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/include/can_lpc2xxx_baudrates.h238
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c1009
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c2294
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_baudrates.c230
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_busload.c252
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_extended_cfg.c251
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_multichan_rx.c338
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_multichan_tx.c291
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_rx_tx.c348
-rw-r--r--ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_test_aux.inl147
-rw-r--r--ecos/packages/devs/can/loop/current/ChangeLog73
-rw-r--r--ecos/packages/devs/can/loop/current/cdl/can_loop.cdl140
-rw-r--r--ecos/packages/devs/can/loop/current/doc/README2
-rw-r--r--ecos/packages/devs/can/loop/current/doc/synth_test.ecm66
-rw-r--r--ecos/packages/devs/can/loop/current/src/loop_can.c408
-rw-r--r--ecos/packages/devs/can/loop/current/tests/can_callback.c240
-rw-r--r--ecos/packages/devs/can/loop/current/tests/can_nonblock.c199
-rw-r--r--ecos/packages/devs/can/loop/current/tests/can_overrun1.c275
-rw-r--r--ecos/packages/devs/can/loop/current/tests/can_overrun2.c354
-rw-r--r--ecos/packages/devs/can/loop/current/tests/can_rdwr.c307
-rw-r--r--ecos/packages/devs/can/loop/current/tests/can_test_aux.inl147
-rw-r--r--ecos/packages/devs/can/loop/current/tests/can_timeout.c247
-rw-r--r--ecos/packages/devs/can/loop/current/tests/can_txevent.c271
-rw-r--r--ecos/packages/devs/can/m68k/mcf52xx/current/ChangeLog125
-rw-r--r--ecos/packages/devs/can/m68k/mcf52xx/current/cdl/can_mcf52xx.cdl275
-rw-r--r--ecos/packages/devs/can/m68k/mcf52xx/current/src/can_mcf52xx.c2739
-rw-r--r--ecos/packages/devs/can/m68k/mcf52xx/current/tests/can_test_aux.inl147
-rw-r--r--ecos/packages/devs/can/m68k/mcf52xx/current/tests/flexcan_wake.c246
-rw-r--r--ecos/packages/devs/disk/generic/mmc/current/ChangeLog122
-rw-r--r--ecos/packages/devs/disk/generic/mmc/current/cdl/devs_disk_mmc.cdl113
-rw-r--r--ecos/packages/devs/disk/generic/mmc/current/doc/disk_mmc.sgml212
-rw-r--r--ecos/packages/devs/disk/generic/mmc/current/include/mmc_protocol.h197
-rw-r--r--ecos/packages/devs/disk/generic/mmc/current/src/mmc_spi.c1372
-rw-r--r--ecos/packages/devs/disk/ide/current/ChangeLog75
-rw-r--r--ecos/packages/devs/disk/ide/current/cdl/ide_disk.cdl154
-rw-r--r--ecos/packages/devs/disk/ide/current/src/ide_disk.c530
-rw-r--r--ecos/packages/devs/disk/ide/current/src/ide_disk.h187
-rw-r--r--ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/ChangeLog29
-rw-r--r--ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/cdl/disk_mmc_freescale_dspi.cdl92
-rw-r--r--ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/src/freescale_dspi_mmc.c99
-rw-r--r--ecos/packages/devs/disk/synth/current/ChangeLog78
-rw-r--r--ecos/packages/devs/disk/synth/current/cdl/synthdisk.cdl173
-rw-r--r--ecos/packages/devs/disk/synth/current/src/synthdisk.c406
-rw-r--r--ecos/packages/devs/disk/v85x/edb_v850/current/ChangeLog59
-rw-r--r--ecos/packages/devs/disk/v85x/edb_v850/current/cdl/v85x_edb_v850_disk.cdl72
-rw-r--r--ecos/packages/devs/disk/v85x/edb_v850/current/src/cf_ata.h184
-rw-r--r--ecos/packages/devs/disk/v85x/edb_v850/current/src/v85x_edb_v850_disk.c415
-rw-r--r--ecos/packages/devs/eth/amd/lancepci/current/ChangeLog63
-rw-r--r--ecos/packages/devs/eth/amd/lancepci/current/cdl/amd_lancepci_eth_drivers.cdl95
-rw-r--r--ecos/packages/devs/eth/amd/lancepci/current/src/amd_lance.h521
-rw-r--r--ecos/packages/devs/eth/amd/lancepci/current/src/if_lancepci.c1312
-rw-r--r--ecos/packages/devs/eth/amd/pcnet/current/ChangeLog175
-rw-r--r--ecos/packages/devs/eth/amd/pcnet/current/cdl/amd_pcnet_eth_drivers.cdl104
-rw-r--r--ecos/packages/devs/eth/amd/pcnet/current/src/amd_pcnet.h535
-rw-r--r--ecos/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c1317
-rw-r--r--ecos/packages/devs/eth/arm/aaed2000/current/ChangeLog63
-rw-r--r--ecos/packages/devs/eth/arm/aaed2000/current/cdl/aaed2000_eth_drivers.cdl108
-rw-r--r--ecos/packages/devs/eth/arm/aaed2000/current/include/devs_eth_arm_aaed2000.inl146
-rwxr-xr-xecos/packages/devs/eth/arm/at91/current/ChangeLog49
-rwxr-xr-xecos/packages/devs/eth/arm/at91/current/cdl/at91_eth.cdl164
-rwxr-xr-xecos/packages/devs/eth/arm/at91/current/src/if_at91.c1030
-rw-r--r--ecos/packages/devs/eth/arm/cerf/current/ChangeLog34
-rw-r--r--ecos/packages/devs/eth/arm/cerf/current/cdl/cerf_eth_drivers.cdl118
-rw-r--r--ecos/packages/devs/eth/arm/cerf/current/doc/README3
-rw-r--r--ecos/packages/devs/eth/arm/cerf/current/include/devs_eth_arm_cerf.inl207
-rw-r--r--ecos/packages/devs/eth/arm/cerfpda/current/ChangeLog34
-rw-r--r--ecos/packages/devs/eth/arm/cerfpda/current/cdl/cerfpda_eth_drivers.cdl118
-rw-r--r--ecos/packages/devs/eth/arm/cerfpda/current/doc/README2
-rw-r--r--ecos/packages/devs/eth/arm/cerfpda/current/include/devs_eth_arm_cerfpda.inl207
-rw-r--r--ecos/packages/devs/eth/arm/ebsa285/current/ChangeLog448
-rw-r--r--ecos/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl153
-rw-r--r--ecos/packages/devs/eth/arm/ebsa285/current/include/devs_eth_ebsa285.inl223
-rw-r--r--ecos/packages/devs/eth/arm/ebsa285/current/tests/test_net_realtime.h293
-rw-r--r--ecos/packages/devs/eth/arm/edb7xxx/current/ChangeLog209
-rw-r--r--ecos/packages/devs/eth/arm/edb7xxx/current/cdl/edb7xxx_eth_drivers.cdl113
-rw-r--r--ecos/packages/devs/eth/arm/edb7xxx/current/doc/README18
-rw-r--r--ecos/packages/devs/eth/arm/edb7xxx/current/include/devs_eth_arm_edb7xxx.inl155
-rw-r--r--ecos/packages/devs/eth/arm/flexanet/current/ChangeLog40
-rw-r--r--ecos/packages/devs/eth/arm/flexanet/current/cdl/flexanet_eth_drivers.cdl116
-rw-r--r--ecos/packages/devs/eth/arm/flexanet/current/include/devs_eth_flexanet.inl119
-rw-r--r--ecos/packages/devs/eth/arm/flexanet/current/src/if_flexanet.c71
-rw-r--r--ecos/packages/devs/eth/arm/grg/i82559/current/ChangeLog39
-rwxr-xr-xecos/packages/devs/eth/arm/grg/i82559/current/cdl/grg_i82559_eth_driver.cdl149
-rwxr-xr-xecos/packages/devs/eth/arm/grg/i82559/current/include/grg_i82559.inl188
-rw-r--r--ecos/packages/devs/eth/arm/innovator/current/ChangeLog36
-rw-r--r--ecos/packages/devs/eth/arm/innovator/current/cdl/innovator_eth_drivers.cdl116
-rw-r--r--ecos/packages/devs/eth/arm/innovator/current/include/devs_eth_innovator.inl143
-rw-r--r--ecos/packages/devs/eth/arm/integrator/current/ChangeLog41
-rw-r--r--ecos/packages/devs/eth/arm/integrator/current/cdl/integrator_eth_drivers.cdl111
-rw-r--r--ecos/packages/devs/eth/arm/integrator/current/include/devs_eth_arm_integrator_i82559.inl117
-rw-r--r--ecos/packages/devs/eth/arm/iq80310/current/ChangeLog98
-rw-r--r--ecos/packages/devs/eth/arm/iq80310/current/cdl/iq80310_eth_drivers.cdl116
-rw-r--r--ecos/packages/devs/eth/arm/iq80310/current/include/devs_eth_iq80310.inl134
-rw-r--r--ecos/packages/devs/eth/arm/iq80321/current/ChangeLog43
-rw-r--r--ecos/packages/devs/eth/arm/iq80321/current/cdl/iq80321_eth_drivers.cdl116
-rw-r--r--ecos/packages/devs/eth/arm/iq80321/current/include/devs_eth_iq80321.inl129
-rw-r--r--ecos/packages/devs/eth/arm/ixdp425/i82559/current/ChangeLog44
-rwxr-xr-xecos/packages/devs/eth/arm/ixdp425/i82559/current/cdl/ixdp425_i82559_eth_driver.cdl149
-rwxr-xr-xecos/packages/devs/eth/arm/ixdp425/i82559/current/include/ixdp425_i82559.inl188
-rw-r--r--ecos/packages/devs/eth/arm/ks32c5000/current/ChangeLog134
-rw-r--r--ecos/packages/devs/eth/arm/ks32c5000/current/cdl/ks32c5000_eth.cdl222
-rwxr-xr-xecos/packages/devs/eth/arm/ks32c5000/current/src/ics1890.c103
-rwxr-xr-xecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.c1479
-rw-r--r--ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.h271
-rw-r--r--ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_regs.h226
-rw-r--r--ecos/packages/devs/eth/arm/ks32c5000/current/src/lxt970.c160
-rw-r--r--ecos/packages/devs/eth/arm/ks32c5000/current/src/lxt972.c234
-rw-r--r--ecos/packages/devs/eth/arm/ks32c5000/current/src/phy.h67
-rw-r--r--ecos/packages/devs/eth/arm/ks32c5000/current/src/rtl8201.c208
-rw-r--r--ecos/packages/devs/eth/arm/ks32c5000/current/src/std.h106
-rw-r--r--ecos/packages/devs/eth/arm/lpc2xxx/current/ChangeLog39
-rwxr-xr-xecos/packages/devs/eth/arm/lpc2xxx/current/cdl/lpc2xxx_eth.cdl194
-rwxr-xr-xecos/packages/devs/eth/arm/lpc2xxx/current/doc/readme.txt35
-rwxr-xr-xecos/packages/devs/eth/arm/lpc2xxx/current/src/if_lpc2xxx.c1314
-rw-r--r--ecos/packages/devs/eth/arm/nano/current/ChangeLog78
-rw-r--r--ecos/packages/devs/eth/arm/nano/current/cdl/nano_eth_drivers.cdl208
-rw-r--r--ecos/packages/devs/eth/arm/nano/current/include/devs_eth_nano.inl288
-rw-r--r--ecos/packages/devs/eth/arm/netarm/current/ChangeLog34
-rwxr-xr-xecos/packages/devs/eth/arm/netarm/current/cdl/netarm_eth_driver.cdl137
-rwxr-xr-xecos/packages/devs/eth/arm/netarm/current/doc/netarm_hal.patch535
-rwxr-xr-xecos/packages/devs/eth/arm/netarm/current/doc/readme4
-rwxr-xr-xecos/packages/devs/eth/arm/netarm/current/src/MII.c236
-rwxr-xr-xecos/packages/devs/eth/arm/netarm/current/src/MII.h60
-rwxr-xr-xecos/packages/devs/eth/arm/netarm/current/src/eeprom.c227
-rwxr-xr-xecos/packages/devs/eth/arm/netarm/current/src/eeprom.h62
-rwxr-xr-xecos/packages/devs/eth/arm/netarm/current/src/eth_regs.h149
-rwxr-xr-xecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.c711
-rwxr-xr-xecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.h88
-rw-r--r--ecos/packages/devs/eth/arm/npwr/current/ChangeLog29
-rw-r--r--ecos/packages/devs/eth/arm/npwr/current/cdl/npwr_eth_drivers.cdl116
-rw-r--r--ecos/packages/devs/eth/arm/npwr/current/include/devs_eth_npwr.inl129
-rw-r--r--ecos/packages/devs/eth/arm/olpce2294/current/ChangeLog30
-rw-r--r--ecos/packages/devs/eth/arm/olpce2294/current/cdl/olpce2294_eth_drivers.cdl126
-rw-r--r--ecos/packages/devs/eth/arm/olpce2294/current/doc/README14
-rw-r--r--ecos/packages/devs/eth/arm/olpce2294/current/include/devs_eth_arm_olpce2294.h57
-rw-r--r--ecos/packages/devs/eth/arm/olpce2294/current/include/devs_eth_arm_olpce2294.inl175
-rw-r--r--ecos/packages/devs/eth/arm/olpcl2294/current/ChangeLog31
-rw-r--r--ecos/packages/devs/eth/arm/olpcl2294/current/cdl/olpcl2294_eth_drivers.cdl112
-rw-r--r--ecos/packages/devs/eth/arm/olpcl2294/current/include/devs_eth_arm_olpcl2294.h57
-rw-r--r--ecos/packages/devs/eth/arm/olpcl2294/current/include/devs_eth_arm_olpcl2294.inl169
-rw-r--r--ecos/packages/devs/eth/arm/phycore229x/current/ChangeLog29
-rwxr-xr-xecos/packages/devs/eth/arm/phycore229x/current/cdl/phycore229x_eth_drivers.cdl117
-rwxr-xr-xecos/packages/devs/eth/arm/phycore229x/current/include/devs_eth_phycore229x.inl203
-rw-r--r--ecos/packages/devs/eth/arm/picasso/current/ChangeLog29
-rw-r--r--ecos/packages/devs/eth/arm/picasso/current/cdl/picasso_eth_drivers.cdl130
-rw-r--r--ecos/packages/devs/eth/arm/picasso/current/include/devs_eth_picasso.inl231
-rw-r--r--ecos/packages/devs/eth/arm/uE250/current/ChangeLog29
-rw-r--r--ecos/packages/devs/eth/arm/uE250/current/cdl/uE250_eth_drivers.cdl130
-rw-r--r--ecos/packages/devs/eth/arm/uE250/current/include/devs_eth_uE250.inl231
-rw-r--r--ecos/packages/devs/eth/arm/xsengine/current/ChangeLog29
-rw-r--r--ecos/packages/devs/eth/arm/xsengine/current/cdl/xsengine_eth_drivers.cdl116
-rw-r--r--ecos/packages/devs/eth/arm/xsengine/current/include/devs_eth_xsengine.inl141
-rw-r--r--ecos/packages/devs/eth/cf/current/ChangeLog157
-rw-r--r--ecos/packages/devs/eth/cf/current/cdl/cf_eth_drivers.cdl131
-rw-r--r--ecos/packages/devs/eth/cf/current/include/devs_eth_cf.inl107
-rw-r--r--ecos/packages/devs/eth/cf/current/src/if_sc_lpe.c314
-rw-r--r--ecos/packages/devs/eth/cl/cs8900a/current/ChangeLog194
-rw-r--r--ecos/packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl139
-rw-r--r--ecos/packages/devs/eth/cl/cs8900a/current/include/cs8900.h452
-rw-r--r--ecos/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c759
-rw-r--r--ecos/packages/devs/eth/cortexm/a2f200_eval/current/ChangeLog31
-rw-r--r--ecos/packages/devs/eth/cortexm/a2f200_eval/current/cdl/a2f200_eval.cdl121
-rw-r--r--ecos/packages/devs/eth/cortexm/a2f200_eval/current/include/a2f200_eval_eth.inl129
-rw-r--r--ecos/packages/devs/eth/cortexm/a2fxxx/current/ChangeLog31
-rw-r--r--ecos/packages/devs/eth/cortexm/a2fxxx/current/cdl/a2fxxx_eth.cdl152
-rw-r--r--ecos/packages/devs/eth/cortexm/a2fxxx/current/src/if_a2fxxx.c1088
-rw-r--r--ecos/packages/devs/eth/cortexm/stm32/current/ChangeLog29
-rw-r--r--ecos/packages/devs/eth/cortexm/stm32/current/cdl/stm32_eth.cdl241
-rw-r--r--ecos/packages/devs/eth/cortexm/stm32/current/src/if_stm32.c1030
-rw-r--r--ecos/packages/devs/eth/davicom/dm9000/current/ChangeLog51
-rw-r--r--ecos/packages/devs/eth/davicom/dm9000/current/cdl/davicom_dm9000_eth_drivers.cdl105
-rw-r--r--ecos/packages/devs/eth/davicom/dm9000/current/include/dm9000_info.h77
-rw-r--r--ecos/packages/devs/eth/davicom/dm9000/current/src/if_dm9000.c950
-rw-r--r--ecos/packages/devs/eth/freescale/enet/current/ChangeLog47
-rw-r--r--ecos/packages/devs/eth/freescale/enet/current/cdl/eth_freescale_enet.cdl453
-rw-r--r--ecos/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_bd.h209
-rw-r--r--ecos/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_io.h685
-rw-r--r--ecos/packages/devs/eth/freescale/enet/current/src/if_freescale_enet.c1616
-rw-r--r--ecos/packages/devs/eth/frv/cb70/current/ChangeLog27
-rwxr-xr-xecos/packages/devs/eth/frv/cb70/current/cdl/cb70_eth_driver.cdl147
-rw-r--r--ecos/packages/devs/eth/frv/cb70/current/include/cb70_eth_driver.inl157
-rw-r--r--ecos/packages/devs/eth/frv/frv400/current/ChangeLog68
-rw-r--r--ecos/packages/devs/eth/frv/frv400/current/cdl/frv400_eth_drivers.cdl133
-rw-r--r--ecos/packages/devs/eth/frv/frv400/current/include/devs_eth_frv400.inl391
-rw-r--r--ecos/packages/devs/eth/frv/pdk403/current/ChangeLog29
-rw-r--r--ecos/packages/devs/eth/frv/pdk403/current/cdl/pdk403_eth_drivers.cdl132
-rw-r--r--ecos/packages/devs/eth/frv/pdk403/current/include/devs_eth_pdk403.inl134
-rw-r--r--ecos/packages/devs/eth/frv/pdk403/current/src/pdk403_eth_init.c178
-rw-r--r--ecos/packages/devs/eth/h8300/aki3068net/current/ChangeLog46
-rw-r--r--ecos/packages/devs/eth/h8300/aki3068net/current/cdl/h8300_aki3068net_eth_drivers.cdl130
-rw-r--r--ecos/packages/devs/eth/h8300/aki3068net/current/include/devs_eth_h8300_aki3068net.inl95
-rw-r--r--ecos/packages/devs/eth/h8300/aki3068net/current/src/if_aki3068net.c114
-rw-r--r--ecos/packages/devs/eth/h8300/edosk2674/current/ChangeLog28
-rw-r--r--ecos/packages/devs/eth/h8300/edosk2674/current/cdl/h8300_edosk2674_eth_drivers.cdl112
-rw-r--r--ecos/packages/devs/eth/h8300/edosk2674/current/include/devs_eth_edosk2674.inl87
-rw-r--r--ecos/packages/devs/eth/h8300/h8max/current/ChangeLog31
-rw-r--r--ecos/packages/devs/eth/h8300/h8max/current/cdl/h8300_h8max_eth_drivers.cdl129
-rw-r--r--ecos/packages/devs/eth/h8300/h8max/current/include/devs_eth_h8300_h8max.inl100
-rw-r--r--ecos/packages/devs/eth/h8300/h8max/current/src/if_h8max.c100
-rw-r--r--ecos/packages/devs/eth/i386/pc/i82544/current/ChangeLog30
-rw-r--r--ecos/packages/devs/eth/i386/pc/i82544/current/cdl/i386_pc_i82544_eth_drivers.cdl108
-rw-r--r--ecos/packages/devs/eth/i386/pc/i82544/current/include/devs_eth_i386_pc_i82544.inl112
-rw-r--r--ecos/packages/devs/eth/i386/pc/i82559/current/ChangeLog35
-rw-r--r--ecos/packages/devs/eth/i386/pc/i82559/current/cdl/i386_pc_i82559_eth_drivers.cdl108
-rw-r--r--ecos/packages/devs/eth/i386/pc/i82559/current/include/devs_eth_i386_pc_i82559.inl112
-rw-r--r--ecos/packages/devs/eth/i386/pc/lancepci/current/ChangeLog28
-rw-r--r--ecos/packages/devs/eth/i386/pc/lancepci/current/cdl/i386_pc_lancepci_eth_drivers.cdl128
-rw-r--r--ecos/packages/devs/eth/i386/pc/lancepci/current/include/devs_eth_i386_pc_lancepci.inl110
-rw-r--r--ecos/packages/devs/eth/i386/pc/rltk8139/current/ChangeLog34
-rw-r--r--ecos/packages/devs/eth/i386/pc/rltk8139/current/cdl/i386_pc_rltk8139_eth_drivers.cdl110
-rw-r--r--ecos/packages/devs/eth/i386/pc/rltk8139/current/include/devs_eth_i386_pc_rltk8139.inl120
-rw-r--r--ecos/packages/devs/eth/intel/i21143/current/ChangeLog78
-rw-r--r--ecos/packages/devs/eth/intel/i21143/current/cdl/intel_i21143_eth_drivers.cdl101
-rw-r--r--ecos/packages/devs/eth/intel/i21143/current/src/if_i21143.c2843
-rw-r--r--ecos/packages/devs/eth/intel/i82544/current/ChangeLog107
-rw-r--r--ecos/packages/devs/eth/intel/i82544/current/cdl/intel_i82544_eth_drivers.cdl182
-rw-r--r--ecos/packages/devs/eth/intel/i82544/current/include/i82544_info.h212
-rw-r--r--ecos/packages/devs/eth/intel/i82544/current/src/if_i82544.c2916
-rw-r--r--ecos/packages/devs/eth/intel/i82559/current/ChangeLog833
-rw-r--r--ecos/packages/devs/eth/intel/i82559/current/cdl/intel_i82559_eth_drivers.cdl186
-rw-r--r--ecos/packages/devs/eth/intel/i82559/current/include/i82559_info.h220
-rw-r--r--ecos/packages/devs/eth/intel/i82559/current/src/if_i82559.c3931
-rw-r--r--ecos/packages/devs/eth/m68k/mcf5272/current/ChangeLog182
-rw-r--r--ecos/packages/devs/eth/m68k/mcf5272/current/cdl/mcf5272_eth.cdl194
-rw-r--r--ecos/packages/devs/eth/m68k/mcf5272/current/doc/mcf5272_eth.sgml206
-rw-r--r--ecos/packages/devs/eth/m68k/mcf5272/current/src/if_mcf5272.c1354
-rw-r--r--ecos/packages/devs/eth/mcf52xx/mcf5272/current/ChangeLog28
-rw-r--r--ecos/packages/devs/eth/mcf52xx/mcf5272/current/cdl/mcf5272_eth_driver.cdl88
-rw-r--r--ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/if_mcf5272.h329
-rw-r--r--ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/if_mcf5272_private_data.h95
-rw-r--r--ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/nbuf.h647
-rw-r--r--ecos/packages/devs/eth/mcf52xx/mcf5272/current/src/if_mcf5272.c1885
-rw-r--r--ecos/packages/devs/eth/mcf52xx/mcf5272/current/src/nbuf.c97
-rw-r--r--ecos/packages/devs/eth/microchip/enc424j600/current/ChangeLog33
-rw-r--r--ecos/packages/devs/eth/microchip/enc424j600/current/cdl/enc424j600_eth_drivers.cdl271
-rw-r--r--ecos/packages/devs/eth/microchip/enc424j600/current/host/test_tcp_client.c198
-rw-r--r--ecos/packages/devs/eth/microchip/enc424j600/current/include/enc424j600_eth.h100
-rw-r--r--ecos/packages/devs/eth/microchip/enc424j600/current/src/enc424j600_spi.c1340
-rw-r--r--ecos/packages/devs/eth/microchip/enc424j600/current/src/enc424j600_spi.h344
-rw-r--r--ecos/packages/devs/eth/microchip/enc424j600/current/tests/netconn_test_server.c354
-rw-r--r--ecos/packages/devs/eth/mips/atlas/current/ChangeLog71
-rw-r--r--ecos/packages/devs/eth/mips/atlas/current/cdl/atlas_eth_drivers.cdl101
-rw-r--r--ecos/packages/devs/eth/mips/atlas/current/src/if_atlas.c1042
-rw-r--r--ecos/packages/devs/eth/mips/atlas/current/src/if_buffers.S63
-rw-r--r--ecos/packages/devs/eth/mips/atlas/current/src/saa9730.h362
-rw-r--r--ecos/packages/devs/eth/mips/idt79s334a/current/ChangeLog28
-rwxr-xr-xecos/packages/devs/eth/mips/idt79s334a/current/cdl/refidt334_eth_drivers.cdl148
-rw-r--r--ecos/packages/devs/eth/mips/idt79s334a/current/include/devs_eth_refidt334.inl172
-rw-r--r--ecos/packages/devs/eth/mips/malta/current/ChangeLog59
-rw-r--r--ecos/packages/devs/eth/mips/malta/current/cdl/mips_mips32_malta_eth_drivers.cdl129
-rw-r--r--ecos/packages/devs/eth/mips/malta/current/include/devs_eth_mips_mips32_malta.inl108
-rw-r--r--ecos/packages/devs/eth/mips/ocelot/current/ChangeLog43
-rw-r--r--ecos/packages/devs/eth/mips/ocelot/current/cdl/mips_rm7000_ocelot_eth_drivers.cdl112
-rw-r--r--ecos/packages/devs/eth/mips/ocelot/current/include/devs_eth_mips_rm7000_ocelot.inl117
-rw-r--r--ecos/packages/devs/eth/mips/upd985xx/current/ChangeLog254
-rw-r--r--ecos/packages/devs/eth/mips/upd985xx/current/cdl/upd985xx_eth_drivers.cdl204
-rw-r--r--ecos/packages/devs/eth/mips/upd985xx/current/include/upd985xx_eth.h464
-rw-r--r--ecos/packages/devs/eth/mips/upd985xx/current/src/if_upd985xx.c1610
-rw-r--r--ecos/packages/devs/eth/mips/vrc4375/current/ChangeLog30
-rw-r--r--ecos/packages/devs/eth/mips/vrc4375/current/cdl/vrc4375_eth_drivers.cdl115
-rw-r--r--ecos/packages/devs/eth/mips/vrc4375/current/include/devs_eth_vrc4375.inl126
-rw-r--r--ecos/packages/devs/eth/mn10300/asb2305/current/ChangeLog27
-rw-r--r--ecos/packages/devs/eth/mn10300/asb2305/current/cdl/mn10300_asb2305_eth.cdl129
-rw-r--r--ecos/packages/devs/eth/mn10300/asb2305/current/include/mn10300_asb2305_eth.inl108
-rw-r--r--ecos/packages/devs/eth/ns/dp83816/current/ChangeLog77
-rw-r--r--ecos/packages/devs/eth/ns/dp83816/current/cdl/ns_dp83816_eth_drivers.cdl85
-rw-r--r--ecos/packages/devs/eth/ns/dp83816/current/src/dp83816.h276
-rw-r--r--ecos/packages/devs/eth/ns/dp83816/current/src/if_dp83816.c587
-rw-r--r--ecos/packages/devs/eth/ns/dp83902a/current/ChangeLog144
-rw-r--r--ecos/packages/devs/eth/ns/dp83902a/current/cdl/ns_dp83902a_eth_drivers.cdl85
-rw-r--r--ecos/packages/devs/eth/ns/dp83902a/current/include/dp83902a.h373
-rw-r--r--ecos/packages/devs/eth/ns/dp83902a/current/src/if_dp83902a.c788
-rw-r--r--ecos/packages/devs/eth/phy/current/ChangeLog124
-rw-r--r--ecos/packages/devs/eth/phy/current/cdl/phy_eth_drivers.cdl198
-rw-r--r--ecos/packages/devs/eth/phy/current/doc/eth_phy.sgml172
-rw-r--r--ecos/packages/devs/eth/phy/current/include/eth_phy.h103
-rw-r--r--ecos/packages/devs/eth/phy/current/include/eth_phy_dev.h111
-rw-r--r--ecos/packages/devs/eth/phy/current/src/AM79C874.c101
-rw-r--r--ecos/packages/devs/eth/phy/current/src/DM9161A.c133
-rw-r--r--ecos/packages/devs/eth/phy/current/src/DP83847.c98
-rw-r--r--ecos/packages/devs/eth/phy/current/src/INLXT972.c96
-rw-r--r--ecos/packages/devs/eth/phy/current/src/IP101A.c117
-rw-r--r--ecos/packages/devs/eth/phy/current/src/IP101A.h92
-rw-r--r--ecos/packages/devs/eth/phy/current/src/KS8721.c114
-rw-r--r--ecos/packages/devs/eth/phy/current/src/KSZ8001.c160
-rw-r--r--ecos/packages/devs/eth/phy/current/src/KSZ8041.c188
-rw-r--r--ecos/packages/devs/eth/phy/current/src/VSC8244.c122
-rw-r--r--ecos/packages/devs/eth/phy/current/src/VSC8244.h67
-rw-r--r--ecos/packages/devs/eth/phy/current/src/VSC8641.c123
-rw-r--r--ecos/packages/devs/eth/phy/current/src/VSC8641.h86
-rw-r--r--ecos/packages/devs/eth/phy/current/src/eth_phy.c292
-rw-r--r--ecos/packages/devs/eth/phy/current/src/ics189x.c118
-rw-r--r--ecos/packages/devs/eth/powerpc/adder/current/ChangeLog38
-rw-r--r--ecos/packages/devs/eth/powerpc/adder/current/cdl/adder_eth_drivers.cdl70
-rw-r--r--ecos/packages/devs/eth/powerpc/adder/current/include/adder_eth.inl95
-rw-r--r--ecos/packages/devs/eth/powerpc/adder/current/src/adder_eth.c267
-rw-r--r--ecos/packages/devs/eth/powerpc/adderII/current/ChangeLog38
-rw-r--r--ecos/packages/devs/eth/powerpc/adderII/current/cdl/adderII_eth_drivers.cdl68
-rw-r--r--ecos/packages/devs/eth/powerpc/adderII/current/include/adderII_eth.inl77
-rw-r--r--ecos/packages/devs/eth/powerpc/csb281/current/ChangeLog38
-rw-r--r--ecos/packages/devs/eth/powerpc/csb281/current/cdl/csb281_eth_drivers.cdl199
-rw-r--r--ecos/packages/devs/eth/powerpc/csb281/current/include/devs_eth_csb281.inl159
-rw-r--r--ecos/packages/devs/eth/powerpc/ec555/current/ChangeLog39
-rw-r--r--ecos/packages/devs/eth/powerpc/ec555/current/cdl/ec555_eth_drivers.cdl145
-rw-r--r--ecos/packages/devs/eth/powerpc/ec555/current/include/devs_eth_powerpc_ec555.inl256
-rw-r--r--ecos/packages/devs/eth/powerpc/fcc/current/ChangeLog73
-rw-r--r--ecos/packages/devs/eth/powerpc/fcc/current/cdl/fcc_eth_drivers.cdl133
-rw-r--r--ecos/packages/devs/eth/powerpc/fcc/current/src/fcc.h182
-rw-r--r--ecos/packages/devs/eth/powerpc/fcc/current/src/if_fcc.c670
-rw-r--r--ecos/packages/devs/eth/powerpc/fec/current/ChangeLog212
-rw-r--r--ecos/packages/devs/eth/powerpc/fec/current/cdl/fec_eth_drivers.cdl155
-rw-r--r--ecos/packages/devs/eth/powerpc/fec/current/src/fec.h188
-rw-r--r--ecos/packages/devs/eth/powerpc/fec/current/src/if_fec.c797
-rw-r--r--ecos/packages/devs/eth/powerpc/mbx/current/ChangeLog32
-rw-r--r--ecos/packages/devs/eth/powerpc/mbx/current/cdl/mbx_eth_drivers.cdl67
-rw-r--r--ecos/packages/devs/eth/powerpc/mbx/current/include/mbx_eth.inl97
-rw-r--r--ecos/packages/devs/eth/powerpc/moab/current/ChangeLog57
-rw-r--r--ecos/packages/devs/eth/powerpc/moab/current/cdl/moab_eth_drivers.cdl126
-rw-r--r--ecos/packages/devs/eth/powerpc/moab/current/include/moab_eth.inl119
-rw-r--r--ecos/packages/devs/eth/powerpc/moab/current/include/moab_eth_dp83816.inl137
-rw-r--r--ecos/packages/devs/eth/powerpc/ppc405/current/ChangeLog47
-rw-r--r--ecos/packages/devs/eth/powerpc/ppc405/current/cdl/ppc405_eth_drivers.cdl141
-rw-r--r--ecos/packages/devs/eth/powerpc/ppc405/current/src/if_ppc405.c685
-rw-r--r--ecos/packages/devs/eth/powerpc/ppc405/current/src/ppc405_enet.h360
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc/current/ChangeLog223
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc/current/cdl/quicc_eth_drivers.cdl115
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c815
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc/current/src/quicc_eth.h190
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc2/current/ChangeLog50
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc2/current/cdl/quicc2_eth_drivers.cdl113
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc2/current/src/EnetPHY.c378
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc2/current/src/EnetPHY.h109
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc2/current/src/fec.h171
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc2/current/src/if_fec.c708
-rw-r--r--ecos/packages/devs/eth/powerpc/quicc2/current/src/types.h98
-rw-r--r--ecos/packages/devs/eth/powerpc/rattler/current/ChangeLog37
-rw-r--r--ecos/packages/devs/eth/powerpc/rattler/current/cdl/rattler_eth_drivers.cdl91
-rw-r--r--ecos/packages/devs/eth/powerpc/rattler/current/include/rattler_eth.inl331
-rw-r--r--ecos/packages/devs/eth/powerpc/ts1000/current/ChangeLog31
-rw-r--r--ecos/packages/devs/eth/powerpc/ts1000/current/cdl/ts1000_eth_drivers.cdl65
-rw-r--r--ecos/packages/devs/eth/powerpc/ts1000/current/include/ts1000_eth.inl77
-rw-r--r--ecos/packages/devs/eth/powerpc/viper/current/ChangeLog37
-rw-r--r--ecos/packages/devs/eth/powerpc/viper/current/cdl/viper_eth_drivers.cdl67
-rw-r--r--ecos/packages/devs/eth/powerpc/viper/current/include/viper_eth.inl77
-rw-r--r--ecos/packages/devs/eth/rltk/8139/current/ChangeLog84
-rw-r--r--ecos/packages/devs/eth/rltk/8139/current/cdl/rltk_8139_eth_drivers.cdl170
-rw-r--r--ecos/packages/devs/eth/rltk/8139/current/doc/README164
-rw-r--r--ecos/packages/devs/eth/rltk/8139/current/src/if_8139.c1516
-rw-r--r--ecos/packages/devs/eth/rltk/8139/current/src/if_8139.h369
-rw-r--r--ecos/packages/devs/eth/sh/dreamcast/current/ChangeLog35
-rw-r--r--ecos/packages/devs/eth/sh/dreamcast/current/cdl/sh_dreamcast_rltk8139_eth_drivers.cdl109
-rw-r--r--ecos/packages/devs/eth/sh/dreamcast/current/include/devs_eth_sh_dreamcast_rltk8139.inl79
-rw-r--r--ecos/packages/devs/eth/sh/dreamcast/current/src/if_dreamcast.c92
-rw-r--r--ecos/packages/devs/eth/sh/etherc/current/ChangeLog105
-rw-r--r--ecos/packages/devs/eth/sh/etherc/current/cdl/sh_etherc_eth_drivers.cdl104
-rw-r--r--ecos/packages/devs/eth/sh/etherc/current/src/if_etherc.c1126
-rw-r--r--ecos/packages/devs/eth/sh/etherc/current/src/phyter.inl185
-rw-r--r--ecos/packages/devs/eth/sh/etherc/current/src/sh_etherc.h343
-rw-r--r--ecos/packages/devs/eth/sh/hs7729pci/current/ChangeLog47
-rw-r--r--ecos/packages/devs/eth/sh/hs7729pci/current/cdl/sh_hs7729pci_eth_drivers.cdl129
-rw-r--r--ecos/packages/devs/eth/sh/hs7729pci/current/include/devs_eth_sh_hs7729pci.inl99
-rw-r--r--ecos/packages/devs/eth/sh/se7751/current/ChangeLog39
-rw-r--r--ecos/packages/devs/eth/sh/se7751/current/cdl/sh_se7751_eth_drivers.cdl129
-rw-r--r--ecos/packages/devs/eth/sh/se7751/current/include/devs_eth_sh_se7751.inl109
-rw-r--r--ecos/packages/devs/eth/sh/se77x9/current/ChangeLog65
-rw-r--r--ecos/packages/devs/eth/sh/se77x9/current/cdl/sh_se77x9_eth_drivers.cdl108
-rw-r--r--ecos/packages/devs/eth/sh/se77x9/current/include/devs_eth_sh_se77x9.inl142
-rw-r--r--ecos/packages/devs/eth/sh/sh4_202_md/current/ChangeLog30
-rw-r--r--ecos/packages/devs/eth/sh/sh4_202_md/current/cdl/sh4_202_md_eth_drivers.cdl116
-rw-r--r--ecos/packages/devs/eth/sh/sh4_202_md/current/include/devs_eth_sh4_202_md.inl145
-rw-r--r--ecos/packages/devs/eth/smsc/lan91cxx/current/ChangeLog226
-rw-r--r--ecos/packages/devs/eth/smsc/lan91cxx/current/cdl/smsc_lan91cxx_eth_drivers.cdl127
-rw-r--r--ecos/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c1473
-rw-r--r--ecos/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h467
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/ChangeLog128
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/cdl/syntheth.cdl146
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/doc/devs-eth-synth-ecosynth.html928
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/doc/makefile54
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/doc/overview.fig54
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/doc/overview.pngbin0 -> 905 bytes
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/doc/syntheth.sgml554
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/Makefile.am94
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/Makefile.in721
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/acinclude.m443
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/aclocal.m4992
-rwxr-xr-xecos/packages/devs/eth/synth/ecosynth/current/host/configure6403
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/configure.in94
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/ethernet.tcl1224
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/ethernet.tdf117
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/fromnet.xbm4
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/netrecord.xbm6
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/rawether.c793
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/host/tonet.xbm4
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/src/protocol.h71
-rw-r--r--ecos/packages/devs/eth/synth/ecosynth/current/src/syntheth.c457
-rw-r--r--ecos/packages/devs/eth/via/rhine/current/ChangeLog168
-rw-r--r--ecos/packages/devs/eth/via/rhine/current/cdl/via_rhine_eth_drivers.cdl95
-rw-r--r--ecos/packages/devs/eth/via/rhine/current/src/if_rhine.c1306
-rw-r--r--ecos/packages/devs/eth/via/rhine/current/src/via_rhine.h468
-rw-r--r--ecos/packages/devs/flash/amd/am29xxxxx/current/ChangeLog384
-rw-r--r--ecos/packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl429
-rw-r--r--ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl633
-rw-r--r--ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl1547
-rw-r--r--ecos/packages/devs/flash/amd/am29xxxxxv2/current/ChangeLog220
-rw-r--r--ecos/packages/devs/flash/amd/am29xxxxxv2/current/cdl/flash_am29xxxxx_v2.cdl222
-rw-r--r--ecos/packages/devs/flash/amd/am29xxxxxv2/current/doc/am29xxxxx.sgml789
-rw-r--r--ecos/packages/devs/flash/amd/am29xxxxxv2/current/include/am29xxxxx_dev.h138
-rw-r--r--ecos/packages/devs/flash/amd/am29xxxxxv2/current/src/am29xxxxx.c514
-rw-r--r--ecos/packages/devs/flash/amd/am29xxxxxv2/current/src/am29xxxxx_aux.c985
-rw-r--r--ecos/packages/devs/flash/arm/aaed2000/current/ChangeLog43
-rw-r--r--ecos/packages/devs/flash/arm/aaed2000/current/cdl/flash_arm_aaed2000.cdl68
-rw-r--r--ecos/packages/devs/flash/arm/aaed2000/current/src/aaed2000_flash.c73
-rwxr-xr-xecos/packages/devs/flash/arm/aim711/current/ChangeLog39
-rwxr-xr-xecos/packages/devs/flash/arm/aim711/current/cdl/flash_arm_aim711.cdl78
-rwxr-xr-xecos/packages/devs/flash/arm/aim711/current/src/arm_aim711_flash.c86
-rw-r--r--ecos/packages/devs/flash/arm/assabet/current/ChangeLog67
-rw-r--r--ecos/packages/devs/flash/arm/assabet/current/cdl/flash_assabet.cdl79
-rw-r--r--ecos/packages/devs/flash/arm/assabet/current/include/assabet_strataflash.inl67
-rw-r--r--ecos/packages/devs/flash/arm/at91/current/ChangeLog65
-rw-r--r--ecos/packages/devs/flash/arm/at91/current/cdl/flash_at91.cdl79
-rw-r--r--ecos/packages/devs/flash/arm/at91/current/src/at91_flash.c499
-rw-r--r--ecos/packages/devs/flash/arm/cerf/current/ChangeLog28
-rw-r--r--ecos/packages/devs/flash/arm/cerf/current/cdl/flash_cerf.cdl79
-rw-r--r--ecos/packages/devs/flash/arm/cerf/current/include/cerf_strataflash.inl69
-rw-r--r--ecos/packages/devs/flash/arm/cerfpda/current/ChangeLog28
-rw-r--r--ecos/packages/devs/flash/arm/cerfpda/current/cdl/flash_cerfpda.cdl79
-rw-r--r--ecos/packages/devs/flash/arm/cerfpda/current/include/cerfpda_strataflash.inl68
-rwxr-xr-xecos/packages/devs/flash/arm/e7t/current/ChangeLog44
-rwxr-xr-xecos/packages/devs/flash/arm/e7t/current/cdl/flash_e7t.cdl76
-rwxr-xr-xecos/packages/devs/flash/arm/e7t/current/src/arm_e7t_flash.c91
-rwxr-xr-xecos/packages/devs/flash/arm/ea2468/current/ChangeLog34
-rwxr-xr-xecos/packages/devs/flash/arm/ea2468/current/cdl/flash_ea2468.cdl73
-rwxr-xr-xecos/packages/devs/flash/arm/ea2468/current/src/flash_ea2468.c73
-rw-r--r--ecos/packages/devs/flash/arm/eb40/current/ChangeLog28
-rw-r--r--ecos/packages/devs/flash/arm/eb40/current/cdl/flash_eb40.cdl69
-rw-r--r--ecos/packages/devs/flash/arm/eb40/current/src/eb40_flash.c64
-rw-r--r--ecos/packages/devs/flash/arm/eb40a/current/ChangeLog42
-rw-r--r--ecos/packages/devs/flash/arm/eb40a/current/cdl/flash_eb40a.cdl69
-rw-r--r--ecos/packages/devs/flash/arm/eb40a/current/src/eb40a_flash.c66
-rw-r--r--ecos/packages/devs/flash/arm/eb42/current/ChangeLog39
-rw-r--r--ecos/packages/devs/flash/arm/eb42/current/cdl/flash_eb42.cdl69
-rw-r--r--ecos/packages/devs/flash/arm/eb42/current/src/eb42_flash.c65
-rw-r--r--ecos/packages/devs/flash/arm/eb55/current/ChangeLog53
-rw-r--r--ecos/packages/devs/flash/arm/eb55/current/cdl/flash_eb55.cdl74
-rw-r--r--ecos/packages/devs/flash/arm/eb55/current/src/eb55_flash.c85
-rw-r--r--ecos/packages/devs/flash/arm/ebsa285/current/ChangeLog99
-rw-r--r--ecos/packages/devs/flash/arm/ebsa285/current/cdl/flash_ebsa285.cdl67
-rw-r--r--ecos/packages/devs/flash/arm/ebsa285/current/src/ebsa285_flash.c112
-rw-r--r--ecos/packages/devs/flash/arm/ebsa285/current/src/flash.h73
-rw-r--r--ecos/packages/devs/flash/arm/ebsa285/current/src/flash_erase_block.c80
-rw-r--r--ecos/packages/devs/flash/arm/ebsa285/current/src/flash_program_buf.c89
-rw-r--r--ecos/packages/devs/flash/arm/ebsa285/current/src/flash_query.c81
-rw-r--r--ecos/packages/devs/flash/arm/edb7xxx/current/ChangeLog95
-rw-r--r--ecos/packages/devs/flash/arm/edb7xxx/current/cdl/flash_edb7xxx.cdl101
-rw-r--r--ecos/packages/devs/flash/arm/edb7xxx/current/include/edb7xxx_strataflash.inl65
-rw-r--r--ecos/packages/devs/flash/arm/edb7xxx/current/src/edb7xxx_flash.c169
-rw-r--r--ecos/packages/devs/flash/arm/edb7xxx/current/src/flash.h69
-rw-r--r--ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_erase_block.c107
-rw-r--r--ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_program_buf.c97
-rw-r--r--ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_query.c79
-rw-r--r--ecos/packages/devs/flash/arm/excalibur/current/ChangeLog39
-rw-r--r--ecos/packages/devs/flash/arm/excalibur/current/cdl/flash_excalibur.cdl68
-rw-r--r--ecos/packages/devs/flash/arm/excalibur/current/src/arm_excalibur_flash.c71
-rw-r--r--ecos/packages/devs/flash/arm/flexanet/current/ChangeLog27
-rw-r--r--ecos/packages/devs/flash/arm/flexanet/current/cdl/flash_flexanet.cdl79
-rw-r--r--ecos/packages/devs/flash/arm/flexanet/current/include/flexanet_strataflash.inl67
-rw-r--r--ecos/packages/devs/flash/arm/gps4020/current/ChangeLog28
-rw-r--r--ecos/packages/devs/flash/arm/gps4020/current/cdl/flash_gps4020.cdl68
-rw-r--r--ecos/packages/devs/flash/arm/gps4020/current/src/gps4020_flash.c66
-rw-r--r--ecos/packages/devs/flash/arm/grg/current/ChangeLog35
-rw-r--r--ecos/packages/devs/flash/arm/grg/current/cdl/flash_grg.cdl77
-rw-r--r--ecos/packages/devs/flash/arm/grg/current/include/grg_strataflash.inl75
-rw-r--r--ecos/packages/devs/flash/arm/innovator/current/ChangeLog34
-rw-r--r--ecos/packages/devs/flash/arm/innovator/current/cdl/flash_innovator.cdl68
-rw-r--r--ecos/packages/devs/flash/arm/innovator/current/src/arm_innovator_flash.c71
-rw-r--r--ecos/packages/devs/flash/arm/integrator/current/ChangeLog50
-rw-r--r--ecos/packages/devs/flash/arm/integrator/current/cdl/flash_integrator.cdl68
-rw-r--r--ecos/packages/devs/flash/arm/integrator/current/src/arm_integrator_flash.c105
-rw-r--r--ecos/packages/devs/flash/arm/ipaq/current/ChangeLog35
-rw-r--r--ecos/packages/devs/flash/arm/ipaq/current/cdl/flash_ipaq.cdl84
-rw-r--r--ecos/packages/devs/flash/arm/ipaq/current/include/ipaq_strataflash.inl67
-rw-r--r--ecos/packages/devs/flash/arm/ipaq/current/src/ipaq_flash.c64
-rw-r--r--ecos/packages/devs/flash/arm/iq80310/current/ChangeLog98
-rw-r--r--ecos/packages/devs/flash/arm/iq80310/current/cdl/flash_iq80310.cdl74
-rw-r--r--ecos/packages/devs/flash/arm/iq80310/current/src/flash.h105
-rw-r--r--ecos/packages/devs/flash/arm/iq80310/current/src/flash_erase_block.c98
-rw-r--r--ecos/packages/devs/flash/arm/iq80310/current/src/flash_lock_block.c82
-rw-r--r--ecos/packages/devs/flash/arm/iq80310/current/src/flash_program_buf.c143
-rw-r--r--ecos/packages/devs/flash/arm/iq80310/current/src/flash_query.c79
-rw-r--r--ecos/packages/devs/flash/arm/iq80310/current/src/flash_unlock_block.c123
-rw-r--r--ecos/packages/devs/flash/arm/iq80310/current/src/iq80310_flash.c118
-rw-r--r--ecos/packages/devs/flash/arm/iq80321/current/ChangeLog37
-rw-r--r--ecos/packages/devs/flash/arm/iq80321/current/cdl/flash_iq80321.cdl79
-rw-r--r--ecos/packages/devs/flash/arm/iq80321/current/include/iq80321_strataflash.inl66
-rw-r--r--ecos/packages/devs/flash/arm/ixdp425/current/ChangeLog31
-rwxr-xr-xecos/packages/devs/flash/arm/ixdp425/current/cdl/flash_ixdp425.cdl77
-rw-r--r--ecos/packages/devs/flash/arm/ixdp425/current/include/ixdp425_strataflash.inl75
-rw-r--r--ecos/packages/devs/flash/arm/jtst/current/ChangeLog29
-rw-r--r--ecos/packages/devs/flash/arm/jtst/current/cdl/flash_jtst.cdl71
-rw-r--r--ecos/packages/devs/flash/arm/jtst/current/src/jtst_flash.c65
-rw-r--r--ecos/packages/devs/flash/arm/lpc2xxx/current/ChangeLog36
-rw-r--r--ecos/packages/devs/flash/arm/lpc2xxx/current/cdl/flash_arm_lpc2xxx.cdl86
-rw-r--r--ecos/packages/devs/flash/arm/lpc2xxx/current/include/flash_arm_lpc2xxx.h83
-rw-r--r--ecos/packages/devs/flash/arm/lpc2xxx/current/src/flash_arm_lpc2xxx.c218
-rw-r--r--ecos/packages/devs/flash/arm/mpc50/current/ChangeLog28
-rw-r--r--ecos/packages/devs/flash/arm/mpc50/current/cdl/flash_mpc50.cdl70
-rw-r--r--ecos/packages/devs/flash/arm/mpc50/current/include/mpc50_strataflash.inl62
-rw-r--r--ecos/packages/devs/flash/arm/nano/current/ChangeLog32
-rw-r--r--ecos/packages/devs/flash/arm/nano/current/cdl/flash_nano.cdl77
-rw-r--r--ecos/packages/devs/flash/arm/nano/current/include/nano_strataflash.inl70
-rw-r--r--ecos/packages/devs/flash/arm/olpcx2294/current/ChangeLog34
-rw-r--r--ecos/packages/devs/flash/arm/olpcx2294/current/cdl/flash_olpcx2294.cdl82
-rw-r--r--ecos/packages/devs/flash/arm/olpcx2294/current/src/arm_olpcx2294_flash.c67
-rw-r--r--ecos/packages/devs/flash/arm/olpcx2294v2/current/ChangeLog8
-rw-r--r--ecos/packages/devs/flash/arm/olpcx2294v2/current/cdl/flash_olpcx2294.cdl73
-rw-r--r--ecos/packages/devs/flash/arm/olpcx2294v2/current/src/arm_olpcx2294_flash.c122
-rw-r--r--ecos/packages/devs/flash/arm/phycore/current/ChangeLog29
-rw-r--r--ecos/packages/devs/flash/arm/phycore/current/cdl/flash_phycore.cdl71
-rw-r--r--ecos/packages/devs/flash/arm/phycore/current/src/phycore_flash.c64
-rwxr-xr-xecos/packages/devs/flash/arm/phycore229x/current/ChangeLog29
-rwxr-xr-xecos/packages/devs/flash/arm/phycore229x/current/cdl/flash_phycore229x.cdl102
-rwxr-xr-xecos/packages/devs/flash/arm/phycore229x/current/src/flash_phycore229x.c67
-rw-r--r--ecos/packages/devs/flash/arm/picasso/current/ChangeLog29
-rw-r--r--ecos/packages/devs/flash/arm/picasso/current/cdl/flash_picasso.cdl79
-rw-r--r--ecos/packages/devs/flash/arm/picasso/current/include/picasso_strataflash.inl66
-rw-r--r--ecos/packages/devs/flash/arm/pid/current/ChangeLog32
-rw-r--r--ecos/packages/devs/flash/arm/pid/current/cdl/flash_arm_pid.cdl68
-rw-r--r--ecos/packages/devs/flash/arm/pid/current/src/arm_pid_flash.c64
-rw-r--r--ecos/packages/devs/flash/arm/prpmc1100/current/ChangeLog24
-rwxr-xr-xecos/packages/devs/flash/arm/prpmc1100/current/cdl/flash_prpmc1100.cdl77
-rw-r--r--ecos/packages/devs/flash/arm/prpmc1100/current/include/prpmc1100_strataflash.inl66
-rw-r--r--ecos/packages/devs/flash/arm/sa1100mm/current/ChangeLog78
-rw-r--r--ecos/packages/devs/flash/arm/sa1100mm/current/cdl/flash_sa1100mm.cdl67
-rw-r--r--ecos/packages/devs/flash/arm/sa1100mm/current/src/flash.h74
-rw-r--r--ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_erase_block.c81
-rw-r--r--ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_program_buf.c89
-rw-r--r--ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_query.c81
-rw-r--r--ecos/packages/devs/flash/arm/sa1100mm/current/src/sa1100mm_flash.c112
-rw-r--r--ecos/packages/devs/flash/arm/smdk2410/current/ChangeLog12
-rw-r--r--ecos/packages/devs/flash/arm/smdk2410/current/cdl/flash_smdk2410.cdl72
-rw-r--r--ecos/packages/devs/flash/arm/smdk2410/current/src/smdk2410_flash.c69
-rw-r--r--ecos/packages/devs/flash/arm/uE250/current/ChangeLog34
-rw-r--r--ecos/packages/devs/flash/arm/uE250/current/cdl/flash_uE250.cdl79
-rw-r--r--ecos/packages/devs/flash/arm/uE250/current/include/uE250_strataflash.inl66
-rw-r--r--ecos/packages/devs/flash/arm/xsengine/current/ChangeLog36
-rw-r--r--ecos/packages/devs/flash/arm/xsengine/current/cdl/flash_xsengine.cdl70
-rw-r--r--ecos/packages/devs/flash/arm/xsengine/current/src/xsengine_flash.c68
-rw-r--r--ecos/packages/devs/flash/atmel/at29cxxxx/current/ChangeLog96
-rw-r--r--ecos/packages/devs/flash/atmel/at29cxxxx/current/cdl/flash_atmel_at29cxxxx.cdl62
-rw-r--r--ecos/packages/devs/flash/atmel/at29cxxxx/current/include/flash_at29cxxxx.inl351
-rw-r--r--ecos/packages/devs/flash/atmel/at49xxxx/current/ChangeLog88
-rw-r--r--ecos/packages/devs/flash/atmel/at49xxxx/current/cdl/flash_atmel_at49xxxx.cdl76
-rw-r--r--ecos/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl420
-rw-r--r--ecos/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx_parts.inl247
-rw-r--r--ecos/packages/devs/flash/atmel/dataflash/current/ChangeLog94
-rw-r--r--ecos/packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl71
-rw-r--r--ecos/packages/devs/flash/atmel/dataflash/current/include/dataflash.h248
-rw-r--r--ecos/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c922
-rw-r--r--ecos/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c223
-rw-r--r--ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/ChangeLog31
-rw-r--r--ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/cdl/flash_a2f200_eval.cdl62
-rw-r--r--ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/src/flash_a2f200_eval.c78
-rw-r--r--ecos/packages/devs/flash/cortexm/stm32/current/ChangeLog78
-rw-r--r--ecos/packages/devs/flash/cortexm/stm32/current/cdl/flash_stm32.cdl132
-rw-r--r--ecos/packages/devs/flash/cortexm/stm32/current/include/stm32_flash.h81
-rw-r--r--ecos/packages/devs/flash/cortexm/stm32/current/src/stm32_flash.c738
-rw-r--r--ecos/packages/devs/flash/fr30/skmb91302/current/ChangeLog39
-rw-r--r--ecos/packages/devs/flash/fr30/skmb91302/current/cdl/flash_skmb91302.cdl70
-rw-r--r--ecos/packages/devs/flash/fr30/skmb91302/current/src/skmb91302_flash.c71
-rw-r--r--ecos/packages/devs/flash/freescale/dspi/sst25xx/current/ChangeLog35
-rw-r--r--ecos/packages/devs/flash/freescale/dspi/sst25xx/current/cdl/flash_sst25xx_freescale_dspi.cdl100
-rw-r--r--ecos/packages/devs/flash/freescale/dspi/sst25xx/current/src/sst25xx_freescale_dspi.c99
-rw-r--r--ecos/packages/devs/flash/freescale/kinetis/current/ChangeLog30
-rw-r--r--ecos/packages/devs/flash/freescale/kinetis/current/cdl/kinetis_flash.cdl104
-rw-r--r--ecos/packages/devs/flash/freescale/kinetis/current/include/kinetis_flash.h63
-rw-r--r--ecos/packages/devs/flash/freescale/kinetis/current/src/kinetis_flash.c395
-rw-r--r--ecos/packages/devs/flash/frv/frv400/current/ChangeLog34
-rw-r--r--ecos/packages/devs/flash/frv/frv400/current/cdl/flash_frv_frv400.cdl68
-rw-r--r--ecos/packages/devs/flash/frv/frv400/current/src/frv400_flash.c73
-rw-r--r--ecos/packages/devs/flash/frv/pdk403/current/ChangeLog33
-rw-r--r--ecos/packages/devs/flash/frv/pdk403/current/cdl/flash_frv_pdk403.cdl68
-rw-r--r--ecos/packages/devs/flash/frv/pdk403/current/src/pdk403_flash.c73
-rw-r--r--ecos/packages/devs/flash/intel/28fxxx/current/ChangeLog141
-rw-r--r--ecos/packages/devs/flash/intel/28fxxx/current/cdl/flash_intel_28fxxx.cdl232
-rw-r--r--ecos/packages/devs/flash/intel/28fxxx/current/include/flash_28fxxx.inl768
-rw-r--r--ecos/packages/devs/flash/intel/28fxxx/current/include/flash_28fxxx_parts.inl359
-rw-r--r--ecos/packages/devs/flash/intel/strata/current/ChangeLog320
-rw-r--r--ecos/packages/devs/flash/intel/strata/current/cdl/flash_strata.cdl92
-rw-r--r--ecos/packages/devs/flash/intel/strata/current/src/flash_erase_block.c115
-rw-r--r--ecos/packages/devs/flash/intel/strata/current/src/flash_lock_block.c83
-rw-r--r--ecos/packages/devs/flash/intel/strata/current/src/flash_program_buf.c162
-rw-r--r--ecos/packages/devs/flash/intel/strata/current/src/flash_query.c107
-rw-r--r--ecos/packages/devs/flash/intel/strata/current/src/flash_unlock_block.c141
-rw-r--r--ecos/packages/devs/flash/intel/strata/current/src/strata.c185
-rw-r--r--ecos/packages/devs/flash/intel/strata/current/src/strata.h177
-rw-r--r--ecos/packages/devs/flash/intel/stratav2/current/ChangeLog507
-rw-r--r--ecos/packages/devs/flash/intel/stratav2/current/cdl/flash_strata_v2.cdl208
-rw-r--r--ecos/packages/devs/flash/intel/stratav2/current/doc/strata.sgml914
-rw-r--r--ecos/packages/devs/flash/intel/stratav2/current/include/strata_dev.h164
-rw-r--r--ecos/packages/devs/flash/intel/stratav2/current/src/strata.c476
-rw-r--r--ecos/packages/devs/flash/intel/stratav2/current/src/strata_aux.c873
-rw-r--r--ecos/packages/devs/flash/mips/atlas/current/ChangeLog56
-rw-r--r--ecos/packages/devs/flash/mips/atlas/current/cdl/flash_atlas.cdl74
-rw-r--r--ecos/packages/devs/flash/mips/atlas/current/src/atlas_flash.c131
-rw-r--r--ecos/packages/devs/flash/mips/atlas/current/src/flash.h104
-rw-r--r--ecos/packages/devs/flash/mips/atlas/current/src/flash_erase_block.c100
-rw-r--r--ecos/packages/devs/flash/mips/atlas/current/src/flash_lock_block.c87
-rw-r--r--ecos/packages/devs/flash/mips/atlas/current/src/flash_program_buf.c103
-rw-r--r--ecos/packages/devs/flash/mips/atlas/current/src/flash_query.c81
-rw-r--r--ecos/packages/devs/flash/mips/atlas/current/src/flash_unlock_block.c128
-rw-r--r--ecos/packages/devs/flash/mips/idt79s334a/current/ChangeLog34
-rwxr-xr-xecos/packages/devs/flash/mips/idt79s334a/current/cdl/flash_mips_refidt334.cdl69
-rwxr-xr-xecos/packages/devs/flash/mips/idt79s334a/current/src/mips_idt334a_flash.c68
-rw-r--r--ecos/packages/devs/flash/mips/malta/current/ChangeLog49
-rw-r--r--ecos/packages/devs/flash/mips/malta/current/cdl/flash_malta.cdl68
-rw-r--r--ecos/packages/devs/flash/mips/malta/current/src/mips_malta_flash.c69
-rw-r--r--ecos/packages/devs/flash/mips/ocelot/current/ChangeLog47
-rw-r--r--ecos/packages/devs/flash/mips/ocelot/current/cdl/flash_mips_ocelot.cdl67
-rw-r--r--ecos/packages/devs/flash/mips/ocelot/current/src/mips_ocelot_flash.c68
-rw-r--r--ecos/packages/devs/flash/mips/vrc437x/current/ChangeLog35
-rw-r--r--ecos/packages/devs/flash/mips/vrc437x/current/cdl/flash_mips_vrc437x.cdl67
-rw-r--r--ecos/packages/devs/flash/mips/vrc437x/current/src/mips_vrc437x_flash.c68
-rw-r--r--ecos/packages/devs/flash/mn10300/asb2303/current/ChangeLog38
-rw-r--r--ecos/packages/devs/flash/mn10300/asb2303/current/cdl/flash_asb2303.cdl79
-rw-r--r--ecos/packages/devs/flash/mn10300/asb2303/current/src/mn10300_asb2303_flash.c87
-rw-r--r--ecos/packages/devs/flash/mn10300/asb2305/current/ChangeLog43
-rw-r--r--ecos/packages/devs/flash/mn10300/asb2305/current/cdl/flash_asb2305.cdl79
-rw-r--r--ecos/packages/devs/flash/mn10300/asb2305/current/src/mn10300_asb2305_flash.c87
-rw-r--r--ecos/packages/devs/flash/mn10300/stb/current/ChangeLog43
-rw-r--r--ecos/packages/devs/flash/mn10300/stb/current/cdl/flash_stb.cdl69
-rw-r--r--ecos/packages/devs/flash/mn10300/stb/current/src/mn10300_stb_flash.c71
-rw-r--r--ecos/packages/devs/flash/openrisc/orp/current/ChangeLog35
-rw-r--r--ecos/packages/devs/flash/openrisc/orp/current/cdl/flash_openrisc_orp.cdl69
-rw-r--r--ecos/packages/devs/flash/openrisc/orp/current/src/openrisc_orp_flash.c69
-rw-r--r--ecos/packages/devs/flash/powerpc/adder/current/ChangeLog35
-rw-r--r--ecos/packages/devs/flash/powerpc/adder/current/cdl/flash_adder.cdl70
-rw-r--r--ecos/packages/devs/flash/powerpc/adder/current/src/adder_flash.c72
-rw-r--r--ecos/packages/devs/flash/powerpc/cme555/current/ChangeLog33
-rw-r--r--ecos/packages/devs/flash/powerpc/cme555/current/cdl/flash_cme555.cdl68
-rw-r--r--ecos/packages/devs/flash/powerpc/cme555/current/src/powerpc_cme555_flash.c68
-rw-r--r--ecos/packages/devs/flash/powerpc/csb281/current/ChangeLog29
-rw-r--r--ecos/packages/devs/flash/powerpc/csb281/current/cdl/flash_csb281.cdl79
-rw-r--r--ecos/packages/devs/flash/powerpc/csb281/current/include/csb281_strataflash.inl66
-rw-r--r--ecos/packages/devs/flash/powerpc/ec555/current/ChangeLog38
-rw-r--r--ecos/packages/devs/flash/powerpc/ec555/current/cdl/flash_ec555.cdl68
-rw-r--r--ecos/packages/devs/flash/powerpc/ec555/current/src/powerpc_ec555_flash.c68
-rw-r--r--ecos/packages/devs/flash/powerpc/mbx/current/ChangeLog63
-rw-r--r--ecos/packages/devs/flash/powerpc/mbx/current/cdl/flash_mbx.cdl68
-rw-r--r--ecos/packages/devs/flash/powerpc/mbx/current/src/powerpc_mbx_flash.c68
-rw-r--r--ecos/packages/devs/flash/powerpc/moab/current/ChangeLog23
-rw-r--r--ecos/packages/devs/flash/powerpc/moab/current/cdl/flash_moab.cdl99
-rw-r--r--ecos/packages/devs/flash/powerpc/moab/current/src/moab_flash.c65
-rw-r--r--ecos/packages/devs/flash/powerpc/moab/current/src/moab_nand_flash.c146
-rw-r--r--ecos/packages/devs/flash/powerpc/pati/current/ChangeLog35
-rw-r--r--ecos/packages/devs/flash/powerpc/pati/current/cdl/flash_pati.cdl68
-rw-r--r--ecos/packages/devs/flash/powerpc/pati/current/src/powerpc_pati_flash.c94
-rw-r--r--ecos/packages/devs/flash/powerpc/rattler/current/ChangeLog35
-rw-r--r--ecos/packages/devs/flash/powerpc/rattler/current/cdl/flash_rattler.cdl71
-rw-r--r--ecos/packages/devs/flash/powerpc/rattler/current/src/rattler_flash.c72
-rw-r--r--ecos/packages/devs/flash/powerpc/ts1000/current/ChangeLog42
-rw-r--r--ecos/packages/devs/flash/powerpc/ts1000/current/cdl/flash_ts1000.cdl70
-rw-r--r--ecos/packages/devs/flash/powerpc/ts1000/current/src/ts1000_flash.c71
-rw-r--r--ecos/packages/devs/flash/powerpc/ts6/current/ChangeLog36
-rw-r--r--ecos/packages/devs/flash/powerpc/ts6/current/cdl/flash_ts6.cdl68
-rw-r--r--ecos/packages/devs/flash/powerpc/ts6/current/src/powerpc_ts6_flash.c69
-rw-r--r--ecos/packages/devs/flash/powerpc/vads/current/ChangeLog40
-rw-r--r--ecos/packages/devs/flash/powerpc/vads/current/cdl/flash_vads.cdl67
-rw-r--r--ecos/packages/devs/flash/powerpc/vads/current/src/powerpc_vads_flash.c75
-rw-r--r--ecos/packages/devs/flash/powerpc/viper/current/ChangeLog72
-rw-r--r--ecos/packages/devs/flash/powerpc/viper/current/cdl/flash_viper.cdl72
-rw-r--r--ecos/packages/devs/flash/powerpc/viper/current/src/viper_flash.c78
-rw-r--r--ecos/packages/devs/flash/sh/cq7750/current/ChangeLog27
-rw-r--r--ecos/packages/devs/flash/sh/cq7750/current/cdl/flash_cq7750.cdl71
-rw-r--r--ecos/packages/devs/flash/sh/cq7750/current/src/cq7750_flash.c65
-rw-r--r--ecos/packages/devs/flash/sh/edk7708/current/ChangeLog27
-rw-r--r--ecos/packages/devs/flash/sh/edk7708/current/cdl/flash_sh_edk7708.cdl68
-rw-r--r--ecos/packages/devs/flash/sh/edk7708/current/src/sh_edk7708_flash.c64
-rw-r--r--ecos/packages/devs/flash/sh/hs7729pci/current/ChangeLog45
-rw-r--r--ecos/packages/devs/flash/sh/hs7729pci/current/cdl/flash_sh_hs7729pci.cdl68
-rw-r--r--ecos/packages/devs/flash/sh/hs7729pci/current/src/sh_hs7729pci_flash.c101
-rw-r--r--ecos/packages/devs/flash/sh/microdev/current/ChangeLog31
-rw-r--r--ecos/packages/devs/flash/sh/microdev/current/cdl/flash_microdev.cdl79
-rw-r--r--ecos/packages/devs/flash/sh/microdev/current/include/microdev_strataflash.inl64
-rw-r--r--ecos/packages/devs/flash/sh/se7751/current/ChangeLog33
-rw-r--r--ecos/packages/devs/flash/sh/se7751/current/cdl/flash_sh_se7751.cdl68
-rw-r--r--ecos/packages/devs/flash/sh/se7751/current/src/sh_se7751_flash.c101
-rw-r--r--ecos/packages/devs/flash/sh/se77x9/current/ChangeLog33
-rw-r--r--ecos/packages/devs/flash/sh/se77x9/current/cdl/flash_sh_se77x9.cdl68
-rw-r--r--ecos/packages/devs/flash/sh/se77x9/current/src/sh_se77x9_flash.c101
-rw-r--r--ecos/packages/devs/flash/spi/at25dfxxx/current/ChangeLog37
-rw-r--r--ecos/packages/devs/flash/spi/at25dfxxx/current/cdl/flash_at25dfxxx.cdl133
-rw-r--r--ecos/packages/devs/flash/spi/at25dfxxx/current/include/at25dfxxx.h78
-rw-r--r--ecos/packages/devs/flash/spi/at25dfxxx/current/src/at25dfxxx.c648
-rw-r--r--ecos/packages/devs/flash/spi/at25dfxxx/current/tests/at25dfxxx_test.c398
-rw-r--r--ecos/packages/devs/flash/spi/m25pxx/current/ChangeLog49
-rw-r--r--ecos/packages/devs/flash/spi/m25pxx/current/cdl/flash_m25pxx.cdl77
-rw-r--r--ecos/packages/devs/flash/spi/m25pxx/current/include/m25pxx.h78
-rw-r--r--ecos/packages/devs/flash/spi/m25pxx/current/src/m25pxx.c473
-rw-r--r--ecos/packages/devs/flash/spi/m25pxx/current/test/m25pxx_test.c396
-rw-r--r--ecos/packages/devs/flash/spi/sst25xx/current/ChangeLog38
-rw-r--r--ecos/packages/devs/flash/spi/sst25xx/current/cdl/flash_sst25xx.cdl145
-rw-r--r--ecos/packages/devs/flash/spi/sst25xx/current/include/sst25xx.h83
-rw-r--r--ecos/packages/devs/flash/spi/sst25xx/current/src/sst25xx.c709
-rw-r--r--ecos/packages/devs/flash/spi/sst25xx/current/tests/flash_sst25xx_test.c430
-rw-r--r--ecos/packages/devs/flash/sst/39vf400/current/ChangeLog34
-rwxr-xr-xecos/packages/devs/flash/sst/39vf400/current/cdl/flash_sst_39vf400.cdl60
-rwxr-xr-xecos/packages/devs/flash/sst/39vf400/current/include/flash_sst_39vf400.inl388
-rwxr-xr-xecos/packages/devs/flash/sst/39vfxxx/current/ChangeLog75
-rwxr-xr-xecos/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl62
-rwxr-xr-xecos/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl393
-rw-r--r--ecos/packages/devs/flash/synth/current/ChangeLog122
-rw-r--r--ecos/packages/devs/flash/synth/current/cdl/flash_synth.cdl130
-rw-r--r--ecos/packages/devs/flash/synth/current/src/flash_erase_block.c94
-rw-r--r--ecos/packages/devs/flash/synth/current/src/flash_program_buf.c93
-rw-r--r--ecos/packages/devs/flash/synth/current/src/flash_query.c61
-rw-r--r--ecos/packages/devs/flash/synth/current/src/synth.c157
-rw-r--r--ecos/packages/devs/flash/synth/current/src/synth.h63
-rw-r--r--ecos/packages/devs/flash/synth/current/tests/flash1.c190
-rw-r--r--ecos/packages/devs/flash/synth/current/tests/flash2.c209
-rw-r--r--ecos/packages/devs/flash/synthv2/current/ChangeLog113
-rw-r--r--ecos/packages/devs/flash/synthv2/current/cdl/flash_synth.cdl144
-rw-r--r--ecos/packages/devs/flash/synthv2/current/include/synth.h77
-rw-r--r--ecos/packages/devs/flash/synthv2/current/src/synth.c275
-rw-r--r--ecos/packages/devs/flash/synthv2/current/tests/flash1.c194
-rw-r--r--ecos/packages/devs/flash/synthv2/current/tests/flash2.c215
-rw-r--r--ecos/packages/devs/flash/synthv2/current/tests/flash3.c248
-rw-r--r--ecos/packages/devs/flash/toshiba/tc58xxx/current/ChangeLog53
-rw-r--r--ecos/packages/devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl68
-rw-r--r--ecos/packages/devs/flash/toshiba/tc58xxx/current/include/flash_tc58xxx.inl688
-rw-r--r--ecos/packages/devs/flash/toshiba/tc58xxx/current/include/flash_tc58xxx_parts.inl86
-rw-r--r--ecos/packages/devs/framebuf/synth/current/ChangeLog49
-rw-r--r--ecos/packages/devs/framebuf/synth/current/cdl/framebuf_synth.cdl259
-rw-r--r--ecos/packages/devs/framebuf/synth/current/doc/synth_framebuf.sgml237
-rw-r--r--ecos/packages/devs/framebuf/synth/current/doc/synthfb.pngbin0 -> 9694 bytes
-rw-r--r--ecos/packages/devs/framebuf/synth/current/host/Makefile.am86
-rw-r--r--ecos/packages/devs/framebuf/synth/current/host/Makefile.in720
-rw-r--r--ecos/packages/devs/framebuf/synth/current/host/acinclude.m443
-rw-r--r--ecos/packages/devs/framebuf/synth/current/host/aclocal.m4992
-rwxr-xr-xecos/packages/devs/framebuf/synth/current/host/configure5580
-rw-r--r--ecos/packages/devs/framebuf/synth/current/host/configure.in94
-rw-r--r--ecos/packages/devs/framebuf/synth/current/host/framebuf.c1487
-rw-r--r--ecos/packages/devs/framebuf/synth/current/host/framebuf.tcl375
-rw-r--r--ecos/packages/devs/framebuf/synth/current/host/framebuf.tdf37
-rw-r--r--ecos/packages/devs/framebuf/synth/current/host/framebuf_icon.xbm10
-rw-r--r--ecos/packages/devs/framebuf/synth/current/host/framebuf_iconmask.xbm10
-rw-r--r--ecos/packages/devs/framebuf/synth/current/misc/example.c377
-rw-r--r--ecos/packages/devs/framebuf/synth/current/misc/example.ecm85
-rw-r--r--ecos/packages/devs/framebuf/synth/current/misc/example.tdf42
-rw-r--r--ecos/packages/devs/framebuf/synth/current/src/gen_synthfb.tcl349
-rw-r--r--ecos/packages/devs/framebuf/synth/current/src/protocol.h126
-rw-r--r--ecos/packages/devs/framebuf/synth/current/src/synthfb.c682
-rw-r--r--ecos/packages/devs/framebuf/synth/current/src/synthfb_init.cxx73
-rw-r--r--ecos/packages/devs/i2c/arm/lpc2xxx/current/ChangeLog40
-rw-r--r--ecos/packages/devs/i2c/arm/lpc2xxx/current/cdl/i2c_lpc2xxx.cdl96
-rw-r--r--ecos/packages/devs/i2c/arm/lpc2xxx/current/include/i2c_lpc2xxx.h143
-rw-r--r--ecos/packages/devs/i2c/arm/lpc2xxx/current/src/i2c_lpc2xxx.c491
-rw-r--r--ecos/packages/devs/i2c/cortexm/a2fxxx/current/ChangeLog31
-rw-r--r--ecos/packages/devs/i2c/cortexm/a2fxxx/current/cdl/i2c_a2fxxx.cdl113
-rw-r--r--ecos/packages/devs/i2c/cortexm/a2fxxx/current/include/i2c_a2fxxx.h128
-rw-r--r--ecos/packages/devs/i2c/cortexm/a2fxxx/current/src/i2c_a2fxxx.c450
-rw-r--r--ecos/packages/devs/i2c/cortexm/lm3s/current/ChangeLog30
-rw-r--r--ecos/packages/devs/i2c/cortexm/lm3s/current/cdl/i2c_lm3s.cdl113
-rw-r--r--ecos/packages/devs/i2c/cortexm/lm3s/current/include/i2c_lm3s.h124
-rw-r--r--ecos/packages/devs/i2c/cortexm/lm3s/current/src/i2c_lm3s.c389
-rw-r--r--ecos/packages/devs/i2c/freescale/i2c/current/ChangeLog39
-rw-r--r--ecos/packages/devs/i2c/freescale/i2c/current/cdl/i2c_freescale.cdl183
-rw-r--r--ecos/packages/devs/i2c/freescale/i2c/current/include/i2c_freescale.h254
-rw-r--r--ecos/packages/devs/i2c/freescale/i2c/current/include/i2c_freescale_buses.inl108
-rw-r--r--ecos/packages/devs/i2c/freescale/i2c/current/src/i2c_freescale.c839
-rw-r--r--ecos/packages/devs/i2c/m68k/mcf52xx/current/ChangeLog45
-rw-r--r--ecos/packages/devs/i2c/m68k/mcf52xx/current/cdl/i2c_mcf52xx.cdl111
-rw-r--r--ecos/packages/devs/i2c/m68k/mcf52xx/current/doc/mcf52xx_i2c.sgml277
-rw-r--r--ecos/packages/devs/i2c/m68k/mcf52xx/current/include/i2c_mcf52xx.h119
-rw-r--r--ecos/packages/devs/i2c/m68k/mcf52xx/current/src/i2c_mcf52xx.c452
-rw-r--r--ecos/packages/devs/kbd/arm/aaed2000/current/ChangeLog28
-rw-r--r--ecos/packages/devs/kbd/arm/aaed2000/current/cdl/kbd_aaed2000.cdl99
-rw-r--r--ecos/packages/devs/kbd/arm/aaed2000/current/src/aaed2000_kbd.c245
-rw-r--r--ecos/packages/devs/kbd/arm/ipaq/current/ChangeLog36
-rw-r--r--ecos/packages/devs/kbd/arm/ipaq/current/cdl/kbd_ipaq.cdl99
-rw-r--r--ecos/packages/devs/kbd/arm/ipaq/current/src/ipaq_kbd.c224
-rw-r--r--ecos/packages/devs/pcmcia/arm/assabet/current/ChangeLog62
-rw-r--r--ecos/packages/devs/pcmcia/arm/assabet/current/cdl/pcmcia_assabet.cdl65
-rw-r--r--ecos/packages/devs/pcmcia/arm/assabet/current/src/assabet_pcmcia.c271
-rw-r--r--ecos/packages/devs/pcmcia/arm/cerf/current/ChangeLog28
-rw-r--r--ecos/packages/devs/pcmcia/arm/cerf/current/cdl/pcmcia_cerf.cdl65
-rw-r--r--ecos/packages/devs/pcmcia/arm/cerf/current/src/cerf_pcmcia.c271
-rw-r--r--ecos/packages/devs/pcmcia/arm/cerfpda/current/ChangeLog28
-rw-r--r--ecos/packages/devs/pcmcia/arm/cerfpda/current/cdl/pcmcia_cerfpda.cdl65
-rw-r--r--ecos/packages/devs/pcmcia/arm/cerfpda/current/src/cerfpda_pcmcia.c271
-rw-r--r--ecos/packages/devs/pcmcia/arm/ipaq/current/ChangeLog52
-rw-r--r--ecos/packages/devs/pcmcia/arm/ipaq/current/cdl/pcmcia_ipaq.cdl65
-rw-r--r--ecos/packages/devs/pcmcia/arm/ipaq/current/src/ipaq_pcmcia.c269
-rw-r--r--ecos/packages/devs/serial/arm/aaed2000/current/ChangeLog41
-rw-r--r--ecos/packages/devs/serial/arm/aaed2000/current/cdl/ser_arm_aaed2000.cdl159
-rw-r--r--ecos/packages/devs/serial/arm/aaed2000/current/src/aaed2000_serial.c338
-rw-r--r--ecos/packages/devs/serial/arm/aaed2000/current/src/aaed2000_serial.h105
-rw-r--r--ecos/packages/devs/serial/arm/aeb/current/ChangeLog1190
-rw-r--r--ecos/packages/devs/serial/arm/aeb/current/cdl/ser_arm_aeb.cdl210
-rw-r--r--ecos/packages/devs/serial/arm/aeb/current/src/aeb_serial.c344
-rw-r--r--ecos/packages/devs/serial/arm/aeb/current/src/aeb_serial.h162
-rwxr-xr-xecos/packages/devs/serial/arm/aim711/current/ChangeLog36
-rwxr-xr-xecos/packages/devs/serial/arm/aim711/current/cdl/ser_arm_aim711.cdl297
-rwxr-xr-xecos/packages/devs/serial/arm/aim711/current/include/ser_arm_aim711_16x5x.inl124
-rwxr-xr-xecos/packages/devs/serial/arm/aim711/current/include/ser_arm_aim711_s3c4510.inl140
-rw-r--r--ecos/packages/devs/serial/arm/at91/current/ChangeLog102
-rw-r--r--ecos/packages/devs/serial/arm/at91/current/cdl/ser_arm_at91.cdl292
-rw-r--r--ecos/packages/devs/serial/arm/at91/current/src/at91_serial.c650
-rw-r--r--ecos/packages/devs/serial/arm/at91/current/src/at91_serial.h108
-rw-r--r--ecos/packages/devs/serial/arm/cerfpda/current/ChangeLog32
-rw-r--r--ecos/packages/devs/serial/arm/cerfpda/current/cdl/ser_arm_cerfpda.cdl130
-rw-r--r--ecos/packages/devs/serial/arm/cerfpda/current/include/arm_sa1110_cerfpda_ser.inl122
-rw-r--r--ecos/packages/devs/serial/arm/cma230/current/ChangeLog1187
-rw-r--r--ecos/packages/devs/serial/arm/cma230/current/cdl/ser_arm_cma230.cdl207
-rw-r--r--ecos/packages/devs/serial/arm/cma230/current/src/cma230_serial.c344
-rw-r--r--ecos/packages/devs/serial/arm/cma230/current/src/cma230_serial.h161
-rw-r--r--ecos/packages/devs/serial/arm/e7t/current/ChangeLog38
-rw-r--r--ecos/packages/devs/serial/arm/e7t/current/cdl/ser_arm_e7t.cdl209
-rw-r--r--ecos/packages/devs/serial/arm/e7t/current/src/e7t_serial.c376
-rw-r--r--ecos/packages/devs/serial/arm/e7t/current/src/e7t_serial.h196
-rw-r--r--ecos/packages/devs/serial/arm/ebsa285/current/ChangeLog1198
-rw-r--r--ecos/packages/devs/serial/arm/ebsa285/current/cdl/ser_arm_ebsa285.cdl163
-rw-r--r--ecos/packages/devs/serial/arm/ebsa285/current/src/ebsa285_serial.c453
-rw-r--r--ecos/packages/devs/serial/arm/edb7xxx/current/ChangeLog1189
-rw-r--r--ecos/packages/devs/serial/arm/edb7xxx/current/cdl/ser_arm_edb7xxx.cdl208
-rw-r--r--ecos/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.c408
-rw-r--r--ecos/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.h108
-rw-r--r--ecos/packages/devs/serial/arm/gps4020/current/ChangeLog29
-rw-r--r--ecos/packages/devs/serial/arm/gps4020/current/cdl/ser_arm_gps4020.cdl208
-rw-r--r--ecos/packages/devs/serial/arm/gps4020/current/src/gps4020_serial.c463
-rw-r--r--ecos/packages/devs/serial/arm/integrator/current/ChangeLog47
-rw-r--r--ecos/packages/devs/serial/arm/integrator/current/cdl/ser_arm_integrator.cdl177
-rw-r--r--ecos/packages/devs/serial/arm/integrator/current/src/integrator_serial.h213
-rw-r--r--ecos/packages/devs/serial/arm/integrator/current/src/integrator_serial_with_ints.c410
-rw-r--r--ecos/packages/devs/serial/arm/iop310/current/ChangeLog41
-rw-r--r--ecos/packages/devs/serial/arm/iop310/current/cdl/ser_arm_iop310.cdl197
-rw-r--r--ecos/packages/devs/serial/arm/iop310/current/include/arm_iop310_ser.inl161
-rw-r--r--ecos/packages/devs/serial/arm/iq80321/current/ChangeLog33
-rw-r--r--ecos/packages/devs/serial/arm/iq80321/current/cdl/ser_arm_iq80321.cdl150
-rw-r--r--ecos/packages/devs/serial/arm/iq80321/current/include/arm_iq80321_ser.inl122
-rwxr-xr-xecos/packages/devs/serial/arm/lpc24xx/current/ChangeLog39
-rwxr-xr-xecos/packages/devs/serial/arm/lpc24xx/current/cdl/ser_arm_lpc24xx.cdl192
-rwxr-xr-xecos/packages/devs/serial/arm/lpc24xx/current/include/arm_lpc24xx_ser.inl350
-rw-r--r--ecos/packages/devs/serial/arm/lpc2xxx/current/ChangeLog46
-rw-r--r--ecos/packages/devs/serial/arm/lpc2xxx/current/cdl/ser_arm_lpc2xxx.cdl226
-rw-r--r--ecos/packages/devs/serial/arm/lpc2xxx/current/include/arm_lpc2xxx_ser.inl185
-rw-r--r--ecos/packages/devs/serial/arm/pid/current/ChangeLog213
-rw-r--r--ecos/packages/devs/serial/arm/pid/current/cdl/ser_arm_pid.cdl195
-rw-r--r--ecos/packages/devs/serial/arm/pid/current/include/arm_arm7_pid_ser.inl162
-rw-r--r--ecos/packages/devs/serial/arm/pxa2x0/current/ChangeLog37
-rw-r--r--ecos/packages/devs/serial/arm/pxa2x0/current/cdl/ser_arm_xscale_pxa2x0.cdl154
-rw-r--r--ecos/packages/devs/serial/arm/pxa2x0/current/include/arm_xscale_pxa2x0_ser.inl122
-rwxr-xr-xecos/packages/devs/serial/arm/s3c4510/current/ChangeLog38
-rwxr-xr-xecos/packages/devs/serial/arm/s3c4510/current/cdl/ser_arm_s3c4510.cdl112
-rwxr-xr-xecos/packages/devs/serial/arm/s3c4510/current/src/s3c4510_serial.c296
-rwxr-xr-xecos/packages/devs/serial/arm/s3c4510/current/src/s3c4510_serial.h195
-rw-r--r--ecos/packages/devs/serial/arm/sa11x0/current/ChangeLog65
-rw-r--r--ecos/packages/devs/serial/arm/sa11x0/current/cdl/ser_arm_sa11x0.cdl204
-rw-r--r--ecos/packages/devs/serial/arm/sa11x0/current/src/sa11x0_serial.c354
-rw-r--r--ecos/packages/devs/serial/arm/sa11x0/current/src/sa11x0_serial.h122
-rw-r--r--ecos/packages/devs/serial/arm/smdk2410/current/ChangeLog7
-rw-r--r--ecos/packages/devs/serial/arm/smdk2410/current/cdl/ser_arm_smdk2410.cdl198
-rw-r--r--ecos/packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.c384
-rw-r--r--ecos/packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.h127
-rw-r--r--ecos/packages/devs/serial/coldfire/mcf5272/current/ChangeLog39
-rw-r--r--ecos/packages/devs/serial/coldfire/mcf5272/current/cdl/mcf5272_serial.cdl192
-rw-r--r--ecos/packages/devs/serial/coldfire/mcf5272/current/src/mcf5272_serial.c1138
-rw-r--r--ecos/packages/devs/serial/coldfire/mcf5272/current/src/mcf5272_serial.h141
-rw-r--r--ecos/packages/devs/serial/cortexm/a2fxxx/current/ChangeLog30
-rw-r--r--ecos/packages/devs/serial/cortexm/a2fxxx/current/cdl/ser_cortexm_a2fxxx.cdl219
-rw-r--r--ecos/packages/devs/serial/cortexm/a2fxxx/current/include/ser_cortexm_a2fxxx.inl210
-rw-r--r--ecos/packages/devs/serial/cortexm/stm32/current/ChangeLog70
-rw-r--r--ecos/packages/devs/serial/cortexm/stm32/current/cdl/ser_cortexm_stm32.cdl422
-rw-r--r--ecos/packages/devs/serial/cortexm/stm32/current/src/stm32_serial.c946
-rw-r--r--ecos/packages/devs/serial/cortexm/stm32/current/src/stm32_serial.h105
-rw-r--r--ecos/packages/devs/serial/freescale/esci/drv/current/ChangeLog46
-rw-r--r--ecos/packages/devs/serial/freescale/esci/drv/current/cdl/ser_freescale_esci.cdl305
-rw-r--r--ecos/packages/devs/serial/freescale/esci/drv/current/src/ser_esci.c548
-rw-r--r--ecos/packages/devs/serial/freescale/esci/hdr/current/ChangeLog47
-rw-r--r--ecos/packages/devs/serial/freescale/esci/hdr/current/cdl/ser_freescale_esci_h.cdl68
-rw-r--r--ecos/packages/devs/serial/freescale/esci/hdr/current/include/ser_esci.h162
-rw-r--r--ecos/packages/devs/serial/freescale/uart/drv/current/ChangeLog43
-rw-r--r--ecos/packages/devs/serial/freescale/uart/drv/current/cdl/ser_freescale_uart.cdl269
-rw-r--r--ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_chan.inl378
-rw-r--r--ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_termiostty_add.inl79
-rw-r--r--ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_tty_add.inl79
-rw-r--r--ecos/packages/devs/serial/freescale/uart/drv/current/src/ser_freescale_uart.c397
-rw-r--r--ecos/packages/devs/serial/freescale/uart/hdr/current/ChangeLog34
-rw-r--r--ecos/packages/devs/serial/freescale/uart/hdr/current/cdl/ser_freescale_uart_hdr.cdl68
-rw-r--r--ecos/packages/devs/serial/freescale/uart/hdr/current/include/ser_freescale_uart.h144
-rw-r--r--ecos/packages/devs/serial/generic/16x5x/current/ChangeLog349
-rw-r--r--ecos/packages/devs/serial/generic/16x5x/current/cdl/ser_generic_16x5x.cdl160
-rw-r--r--ecos/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c700
-rw-r--r--ecos/packages/devs/serial/h8300/h8300h/current/ChangeLog31
-rw-r--r--ecos/packages/devs/serial/h8300/h8300h/current/cdl/serial_h8300.cdl112
-rw-r--r--ecos/packages/devs/serial/h8300/h8300h/current/src/h8300_sci_serial.c575
-rw-r--r--ecos/packages/devs/serial/i386/pc/current/ChangeLog1196
-rw-r--r--ecos/packages/devs/serial/i386/pc/current/cdl/ser_i386_pc.cdl268
-rw-r--r--ecos/packages/devs/serial/i386/pc/current/include/i386_pc_ser.inl163
-rw-r--r--ecos/packages/devs/serial/loop/current/ChangeLog53
-rw-r--r--ecos/packages/devs/serial/loop/current/cdl/ser_loop.cdl188
-rw-r--r--ecos/packages/devs/serial/loop/current/src/loop_serial.c456
-rw-r--r--ecos/packages/devs/serial/m68k/mcf52xx/current/ChangeLog115
-rw-r--r--ecos/packages/devs/serial/m68k/mcf52xx/current/cdl/ser_mcf52xx.cdl186
-rw-r--r--ecos/packages/devs/serial/m68k/mcf52xx/current/doc/mcf52xx_ser.sgml208
-rw-r--r--ecos/packages/devs/serial/m68k/mcf52xx/current/src/ser_mcf52xx.c850
-rw-r--r--ecos/packages/devs/serial/mcf52xx/mcf5272/current/ChangeLog27
-rw-r--r--ecos/packages/devs/serial/mcf52xx/mcf5272/current/cdl/ser_mcf5272_uart.cdl141
-rw-r--r--ecos/packages/devs/serial/mcf52xx/mcf5272/current/include/ser_mcf5272_uart.h129
-rw-r--r--ecos/packages/devs/serial/mcf52xx/mcf5272/current/src/ser_mcf5272_uart.c945
-rw-r--r--ecos/packages/devs/serial/mips/atlas/current/ChangeLog43
-rw-r--r--ecos/packages/devs/serial/mips/atlas/current/cdl/ser_mips_atlas.cdl157
-rw-r--r--ecos/packages/devs/serial/mips/atlas/current/src/atlas_serial.c372
-rw-r--r--ecos/packages/devs/serial/mips/atlas/current/src/atlas_serial.h213
-rw-r--r--ecos/packages/devs/serial/mips/idt79s334a/current/ChangeLog38
-rw-r--r--ecos/packages/devs/serial/mips/idt79s334a/current/cdl/ser_mipsidt_334a.cdl196
-rwxr-xr-xecos/packages/devs/serial/mips/idt79s334a/current/src/mipsidt_serial.c409
-rwxr-xr-xecos/packages/devs/serial/mips/idt79s334a/current/src/mipsidt_serial.h218
-rw-r--r--ecos/packages/devs/serial/mips/jmr3904/current/ChangeLog1185
-rw-r--r--ecos/packages/devs/serial/mips/jmr3904/current/cdl/ser_mips_jmr3904.cdl219
-rw-r--r--ecos/packages/devs/serial/mips/jmr3904/current/src/tx3904_serial.c756
-rw-r--r--ecos/packages/devs/serial/mips/ref4955/current/ChangeLog60
-rw-r--r--ecos/packages/devs/serial/mips/ref4955/current/cdl/ser_mips_ref4955.cdl182
-rw-r--r--ecos/packages/devs/serial/mips/ref4955/current/include/mips_tx49_ref4955_ser.inl176
-rw-r--r--ecos/packages/devs/serial/mips/upd985xx/current/ChangeLog43
-rw-r--r--ecos/packages/devs/serial/mips/upd985xx/current/cdl/ser_mips_upd985xx.cdl164
-rw-r--r--ecos/packages/devs/serial/mips/upd985xx/current/src/upd985xx_serial.c312
-rw-r--r--ecos/packages/devs/serial/mips/upd985xx/current/src/upd985xx_serial.h108
-rw-r--r--ecos/packages/devs/serial/mips/vrc437x/current/ChangeLog1206
-rw-r--r--ecos/packages/devs/serial/mips/vrc437x/current/cdl/ser_mips_vrc437x.cdl202
-rw-r--r--ecos/packages/devs/serial/mips/vrc437x/current/src/vrc437x_serial.c493
-rw-r--r--ecos/packages/devs/serial/mips/vrc437x/current/src/vrc437x_serial.h343
-rw-r--r--ecos/packages/devs/serial/mn10300/mn10300/current/ChangeLog1181
-rw-r--r--ecos/packages/devs/serial/mn10300/mn10300/current/cdl/ser_mn10300.cdl237
-rw-r--r--ecos/packages/devs/serial/mn10300/mn10300/current/src/mn10300_serial.c1035
-rw-r--r--ecos/packages/devs/serial/powerpc/cogent/current/ChangeLog1185
-rw-r--r--ecos/packages/devs/serial/powerpc/cogent/current/cdl/ser_powerpc_cogent.cdl206
-rw-r--r--ecos/packages/devs/serial/powerpc/cogent/current/src/cogent_serial.h212
-rw-r--r--ecos/packages/devs/serial/powerpc/cogent/current/src/cogent_serial_with_ints.c412
-rw-r--r--ecos/packages/devs/serial/powerpc/mpc555/current/ChangeLog59
-rw-r--r--ecos/packages/devs/serial/powerpc/mpc555/current/cdl/ser_powerpc_mpc555.cdl196
-rw-r--r--ecos/packages/devs/serial/powerpc/mpc555/current/src/mpc555_serial.h156
-rw-r--r--ecos/packages/devs/serial/powerpc/mpc555/current/src/mpc555_serial_with_ints.c1290
-rw-r--r--ecos/packages/devs/serial/powerpc/mpc8xxx/current/ChangeLog29
-rw-r--r--ecos/packages/devs/serial/powerpc/mpc8xxx/current/cdl/ser_mpc8xxx.cdl511
-rw-r--r--ecos/packages/devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.c1014
-rw-r--r--ecos/packages/devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.h153
-rw-r--r--ecos/packages/devs/serial/powerpc/ppc405/current/ChangeLog33
-rw-r--r--ecos/packages/devs/serial/powerpc/ppc405/current/cdl/ser_powerpc_ppc405.cdl195
-rw-r--r--ecos/packages/devs/serial/powerpc/ppc405/current/include/powerpc_ppc405_ser.inl175
-rw-r--r--ecos/packages/devs/serial/powerpc/quicc/current/ChangeLog1285
-rw-r--r--ecos/packages/devs/serial/powerpc/quicc/current/cdl/ser_quicc_smc.cdl512
-rw-r--r--ecos/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c1122
-rw-r--r--ecos/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.h131
-rw-r--r--ecos/packages/devs/serial/powerpc/quicc2/current/ChangeLog45
-rw-r--r--ecos/packages/devs/serial/powerpc/quicc2/current/cdl/ser_quicc2_scc.cdl287
-rw-r--r--ecos/packages/devs/serial/powerpc/quicc2/current/src/quicc2_scc_serial.c849
-rw-r--r--ecos/packages/devs/serial/powerpc/quicc2/current/src/quicc2_scc_serial.h207
-rw-r--r--ecos/packages/devs/serial/sh/cq7708/current/ChangeLog62
-rw-r--r--ecos/packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl130
-rw-r--r--ecos/packages/devs/serial/sh/cq7708/current/include/sh_sh3_cq7708_sci.inl104
-rw-r--r--ecos/packages/devs/serial/sh/edk7708/current/ChangeLog1204
-rw-r--r--ecos/packages/devs/serial/sh/edk7708/current/cdl/ser_sh_edk7708.cdl130
-rw-r--r--ecos/packages/devs/serial/sh/edk7708/current/include/sh_sh3_edk7708_sci.inl104
-rw-r--r--ecos/packages/devs/serial/sh/sci/current/ChangeLog156
-rw-r--r--ecos/packages/devs/serial/sh/sci/current/cdl/ser_sh_sci.cdl112
-rw-r--r--ecos/packages/devs/serial/sh/sci/current/src/sh_sci_serial.c545
-rw-r--r--ecos/packages/devs/serial/sh/scif/current/ChangeLog188
-rw-r--r--ecos/packages/devs/serial/sh/scif/current/cdl/ser_sh_scif.cdl176
-rw-r--r--ecos/packages/devs/serial/sh/scif/current/src/sh_scif_serial.c1095
-rw-r--r--ecos/packages/devs/serial/sh/se77x9/current/ChangeLog41
-rw-r--r--ecos/packages/devs/serial/sh/se77x9/current/cdl/ser_sh_se77x9.cdl193
-rw-r--r--ecos/packages/devs/serial/sh/se77x9/current/include/sh_sh3_se77x9_16x5x.inl123
-rw-r--r--ecos/packages/devs/serial/sh/se77x9/current/include/sh_sh3_se77x9_scif.inl113
-rw-r--r--ecos/packages/devs/serial/sh/sh4_202_md/current/ChangeLog27
-rw-r--r--ecos/packages/devs/serial/sh/sh4_202_md/current/cdl/ser_sh4_202_md.cdl149
-rw-r--r--ecos/packages/devs/serial/sh/sh4_202_md/current/include/sh4_202_md_scif.inl117
-rw-r--r--ecos/packages/devs/serial/sparclite/sleb/current/ChangeLog1187
-rw-r--r--ecos/packages/devs/serial/sparclite/sleb/current/cdl/ser_sparclite_sleb.cdl209
-rw-r--r--ecos/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.c400
-rw-r--r--ecos/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.h166
-rw-r--r--ecos/packages/devs/serial/v85x/v850/current/ChangeLog83
-rw-r--r--ecos/packages/devs/serial/v85x/v850/current/cdl/ser_v85x_v850.cdl131
-rw-r--r--ecos/packages/devs/serial/v85x/v850/current/src/v85x_v850_serial.c359
-rw-r--r--ecos/packages/devs/serial/v85x/v850/current/src/v85x_v850_serial.h164
-rw-r--r--ecos/packages/devs/spi/arm/at91/current/ChangeLog113
-rw-r--r--ecos/packages/devs/spi/arm/at91/current/cdl/spi_at91.cdl225
-rw-r--r--ecos/packages/devs/spi/arm/at91/current/include/spi_at91.h121
-rw-r--r--ecos/packages/devs/spi/arm/at91/current/src/spi_at91.c707
-rw-r--r--ecos/packages/devs/spi/arm/at91/current/src/spi_at91_init.cxx73
-rw-r--r--ecos/packages/devs/spi/arm/eb55/current/ChangeLog50
-rw-r--r--ecos/packages/devs/spi/arm/eb55/current/cdl/spi_eb55.cdl97
-rw-r--r--ecos/packages/devs/spi/arm/eb55/current/include/spi_eb55.h62
-rw-r--r--ecos/packages/devs/spi/arm/eb55/current/src/spi_eb55.c74
-rw-r--r--ecos/packages/devs/spi/arm/lpc2xxx/current/ChangeLog45
-rw-r--r--ecos/packages/devs/spi/arm/lpc2xxx/current/cdl/spi_lpc2xxx.cdl103
-rw-r--r--ecos/packages/devs/spi/arm/lpc2xxx/current/include/spi_lpc2xxx.h108
-rw-r--r--ecos/packages/devs/spi/arm/lpc2xxx/current/src/spi_lpc2xxx.cxx367
-rw-r--r--ecos/packages/devs/spi/cortexm/a2fxxx/current/ChangeLog35
-rw-r--r--ecos/packages/devs/spi/cortexm/a2fxxx/current/cdl/spi_a2fxxx.cdl175
-rw-r--r--ecos/packages/devs/spi/cortexm/a2fxxx/current/include/spi_a2fxxx.h195
-rw-r--r--ecos/packages/devs/spi/cortexm/a2fxxx/current/src/spi_a2fxxx.c638
-rw-r--r--ecos/packages/devs/spi/cortexm/stm32/current/ChangeLog140
-rw-r--r--ecos/packages/devs/spi/cortexm/stm32/current/cdl/spi_stm32.cdl272
-rw-r--r--ecos/packages/devs/spi/cortexm/stm32/current/include/spi_stm32.h182
-rw-r--r--ecos/packages/devs/spi/cortexm/stm32/current/src/spi_stm32.c805
-rw-r--r--ecos/packages/devs/spi/cortexm/stm32/current/tests/loopback.c185
-rw-r--r--ecos/packages/devs/spi/freescale/dspi/current/ChangeLog79
-rw-r--r--ecos/packages/devs/spi/freescale/dspi/current/cdl/spi_freescale_dspi.cdl387
-rw-r--r--ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi.h207
-rw-r--r--ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_buses.inl586
-rw-r--r--ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_io.h292
-rw-r--r--ecos/packages/devs/spi/freescale/dspi/current/src/spi_freescale_dspi.c1190
-rw-r--r--ecos/packages/devs/spi/freescale/dspi/current/tests/spi_loopback.c285
-rw-r--r--ecos/packages/devs/touch/arm/aaed2000/current/ChangeLog32
-rw-r--r--ecos/packages/devs/touch/arm/aaed2000/current/src/aaed2000_ts.c368
-rw-r--r--ecos/packages/devs/touch/arm/aaed2000/current/touch_aaed2000.cdl99
-rw-r--r--ecos/packages/devs/touch/arm/ipaq/current/ChangeLog44
-rw-r--r--ecos/packages/devs/touch/arm/ipaq/current/cdl/touch_ipaq.cdl99
-rw-r--r--ecos/packages/devs/touch/arm/ipaq/current/src/ipaq_ts.c282
-rw-r--r--ecos/packages/devs/usb/at91/current/ChangeLog131
-rw-r--r--ecos/packages/devs/usb/at91/current/cdl/usbs_at91.cdl286
-rw-r--r--ecos/packages/devs/usb/at91/current/include/usbs_at91.h82
-rw-r--r--ecos/packages/devs/usb/at91/current/src/bitops.h98
-rw-r--r--ecos/packages/devs/usb/at91/current/src/usbs_at91.c1633
-rw-r--r--ecos/packages/devs/usb/at91/current/src/usbs_at91_data.cxx256
-rw-r--r--ecos/packages/devs/usb/cortexm/stm32/current/ChangeLog41
-rw-r--r--ecos/packages/devs/usb/cortexm/stm32/current/cdl/usb_stm32.cdl325
-rw-r--r--ecos/packages/devs/usb/cortexm/stm32/current/include/usb_stm32.h56
-rw-r--r--ecos/packages/devs/usb/cortexm/stm32/current/src/usb_stm32.c2456
-rw-r--r--ecos/packages/devs/usb/d12/current/ChangeLog27
-rw-r--r--ecos/packages/devs/usb/d12/current/cdl/usbs_d12.cdl318
-rw-r--r--ecos/packages/devs/usb/d12/current/include/usbs_d12.h74
-rw-r--r--ecos/packages/devs/usb/d12/current/src/usbs_d12.c2323
-rw-r--r--ecos/packages/devs/usb/d12/current/src/usbs_d12_data.cxx231
-rw-r--r--ecos/packages/devs/usb/i386/SoRoD12/current/ChangeLog28
-rw-r--r--ecos/packages/devs/usb/i386/SoRoD12/current/cdl/usbs_i386_sorod12.cdl92
-rw-r--r--ecos/packages/devs/usb/i386/SoRoD12/current/include/usbs_i386_sorod12.inl130
-rw-r--r--ecos/packages/devs/usb/nec_upd985xx/current/ChangeLog125
-rw-r--r--ecos/packages/devs/usb/nec_upd985xx/current/cdl/usbs_upd985xx.cdl291
-rw-r--r--ecos/packages/devs/usb/nec_upd985xx/current/doc/devs-usb-nec-upd985xx.html372
-rw-r--r--ecos/packages/devs/usb/nec_upd985xx/current/doc/makefile54
-rw-r--r--ecos/packages/devs/usb/nec_upd985xx/current/doc/usbs_upd985xx.sgml257
-rw-r--r--ecos/packages/devs/usb/nec_upd985xx/current/include/usbs_upd985xx.h78
-rw-r--r--ecos/packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx.c2687
-rw-r--r--ecos/packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx_data.cxx189
-rw-r--r--ecos/packages/devs/usb/sa11x0/current/ChangeLog185
-rw-r--r--ecos/packages/devs/usb/sa11x0/current/cdl/usbs_sa11x0.cdl202
-rw-r--r--ecos/packages/devs/usb/sa11x0/current/doc/devs-usb-sa11x0.html341
-rw-r--r--ecos/packages/devs/usb/sa11x0/current/doc/makefile54
-rw-r--r--ecos/packages/devs/usb/sa11x0/current/doc/usbs_sa11x0.sgml234
-rw-r--r--ecos/packages/devs/usb/sa11x0/current/include/usbs_sa11x0.h73
-rw-r--r--ecos/packages/devs/usb/sa11x0/current/src/usbs_sa11x0.c2550
-rw-r--r--ecos/packages/devs/usb/sa11x0/current/src/usbs_sa11x0_data.cxx173
-rwxr-xr-xecos/packages/devs/wallclock/arm/aim711/current/ChangeLog29
-rwxr-xr-xecos/packages/devs/wallclock/arm/aim711/current/cdl/aim711_wallclock_drivers.cdl68
-rwxr-xr-xecos/packages/devs/wallclock/arm/aim711/current/include/devs_wallclock_arm_aim711.inl105
-rw-r--r--ecos/packages/devs/wallclock/arm/lpc2xxx/current/ChangeLog41
-rw-r--r--ecos/packages/devs/wallclock/arm/lpc2xxx/current/cdl/lpc2xxx_wallclock.cdl72
-rw-r--r--ecos/packages/devs/wallclock/arm/lpc2xxx/current/src/lpc2xxx_wallclock.cxx194
-rw-r--r--ecos/packages/devs/wallclock/cortexm/stm32/current/ChangeLog50
-rw-r--r--ecos/packages/devs/wallclock/cortexm/stm32/current/cdl/wallclock_stm32.cdl81
-rw-r--r--ecos/packages/devs/wallclock/cortexm/stm32/current/src/stm32_wallclock.cxx250
-rw-r--r--ecos/packages/devs/wallclock/dallas/ds12887/current/ChangeLog41
-rw-r--r--ecos/packages/devs/wallclock/dallas/ds12887/current/cdl/wallclock_ds12887.cdl104
-rw-r--r--ecos/packages/devs/wallclock/dallas/ds12887/current/src/ds12887.cxx300
-rw-r--r--ecos/packages/devs/wallclock/dallas/ds1307/current/ChangeLog40
-rw-r--r--ecos/packages/devs/wallclock/dallas/ds1307/current/cdl/wallclock_ds1307.cdl113
-rw-r--r--ecos/packages/devs/wallclock/dallas/ds1307/current/doc/ds1307.sgml124
-rw-r--r--ecos/packages/devs/wallclock/dallas/ds1307/current/src/ds1307.cxx335
-rw-r--r--ecos/packages/devs/wallclock/dallas/ds1742/current/ChangeLog27
-rw-r--r--ecos/packages/devs/wallclock/dallas/ds1742/current/ds1742.inl182
-rw-r--r--ecos/packages/devs/wallclock/dallas/ds1742/current/wallclock_ds1742.cdl59
-rw-r--r--ecos/packages/devs/wallclock/freescale/kinetis/current/ChangeLog29
-rw-r--r--ecos/packages/devs/wallclock/freescale/kinetis/current/cdl/wallclock_kinetis_rtc.cdl70
-rw-r--r--ecos/packages/devs/wallclock/freescale/kinetis/current/src/wallclock_kinetis_rtc.cxx105
-rw-r--r--ecos/packages/devs/wallclock/i386/pc/current/ChangeLog36
-rw-r--r--ecos/packages/devs/wallclock/i386/pc/current/cdl/i386_pc_wallclock_drivers.cdl85
-rw-r--r--ecos/packages/devs/wallclock/i386/pc/current/include/devices_wallclock_i386_pc.inl72
-rw-r--r--ecos/packages/devs/wallclock/mips/ref4955/current/ChangeLog42
-rw-r--r--ecos/packages/devs/wallclock/mips/ref4955/current/cdl/wallclock_ref4955.cdl101
-rw-r--r--ecos/packages/devs/wallclock/mips/ref4955/current/src/wallclock_ref4955.cxx121
-rw-r--r--ecos/packages/devs/wallclock/powerpc/moab/current/ChangeLog29
-rw-r--r--ecos/packages/devs/wallclock/powerpc/moab/current/cdl/moab_wallclock_drivers.cdl67
-rw-r--r--ecos/packages/devs/wallclock/powerpc/moab/current/include/devices_wallclock_moab.inl122
-rw-r--r--ecos/packages/devs/wallclock/powerpc/mpc5xx/current/ChangeLog27
-rw-r--r--ecos/packages/devs/wallclock/powerpc/mpc5xx/current/cdl/wallclock_mpc5xx.cdl100
-rw-r--r--ecos/packages/devs/wallclock/powerpc/mpc5xx/current/src/wallclock_mpc5xx.cxx99
-rw-r--r--ecos/packages/devs/wallclock/sh/hs7729pci/current/ChangeLog27
-rw-r--r--ecos/packages/devs/wallclock/sh/hs7729pci/current/cdl/wallclock_hs7729pci.cdl64
-rw-r--r--ecos/packages/devs/wallclock/sh/hs7729pci/current/include/devs_wallclock_sh_hs7729pci.inl69
-rw-r--r--ecos/packages/devs/wallclock/sh/sh3/current/ChangeLog72
-rw-r--r--ecos/packages/devs/wallclock/sh/sh3/current/cdl/wallclock_sh3.cdl100
-rw-r--r--ecos/packages/devs/wallclock/sh/sh3/current/src/wallclock_sh3.cxx174
-rw-r--r--ecos/packages/devs/wallclock/synth/current/ChangeLog35
-rw-r--r--ecos/packages/devs/wallclock/synth/current/cdl/wallclock_synth.cdl112
-rw-r--r--ecos/packages/devs/wallclock/synth/current/src/wallclock_synth.cxx145
-rw-r--r--ecos/packages/devs/watchdog/arm/aeb/current/ChangeLog33
-rw-r--r--ecos/packages/devs/watchdog/arm/aeb/current/cdl/watchdog_aeb.cdl101
-rw-r--r--ecos/packages/devs/watchdog/arm/aeb/current/src/watchdog_aeb.cxx160
-rw-r--r--ecos/packages/devs/watchdog/arm/at91/current/ChangeLog42
-rw-r--r--ecos/packages/devs/watchdog/arm/at91/current/cdl/watchdog_at91.cdl136
-rw-r--r--ecos/packages/devs/watchdog/arm/at91/current/src/watchdog_at91.cxx245
-rw-r--r--ecos/packages/devs/watchdog/arm/at91wdtc/current/ChangeLog38
-rw-r--r--ecos/packages/devs/watchdog/arm/at91wdtc/current/cdl/watchdog_at91wdtc.cdl146
-rw-r--r--ecos/packages/devs/watchdog/arm/at91wdtc/current/src/watchdog_at91wdtc.cxx198
-rw-r--r--ecos/packages/devs/watchdog/arm/ebsa285/current/ChangeLog33
-rw-r--r--ecos/packages/devs/watchdog/arm/ebsa285/current/cdl/watchdog_ebsa285.cdl101
-rw-r--r--ecos/packages/devs/watchdog/arm/ebsa285/current/src/watchdog_ebsa285.cxx150
-rw-r--r--ecos/packages/devs/watchdog/arm/lpc2xxx/current/ChangeLog52
-rw-r--r--ecos/packages/devs/watchdog/arm/lpc2xxx/current/cdl/watchdog_lpc2xxx.cdl132
-rw-r--r--ecos/packages/devs/watchdog/arm/lpc2xxx/current/src/watchdog_lpc2xxx.cxx199
-rw-r--r--ecos/packages/devs/watchdog/arm/sa11x0/current/ChangeLog39
-rw-r--r--ecos/packages/devs/watchdog/arm/sa11x0/current/cdl/watchdog_sa11x0.cdl101
-rw-r--r--ecos/packages/devs/watchdog/arm/sa11x0/current/src/watchdog_sa11x0.cxx146
-rw-r--r--ecos/packages/devs/watchdog/h8300/h8300h/current/ChangeLog29
-rw-r--r--ecos/packages/devs/watchdog/h8300/h8300h/current/cdl/watchdog_h8300h.cdl102
-rw-r--r--ecos/packages/devs/watchdog/h8300/h8300h/current/src/watchdog_h8300h.cxx112
-rw-r--r--ecos/packages/devs/watchdog/mn10300/mn10300/current/ChangeLog79
-rw-r--r--ecos/packages/devs/watchdog/mn10300/mn10300/current/cdl/watchdog_mn10300.cdl100
-rw-r--r--ecos/packages/devs/watchdog/mn10300/mn10300/current/src/watchdog_mn10300.cxx198
-rw-r--r--ecos/packages/devs/watchdog/powerpc/mpc5xx/current/ChangeLog26
-rw-r--r--ecos/packages/devs/watchdog/powerpc/mpc5xx/current/cdl/watchdog_mpc5xx.cdl121
-rw-r--r--ecos/packages/devs/watchdog/powerpc/mpc5xx/current/src/watchdog_mpc5xx.cxx126
-rw-r--r--ecos/packages/devs/watchdog/sh/sh3/current/ChangeLog33
-rw-r--r--ecos/packages/devs/watchdog/sh/sh3/current/cdl/watchdog_sh3.cdl101
-rw-r--r--ecos/packages/devs/watchdog/sh/sh3/current/src/watchdog_sh3.cxx140
-rw-r--r--ecos/packages/devs/watchdog/synth/current/ChangeLog77
-rw-r--r--ecos/packages/devs/watchdog/synth/current/cdl/synth_watchdog.cdl109
-rw-r--r--ecos/packages/devs/watchdog/synth/current/doc/asleep.pngbin0 -> 11229 bytes
-rw-r--r--ecos/packages/devs/watchdog/synth/current/doc/awake.pngbin0 -> 11438 bytes
-rw-r--r--ecos/packages/devs/watchdog/synth/current/doc/devs-watchdog-synth.html526
-rw-r--r--ecos/packages/devs/watchdog/synth/current/doc/makefile54
-rw-r--r--ecos/packages/devs/watchdog/synth/current/doc/synth_watchdog.sgml343
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/Makefile.am59
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/Makefile.in545
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/acinclude.m443
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/aclocal.m4678
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/alarm.gifbin0 -> 5083 bytes
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/asleep.gifbin0 -> 283 bytes
-rwxr-xr-xecos/packages/devs/watchdog/synth/current/host/configure3587
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/configure.in72
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/doghouse.gifbin0 -> 14853 bytes
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/doghouse.pov161
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/eye.gifbin0 -> 93 bytes
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/sound1.aubin0 -> 4464 bytes
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/sound2.aubin0 -> 11691 bytes
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/watchdog.tcl422
-rw-r--r--ecos/packages/devs/watchdog/synth/current/host/watchdog.tdf63
-rw-r--r--ecos/packages/devs/watchdog/synth/current/src/synth_watchdog.cxx132
1179 files changed, 276694 insertions, 0 deletions
diff --git a/ecos/packages/devs/adc/arm/at91/current/ChangeLog b/ecos/packages/devs/adc/arm/at91/current/ChangeLog
new file mode 100644
index 0000000..2c3576e
--- /dev/null
+++ b/ecos/packages/devs/adc/arm/at91/current/ChangeLog
@@ -0,0 +1,31 @@
+2010-05-18 ccoutand <ccoutand@stmi.com>
+
+ * AT91 ADC driver package created
+ * cdl/adc_at91.cdl
+ * src/adc_at91.c
+ * include/adc_at91.inl
+ * tests/at91_adc_test.c
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/adc/arm/at91/current/cdl/adc_at91.cdl b/ecos/packages/devs/adc/arm/at91/current/cdl/adc_at91.cdl
new file mode 100644
index 0000000..14062fb
--- /dev/null
+++ b/ecos/packages/devs/adc/arm/at91/current/cdl/adc_at91.cdl
@@ -0,0 +1,355 @@
+# ====================================================================
+#
+# adc_at91.cdl
+#
+# eCos AT91 ADC configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ccoutand@stmi.com
+# Contributors:
+# Date: 2010-02-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_ADC_ARM_AT91 {
+ display "ADC hardware device driver for AT91 family of ARM controllers"
+
+ parent CYGPKG_IO_ADC_DEVICES
+ active_if CYGPKG_IO_ADC_DEVICES
+ active_if CYGPKG_HAL_ARM_AT91
+ description "
+ This package provides a generic ADC device driver for the on-chip
+ ADC peripherals in AT91 processors."
+
+ include_dir cyg/io
+ compile -library=libextras.a adc_at91.c
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ADC_ARM_AT91_INL <cyg/io/adc_at91.inl>"
+ }
+
+ #
+ # Primary ADC ( ADC0 )
+ #
+ cdl_component CYGPKG_DEVS_ADC_ARM_AT91_ADC0 {
+ display "Atmel AT91 ADC port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the device driver for the on-chip ADC 0 of the
+ AT91 processors"
+
+
+ cdl_interface CYGINT_DEVS_ADC_ARM_AT91_ADC0_CHANNELS {
+ display "Number of ADC0 channels"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SELECT_TIMER {
+ display "Interrupt priority"
+ flavor data
+ legal_values {0 1 2}
+ default_value 1
+ description "
+ This option selects the timer channel to be used for
+ generating the sampling interval. Timer channel 0 can
+ be assigned as Real Time Kernel clock so timer channel
+ 1 is set to be the default value."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_PRESCAL {
+ display "ADC clock setting"
+ flavor data
+ legal_values 0 to 255
+ default_value 128
+ description "
+ This option sets the AT91 ADC PRESCAL value.
+ ADCClock = MCK / ((PRESCAL + 1) * 2)"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_STARTUP_TIME {
+ display "ADC start-up time"
+ flavor data
+ legal_values 0 to 255
+ default_value 128
+ description "
+ This option sets the AT91 ADC start-up time value.
+ ADC start-up time = (STARTUP+1) * 8 / ADCClock"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SHTIM {
+ display "ADC start up time"
+ flavor data
+ legal_values 0 to 15
+ default_value 7
+ description "
+ This option sets the AT91 ADC Sample and Hold Time.
+ Sample and Hold Time = SHTIM / ADCClock"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_INTPRIO {
+ display "Interrupt priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 15
+ description "
+ This option selects the interrupt priority for the ADC
+ interrupts. Timer x is used for generating the sample
+ clock. So this option configures the interrupt priority
+ for timer x. There are 16 priority levels corresponding to
+ the values 0 through 15 decimal, of which 15 is the lowest
+ priority. The reset value of these registers defaults all
+ interrupts to the lowest priority, allowing a single write
+ to elevate the priority of an individual interrupt."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC0_DEFAULT_RATE {
+ display "Default sample rate"
+ flavor data
+ legal_values 1 to 10000
+ default_value 100
+ description "
+ The driver will be initialized with the default sample rate.
+ If you raise the default sample rate you might need to increase
+ the buffer size for each channel."
+ }
+
+ # Support up to 8 ADC channels
+ for { set ::channel 0 } { $::channel < 8 } { incr ::channel } {
+
+ cdl_component CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL[set ::channel] {
+ display "Access ADC channel [set ::channel]"
+ flavor bool
+ default_value [set ::channel] == 0
+ implements CYGINT_DEVS_ADC_ARM_AT91_ADC0_CHANNELS
+ description "
+ If the application needs to access the on-chip ADC
+ channel [set ::channel] via an eCos ADC driver then
+ this option should be enabled."
+
+ cdl_option CYGDAT_DEVS_ADC_ARM_AT91_ADC0_CHANNEL[set ::channel]_NAME {
+ display "Device name"
+ flavor data
+ default_value [format {"\"/dev/adc0%d\""} $::channel]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+ cdl_option CYGDAT_DEVS_ADC_ARM_AT91_ADC0_CHANNEL[set ::channel]_BUFSIZE {
+ display "Size of data buffer"
+ flavor data
+ legal_values 0x01 to 0x2000000
+ default_value 512
+ description "
+ This option controls the number of samples the
+ buffer can store. The required RAM depends on the
+ sample size and on the number of samples. If the
+ sample size is <= 8 bit the the required RAM =
+ size of data buffer. If the sample size is 9 or 10
+ bit then required RAM = size of data buffer * 2."
+ }
+ }
+ }
+ }
+
+ #
+ # ADC1
+ #
+ cdl_component CYGPKG_DEVS_ADC_ARM_AT91_ADC1 {
+ display "Atmel AT91 ADC port 1 driver"
+ flavor bool
+ default_value 0
+
+ requires { CYGHWR_HAL_ARM_AT91 == "M55800A" }
+
+ description "
+ This option includes the device driver for the on-chip ADC 1 of the
+ AT91 processors"
+
+
+ cdl_interface CYGINT_DEVS_ADC_ARM_AT91_ADC1_CHANNELS {
+ display "Number of ADC1 channels"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SELECT_TIMER {
+ display "Interrupt priority"
+ flavor data
+ legal_values {0 1 2}
+ default_value 2
+ description "
+ This option selects the timer channel to be used for
+ generating the sampling interval. Timer channel 0 can
+ be assigned as Real Time Kernel clock so timer channel
+ 1 is set to be the default value."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_PRESCAL {
+ display "ADC clock setting"
+ flavor data
+ legal_values 0 to 255
+ default_value 128
+ description "
+ This option sets the AT91 ADC PRESCAL value.
+ ADCClock = MCK / ((PRESCAL + 1) * 2)"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_STARTUP_TIME {
+ display "ADC start-up time"
+ flavor data
+ legal_values 0 to 255
+ default_value 128
+ description "
+ This option sets the AT91 ADC start-up time value.
+ ADC start-up time = (STARTUP+1) * 8 / ADCClock"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SHTIM {
+ display "ADC start up time"
+ flavor data
+ legal_values 0 to 15
+ default_value 7
+ description "
+ This option sets the AT91 ADC Sample and Hold Time.
+ Sample and Hold Time = SHTIM / ADCClock"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_INTPRIO {
+ display "Interrupt priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 15
+ description "
+ This option selects the interrupt priority for the ADC
+ interrupts. Timer x is used for generating the sample
+ clock. So this option configures the interrupt priority
+ for timer x. There are 16 priority levels corresponding to
+ the values 0 through 15 decimal, of which 15 is the lowest
+ priority. The reset value of these registers defaults all
+ interrupts to the lowest priority, allowing a single write
+ to elevate the priority of an individual interrupt."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_AT91_ADC1_DEFAULT_RATE {
+ display "Default sample rate"
+ flavor data
+ legal_values 1 to 10000
+ default_value 100
+ description "
+ The driver will be initialized with the default sample rate.
+ If you raise the default sample rate you might need to increase
+ the buffer size for each channel."
+ }
+
+ # Support up to 8 ADC channels
+ for { set ::channel 0 } { $::channel < 8 } { incr ::channel } {
+
+ cdl_component CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL[set ::channel] {
+ display "Access ADC channel [set ::channel]"
+ flavor bool
+ default_value [set ::channel] == 0
+ implements CYGINT_DEVS_ADC_ARM_AT91_ADC1_CHANNELS
+ description "
+ If the application needs to access the on-chip ADC
+ channel [set ::channel] via an eCos ADC driver then
+ this option should be enabled."
+
+ cdl_option CYGDAT_DEVS_ADC_ARM_AT91_ADC1_CHANNEL[set ::channel]_NAME {
+ display "Device name"
+ flavor data
+ default_value [format {"\"/dev/adc1%d\""} $::channel]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+ cdl_option CYGDAT_DEVS_ADC_ARM_AT91_ADC1_CHANNEL[set ::channel]_BUFSIZE {
+ display "Size of data buffer"
+ flavor data
+ legal_values 0x01 to 0x2000000
+ default_value 512
+ description "
+ This option controls the number of samples the
+ buffer can store. The required RAM depends on the
+ sample size and on the number of samples. If the
+ sample size is <= 8 bit the the required RAM =
+ size of data buffer. If the sample size is 9 or 10
+ bit then required RAM = size of data buffer * 2."
+ }
+ }
+ }
+ }
+
+ cdl_option CYGPKG_DEVS_ADC_ARM_AT91_DEBUG_LEVEL {
+ display "Driver debug output level"
+ flavor data
+ legal_values {0 1}
+ default_value 0
+ description "
+ This option specifies the level of debug data output by
+ the AT91 ADC device driver. A value of 0 signifies
+ no debug data output; 1 signifies normal debug data
+ output. If an overrun occurred then this can only be
+ detected by debug output messages."
+ }
+
+ cdl_component CYGSEM_DEVS_ADC_ARM_AT91_SAMPLE_SIZE_LIMIT {
+ display "Sample size limit"
+ flavor bool
+ calculated 1
+ requires { ( CYGNUM_IO_ADC_SAMPLE_SIZE == 8 )
+ || ( CYGNUM_IO_ADC_SAMPLE_SIZE == 10 ) }
+ description "
+ This component forces a limit (or rounds) the sample
+ size for AT91 ADC channels which in the most are 10-bit."
+ }
+
+ cdl_option CYGPKG_DEVS_ADC_ARM_AT91_TESTS {
+ display "Tests for AT91 ADC driver"
+ flavor data
+ no_define
+ calculated { "tests/at91_adc_test" }
+ description "
+ This option specifies the set of tests for the AT91
+ ADC device driver."
+ }
+
+}
diff --git a/ecos/packages/devs/adc/arm/at91/current/include/adc_at91.inl b/ecos/packages/devs/adc/arm/at91/current/include/adc_at91.inl
new file mode 100644
index 0000000..523cbf6
--- /dev/null
+++ b/ecos/packages/devs/adc/arm/at91/current/include/adc_at91.inl
@@ -0,0 +1,200 @@
+//==========================================================================
+//
+// adc_at91.inl
+//
+// ADC driver for AT91 on chip ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Atmel AT91 on-chip ADC device driver, ccoutand
+//
+// Contributors:
+// Date: 2010-05-27
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef CYGONCE_DEVS_ADC_ARM_AT91_INL
+#define CYGONCE_DEVS_ADC_ARM_AT91_INL
+
+// Some AT91 HAL are defining the timer 0 vector as TC0 and other as TIMER0
+#ifndef CYGNUM_HAL_INTERRUPT_TC0
+#define CYGNUM_HAL_INTERRUPT_TC0 CYGNUM_HAL_INTERRUPT_TIMER0
+#endif
+
+// Declare ADC0
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0
+
+static at91_adc_info at91_adc0_info =
+{
+ .adc_base = AT91_ADC,
+ .timer_base = AT91_TC,
+ .tc_base = AT91_TC + (AT91_TC_TC_SIZE * CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SELECT_TIMER),
+ .timer_vector = CYGNUM_HAL_INTERRUPT_TC0 + CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SELECT_TIMER,
+ .timer_intprio = CYGNUM_DEVS_ADC_ARM_AT91_ADC0_INTPRIO,
+ .timer_id = CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SELECT_TIMER,
+ .int_handle = 0,
+ .adc_prescal = CYGNUM_DEVS_ADC_ARM_AT91_ADC0_PRESCAL,
+ .adc_startup_time = CYGNUM_DEVS_ADC_ARM_AT91_ADC0_STARTUP_TIME,
+ .adc_shtim = CYGNUM_DEVS_ADC_ARM_AT91_ADC0_SHTIM,
+#if CYGNUM_IO_ADC_SAMPLE_SIZE > 8
+ .resolution = AT91_ADC_MR_LOWREC_10BITS,
+#else
+ .resolution = AT91_ADC_MR_LOWRES_8BITS,
+#endif
+ .chan_mask = 0
+};
+
+CYG_ADC_DEVICE( at91_adc0_device,
+ &at91_adc_funs,
+ &at91_adc0_info,
+ CYGNUM_DEVS_ADC_ARM_AT91_ADC0_DEFAULT_RATE);
+
+#define AT91_ADC0_CHANNEL( __chan ) \
+CYG_ADC_CHANNEL( at91_adc0_channel##__chan, \
+ __chan, \
+ CYGDAT_DEVS_ADC_ARM_AT91_ADC0_CHANNEL##__chan##_BUFSIZE, \
+ &at91_adc0_device ); \
+ \
+DEVTAB_ENTRY( at91_adc0_channel##__chan##_device, \
+ CYGDAT_DEVS_ADC_ARM_AT91_ADC0_CHANNEL##__chan##_NAME, \
+ 0, \
+ &cyg_io_adc_devio, \
+ at91_adc_init, \
+ at91_adc_lookup, \
+ &at91_adc0_channel##__chan );
+
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL0
+AT91_ADC0_CHANNEL(0);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL1
+AT91_ADC0_CHANNEL(1);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL2
+AT91_ADC0_CHANNEL(2);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL3
+AT91_ADC0_CHANNEL(3);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL4
+AT91_ADC0_CHANNEL(4);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL5
+AT91_ADC0_CHANNEL(5);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL6
+AT91_ADC0_CHANNEL(6);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC0_CHANNEL7
+AT91_ADC0_CHANNEL(7);
+#endif
+
+#endif // CYGPKG_DEVS_ADC_ARM_AT91_ADC0
+
+
+
+// Declare ADC1
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1
+
+static at91_adc_info at91_adc1_info =
+{
+ .adc_base = AT91_ADC1,
+ .timer_base = AT91_TC,
+ .tc_base = AT91_TC + (AT91_TC_TC_SIZE * CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SELECT_TIMER),
+ .timer_vector = CYGNUM_HAL_INTERRUPT_TC0 + CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SELECT_TIMER,
+ .timer_intprio = CYGNUM_DEVS_ADC_ARM_AT91_ADC1_INTPRIO,
+ .timer_id = CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SELECT_TIMER,
+ .int_handle = 0,
+ .adc_prescal = CYGNUM_DEVS_ADC_ARM_AT91_ADC1_PRESCAL,
+ .adc_startup_time = CYGNUM_DEVS_ADC_ARM_AT91_ADC1_STARTUP_TIME,
+ .adc_shtim = CYGNUM_DEVS_ADC_ARM_AT91_ADC1_SHTIM,
+#if CYGNUM_IO_ADC_SAMPLE_SIZE > 8
+ .resolution = AT91_ADC_MR_LOWREC_10BITS,
+#else
+ .resolution = AT91_ADC_MR_LOWRES_8BITS,
+#endif
+ .chan_mask = 0
+};
+CYG_ADC_DEVICE( at91_adc1_device,
+ &at91_adc_funs,
+ &at91_adc1_info,
+ CYGNUM_DEVS_ADC_ARM_AT91_ADC1_DEFAULT_RATE);
+
+#define AT91_ADC1_CHANNEL( __chan ) \
+CYG_ADC_CHANNEL( at91_adc1_channel##__chan, \
+ __chan, \
+ CYGDAT_DEVS_ADC_ARM_AT91_ADC1_CHANNEL##__chan##_BUFSIZE, \
+ &at91_adc1_device ); \
+ \
+DEVTAB_ENTRY( at91_adc1_channel##__chan##_device, \
+ CYGDAT_DEVS_ADC_ARM_AT91_ADC1_CHANNEL##__chan##_NAME, \
+ 0, \
+ &cyg_io_adc_devio, \
+ at91_adc_init, \
+ at91_adc_lookup, \
+ &at91_adc1_channel##__chan );
+
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL0
+AT91_ADC1_CHANNEL(0);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL1
+AT91_ADC1_CHANNEL(1);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL2
+AT91_ADC1_CHANNEL(2);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL3
+AT91_ADC1_CHANNEL(3);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL4
+AT91_ADC1_CHANNEL(4);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL5
+AT91_ADC1_CHANNEL(5);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL6
+AT91_ADC1_CHANNEL(6);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_AT91_ADC1_CHANNEL7
+AT91_ADC1_CHANNEL(7);
+#endif
+
+#endif // CYGPKG_DEVS_ADC_ARM_AT91_ADC1
+
+#endif // CYGONCE_DEVS_ADC_ARM_AT91_INL
diff --git a/ecos/packages/devs/adc/arm/at91/current/src/adc_at91.c b/ecos/packages/devs/adc/arm/at91/current/src/adc_at91.c
new file mode 100644
index 0000000..6364bf1
--- /dev/null
+++ b/ecos/packages/devs/adc/arm/at91/current/src/adc_at91.c
@@ -0,0 +1,457 @@
+//==========================================================================
+//
+// adc_at91.c
+//
+// ADC driver for AT91 on chip ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler <uwe_kindler@web.de>
+// Updated for Atmel AT91 device, ccoutand <ccoutand@stmi.com>
+// Contributors:
+// Date: 2010-02-15
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/devs_adc_arm_at91.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/adc.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+#if CYGPKG_DEVS_ADC_ARM_AT91_DEBUG_LEVEL > 0
+ #define at91_adc_printf(args...) diag_printf(args)
+#else
+ #define at91_adc_printf(args...)
+#endif
+
+#define AT91_ADC_CHER_CHx(_ch_) (0x1 << _ch_)
+#define AT91_ADC_CHER_CDRx(_ch_) (_ch_ << 2)
+
+//==========================================================================
+// DATA TYPES
+//==========================================================================
+typedef struct at91_adc_info
+{
+ cyg_uint32 adc_base; // base address of ADC peripheral
+ cyg_uint8 adc_prescal; // ADC prescal value
+ cyg_uint8 adc_startup_time; // ADC Startup Time value
+ cyg_uint8 adc_shtim; // ADC SHTIM value
+ cyg_uint8 timer_id; // select timer
+ cyg_uint32 timer_base; // base address of Timer peripheral
+ cyg_uint32 tc_base; // base address of Timer channel
+ cyg_vector_t timer_vector; // interrupt vector number
+ int timer_intprio; // interrupt priority of ADC interrupt
+ cyg_uint32 timer_cnt; // Timer value
+ cyg_uint8 timer_clk; // Timer clock setting
+ cyg_uint32 resolution;
+ cyg_handle_t int_handle; // For initializing the interrupt
+ cyg_interrupt int_data;
+ struct cyg_adc_channel *channel[AT91_MAX_ADC_CHAN]; // stores references to channel objects
+ cyg_uint8 chan_mask; // mask that indicates channels used
+ // by ADC driver
+} at91_adc_info;
+
+
+//==========================================================================
+// DECLARATIONS
+//==========================================================================
+static bool at91_adc_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo at91_adc_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static void at91_adc_enable( cyg_adc_channel *chan );
+static void at91_adc_disable( cyg_adc_channel *chan );
+static void at91_adc_set_rate( cyg_adc_channel *chan, cyg_uint32 rate );
+static cyg_uint32 at91_adc_isr(cyg_vector_t vector, cyg_addrword_t data);
+static void at91_adc_dsr(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+
+// -------------------------------------------------------------------------
+// Driver functions:
+CYG_ADC_FUNCTIONS( at91_adc_funs,
+ at91_adc_enable,
+ at91_adc_disable,
+ at91_adc_set_rate );
+
+
+#include CYGDAT_DEVS_ADC_ARM_AT91_INL // Instantiate ADCs
+
+//==========================================================================
+// This function is called from the device IO infrastructure to initialize
+// the device. It should perform any work needed to start up the device,
+// short of actually starting the generation of samples. This function will
+// be called for each channel, so if there is initialization that only needs
+// to be done once, such as creating and interrupt object, then care should
+// be taken to do this. This function should also call cyg_adc_device_init()
+// to initialize the generic parts of the driver.
+//==========================================================================
+static bool at91_adc_init(struct cyg_devtab_entry *tab)
+{
+ cyg_adc_channel *chan = (cyg_adc_channel *)tab->priv;
+ cyg_adc_device *device = chan->device;
+ at91_adc_info *info = device->dev_priv;
+ cyg_uint32 regval;
+
+ if (!info->int_handle)
+ {
+ cyg_drv_interrupt_create(info->timer_vector,
+ info->timer_intprio,
+ (cyg_addrword_t)device,
+ &at91_adc_isr,
+ &at91_adc_dsr,
+ &(info->int_handle),
+ &(info->int_data));
+ cyg_drv_interrupt_attach(info->int_handle);
+ cyg_drv_interrupt_mask(info->timer_vector);
+
+ // Reset ADC
+ HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CR), AT91_ADC_CR_SWRST);
+
+ // Disable counter interrupts
+ HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+ HAL_WRITE_UINT32(info->tc_base+AT91_TC_IDR, 0xffffffff);
+
+ // Clear status bit
+ HAL_READ_UINT32(info->tc_base + AT91_TC_SR, regval);
+
+ // Enable peripheral clocks for TC
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, \
+ ((AT91_PMC_PCER_TC0) << info->timer_id));
+
+ //
+ // Disable all interrupts, all channels
+ //
+ HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CHDR), \
+ AT91_ADC_CHER_CH0 |\
+ AT91_ADC_CHER_CH1 |\
+ AT91_ADC_CHER_CH2 |\
+ AT91_ADC_CHER_CH3 |\
+ AT91_ADC_CHER_CH4 |\
+ AT91_ADC_CHER_CH5 |\
+ AT91_ADC_CHER_CH6 |\
+ AT91_ADC_CHER_CH7);
+ HAL_WRITE_UINT32((info->adc_base + AT91_ADC_IDR), \
+ AT91_ADC_CHER_CH0 |\
+ AT91_ADC_CHER_CH1 |\
+ AT91_ADC_CHER_CH2 |\
+ AT91_ADC_CHER_CH3 |\
+ AT91_ADC_CHER_CH4 |\
+ AT91_ADC_CHER_CH5 |\
+ AT91_ADC_CHER_CH6 |\
+ AT91_ADC_CHER_CH7);
+
+ //
+ // setup the default sample rate
+ //
+ at91_adc_set_rate(chan, chan->device->config.rate);
+
+ // setup ADC mode
+ HAL_WRITE_UINT32((info->adc_base + AT91_ADC_MR), \
+ ( ( info->adc_prescal << AT91_ADC_MR_PRESCAL_SHIFT ) & \
+ AT91_ADC_MR_PRESCAL_MASK ) | \
+ ( ( info->adc_startup_time << AT91_ADC_MR_STARTUP_SHIFT ) & \
+ AT91_ADC_MR_STARTUP_MASK ) | \
+ ( ( info->adc_shtim << AT91_ADC_MR_SHTIM_SHIFT ) & \
+ AT91_ADC_MR_SHTIM_MASK ) | \
+ AT91_ADC_MR_TRGSEL_TIOA0 | \
+ info->resolution);
+
+
+ } // if (!info->int_handle)
+
+ cyg_adc_device_init(device); // initialize generic parts of driver
+
+ return true;
+}
+
+
+//==========================================================================
+// This function is called when a client looks up or opens a channel. It
+// should call cyg_adc_channel_init() to initialize the generic part of
+// the channel. It should also perform any operations needed to start the
+// channel generating samples.
+//==========================================================================
+static Cyg_ErrNo at91_adc_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ cyg_adc_channel *chan = (cyg_adc_channel *)(*tab)->priv;
+ at91_adc_info *info = chan->device->dev_priv;
+
+ info->channel[chan->channel] = chan;
+ cyg_adc_channel_init(chan); // initialize generic parts of channel
+
+ //
+ // The generic ADC manual says: When a channel is first looked up or
+ // opened, then it is automatically enabled and samples start to
+ // accumulate - so we start the channel now
+ //
+ chan->enabled = true;
+ at91_adc_enable(chan);
+
+ return ENOERR;
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_ENABLE config operation.
+// It should take any steps needed to start the channel generating samples
+//==========================================================================
+static void at91_adc_enable(cyg_adc_channel *chan)
+{
+ at91_adc_info *info = chan->device->dev_priv;
+
+ // Enable the channel
+ HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CHER), \
+ AT91_ADC_CHER_CHx(chan->channel));
+
+ //
+ // Unmask interrupt as soon as 1 channel is enable
+ //
+ if (!info->chan_mask)
+ {
+ cyg_drv_interrupt_unmask(info->timer_vector);
+
+ // Enable timer interrupt
+ HAL_WRITE_UINT32(info->tc_base+AT91_TC_IER, AT91_TC_IER_CPC);
+
+ // Enable the clock
+ HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
+
+ // Start timer
+ HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_TRIG);
+
+ // Start ADC sampling
+ HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CR), AT91_ADC_CR_START);
+
+ }
+
+ info->chan_mask |= AT91_ADC_CHER_CHx(chan->channel);
+
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_DISABLE config operation.
+// It should take any steps needed to stop the channel generating samples.
+//==========================================================================
+static void at91_adc_disable(cyg_adc_channel *chan)
+{
+ at91_adc_info *info = chan->device->dev_priv;
+ cyg_uint32 sr;
+
+ info->chan_mask &= ~ AT91_ADC_CHER_CHx(chan->channel);
+
+ // Disable the channel
+ HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CHDR), \
+ AT91_ADC_CHER_CHx(chan->channel));
+
+ //
+ // If no channel is enabled the we disable interrupts now
+ //
+ if (!info->chan_mask)
+ {
+ cyg_drv_interrupt_mask(info->timer_vector);
+
+ // Clear interrupt
+ HAL_READ_UINT32(info->tc_base+AT91_TC_SR, sr);
+
+ // Disable timer interrupt
+ HAL_WRITE_UINT32(info->tc_base+AT91_TC_IDR, AT91_TC_IER_CPC);
+
+ // Disable the clock
+ HAL_WRITE_UINT32(info->tc_base+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+
+ }
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_RATE config operation.
+// It should take any steps needed to change the sample rate of the channel,
+// or of the entire device.
+// We use a timer channel to generate the interrupts for sampling the
+// analog channels
+//==========================================================================
+static void at91_adc_set_rate( cyg_adc_channel *chan, cyg_uint32 rate)
+{
+ cyg_adc_device *device = chan->device;
+ at91_adc_info *info = (at91_adc_info *)device->dev_priv;
+ cyg_uint8 timer_clk = AT91_TC_CMR_CLKS_MCK2;
+ cyg_uint32 tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 1);
+
+ if( tmr_period > 0xffff )
+ {
+ tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 5);
+ timer_clk = AT91_TC_CMR_CLKS_MCK32;
+ }
+
+ if( tmr_period > 0xffff )
+ {
+ tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 7);
+ timer_clk = AT91_TC_CMR_CLKS_MCK128;
+ }
+
+ if( tmr_period > 0xffff )
+ {
+ tmr_period = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / ( rate << 10);
+ timer_clk = AT91_TC_CMR_CLKS_MCK1024;
+ }
+
+ if( tmr_period > 0xffff )
+ {
+ tmr_period = 0xffff;
+ timer_clk = AT91_TC_CMR_CLKS_MCK1024;
+ at91_adc_printf("AT91 ADC timer, rate too high!");
+ }
+
+ device->config.rate = rate;
+ info->timer_clk = timer_clk;
+ info->timer_cnt = tmr_period;
+
+ // Set timer values
+ HAL_WRITE_UINT32(info->tc_base+AT91_TC_CMR, AT91_TC_CMR_CPCTRG | info->timer_clk);
+ HAL_WRITE_UINT32(info->tc_base+AT91_TC_RC, info->timer_cnt);
+
+ at91_adc_printf("AT91 ADC Timer settings %d, %d", info->timer_clk, info->timer_cnt);
+
+ return;
+}
+
+
+//==========================================================================
+// This function is the ISR attached to the ADC device's interrupt vector.
+// It is responsible for reading samples from the channels and passing them
+// on to the generic layer. It needs to check each channel for data, and call
+// cyg_adc_receive_sample() for each new sample available, and then ready the
+// device for the next interrupt.
+//==========================================================================
+static cyg_uint32 at91_adc_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_adc_device *device = (cyg_adc_device *) data;
+ at91_adc_info *info = (at91_adc_info *)device->dev_priv;
+ cyg_uint32 regval, adc_status;
+ cyg_uint32 res = 0;
+ cyg_adc_sample_t adcdata;
+ cyg_uint32 sr;
+
+ cyg_uint8 active_channels = info->chan_mask;
+ cyg_uint8 channel_no = 0;
+
+ // Clear timer interrupt
+ HAL_READ_UINT32(info->tc_base+AT91_TC_SR, sr);
+
+ // Check on channel conversion done
+ HAL_READ_UINT32(info->adc_base + AT91_ADC_SR, adc_status);
+
+ while (active_channels)
+ {
+ if (active_channels & 0x01)
+ {
+ // If ADC conversion done, save sample
+ if(adc_status & AT91_ADC_CHER_CHx(channel_no))
+ {
+ HAL_READ_UINT32((info->adc_base + AT91_ADC_CDR0 + AT91_ADC_CHER_CDRx(channel_no)), regval);
+ adcdata = regval & 0x3FF;
+ res |= CYG_ISR_HANDLED
+ | cyg_adc_receive_sample(info->channel[channel_no],
+ adcdata);
+ }
+ } // if (active_channels & 0x01)
+ active_channels >>= 1;
+ channel_no++;
+ } // while (active_channels)
+
+ // Restart sampling
+ HAL_WRITE_UINT32((info->adc_base + AT91_ADC_CR), AT91_ADC_CR_START);
+
+ cyg_drv_interrupt_acknowledge(info->timer_vector);
+
+ return res;
+}
+
+
+//==========================================================================
+// This function is the DSR attached to the ADC device's interrupt vector.
+// It is called by the kernel if the ISR return value contains the
+// CYG_ISR_HANDLED bit. It needs to call cyg_adc_wakeup() for each channel
+// that has its wakeup field set.
+//==========================================================================
+static void at91_adc_dsr(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data)
+{
+ cyg_adc_device *device = (cyg_adc_device *) data;
+ at91_adc_info *info = device->dev_priv;
+ cyg_uint8 active_channels = info->chan_mask;
+ cyg_uint8 chan_no = 0;
+
+ while (active_channels)
+ {
+ if (active_channels & 0x01)
+ {
+ if(info->channel[chan_no]->wakeup)
+ {
+ cyg_adc_wakeup(info->channel[chan_no]);
+ }
+ }
+ chan_no++;
+ active_channels >>= 1;
+ }
+}
+
+
+//---------------------------------------------------------------------------
+// eof adc_at91.c
diff --git a/ecos/packages/devs/adc/arm/at91/current/tests/at91_adc_test.c b/ecos/packages/devs/adc/arm/at91/current/tests/at91_adc_test.c
new file mode 100644
index 0000000..9199b04
--- /dev/null
+++ b/ecos/packages/devs/adc/arm/at91/current/tests/at91_adc_test.c
@@ -0,0 +1,290 @@
+//==========================================================================
+//
+// at91_adc_test.c
+//
+// ADC driver for AT91 on chip ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler <uwe_kindler@web.de>
+// Updated for Atmel AT91 device, ccoutand <ccoutand@stmi.com>
+// Contributors:
+// Date: 2010-02-15
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+// Package requirements
+#if defined(CYGPKG_IO_ADC) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/adc.h>
+#include <pkgconf/devs_adc_arm_at91.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/kernel/kapi.h>
+
+#if CYGINT_DEVS_ADC_ARM_AT91_ADC0_CHANNELS > 0
+
+#define MAX_ADC_CHANNEL_TO_TEST 4
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t adc_thread;
+thread_data_t adc_thread_data;
+
+
+//===========================================================================
+// ADC THREAD
+//===========================================================================
+void adc_thread(cyg_addrword_t data)
+{
+ int res;
+ cyg_io_handle_t handle[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ cyg_uint32 sample_cnt[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ cyg_uint32 cfg_data;
+ cyg_uint32 len;
+ cyg_uint32 start_time;
+ cyg_uint32 end_time;
+ int i;
+ cyg_uint8 seconds = 0;
+ float final_seconds;
+ cyg_uint32 samples_expected;
+
+
+ diag_printf("This test reads samples from all enabled ADC channels.\n"
+ "Each second the number of already acquired samples\n"
+ "will be printed. After 10 seconds all ADC channels\n"
+ "will be stopped and each ADC buffer will be read until\n"
+ "it is empty. If the number of acquired samples is much\n"
+ "smaller than the number of expected samples, then you\n"
+ "should lower the sample rate.\n\n");
+
+ // Get a handle for ADC device 0 channel 0 - 3 (lookup also trigger a channel enable)
+ res = cyg_io_lookup( "/dev/adc00", &handle[0]);
+ res = cyg_io_lookup( "/dev/adc01", &handle[1]);
+ res = cyg_io_lookup( "/dev/adc02", &handle[2]);
+ res = cyg_io_lookup( "/dev/adc03", &handle[3]);
+
+ //
+ // switch all channels to non blocking
+ //
+ for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+ {
+ if (handle[i])
+ {
+ cfg_data = 0;
+ len = sizeof(cfg_data);
+ res = cyg_io_set_config(handle[i],
+ CYG_IO_SET_CONFIG_READ_BLOCKING,
+ &cfg_data,
+ &len);
+ if (ENOERR != res)
+ {
+ CYG_TEST_FAIL_FINISH("Error switching ADC channel to non blocking");
+ }
+ sample_cnt[i] = 0;
+ }
+ }
+
+ start_time = cyg_current_time();
+ do
+ {
+ for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+ {
+ if (handle[i])
+ {
+ cyg_adc_sample_t sample;
+
+ // read a sample from the channel
+ do
+ {
+ cyg_uint32 len = sizeof(sample);
+ res = cyg_io_read( handle[i], &sample, &len );
+ }
+ while (-EAGAIN == res);
+ if (ENOERR == res)
+ {
+ sample_cnt[i]++;
+ }
+ } // if (handle[i])
+ }
+ //
+ // print number of acquired samples - if one second is expired.
+ // we expect that the number of acquired samples is nearly the
+ // sample rate
+ //
+ end_time = cyg_current_time();
+ if ((end_time - start_time) >= 100)
+ {
+ start_time = end_time;
+ diag_printf("%d\t %d\t %d\t %d\n",
+ sample_cnt[0],
+ sample_cnt[1],
+ sample_cnt[2],
+ sample_cnt[3]);
+ seconds++;
+ } // if ((end_time - start_time) >= 100)
+ } while (seconds < 10);
+
+ //
+ // Now stop all channels
+ //
+ for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+ {
+ if (handle[i])
+ {
+ res = cyg_io_set_config(handle[i],
+ CYG_IO_SET_CONFIG_ADC_DISABLE,
+ 0,
+ 0);
+ if (ENOERR != res)
+ {
+ CYG_TEST_FAIL_FINISH("Error disabling ADC channel");
+ }
+ } // if (handle[i])
+ }
+ end_time = cyg_current_time();
+ end_time = seconds * 1000 + (end_time - start_time) * 10;
+ final_seconds = end_time / 1000.0;
+
+ //
+ // Now read all remaining samples from buffer
+ //
+ for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i)
+ {
+ if (handle[i])
+ {
+ do
+ {
+ cyg_adc_sample_t sample;
+ cyg_uint32 len = sizeof(sample);
+ res = cyg_io_read( handle[i], &sample, &len );
+ if (ENOERR == res)
+ {
+ sample_cnt[i]++;
+ }
+ } while (ENOERR == res);
+ } // if (handle[i])
+ }
+
+ diag_printf("\n\n----------------------------------------\n");
+ samples_expected = final_seconds * CYGNUM_DEVS_ADC_ARM_AT91_ADC0_DEFAULT_RATE;
+ diag_printf("Samples expected after %d milliseconds: %d\n",
+ end_time, samples_expected);
+ diag_printf("Samples read (per channel):\n");
+ diag_printf("%d\t %d\t %d\t %d\n",
+ sample_cnt[0],
+ sample_cnt[1],
+ sample_cnt[2],
+ sample_cnt[3]);
+
+ CYG_TEST_PASS_FINISH("ADC test OK");
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // create the main ADC test thread
+ //
+ cyg_thread_create(4, adc_thread,
+ (cyg_addrword_t) 0,
+ "at91_adc_thread",
+ (void *) adc_thread_data.stack,
+ 1024 * sizeof(long),
+ &adc_thread_data.hdl,
+ &adc_thread_data.obj);
+
+ cyg_thread_resume(adc_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+#else // CYGINT_DEVS_ADC_ARM_AT91_CHANNELS > 0
+#define N_A_MSG "Needs at least one enabled ADC channel"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_ADC && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel and ADC support"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+
+// EOF can_tx.c
+
+//---------------------------------------------------------------------------
+// eof at91_adc_test.c
diff --git a/ecos/packages/devs/adc/arm/lpc24xx/current/ChangeLog b/ecos/packages/devs/adc/arm/lpc24xx/current/ChangeLog
new file mode 100755
index 0000000..b2b727f
--- /dev/null
+++ b/ecos/packages/devs/adc/arm/lpc24xx/current/ChangeLog
@@ -0,0 +1,30 @@
+2008-11-01 Uwe Kindler <uwe_kindler@web.de>
+
+ * LPC24xx ADC driver package created
+ * cdl/adc_lpc24xx.cdl
+ * src/adc_lpc24xx.c
+ * tests/lpc24xx_adc_test.c
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/adc/arm/lpc24xx/current/cdl/adc_lpc24xx.cdl b/ecos/packages/devs/adc/arm/lpc24xx/current/cdl/adc_lpc24xx.cdl
new file mode 100755
index 0000000..75c737d
--- /dev/null
+++ b/ecos/packages/devs/adc/arm/lpc24xx/current/cdl/adc_lpc24xx.cdl
@@ -0,0 +1,160 @@
+# ====================================================================
+#
+# adc_lpc24xx.cdl
+#
+# eCos LPC24xx ADC configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler <uwe_kindler@web.de>
+# Contributors:
+# Date: 2008-09-24
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_ADC_ARM_LPC24XX {
+ display "ADC hardware device driver for LPC24xx family of ARM controllers"
+
+ parent CYGPKG_IO_ADC_DEVICES
+ active_if CYGPKG_IO_ADC_DEVICES
+ active_if CYGPKG_HAL_ARM_LPC24XX
+ requires {CYGNUM_IO_ADC_SAMPLE_SIZE <= 10}
+ requires {CYGNUM_IO_ADC_SAMPLE_SIZE >= 3}
+ description "
+ This package provides a generic ADC device driver for the on-chip
+ ADC peripherals in LPX24xx processors."
+
+ include_dir cyg/io
+ compile -library=libextras.a adc_lpc24xx.c
+
+ cdl_interface CYGINT_DEVS_ADC_ARM_LPC24XX_CHANNELS {
+ display "Number of ADC channels"
+ }
+
+ cdl_option CYGPKG_DEVS_ADC_ARM_LPC24XX_DEBUG_LEVEL {
+ display "Driver debug output level"
+ flavor data
+ legal_values {0 1 2}
+ default_value 0
+ description "
+ This option specifies the level of debug data output by
+ the LPC24XX ADC device driver. A value of 0 signifies
+ no debug data output; 1 signifies normal debug data
+ output. If an overrun occurred then this can only be
+ detected by debug output messages."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_LPC24XX_INTPRIO {
+ display "Interrupt priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 15
+ description "
+ This option selects the interrupt priority for the ADC
+ interrupts. Timer 1 is used for generating the sample
+ clock. So this option configures the interrupt priority
+ for timer 1. There are 16 priority levels corresponding to
+ the values 0 through 15 decimal, of which 15 is the lowest
+ priority. The reset value of these registers defaults all
+ interrupts to the lowest priority, allowing a single write
+ to elevate the priority of an individual interrupt."
+ }
+
+
+ cdl_option CYGNUM_DEVS_ADC_ARM_LPC24XX_DEFAULT_RATE {
+ display "Default sample rate"
+ flavor data
+ legal_values 1 to 10000
+ default_value 100
+ description "
+ The driver will be initialized with the default sample rate.
+ If you raise the default sample rate you might need to increase
+ the buffer size for each channel."
+ }
+
+ # Support up to 8 ADC channels
+ for { set ::channel 0 } { $::channel < 8 } { incr ::channel } {
+
+ cdl_component CYGPKG_DEVS_ADC_ARM_LPC24XX_CHANNEL[set ::channel] {
+ display "Access ADC channel [set ::channel]"
+ flavor bool
+ default_value [set ::channel] == 0
+ implements CYGINT_DEVS_ADC_ARM_LPC24XX_CHANNELS
+ description "
+ If the application needs to access the on-chip ADC
+ channel [set ::channel] via an eCos ADC driver then
+ this option should be enabled."
+
+ cdl_option CYGDAT_DEVS_ADC_ARM_LPC24XX_CHANNEL[set ::channel]_NAME {
+ display "Device name"
+ flavor data
+ default_value [format {"\"/dev/adc0%d\""} $::channel]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+ cdl_option CYGDAT_DEVS_ADC_ARM_LPC24XX_CHANNEL[set ::channel]_BUFSIZE {
+ display "Size of data buffer"
+ flavor data
+ legal_values 0x01 to 0x2000000
+ default_value 512
+ description "
+ This option controls the number of samples the
+ buffer can store. The required RAM depends on the
+ sample size and on the number of samples. If the
+ sample size is <= 8 bit the the required RAM =
+ size of data buffer. If the sample size is 9 or 10
+ bit then required RAM = size of data buffer * 2."
+ }
+ }
+ }
+
+ cdl_option CYGPKG_DEVS_ADC_ARM_LPC24XX_TESTS {
+ display "Tests for LPC24xx ADC driver"
+ flavor data
+ no_define
+ calculated { "tests/lpc24xx_adc_test" }
+ description "
+ This option specifies the set of tests for the LPC24xx
+ ADC device driver."
+ }
+
+}
diff --git a/ecos/packages/devs/adc/arm/lpc24xx/current/src/adc_lpc24xx.c b/ecos/packages/devs/adc/arm/lpc24xx/current/src/adc_lpc24xx.c
new file mode 100755
index 0000000..5f8863f
--- /dev/null
+++ b/ecos/packages/devs/adc/arm/lpc24xx/current/src/adc_lpc24xx.c
@@ -0,0 +1,509 @@
+//==========================================================================
+//
+// adc_lpc24xx.c
+//
+// ADC driver for LPC24xx on chip ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler <uwe_kindler@web.de>
+// Contributors:
+// Date: 2008-09-21
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/devs_adc_arm_lpc24xx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/adc.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+
+
+//==========================================================================
+// DEFINES
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Register definition
+//
+#define ADC_BASE CYGARC_HAL_LPC24XX_REG_AD_BASE
+#define ADC_CR (ADC_BASE + 0x0000)
+#define ADC_GDR (ADC_BASE + 0x0004)
+#define ADC_INTEN (ADC_BASE + 0x000C)
+#define ADC_DR(_chan_) (ADC_BASE + 0x0010 + ((_chan_) << 2))
+#define ADC_STAT (ADC_BASE + 0x0030)
+
+#define DR_OVR (0x01 << 30)
+#define DR_DONE (0x01 << 31)
+#define CR_BURST (0x01 << 16)
+#define CR_PDN (0x01 << 21)
+
+
+#if CYGPKG_DEVS_ADC_ARM_LPC24XX_DEBUG_LEVEL > 0
+ #define debug1_printf(args...) diag_printf(args)
+#else
+ #define debug1_printf(args...)
+#endif
+
+#define LPC2XXX_CHAN_CNT 8 // maximum number of channels for LPC2xxx device
+
+
+//==========================================================================
+// DATA TYPES
+//==========================================================================
+typedef struct lpc2xxx_adc_info
+{
+ cyg_uint32 base; // base address of ADC peripheral
+ cyg_vector_t vector; // interrupt vector number
+ int intprio; // interrupt priority of ADC interrupt
+ cyg_handle_t int_handle; // For initializing the interrupt
+ cyg_interrupt int_data;
+ struct cyg_adc_channel* channel[LPC2XXX_CHAN_CNT]; // stores references to
+ // channel objects
+#if CYGPKG_DEVS_ADC_ARM_LPC24XX_DEBUG_LEVEL > 1
+ cyg_uint32 isr_cnt; // number of ISR = number of samples
+ cyg_uint32 zero_time;
+#endif // CYGPKG_DEVS_ADC_ARM_LPC24XX_DEBUG_LEVEL > 1
+ cyg_uint8 chan_mask; // mask that indicates channels used
+ // by ADC driver
+} lpc2xxx_adc_info;
+
+
+//==========================================================================
+// DECLARATIONS
+//==========================================================================
+static bool lpc2xxx_adc_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo lpc2xxx_adc_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static void lpc2xxx_adc_enable( cyg_adc_channel *chan );
+static void lpc2xxx_adc_disable( cyg_adc_channel *chan );
+static void lpc2xxx_adc_set_rate( cyg_adc_channel *chan, cyg_uint32 rate );
+static cyg_uint32 lpc2xxx_adc_isr(cyg_vector_t vector, cyg_addrword_t data);
+static void lpc2xxx_adc_dsr(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+
+
+//==========================================================================
+// Instantiate data structures
+
+// -------------------------------------------------------------------------
+// Driver functions:
+CYG_ADC_FUNCTIONS( lpc2xxx_adc_funs,
+ lpc2xxx_adc_enable,
+ lpc2xxx_adc_disable,
+ lpc2xxx_adc_set_rate );
+
+// -------------------------------------------------------------------------
+// Device instance:
+static lpc2xxx_adc_info lpc2xxx_adc_info0 =
+{
+ .base = CYGARC_HAL_LPC2XXX_REG_AD_BASE,
+ .vector = CYGNUM_HAL_INTERRUPT_TIMER1,
+ .intprio = CYGNUM_DEVS_ADC_ARM_LPC24XX_INTPRIO,
+ .int_handle = 0,
+#if CYGPKG_DEVS_ADC_ARM_LPC24XX_DEBUG_LEVEL > 0
+ .isr_cnt = 0,
+#endif
+ .chan_mask = 0
+};
+
+CYG_ADC_DEVICE( lpc2xxx_adc_device,
+ &lpc2xxx_adc_funs,
+ &lpc2xxx_adc_info0,
+ CYGNUM_DEVS_ADC_ARM_LPC24XX_DEFAULT_RATE);
+
+// -------------------------------------------------------------------------
+// Channel instances:
+
+#define LPC2XXX_ADC_CHANNEL( __chan ) \
+CYG_ADC_CHANNEL( lpc2xxx_adc_channel##__chan, \
+ __chan, \
+ CYGDAT_DEVS_ADC_ARM_LPC24XX_CHANNEL##__chan##_BUFSIZE, \
+ &lpc2xxx_adc_device ); \
+ \
+DEVTAB_ENTRY( lpc2xxx_adc_channel##__chan##_device, \
+ CYGDAT_DEVS_ADC_ARM_LPC24XX_CHANNEL##__chan##_NAME, \
+ 0, \
+ &cyg_io_adc_devio, \
+ lpc2xxx_adc_init, \
+ lpc2xxx_adc_lookup, \
+ &lpc2xxx_adc_channel##__chan );
+
+#ifdef CYGPKG_DEVS_ADC_ARM_LPC24XX_CHANNEL0
+LPC2XXX_ADC_CHANNEL(0);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_LPC24XX_CHANNEL1
+LPC2XXX_ADC_CHANNEL(1);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_LPC24XX_CHANNEL2
+LPC2XXX_ADC_CHANNEL(2);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_LPC24XX_CHANNEL3
+LPC2XXX_ADC_CHANNEL(3);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_LPC24XX_CHANNEL4
+LPC2XXX_ADC_CHANNEL(4);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_LPC24XX_CHANNEL5
+LPC2XXX_ADC_CHANNEL(5);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_LPC24XX_CHANNEL6
+LPC2XXX_ADC_CHANNEL(6);
+#endif
+#ifdef CYGPKG_DEVS_ADC_ARM_LPC24XX_CHANNEL7
+LPC2XXX_ADC_CHANNEL(7);
+#endif
+
+//==========================================================================
+// This function is called from the device IO infrastructure to initialize
+// the device. It should perform any work needed to start up the device,
+// short of actually starting the generation of samples. This function will
+// be called for each channel, so if there is initialization that only needs
+// to be done once, such as creating and interrupt object, then care should
+// be taken to do this. This function should also call cyg_adc_device_init()
+// to initialize the generic parts of the driver.
+//==========================================================================
+static bool lpc2xxx_adc_init(struct cyg_devtab_entry *tab)
+{
+ cyg_adc_channel *chan = (cyg_adc_channel *)tab->priv;
+ cyg_adc_device *device = chan->device;
+ lpc2xxx_adc_info *info = device->dev_priv;
+
+ if (!info->int_handle)
+ {
+ cyg_drv_interrupt_create(info->vector,
+ info->intprio,
+ (cyg_addrword_t)device,
+ &lpc2xxx_adc_isr,
+ &lpc2xxx_adc_dsr,
+ &(info->int_handle),
+ &(info->int_data));
+ cyg_drv_interrupt_attach(info->int_handle);
+ cyg_drv_interrupt_unmask(info->vector);
+
+ //
+ // The APB clock (PCLK) is divided by (this value plus one) to produce
+ // the clock for the A/D converter, which should be less than or equal
+ // to 4.5 MHz. Typically, software should program the smallest value in
+ // this field that yields a clock of 4.5 MHz or slightly less, but in
+ // certain cases (such as a high-impedance analog source) a slower
+ // clock may be desirable.
+ // Set clock division factor so ADC clock is <= 4.5 MHz
+ //
+ cyg_uint8 clkdiv = CYGNUM_HAL_ARM_LPC24XX_ADC_CLK / 4500001;
+
+ //
+ // Enable A/D converter and setup the configured sample size
+ // The eCos ADC I/O manual says: Channels are initialized in a disabled
+ // state and generate no samples - let's do this now
+ // We initialize the device to operate in burst mode and we enable
+ // conversion for all channels here
+ //
+ HAL_WRITE_UINT32(ADC_INTEN, 0); // disables all interrupts
+ HAL_WRITE_UINT32(ADC_CR, CR_BURST // burst mode
+ | CR_PDN // A/D converter is operational
+ | 0xFF // enable all channels
+ | ((10 - CYGNUM_IO_ADC_SAMPLE_SIZE) << 17)
+ | (clkdiv << 8));// set clock divider
+
+ //
+ // setup the default sample rate
+ //
+ lpc2xxx_adc_set_rate(chan, chan->device->config.rate);
+ } // if (!info->int_handle)
+
+ cyg_adc_device_init(device); // initialize generic parts of driver
+ return true;
+}
+
+
+//==========================================================================
+// This function is called when a client looks up or opens a channel. It
+// should call cyg_adc_channel_init() to initialize the generic part of
+// the channel. It should also perform any operations needed to start the
+// channel generating samples.
+//==========================================================================
+static Cyg_ErrNo lpc2xxx_adc_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ typedef struct adc_pin_cfg_st
+ {
+ cyg_uint8 port;
+ cyg_uint8 pin;
+ cyg_uint8 func;
+ } adc_pin_cfg_t;
+ static const adc_pin_cfg_t acd_pin_cfg_tbl[] =
+ {
+ {0, 23, 1},
+ {0, 24, 1},
+ {0, 25, 1},
+ {0, 26, 1},
+ {1, 30, 3},
+ {1, 31, 3},
+ {0, 12, 3},
+ {0, 13, 3},
+ };
+ cyg_adc_channel *chan = (cyg_adc_channel *)(*tab)->priv;
+ lpc2xxx_adc_info *info = chan->device->dev_priv;
+ adc_pin_cfg_t *pin_cfg = (adc_pin_cfg_t *)&acd_pin_cfg_tbl[chan->channel];
+
+ //
+ // This ADC driver is quite LP24xx specific. The pin function of each pin
+ // is well defined in the LP24xx specification. Therefore we can setup
+ // the pin function here. If someone decides that this driver can be used
+ // by other LPC2xxx or LPC3xxx variants too and that the driver should
+ // become more generic, then we might need to move the pin configuration
+ // out of this driver an into the variant / platform HAL
+ //
+ CYG_HAL_ARM_LPC24XX_PIN_CFG(pin_cfg->port, pin_cfg->pin, pin_cfg->func);
+ info->channel[chan->channel] = chan;
+ cyg_adc_channel_init(chan); // initialize generic parts of channel
+
+ //
+ // The generic ADC manual says: When a channel is first looked up or
+ // opened, then it is automatically enabled and samples start to
+ // accumulate - so we start the channel now
+ //
+ chan->enabled = true;
+ lpc2xxx_adc_enable(chan);
+
+ return ENOERR;
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_ENABLE config operation.
+// It should take any steps needed to start the channel generating samples
+//==========================================================================
+static void lpc2xxx_adc_enable(cyg_adc_channel *chan)
+{
+ cyg_uint32 regval;
+ lpc2xxx_adc_info *info = chan->device->dev_priv;
+
+ //
+ // Enable interrupts for timer to start generation of samples in timer
+ // ISR if this is the first channel that is enabled. If there are
+ // already some channels enabled, then the interrupt is already enabled
+ //
+ if (!info->chan_mask)
+ {
+ HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxMCR, regval);
+#if CYGPKG_DEVS_ADC_ARM_LPC24XX_DEBUG_LEVEL > 0
+ info->zero_time = cyg_current_time() * 10;
+#endif
+ regval |= CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_INT;
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxMCR, regval);
+ }
+
+ info->chan_mask |= (0x01 << chan->channel);
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_DISABLE config operation.
+// It should take any steps needed to stop the channel generating samples.
+//==========================================================================
+static void lpc2xxx_adc_disable(cyg_adc_channel *chan)
+{
+ cyg_uint32 regval;
+ lpc2xxx_adc_info *info = chan->device->dev_priv;
+
+ info->chan_mask &= ~(0x01 << chan->channel);
+
+ //
+ // If no channel is enabled the we disable interrupts now
+ //
+ if (!info->chan_mask)
+ {
+ HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxMCR, regval);
+ regval &= ~CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_INT;
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxMCR, regval);
+ }
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_RATE config operation.
+// It should take any steps needed to change the sample rate of the channel,
+// or of the entire device.
+// We use a timer channel to generate the interrupts for sampling the
+// analog channels
+//==========================================================================
+static void lpc2xxx_adc_set_rate( cyg_adc_channel *chan, cyg_uint32 rate)
+{
+ cyg_adc_device *device = chan->device;
+ cyg_uint32 regval;
+
+ cyg_uint32 tmr_period = hal_lpc_get_pclk(CYNUM_HAL_LPC24XX_PCLK_TIMER1) /
+ rate;
+ device->config.rate = rate;
+
+ //
+ // Disable and reset counter, set prescale register to 0 and
+ // Set up match register
+ //
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxTCR,
+ CYGARC_HAL_LPC24XX_REG_TxTCR_CTR_RESET);
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxPR, 0);
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxMR0, tmr_period);
+ //
+ // Reset on match and Enable counter
+ //
+ HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxMCR, regval);
+ regval |= CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_RESET; // reset on match
+ regval &= ~CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_STOP; // do not stop on match
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxMCR, regval);
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxTCR,
+ CYGARC_HAL_LPC24XX_REG_TxTCR_CTR_ENABLE);
+}
+
+
+//==========================================================================
+// This function is the ISR attached to the ADC device's interrupt vector.
+// It is responsible for reading samples from the channels and passing them
+// on to the generic layer. It needs to check each channel for data, and call
+// cyg_adc_receive_sample() for each new sample available, and then ready the
+// device for the next interrupt.
+//==========================================================================
+static cyg_uint32 lpc2xxx_adc_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_adc_device *device = (cyg_adc_device *) data;
+ lpc2xxx_adc_info *info = (lpc2xxx_adc_info *)device->dev_priv;
+ cyg_uint32 regval;
+ cyg_uint32 res = 0;
+ cyg_adc_sample_t adcdata;
+
+#if CYGPKG_DEVS_ADC_ARM_LPC24XX_DEBUG_LEVEL > 1
+ //
+ // Print debug information for channel 1 - this is the channel that
+ // triggers the interrupt and that is used for measuring lost samples
+ //
+ if (!(++info->isr_cnt % device->config.rate))
+ {
+ cyg_uint32 current_time_ms = cyg_current_time() * 10;
+ debug1_printf("ms %d smpl. %d\n",
+ current_time_ms - info->zero_time, info->isr_cnt);
+ info->zero_time = current_time_ms;
+ } // if (!(info->isr_count % device->config.rate))
+#endif // CYGPKG_DEVS_ADC_ARM_LPC24XX_DEBUG_LEVEL > 1
+
+ cyg_uint8 active_channels = info->chan_mask;
+ cyg_uint8 channel_no = 0;
+ while (active_channels)
+ {
+ if (active_channels & 0x01)
+ {
+ HAL_READ_UINT32(ADC_DR(channel_no), regval);
+ adcdata = (regval >> 6) & 0x3FF;
+ res |= CYG_ISR_HANDLED
+ | cyg_adc_receive_sample(info->channel[channel_no],
+ adcdata);
+ } // if (active_channels & 0x01)
+ active_channels >>= 1;
+ channel_no++;
+ } // while (active_channels)
+
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_TIMER1_BASE +
+ CYGARC_HAL_LPC24XX_REG_TxIR,
+ CYGARC_HAL_LPC24XX_REG_TxIR_MR0); // Clear interrupt
+ cyg_drv_interrupt_acknowledge(info->vector);
+ return res;
+}
+
+
+//==========================================================================
+// This function is the DSR attached to the ADC device's interrupt vector.
+// It is called by the kernel if the ISR return value contains the
+// CYG_ISR_HANDLED bit. It needs to call cyg_adc_wakeup() for each channel
+// that has its wakeup field set.
+//==========================================================================
+static void lpc2xxx_adc_dsr(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data)
+{
+ cyg_adc_device *device = (cyg_adc_device *) data;
+ lpc2xxx_adc_info *info = device->dev_priv;
+ cyg_uint8 active_channels = info->chan_mask;
+ cyg_uint8 chan_no = 0;
+
+ while (active_channels)
+ {
+ if (active_channels & 0x01)
+ {
+ if(info->channel[chan_no]->wakeup)
+ {
+ cyg_adc_wakeup(info->channel[chan_no]);
+ }
+ }
+ chan_no++;
+ active_channels >>= 1;
+ }
+}
+
+
+//---------------------------------------------------------------------------
+// eof adc_lpc24xx.c
diff --git a/ecos/packages/devs/adc/arm/lpc24xx/current/tests/lpc24xx_adc_test.c b/ecos/packages/devs/adc/arm/lpc24xx/current/tests/lpc24xx_adc_test.c
new file mode 100755
index 0000000..dae9531
--- /dev/null
+++ b/ecos/packages/devs/adc/arm/lpc24xx/current/tests/lpc24xx_adc_test.c
@@ -0,0 +1,300 @@
+//==========================================================================
+//
+// lpc24xx_adc_test.c
+//
+// ADC performance test for LPC24xxx
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors:
+// Date: 2008-11-01
+// Description: ADC performance test for LPC24xxx
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+// Package requirements
+#if defined(CYGPKG_IO_ADC) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/adc.h>
+#include <pkgconf/devs_adc_arm_lpc24xx.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/kernel/kapi.h>
+
+#if CYGINT_DEVS_ADC_ARM_LPC24XX_CHANNELS > 0
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t adc_thread;
+thread_data_t adc_thread_data;
+
+
+//===========================================================================
+// ADC THREAD
+//===========================================================================
+void adc_thread(cyg_addrword_t data)
+{
+ int res;
+ cyg_io_handle_t handle[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ cyg_uint32 sample_cnt[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ cyg_uint32 cfg_data;
+ cyg_uint32 len;
+ cyg_uint32 start_time;
+ cyg_uint32 end_time;
+ int i;
+ cyg_uint8 seconds = 0;
+ float final_seconds;
+ cyg_uint32 samples_expected;
+
+
+ diag_printf("This test reads samples from all enabled ADC channels.\n"
+ "Each second the number of already acquired samples\n"
+ "will be printed. After 10 seconds all ADC channels\n"
+ "will be stopped and each ADC buffer will be read until\n"
+ "it is empty. If the number of acquired samples is much\n"
+ "smaller than the number of expected samples, then you\n"
+ "should lower the sample rate.\n\n");
+
+ // Get a handle for ADC device 0 channel 1 - 8
+ res = cyg_io_lookup( "/dev/adc00", &handle[0]);
+ res = cyg_io_lookup( "/dev/adc01", &handle[1]);
+ res = cyg_io_lookup( "/dev/adc02", &handle[2]);
+ res = cyg_io_lookup( "/dev/adc03", &handle[3]);
+ res = cyg_io_lookup( "/dev/adc04", &handle[4]);
+ res = cyg_io_lookup( "/dev/adc05", &handle[5]);
+ res = cyg_io_lookup( "/dev/adc06", &handle[6]);
+ res = cyg_io_lookup( "/dev/adc07", &handle[7]);
+
+ //
+ // switch all channels to non blocking
+ //
+ for (i = 0; i < 8; ++i)
+ {
+ if (handle[i])
+ {
+ cfg_data = 0;
+ len = sizeof(cfg_data);
+ res = cyg_io_set_config(handle[i],
+ CYG_IO_SET_CONFIG_READ_BLOCKING,
+ &cfg_data,
+ &len);
+ if (ENOERR != res)
+ {
+ CYG_TEST_FAIL_FINISH("Error switching ADC channel to non blocking");
+ }
+ sample_cnt[i] = 0;
+ } // if (handle[i])
+ } // for (i = 0; i < 8; ++i)
+
+ start_time = cyg_current_time();
+ do
+ {
+ for (i = 0; i < 8; ++i)
+ {
+ if (handle[i])
+ {
+ cyg_adc_sample_t sample;
+
+ // read a sample from the channel
+ do
+ {
+ cyg_uint32 len = sizeof(sample);
+ res = cyg_io_read( handle[i], &sample, &len );
+ }
+ while (-EAGAIN == res);
+ if (ENOERR == res)
+ {
+ sample_cnt[i]++;
+ }
+ } // if (handle[i])
+ }
+ //
+ // print number of acquired samples - if one second is expired.
+ // we expect that the number of acquired samples is nearly the
+ // sample rate
+ //
+ end_time = cyg_current_time();
+ if ((end_time - start_time) >= 100)
+ {
+ start_time = end_time;
+ diag_printf("%d\t %d\t %d\t %d\t %d\t %d\t %d\t %d\n",
+ sample_cnt[0],
+ sample_cnt[1],
+ sample_cnt[2],
+ sample_cnt[3],
+ sample_cnt[4],
+ sample_cnt[5],
+ sample_cnt[6],
+ sample_cnt[7]);
+ seconds++;
+ } // if ((end_time - start_time) >= 100)
+ } while (seconds < 10);
+
+ //
+ // Now stop all channels
+ //
+ for (i = 0; i < 8; ++i)
+ {
+ if (handle[i])
+ {
+ res = cyg_io_set_config(handle[i],
+ CYG_IO_SET_CONFIG_ADC_DISABLE,
+ 0,
+ 0);
+ if (ENOERR != res)
+ {
+ CYG_TEST_FAIL_FINISH("Error disabling ADC channel");
+ }
+ } // if (handle[i])
+ }
+ end_time = cyg_current_time();
+ end_time = seconds * 1000 + (end_time - start_time) * 10;
+ final_seconds = end_time / 1000.0;
+
+ //
+ // Now read all remaining samples from buffer
+ //
+ for (i = 0; i < 8; ++i)
+ {
+ if (handle[i])
+ {
+ do
+ {
+ cyg_adc_sample_t sample;
+ cyg_uint32 len = sizeof(sample);
+ res = cyg_io_read( handle[i], &sample, &len );
+ if (ENOERR == res)
+ {
+ sample_cnt[i]++;
+ }
+ } while (ENOERR == res);
+ } // if (handle[i])
+ }
+
+ diag_printf("\n\n----------------------------------------\n");
+ samples_expected = final_seconds * CYGNUM_DEVS_ADC_ARM_LPC24XX_DEFAULT_RATE;
+ diag_printf("Samples expected after %d milliseconds: %d\n",
+ end_time, samples_expected);
+ diag_printf("Samples read (per channel):\n");
+ diag_printf("%d\t %d\t %d\t %d\t %d\t %d\t %d\t %d\n",
+ sample_cnt[0],
+ sample_cnt[1],
+ sample_cnt[2],
+ sample_cnt[3],
+ sample_cnt[4],
+ sample_cnt[5],
+ sample_cnt[6],
+ sample_cnt[7]);
+
+ CYG_TEST_PASS_FINISH("ADC test OK");
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // create the main ADC test thread
+ //
+ cyg_thread_create(4, adc_thread,
+ (cyg_addrword_t) 0,
+ "lpc24xx_adc_thread",
+ (void *) adc_thread_data.stack,
+ 1024 * sizeof(long),
+ &adc_thread_data.hdl,
+ &adc_thread_data.obj);
+
+ cyg_thread_resume(adc_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+#else // CYGINT_DEVS_ADC_ARM_LPC24XX_CHANNELS > 0
+#define N_A_MSG "Needs at least one enabled ADC channel"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_ADC && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel and ADC support"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+
+// EOF can_tx.c
+
+//---------------------------------------------------------------------------
+// eof i2c_test.c
+
diff --git a/ecos/packages/devs/adc/cortexm/lm3s/current/ChangeLog b/ecos/packages/devs/adc/cortexm/lm3s/current/ChangeLog
new file mode 100644
index 0000000..baabea6
--- /dev/null
+++ b/ecos/packages/devs/adc/cortexm/lm3s/current/ChangeLog
@@ -0,0 +1,31 @@
+2011-01-18 Christophe Coutand <ccoutand@stmi.com>
+
+ * cdl/adc_lm3s.cdl:
+ * src/adc_lm3s.c:
+ * include/adc_lm3s.inl:
+ * tests/lm3s_adc_test.c:
+ New package -- Stellaris Cortex M3 ADC driver package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/adc/cortexm/lm3s/current/cdl/adc_lm3s.cdl b/ecos/packages/devs/adc/cortexm/lm3s/current/cdl/adc_lm3s.cdl
new file mode 100644
index 0000000..ab2b765
--- /dev/null
+++ b/ecos/packages/devs/adc/cortexm/lm3s/current/cdl/adc_lm3s.cdl
@@ -0,0 +1,217 @@
+# ====================================================================
+#
+# adc_lm3s.cdl
+#
+# eCos Stellaris Cortex M3 ADC configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ccoutand
+# Contributors:
+# Date: 2011-01-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ADC_CORTEXM_LM3S {
+ display "ADC driver for Stellaris Cortex M3 microcontroller family"
+
+ parent CYGPKG_IO_ADC_DEVICES
+ active_if CYGPKG_IO_ADC_DEVICES
+ active_if CYGPKG_HAL_CORTEXM_LM3S
+ include_dir cyg/io
+ description "
+ This package provides a generic ADC device driver for the on-chip
+ ADC peripherals in Stellaris microcontroller."
+
+ compile -library=libextras.a adc_lm3s.c
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ADC_CORTEXM_LM3S_INL <cyg/io/adc_lm3s.inl>"
+ }
+
+ # ---------------------------------------------------------------------
+ # Primary ADC ( ADC0 ) port
+
+ cdl_component CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0 {
+ display "ADC port 0"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the device driver for the on-chip ADC0
+ of the Stellaris device."
+
+ cdl_interface CYGINT_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNELS {
+ display "Number of ADC0 channels"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_SELECT_TIMER {
+ display "ADC sampling timer"
+ flavor data
+ legal_values { 0 1 2 }
+ default_value 0
+ description "
+ This option selects the timer channel generating the
+ ADC sampling interval."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_INTPRIO {
+ display "ADC Interrupt priority"
+ flavor data
+ default_value 0x60
+ description "
+ This option selects the interrupt priority for the ADC
+ interrupts."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_DEFAULT_RATE {
+ display "Default sample rate"
+ flavor data
+ legal_values 1 to 10000
+ default_value 100
+ description "
+ The driver will be initialized with the default sample
+ rate. If you raise the default sample rate you might
+ need to increase the buffer size for each channel."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_AVERAGING {
+ display "Sample averaging"
+ flavor data
+ legal_values { 0 2 4 8 16 32 64 }
+ default_value 0
+ description "
+ Select the ADC sample averaging."
+ }
+
+ cdl_component CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_TEMP_SENSOR {
+ display "Internal Temperature Sensor"
+ flavor bool
+ default_value 0
+ description "
+ Enable one ADC channel for internal temperature sensor
+ reading."
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_TEMP_SENSOR_CHANNEL {
+ display "Select sensor channel"
+ flavor data
+ legal_values { 0 to (CYGINT_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNELS-1) }
+ default_value 1
+ description "
+ This option select ADC channel reserved for
+ temperature sensor reading."
+ }
+ }
+
+ # -----------------------------------------------------------------
+ # Support up to 8 ADC channels
+
+ for { set ::channel 0 } { $::channel < 8 } { incr ::channel } {
+ cdl_component CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL[set ::channel] {
+ display "Access ADC channel [set ::channel]"
+ flavor bool
+ default_value [set ::channel] == 0
+ implements CYGINT_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNELS
+ description "
+ If the application needs to access the on-chip ADC0
+ channel [set ::channel] via an eCos ADC driver then
+ this option should be enabled."
+
+ cdl_option CYGDAT_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL[set ::channel]_NAME {
+ display "Device name"
+ flavor data
+ default_value [format {"\"/dev/adc0%d\""} $::channel]
+ description "
+ This option controls the name that an eCos
+ application should use to access this device
+ via cyg_io_lookup(), open(), or similar calls."
+ }
+
+ cdl_option CYGDAT_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL[set ::channel]_BUFSIZE {
+ display "Size of data buffer"
+ flavor data
+ legal_values 0x01 to 0x16
+ default_value 0x4
+ description "
+ This option controls the number of samples the
+ buffer can store. The required RAM depends on the
+ sample size and on the number of samples. If the
+ sample size is <= 8 bit the the required RAM =
+ size of data buffer. If the sample size is 9 or 10
+ bit then required RAM = size of data buffer * 2."
+ }
+ }
+ }
+ }
+
+ cdl_option CYGPKG_DEVS_ADC_CORTEXM_LM3S_DEBUG_LEVEL {
+ display "Driver debug output level"
+ flavor data
+ legal_values { 0 1 }
+ default_value 0
+ description "
+ This option specifies the level of debug data output by
+ the Stellaris ADC device driver. A value of 0 signifies no
+ debug data output; 1 signifies normal debug data output. If
+ an overrun occurred then this can only be detected by debug
+ output messages."
+ }
+
+ cdl_component CYGSEM_DEVS_ADC_CORTEXM_LM3S_SAMPLE_SIZE_LIMIT {
+ display "Sample size limit"
+ flavor bool
+ calculated 1
+ requires { ( CYGNUM_IO_ADC_SAMPLE_SIZE == 10 ) }
+ description "
+ This component forces a limit (or rounds) the sample size
+ for Stellaris ADC channels which in the most are 10-bit."
+ }
+
+ cdl_option CYGPKG_DEVS_ADC_CORTEXM_LM3S_TESTS {
+ display "Tests for Stellaris 800 Series ADC driver"
+ flavor data
+ no_define
+ active_if CYGPKG_KERNEL
+ active_if CYGPKG_IO_ADC
+ calculated { "tests/lm3s_adc_test" }
+ description "
+ This option specifies the set of tests for the Stellaris
+ ADC device driver."
+ }
+}
+
+# EOF adc_lm3s.cdl
diff --git a/ecos/packages/devs/adc/cortexm/lm3s/current/include/adc_lm3s.inl b/ecos/packages/devs/adc/cortexm/lm3s/current/include/adc_lm3s.inl
new file mode 100644
index 0000000..655da59
--- /dev/null
+++ b/ecos/packages/devs/adc/cortexm/lm3s/current/include/adc_lm3s.inl
@@ -0,0 +1,140 @@
+//==========================================================================
+//
+// adc_lm3s.inl
+//
+// ADC driver for Stellaris Cortex M3 microcontroller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+//
+// Contributors:
+// Date: 2011-01-08
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef CYGONCE_DEVS_ADC_CORTEXM_LM3S_INL
+#define CYGONCE_DEVS_ADC_CORTEXM_LM3S_INL
+
+// Declare ADC0
+#ifdef CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0
+
+static lm3s_adc_info lm3s_adc0_info =
+{
+ .timer_base = CYGHWR_HAL_LM3S_GPTIM0 + ( 0x1000 * CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_SELECT_TIMER ),
+ .adc_intprio = CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_INTPRIO,
+ .adc_vector = CYGNUM_HAL_INTERRUPT_ADC0_S0,
+ .adc_base = CYGHWR_HAL_LM3S_ADC0,
+ .adc_periph = CYGHWR_HAL_LM3S_P_ADC0,
+ .timer_periph = (CYGHWR_HAL_LM3S_SC_RCGC1_TIMER0 << CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_SELECT_TIMER),
+#if CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_AVERAGING == 0
+ .adc_avg = 0,
+#elif CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_AVERAGING == 2
+ .adc_avg = 1,
+#elif CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_AVERAGING == 4
+ .adc_avg = 2,
+#elif CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_AVERAGING == 8
+ .adc_avg = 3,
+#elif CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_AVERAGING == 16
+ .adc_avg = 4,
+#elif CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_AVERAGING == 32
+ .adc_avg = 5,
+#elif CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_AVERAGING == 64
+ .adc_avg = 6,
+#endif
+#if defined(CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_TEMP_SENSOR)
+ .sensor_channel = CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_TEMP_SENSOR_CHANNEL,
+#else
+ .sensor_channel = 0xff,
+#endif
+ .max_channel = CYGINT_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNELS,
+ .int_handle = 0,
+ .chan_mask = 0
+};
+
+CYG_ADC_DEVICE( \
+ lm3s_adc0_device, \
+ &lm3s_adc_funs, \
+ &lm3s_adc0_info, \
+ CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_DEFAULT_RATE);
+
+#define LM3S_ADC0_CHANNEL( __chan ) \
+CYG_ADC_CHANNEL( \
+ lm3s_adc0_channel##__chan, \
+ __chan, \
+ CYGDAT_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL##__chan##_BUFSIZE, \
+ &lm3s_adc0_device ); \
+DEVTAB_ENTRY( \
+ lm3s_adc0_channel##__chan##_device, \
+ CYGDAT_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL##__chan##_NAME, \
+ 0, \
+ &cyg_io_adc_devio, \
+ lm3s_adc_init, \
+ lm3s_adc_lookup, \
+ &lm3s_adc0_channel##__chan );
+
+#ifdef CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL0
+LM3S_ADC0_CHANNEL(0);
+#endif
+#ifdef CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL1
+LM3S_ADC0_CHANNEL(1);
+#endif
+#ifdef CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL2
+LM3S_ADC0_CHANNEL(2);
+#endif
+#ifdef CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL3
+LM3S_ADC0_CHANNEL(3);
+#endif
+#ifdef CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL4
+LM3S_ADC0_CHANNEL(4);
+#endif
+#ifdef CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL5
+LM3S_ADC0_CHANNEL(5);
+#endif
+#ifdef CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL6
+LM3S_ADC0_CHANNEL(6);
+#endif
+#ifdef CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNEL7
+LM3S_ADC0_CHANNEL(7);
+#endif
+
+#endif // CYGPKG_DEVS_ADC_CORTEXM_LM3S_ADC0
+
+#endif // CYGONCE_DEVS_ADC_CORTEXM_LM3S_INL
diff --git a/ecos/packages/devs/adc/cortexm/lm3s/current/src/adc_lm3s.c b/ecos/packages/devs/adc/cortexm/lm3s/current/src/adc_lm3s.c
new file mode 100644
index 0000000..027e9c1
--- /dev/null
+++ b/ecos/packages/devs/adc/cortexm/lm3s/current/src/adc_lm3s.c
@@ -0,0 +1,489 @@
+//==========================================================================
+//
+// adc_lm3s.c
+//
+// ADC driver for Stellaris Cortex M3 microcontroller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler <uwe_kindler@web.de>
+// Updated for Stellaris device, ccoutand
+// Contributors:
+// Date: 2011-01-08
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/devs_adc_cortexm_lm3s.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/adc.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+#if CYGPKG_DEVS_ADC_CORTEXM_LM3S_DEBUG_LEVEL > 0
+# define lm3s_adc_diag(args...) diag_printf(args)
+#else
+# define lm3s_adc_diag(args...)
+#endif
+
+#define CYGHWR_HAL_LM3S_ADC_MAX_CHAN 8
+
+//==========================================================================
+// DATA TYPES
+//==========================================================================
+typedef struct lm3s_adc_info {
+ cyg_uint32 adc_base; // ADC base address
+ cyg_uint32 adc_periph; // ADC peripheral mask
+ cyg_vector_t adc_vector; // Interrupt vector number
+ cyg_priority_t adc_intprio; // Interrupt priority of ADC interrupt
+ cyg_uint32 timer_base; // Base address of Timer peripheral
+ cyg_uint32 timer_interval; // Timer value
+ cyg_uint32 timer_periph; // Timer peripheral mask
+ cyg_uint8 sensor_channel; // Temperature sensor channel if any
+ cyg_uint8 max_channel; // Number of ADC channel
+ cyg_handle_t int_handle; // For initializing the interrupt
+ cyg_interrupt int_data;
+ cyg_uint8 adc_avg; // Sample averaging
+ // Stores references to channel objects
+ struct cyg_adc_channel *channel[CYGHWR_HAL_LM3S_ADC_MAX_CHAN];
+ cyg_uint8 chan_mask; // Mask that indicates channels used
+ // by ADC driver
+} lm3s_adc_info;
+
+
+//==========================================================================
+// DECLARATIONS
+//==========================================================================
+static bool lm3s_adc_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo lm3s_adc_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static void lm3s_adc_enable(cyg_adc_channel * chan);
+static void lm3s_adc_disable(cyg_adc_channel * chan);
+static void lm3s_adc_set_rate(cyg_adc_channel * chan, cyg_uint32 rate);
+static cyg_uint32 lm3s_adc_isr(cyg_vector_t vector, cyg_addrword_t data);
+static void lm3s_adc_dsr(cyg_vector_t vector,
+ cyg_ucount32 count, cyg_addrword_t data);
+
+static void lm3s_adc_disable_sequencer0(cyg_uint32);
+static void lm3s_adc_enable_sequencer0(cyg_uint32);
+static void lm3s_adc_flush(cyg_uint32);
+static void lm3s_adc_update_sequencer0(cyg_adc_channel *);
+
+// -------------------------------------------------------------------------
+// Driver functions:
+CYG_ADC_FUNCTIONS( lm3s_adc_funs,
+ lm3s_adc_enable,
+ lm3s_adc_disable,
+ lm3s_adc_set_rate );
+
+
+#include CYGDAT_DEVS_ADC_CORTEXM_LM3S_INL // Instantiate ADCs
+
+
+//==========================================================================
+//
+// The eCos Sellaris ADC drivers uses a single sequencer ( sequencer 0 ).
+// The same sequencer is used to sample all channels.
+// Sampling of the different channel is triggered from a timer interrupt.
+// The ADC driver flexibility does not allow to trigger sampling from
+// external GPIO or analog comparator event. It should be noted that enabling
+// / disabling an ADC channel disturbs the sampling of other channels since it
+// requires to stop sampling to re-organize the sequencer. Also the FIFO
+// is flushed to ensure correct sample order out of the sequencer FIFO.
+//
+//==========================================================================
+static bool
+lm3s_adc_init(struct cyg_devtab_entry *tab)
+{
+ cyg_adc_channel *chan = (cyg_adc_channel *) tab->priv;
+ cyg_adc_device *device = chan->device;
+ lm3s_adc_info *info = device->dev_priv;
+
+ lm3s_adc_diag("ADC: Init\n");
+
+ if (!info->int_handle) {
+ lm3s_adc_diag("ADC: IRQ vect %d, pri %d\n",
+ info->adc_vector, info->adc_intprio);
+
+ cyg_drv_interrupt_create(info->adc_vector,
+ info->adc_intprio,
+ (cyg_addrword_t)device,
+ &lm3s_adc_isr,
+ &lm3s_adc_dsr,
+ &(info->int_handle), &(info->int_data));
+ cyg_drv_interrupt_attach(info->int_handle);
+ cyg_drv_interrupt_mask(info->adc_vector);
+
+ // Enable ADC and sampling timer peripheral
+ CYGHWR_HAL_LM3S_PERIPH_SET(info->adc_periph, 1);
+ CYGHWR_HAL_LM3S_PERIPH_SET((CYGHWR_HAL_LM3S_PERIPH_GC1 | info->
+ timer_periph), 1);
+
+ // Disable timer
+ HAL_WRITE_UINT32(info->timer_base + CYGHWR_HAL_LM3S_GPTIM_CTL, 0);
+
+ // Disable / reset sequencer
+ HAL_WRITE_UINT32(info->adc_base + CYGHWR_HAL_LM3S_ADC_ACTSS, 0);
+ HAL_WRITE_UINT32(info->adc_base + CYGHWR_HAL_LM3S_ADC_SS_MUX0, 0);
+ HAL_WRITE_UINT32(info->adc_base + CYGHWR_HAL_LM3S_ADC_SS_CTL0, 0);
+
+ // Trigger sampling from timer
+ HAL_WRITE_UINT32(info->adc_base + CYGHWR_HAL_LM3S_ADC_EMUX,
+ CYGHWR_HAL_LM3S_ADC_EMUX_EM_TIMER(0));
+
+ // Set Averaging
+ HAL_WRITE_UINT32(info->adc_base + CYGHWR_HAL_LM3S_ADC_SAC,
+ info->adc_avg);
+
+ // Setup timer
+ HAL_WRITE_UINT32(info->timer_base + CYGHWR_HAL_LM3S_GPTIM_CFG,
+ CYGHWR_HAL_LM3S_GPTIM_CFG_32BIT);
+ HAL_WRITE_UINT32(info->timer_base + CYGHWR_HAL_LM3S_GPTIM_TAMR,
+ CYGHWR_HAL_LM3S_GPTIM_TAMR_PERIODIC);
+
+ // Setup the default sample rate
+ lm3s_adc_set_rate(chan, chan->device->config.rate);
+
+ }
+
+ // Initialize generic parts of driver
+ cyg_adc_device_init(device);
+
+ return true;
+}
+
+
+//==========================================================================
+// This function is called when a client looks up or opens a channel. It
+// should call cyg_adc_channel_init() to initialize the generic part of
+// the channel. It should also perform any operations needed to start the
+// channel generating samples.
+//==========================================================================
+static Cyg_ErrNo
+lm3s_adc_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab, const char *name)
+{
+ cyg_adc_channel *chan = (cyg_adc_channel *) (*tab)->priv;
+ lm3s_adc_info *info = chan->device->dev_priv;
+
+ lm3s_adc_diag("ADC: Opening channel %d\n", chan->channel);
+
+ if (chan->channel > info->max_channel)
+ return ENOENT;
+
+ info->channel[chan->channel] = chan;
+
+ // Initialize generic parts of channel
+ cyg_adc_channel_init(chan);
+
+ // The generic ADC manual says: When a channel is first looked up or
+ // opened, then it is automatically enabled and samples start to
+ // accumulate - so we start the channel now
+ chan->enabled = true;
+ lm3s_adc_enable(chan);
+
+ return ENOERR;
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_ENABLE config operation.
+// It should take any steps needed to start the channel generating samples
+//==========================================================================
+static void
+lm3s_adc_enable(cyg_adc_channel * chan)
+{
+ lm3s_adc_info *info = chan->device->dev_priv;
+ cyg_uint32 ctl =
+ CYGHWR_HAL_LM3S_GPTIM_CTL_TAEN | CYGHWR_HAL_LM3S_GPTIM_CTL_TAOTE;
+ cyg_uint32 start = !info->chan_mask;
+
+ // Disable ADC sequencer 0 and timer
+ HAL_WRITE_UINT32(info->timer_base + CYGHWR_HAL_LM3S_GPTIM_CTL, 0);
+ lm3s_adc_disable_sequencer0(info->adc_base);
+
+ // Update sequencer
+ info->chan_mask |= (1 << chan->channel);
+ lm3s_adc_update_sequencer0(chan);
+
+ // Unmask interrupt as soon as 1 channel is enable
+ if (start) {
+ cyg_drv_interrupt_unmask(info->adc_vector);
+ }
+ // Enable sequencer and timer
+ lm3s_adc_enable_sequencer0(info->adc_base);
+ HAL_WRITE_UINT32(info->timer_base + CYGHWR_HAL_LM3S_GPTIM_CTL, ctl);
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_DISABLE config operation.
+// It should take any steps needed to stop the channel generating samples.
+//==========================================================================
+static void
+lm3s_adc_disable(cyg_adc_channel * chan)
+{
+ lm3s_adc_info *info = chan->device->dev_priv;
+ cyg_uint32 ctl =
+ CYGHWR_HAL_LM3S_GPTIM_CTL_TAEN | CYGHWR_HAL_LM3S_GPTIM_CTL_TAOTE;
+
+ // Disable ADC sequencer 0 and timer
+ HAL_WRITE_UINT32(info->timer_base + CYGHWR_HAL_LM3S_GPTIM_CTL, 0);
+ lm3s_adc_disable_sequencer0(info->adc_base);
+
+ // Update sequencer
+ info->chan_mask &= ~(1 << chan->channel);
+ lm3s_adc_update_sequencer0(chan);
+
+ // Stop scanning when no channel is active
+ if (!info->chan_mask) {
+ cyg_drv_interrupt_mask(info->adc_vector);
+ return;
+ }
+ // Enable sequencer and timer
+ lm3s_adc_enable_sequencer0(info->adc_base);
+ HAL_WRITE_UINT32(info->timer_base + CYGHWR_HAL_LM3S_GPTIM_CTL, ctl);
+}
+
+
+//==========================================================================
+// This function is called from the generic ADC package to enable the
+// channel in response to a CYG_IO_SET_CONFIG_ADC_RATE config operation.
+// It should take any steps needed to change the sample rate of the channel,
+// or of the entire device.
+// We use a timer channel to generate the interrupts for sampling the
+// analog channels
+//==========================================================================
+static void
+lm3s_adc_set_rate(cyg_adc_channel * chan, cyg_uint32 rate)
+{
+ cyg_adc_device *device = chan->device;
+ lm3s_adc_info *info = (lm3s_adc_info *) device->dev_priv;
+
+ info->timer_interval = hal_lm3s_timer_clock() / rate;
+
+ lm3s_adc_diag("ADC: Timer interval %d\n", info->timer_interval);
+
+ HAL_WRITE_UINT32(info->timer_base + CYGHWR_HAL_LM3S_GPTIM_TAILR,
+ info->timer_interval);
+}
+
+
+//==========================================================================
+// This function is the ISR attached to the ADC device's interrupt vector.
+// It is responsible for reading samples from the channels and passing them
+// on to the generic layer. It needs to check each channel for data, and call
+// cyg_adc_receive_sample() for each new sample available, and then ready the
+// device for the next interrupt.
+//==========================================================================
+static cyg_uint32
+lm3s_adc_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_adc_device *device = (cyg_adc_device *) data;
+ lm3s_adc_info *info = (lm3s_adc_info *) device->dev_priv;
+ cyg_uint32 regval;
+ cyg_uint32 res = 0;
+ cyg_adc_sample_t adcdata;
+ cyg_uint32 sr;
+
+ cyg_uint8 active_channels = info->chan_mask;
+ cyg_uint8 channel_no = 0;
+
+ while (active_channels) {
+ HAL_READ_UINT32(info->adc_base + CYGHWR_HAL_LM3S_ADC_SS_FIFO0_SR, sr);
+ // Check FIFO Full
+ if ((sr & CYGHWR_HAL_LM3S_ADC_SS_FIFO_SR_FULL)) {
+ lm3s_adc_diag("ADC: FIFO Full\n");
+ }
+ // Check FIFO Empty
+ if ((sr & CYGHWR_HAL_LM3S_ADC_SS_FIFO_SR_EMPTY)) {
+ lm3s_adc_diag("ADC: FIFO Empty\n");
+ }
+ if (active_channels & 0x01) {
+ // If ADC conversion done, save sample
+ if (!(sr & CYGHWR_HAL_LM3S_ADC_SS_FIFO_SR_EMPTY)) {
+ HAL_READ_UINT32(info->adc_base + CYGHWR_HAL_LM3S_ADC_SS_FIFO0,
+ regval);
+ adcdata = regval & 0x3FF;
+ res |= CYG_ISR_HANDLED
+ | cyg_adc_receive_sample(info->channel[channel_no],
+ adcdata);
+ }
+ }
+ active_channels >>= 1;
+ channel_no++;
+ }
+
+ HAL_WRITE_UINT32(info->adc_base + CYGHWR_HAL_LM3S_ADC_ISCR,
+ CYGHWR_HAL_LM3S_ADC_ISCR_IN(0));
+
+ cyg_drv_interrupt_acknowledge(info->adc_vector);
+
+ return res;
+}
+
+
+//==========================================================================
+// This function is the DSR attached to the ADC device's interrupt vector.
+// It is called by the kernel if the ISR return value contains the
+// CYG_ISR_HANDLED bit. It needs to call cyg_adc_wakeup() for each channel
+// that has its wakeup field set.
+//==========================================================================
+static void
+lm3s_adc_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_adc_device *device = (cyg_adc_device *) data;
+ lm3s_adc_info *info = device->dev_priv;
+ cyg_uint8 active_channels = info->chan_mask;
+ cyg_uint8 chan_no = 0;
+
+ while (active_channels) {
+ if (active_channels & 0x01) {
+ if (info->channel[chan_no]->wakeup) {
+ cyg_adc_wakeup(info->channel[chan_no]);
+ }
+ }
+ chan_no++;
+ active_channels >>= 1;
+ }
+}
+
+
+static void
+lm3s_adc_disable_sequencer0(cyg_uint32 base)
+{
+ cyg_uint32 reg;
+
+ HAL_WRITE_UINT32(base + CYGHWR_HAL_LM3S_ADC_IMR, 0);
+ HAL_WRITE_UINT32(base + CYGHWR_HAL_LM3S_ADC_ISCR,
+ CYGHWR_HAL_LM3S_ADC_ISCR_IN(0));
+ HAL_READ_UINT32(base + CYGHWR_HAL_LM3S_ADC_ACTSS, reg);
+ reg &= ~(CYGHWR_HAL_LM3S_ADC_ACTSS_ASEN(0));
+ HAL_WRITE_UINT32(base + CYGHWR_HAL_LM3S_ADC_ACTSS, reg);
+}
+
+
+static void
+lm3s_adc_enable_sequencer0(cyg_uint32 base)
+{
+ cyg_uint32 reg;
+
+ HAL_READ_UINT32(base + CYGHWR_HAL_LM3S_ADC_ACTSS, reg);
+ reg |= (CYGHWR_HAL_LM3S_ADC_ACTSS_ASEN(0));
+ HAL_WRITE_UINT32(base + CYGHWR_HAL_LM3S_ADC_ACTSS, reg);
+ HAL_WRITE_UINT32(base + CYGHWR_HAL_LM3S_ADC_IMR,
+ CYGHWR_HAL_LM3S_ADC_IMR_MASK(0));
+}
+
+
+static void
+lm3s_adc_flush(cyg_uint32 base)
+{
+ volatile cyg_uint32 d;
+ volatile cyg_uint32 i;
+
+ HAL_READ_UINT32(base + CYGHWR_HAL_LM3S_ADC_SS_FIFO0_SR, i);
+ while (!(i & CYGHWR_HAL_LM3S_ADC_SS_FIFO_SR_EMPTY)) {
+ HAL_READ_UINT32(base + CYGHWR_HAL_LM3S_ADC_SS_FIFO0, d);
+ HAL_READ_UINT32(base + CYGHWR_HAL_LM3S_ADC_SS_FIFO0_SR, i);
+ }
+}
+
+
+static void
+lm3s_adc_update_sequencer0(cyg_adc_channel * chan)
+{
+ lm3s_adc_info *info = chan->device->dev_priv;
+ cyg_uint8 i;
+ cyg_uint8 cnt = 0;
+ cyg_uint32 mux = 0;
+ cyg_uint32 ctl = 0;
+
+ lm3s_adc_diag("ADC: Update sequencer for channel %d\n", chan->channel);
+
+ // Update sequencer
+ for (i = 0; i < info->max_channel; i++) {
+ if (!(info->chan_mask & (1 << i)))
+ continue;
+
+ // Clear and update MUX register
+ mux &= ~(CYGHWR_HAL_LM3S_ADC_SS_MUX0_M(cnt));
+ mux |= CYGHWR_HAL_LM3S_ADC_SS_MUX0_V(i, cnt);
+
+ // Temperature sensor channel
+ if (i == info->sensor_channel) {
+ ctl |= CYGHWR_HAL_LM3S_ADC_SS_CTL0_TS(cnt);
+ lm3s_adc_diag("ADC: Channel %d mapped to temperature sensor\n",
+ i);
+ }
+
+ cnt++;
+ }
+
+ lm3s_adc_diag("ADC: MUX0 Register: 0x%x\n", mux);
+ HAL_WRITE_UINT32(info->adc_base + CYGHWR_HAL_LM3S_ADC_SS_MUX0, mux);
+
+ if (info->chan_mask) {
+ ctl |= CYGHWR_HAL_LM3S_ADC_SS_CTL0_END((cnt - 1));
+ ctl |= CYGHWR_HAL_LM3S_ADC_SS_CTL0_IE((cnt - 1));
+ }
+
+ lm3s_adc_diag("ADC: CTL0 Register: 0x%x\n", ctl);
+ HAL_WRITE_UINT32(info->adc_base + CYGHWR_HAL_LM3S_ADC_SS_CTL0, ctl);
+
+ lm3s_adc_flush(info->adc_base);
+}
+
+
+//---------------------------------------------------------------------------
+// EOF adc_lm3s.c
diff --git a/ecos/packages/devs/adc/cortexm/lm3s/current/tests/lm3s_adc_test.c b/ecos/packages/devs/adc/cortexm/lm3s/current/tests/lm3s_adc_test.c
new file mode 100644
index 0000000..ff0f161
--- /dev/null
+++ b/ecos/packages/devs/adc/cortexm/lm3s/current/tests/lm3s_adc_test.c
@@ -0,0 +1,256 @@
+//==========================================================================
+//
+// lm3s_adc_test.c
+//
+// ADC driver for Stellaris Cortex M3 microcontroller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler <uwe_kindler@web.de>
+// Updated for Stellaris Cortex microcontroller, ccoutand
+// Contributors:
+// Date: 2011-01-11
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/adc.h>
+#include <pkgconf/devs_adc_cortexm_lm3s.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+# include <cyg/kernel/kapi.h>
+
+# if CYGINT_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNELS > 0
+
+# define MAX_ADC_CHANNEL_TO_TEST 4
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data {
+ cyg_thread obj;
+ int stack[(CYGNUM_HAL_STACK_SIZE_MINIMUM / sizeof(int))];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t adc_thread;
+thread_data_t adc_thread_data;
+
+
+//===========================================================================
+// ADC THREAD
+//===========================================================================
+void
+adc_thread(cyg_addrword_t data)
+{
+ int res;
+ cyg_io_handle_t handle[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ cyg_uint32 sample_cnt[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ cyg_uint32 cfg_data;
+ cyg_uint32 len;
+ cyg_uint32 start_time;
+ cyg_uint32 end_time;
+ int i;
+ cyg_uint8 seconds = 0;
+ float final_seconds;
+ cyg_uint32 samples_expected;
+
+
+ diag_printf("This test reads samples from all enabled ADC channels.\n"
+ "Each second the number of already acquired samples\n"
+ "will be printed. After 10 seconds all ADC channels\n"
+ "will be stopped and each ADC buffer will be read until\n"
+ "it is empty. If the number of acquired samples is much\n"
+ "smaller than the number of expected samples, then you\n"
+ "should lower the sample rate.\n\n");
+
+ // Get a handle for ADC device 0 channel 0 - 3 (lookup also trigger a
+ // channel enable)
+ res = cyg_io_lookup("/dev/adc00", &handle[0]);
+ res = cyg_io_lookup("/dev/adc01", &handle[1]);
+ res = cyg_io_lookup("/dev/adc02", &handle[2]);
+ res = cyg_io_lookup("/dev/adc03", &handle[3]);
+
+ // Switch all channels to non blocking
+ for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i) {
+ if (handle[i]) {
+ cfg_data = 0;
+ len = sizeof(cfg_data);
+ res = cyg_io_set_config(handle[i],
+ CYG_IO_SET_CONFIG_READ_BLOCKING,
+ &cfg_data, &len);
+ if (ENOERR != res) {
+ CYG_TEST_FAIL_FINISH
+ ("Error switching ADC channel to non blocking");
+ }
+ sample_cnt[i] = 0;
+ }
+ }
+
+ start_time = cyg_current_time();
+
+ do {
+ for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i) {
+ if (handle[i]) {
+ cyg_adc_sample_t sample;
+
+ // read a sample from the channel
+ do {
+ cyg_uint32 len = sizeof(sample);
+ res = cyg_io_read(handle[i], &sample, &len);
+ }
+ while (-EAGAIN == res);
+ if (ENOERR == res) {
+ sample_cnt[i]++;
+ }
+ }
+ }
+
+ end_time = cyg_current_time();
+
+ // Print number of acquired samples - if one second is expired.
+ // we expect that the number of acquired samples is nearly the
+ // sample rate.
+ if ((end_time - start_time) >= 100) {
+ start_time = end_time;
+ diag_printf("%d\t %d\t %d\t %d\n",
+ sample_cnt[0],
+ sample_cnt[1], sample_cnt[2], sample_cnt[3]);
+ seconds++;
+ }
+ } while (seconds < 10);
+
+ // Now stop all channels
+ for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i) {
+ if (handle[i]) {
+ res = cyg_io_set_config(handle[i],
+ CYG_IO_SET_CONFIG_ADC_DISABLE, 0, 0);
+ if (ENOERR != res) {
+ CYG_TEST_FAIL_FINISH("Error disabling ADC channel");
+ }
+ }
+ }
+
+ end_time = cyg_current_time();
+ end_time = seconds * 1000 + (end_time - start_time) * 10;
+ final_seconds = end_time / 1000.0;
+
+ // Now read all remaining samples from buffer
+ for (i = 0; i < MAX_ADC_CHANNEL_TO_TEST; ++i) {
+ if (handle[i]) {
+ do {
+ cyg_adc_sample_t sample;
+ cyg_uint32 len = sizeof(sample);
+ res = cyg_io_read(handle[i], &sample, &len);
+ if (ENOERR == res) {
+ sample_cnt[i]++;
+ }
+ } while (ENOERR == res);
+ }
+ }
+
+ diag_printf("\n\n----------------------------------------\n");
+ samples_expected =
+ final_seconds * CYGNUM_DEVS_ADC_CORTEXM_LM3S_ADC0_DEFAULT_RATE;
+ diag_printf("Samples expected after %d milliseconds: %d\n", end_time,
+ samples_expected);
+ diag_printf("Samples read (per channel):\n");
+ diag_printf("%d\t %d\t %d\t %d\n",
+ sample_cnt[0], sample_cnt[1], sample_cnt[2], sample_cnt[3]);
+
+ CYG_TEST_PASS_FINISH("ADC test OK");
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ // Create the main ADC test thread
+ cyg_thread_create(4,
+ adc_thread,
+ (cyg_addrword_t)0,
+ "lm3s_adc_thread",
+ (void *)adc_thread_data.stack,
+ CYGNUM_HAL_STACK_SIZE_MINIMUM,
+ &adc_thread_data.hdl,
+ &adc_thread_data.obj
+ );
+
+ cyg_thread_resume(adc_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+# else// CYGINT_DEVS_ADC_CORTEXM_LM3S_ADC0_CHANNELS > 0
+# define N_A_MSG "Needs at least one enabled ADC channel"
+# endif
+
+#else // CYGFUN_KERNEL_API_C
+# define N_A_MSG "Needs kernel C API"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+
+//---------------------------------------------------------------------------
+// EOF lm3s_adc_test.c
diff --git a/ecos/packages/devs/adc/cortexm/stm32/current/ChangeLog b/ecos/packages/devs/adc/cortexm/stm32/current/ChangeLog
new file mode 100644
index 0000000..30f9008
--- /dev/null
+++ b/ecos/packages/devs/adc/cortexm/stm32/current/ChangeLog
@@ -0,0 +1,53 @@
+2012-04-13 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * src/adc_stm32.c:
+ * src/adc1.inl:
+ * src/adc3.inl:
+ Peripheral clocks are enable / disable using new
+ CYGHWR_HAL_STM32_CLOCK_DISABLE / CYGHWR_HAL_STM32_CLOCK_ENABLE
+ macro supplied from the variant HAL. In addition, make sure timer
+ clock is enable.
+
+2011-05-02 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * cdl/adc_stm32.cdl:
+ * src/adc_stm32.c:
+ Make sure DMA clock is enabled. Fix ADC clock divider not set in
+ stm32_adc_init_clock.
+
+2009-03-05 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/adc_stm32.c:
+ Fixed a bug in setup and usage of the timer.
+
+2009-02-24 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * cdl/adc_stm32.cdl:
+ * src/adc_stm32.c:
+ * src/adc1.inl:
+ * src/adc3.inl:
+ STM32 ADC driver package created.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/adc/cortexm/stm32/current/cdl/adc_stm32.cdl b/ecos/packages/devs/adc/cortexm/stm32/current/cdl/adc_stm32.cdl
new file mode 100644
index 0000000..4187a50
--- /dev/null
+++ b/ecos/packages/devs/adc/cortexm/stm32/current/cdl/adc_stm32.cdl
@@ -0,0 +1,242 @@
+# ====================================================================
+#
+# adc_stm32.cdl
+#
+# eCos STM32 ADC configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2009, 2011 Free Software Foundation, Inc
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Simon Kallweit <simon.kallweit@intefo.ch>
+# Contributors:
+# Date: 2009-02-24
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_ADC_CORTEXM_STM32 {
+ display "ST STM32 ADC device driver"
+
+ parent CYGPKG_IO_ADC_DEVICES
+ active_if CYGPKG_IO_ADC_DEVICES
+ active_if CYGPKG_HAL_CORTEXM_STM32
+ requires {CYGNUM_IO_ADC_SAMPLE_SIZE >= 12}
+ description "
+ This option enables the ADC device drivers for the ST STM32. The STM32
+ has up to 3 ADC devices. The driver supports both ADC1 and ADC3. ADC2
+ is not supported as it does cover the same inputs as ADC2 and does not
+ support DMA directly."
+
+ include_dir cyg/io
+ compile -library=libextras.a adc_stm32.c
+
+ cdl_option CYGPKG_DEVS_ADC_CORTEXM_STM32_TRACE {
+ display "ADC driver tracing"
+ flavor bool
+ default_value 0
+ description "
+ Enable tracing of the ADC driver. Select to debug the driver."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_STM32_CLOCK_DIV {
+ display "ADC clock divider"
+ flavor data
+ legal_values { 2 4 6 8 }
+ default_value 8
+ description "
+ This option specifies the ADC clock divider value. The
+ ADC clock frequency is defined as PCLK2 / ADC divider. "
+ }
+
+ cdl_component CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1 {
+ display "ADC1"
+ default_value 0
+ description "
+ ADC1 supports 16 analog input channels as well as additional
+ channels for CPU temperature and internal VREF. This is a total of
+ 18 channels. Note that only 16 channels may be active at once!
+ ADC1 uses TIM3 to generate scan events and DMA1 channel 1 for data
+ transmission."
+
+ cdl_interface CYGINT_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNELS {
+ display "Number of ADC channels"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC1_SAMPLE_TIME {
+ display "Sample time"
+ flavor data
+ legal_values 1 to 1000
+ default_value 20
+ description "
+ Sampling time in us. When sampling the internal temperatur,
+ this needs to be at least 17.1 us."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC1_DEFAULT_RATE {
+ display "Default sample rate"
+ flavor data
+ legal_values 1 to 10000
+ default_value 100
+ description "
+ The driver will be initialized with the default sample rate.
+ If you raise the default sample rate you might need to increase
+ the buffer size for each channel."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC1_DMA_INT_PRI {
+ display "DMA interrupt priority"
+ flavor data
+ default_value 0x80
+ description "
+ Priority of the DMA request interrupt."
+ }
+
+ # ADC1 supports 16 analog inputs + 2 additional channels (temperature/vref)
+ for { set ::channel 0 } { $::channel < 18 } { incr ::channel } {
+
+ cdl_component CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL[set ::channel] {
+ display "ADC channel [set ::channel]"
+ flavor bool
+ default_value [set ::channel] == 0
+ implements CYGINT_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNELS
+ description "
+ If the application needs to access the on-chip ADC
+ channel [set ::channel] via an eCos ADC driver then
+ this option should be enabled."
+
+ cdl_option CYGDAT_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL[set ::channel]_NAME {
+ display "Device name"
+ flavor data
+ default_value [format {"\"/dev/adc0%d\""} $::channel]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+ cdl_option CYGDAT_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL[set ::channel]_BUFSIZE {
+ display "Size of data buffer"
+ flavor data
+ legal_values 1 to 65536
+ default_value 128
+ description "
+ This option controls the number of samples the
+ buffer can store. The required RAM is = size of
+ data buffer * 2."
+ }
+ }
+ }
+ }
+
+ cdl_component CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3 {
+ display "ADC3"
+ default_value 0
+ description "
+ ADC3 supports 16 analog input channels. All channels may be active
+ at once. ADC3 uses TIM8 to generate scan events and DMA2 channel 5
+ for data transmission."
+
+ cdl_interface CYGINT_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNELS {
+ display "Number of ADC channels"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC3_SAMPLE_TIME {
+ display "Sample time"
+ flavor data
+ legal_values 1 to 1000
+ default_value 20
+ description "
+ Sampling time in us. When sampling the internal temperatur,
+ this needs to be at least 17.1 us."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC3_DEFAULT_RATE {
+ display "Default sample rate"
+ flavor data
+ legal_values 1 to 10000
+ default_value 100
+ description "
+ The driver will be initialized with the default sample rate.
+ If you raise the default sample rate you might need to increase
+ the buffer size for each channel."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC3_DMA_INT_PRI {
+ display "DMA interrupt priority"
+ flavor data
+ default_value 0x80
+ description "
+ Priority of the DMA request interrupt."
+ }
+
+ # ADC3 supports 16 analog inputs
+ for { set ::channel 0 } { $::channel < 16 } { incr ::channel } {
+
+ cdl_component CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL[set ::channel] {
+ display "ADC channel [set ::channel]"
+ flavor bool
+ default_value [set ::channel] == 0
+ implements CYGINT_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNELS
+ description "
+ If the application needs to access the on-chip ADC
+ channel [set ::channel] via an eCos ADC driver then
+ this option should be enabled."
+
+ cdl_option CYGDAT_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL[set ::channel]_NAME {
+ display "Device name"
+ flavor data
+ default_value [format {"\"/dev/adc1%d\""} $::channel]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+ cdl_option CYGDAT_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL[set ::channel]_BUFSIZE {
+ display "Size of data buffer"
+ flavor data
+ legal_values 1 to 65536
+ default_value 128
+ description "
+ This option controls the number of samples the
+ buffer can store. The required RAM is = size of
+ data buffer * 2."
+ }
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/adc/cortexm/stm32/current/src/adc1.inl b/ecos/packages/devs/adc/cortexm/stm32/current/src/adc1.inl
new file mode 100644
index 0000000..0394c1f
--- /dev/null
+++ b/ecos/packages/devs/adc/cortexm/stm32/current/src/adc1.inl
@@ -0,0 +1,163 @@
+//==========================================================================
+//
+// adc1.inl
+//
+// Parameters for ADC device 1
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Simon Kallweit <simon.kallweit@intefo.ch>
+// Contributors:
+// Date: 2009-02-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// ADC input pins
+static const cyg_uint32 stm32_adc_pins1[] = {
+ CYGHWR_HAL_STM32_ADC1_IN0,
+ CYGHWR_HAL_STM32_ADC1_IN1,
+ CYGHWR_HAL_STM32_ADC1_IN2,
+ CYGHWR_HAL_STM32_ADC1_IN3,
+ CYGHWR_HAL_STM32_ADC1_IN4,
+ CYGHWR_HAL_STM32_ADC1_IN5,
+ CYGHWR_HAL_STM32_ADC1_IN6,
+ CYGHWR_HAL_STM32_ADC1_IN7,
+ CYGHWR_HAL_STM32_ADC1_IN8,
+ CYGHWR_HAL_STM32_ADC1_IN9,
+ CYGHWR_HAL_STM32_ADC1_IN10,
+ CYGHWR_HAL_STM32_ADC1_IN11,
+ CYGHWR_HAL_STM32_ADC1_IN12,
+ CYGHWR_HAL_STM32_ADC1_IN13,
+ CYGHWR_HAL_STM32_ADC1_IN14,
+ CYGHWR_HAL_STM32_ADC1_IN15,
+ CYGHWR_HAL_STM32_GPIO_NONE,
+ CYGHWR_HAL_STM32_GPIO_NONE,
+};
+
+// ADC setup
+static const stm32_adc_setup stm32_adc_setup1 = {
+ .adc_base = CYGHWR_HAL_STM32_ADC1,
+ .dma_base = CYGHWR_HAL_STM32_DMA1,
+ .dma_int_vector = CYGNUM_HAL_INTERRUPT_DMA1_CH1,
+ .dma_int_pri = CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC1_DMA_INT_PRI,
+ .dma_channel = 1,
+ .tim_base = CYGHWR_HAL_STM32_TIM3,
+ .pins = stm32_adc_pins1,
+ .extsel = 4,
+ .sample_time = CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC1_SAMPLE_TIME,
+ .adc_clkena = CYGHWR_HAL_STM32_ADC1_CLOCK,
+ .tim_clkena = CYGHWR_HAL_STM32_TIM3_CLOCK,
+};
+
+// ADC DMA buffer
+static cyg_uint16
+ stm32_adc_dma_buf1[CYGINT_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNELS]
+ __attribute__((aligned(2), section(".sram")));
+
+// ADC device info
+static stm32_adc_info stm32_adc_info1 = {
+ .setup = &stm32_adc_setup1,
+ .dma_buf = stm32_adc_dma_buf1,
+};
+
+// ADC device instance
+CYG_ADC_DEVICE(stm32_adc_device1,
+ &stm32_adc_funs,
+ &stm32_adc_info1,
+ CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC1_DEFAULT_RATE);
+
+// ADC channels
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL0
+STM32_ADC_CHANNEL(1, 0)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL1
+STM32_ADC_CHANNEL(1, 1)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL2
+STM32_ADC_CHANNEL(1, 2)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL3
+STM32_ADC_CHANNEL(1, 3)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL4
+STM32_ADC_CHANNEL(1, 4)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL5
+STM32_ADC_CHANNEL(1, 5)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL6
+STM32_ADC_CHANNEL(1, 6)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL7
+STM32_ADC_CHANNEL(1, 7)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL8
+STM32_ADC_CHANNEL(1, 8)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL9
+STM32_ADC_CHANNEL(1, 9)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL10
+STM32_ADC_CHANNEL(1, 10)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL11
+STM32_ADC_CHANNEL(1, 11)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL12
+STM32_ADC_CHANNEL(1, 12)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL13
+STM32_ADC_CHANNEL(1, 13)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL14
+STM32_ADC_CHANNEL(1, 14)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL15
+STM32_ADC_CHANNEL(1, 15)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL16
+STM32_ADC_CHANNEL(1, 16)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1_CHANNEL17
+STM32_ADC_CHANNEL(1, 17)
+#endif
+
+//-----------------------------------------------------------------------------
+// End of adc1.inl
diff --git a/ecos/packages/devs/adc/cortexm/stm32/current/src/adc3.inl b/ecos/packages/devs/adc/cortexm/stm32/current/src/adc3.inl
new file mode 100644
index 0000000..790c1ac
--- /dev/null
+++ b/ecos/packages/devs/adc/cortexm/stm32/current/src/adc3.inl
@@ -0,0 +1,155 @@
+//==========================================================================
+//
+// adc3.inl
+//
+// Parameters for ADC device 3
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Simon Kallweit <simon.kallweit@intefo.ch>
+// Contributors:
+// Date: 2009-02-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// ADC input pins
+static const cyg_uint32 stm32_adc_pins3[] = {
+ CYGHWR_HAL_STM32_ADC3_IN0,
+ CYGHWR_HAL_STM32_ADC3_IN1,
+ CYGHWR_HAL_STM32_ADC3_IN2,
+ CYGHWR_HAL_STM32_ADC3_IN3,
+ CYGHWR_HAL_STM32_ADC3_IN4,
+ CYGHWR_HAL_STM32_ADC3_IN5,
+ CYGHWR_HAL_STM32_ADC3_IN6,
+ CYGHWR_HAL_STM32_ADC3_IN7,
+ CYGHWR_HAL_STM32_ADC3_IN8,
+ CYGHWR_HAL_STM32_ADC3_IN9,
+ CYGHWR_HAL_STM32_ADC3_IN10,
+ CYGHWR_HAL_STM32_ADC3_IN11,
+ CYGHWR_HAL_STM32_ADC3_IN12,
+ CYGHWR_HAL_STM32_ADC3_IN13,
+ CYGHWR_HAL_STM32_ADC3_IN14,
+ CYGHWR_HAL_STM32_ADC3_IN15,
+};
+
+// ADC setup
+static const stm32_adc_setup stm32_adc_setup3 = {
+ .adc_base = CYGHWR_HAL_STM32_ADC3,
+ .dma_base = CYGHWR_HAL_STM32_DMA2,
+ .dma_int_vector = CYGNUM_HAL_INTERRUPT_DMA2_CH4_5,
+ .dma_int_pri = 0x80,
+ .dma_channel = 5,
+ .tim_base = CYGHWR_HAL_STM32_TIM8,
+ .pins = stm32_adc_pins3,
+ .extsel = 4,
+ .sample_time = CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC3_SAMPLE_TIME,
+ .adc_clkena = CYGHWR_HAL_STM32_ADC3_CLOCK,
+ .tim_clkena = CYGHWR_HAL_STM32_TIM8_CLOCK,
+};
+
+// ADC DMA buffer
+static cyg_uint16
+ stm32_adc_dma_buf3[CYGINT_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNELS]
+ __attribute__((aligned(2), section(".sram")));
+
+// ADC device info
+static stm32_adc_info stm32_adc_info3 = {
+ .setup = &stm32_adc_setup3,
+ .dma_buf = stm32_adc_dma_buf3,
+};
+
+// ADC device instance
+CYG_ADC_DEVICE(stm32_adc_device3,
+ &stm32_adc_funs,
+ &stm32_adc_info3,
+ CYGNUM_DEVS_ADC_CORTEXM_STM32_ADC3_DEFAULT_RATE);
+
+// ADC channels
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL0
+STM32_ADC_CHANNEL(3, 0)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL1
+STM32_ADC_CHANNEL(3, 1)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL2
+STM32_ADC_CHANNEL(3, 2)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL3
+STM32_ADC_CHANNEL(3, 3)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL4
+STM32_ADC_CHANNEL(3, 4)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL5
+STM32_ADC_CHANNEL(3, 5)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL6
+STM32_ADC_CHANNEL(3, 6)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL7
+STM32_ADC_CHANNEL(3, 7)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL8
+STM32_ADC_CHANNEL(3, 8)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL9
+STM32_ADC_CHANNEL(3, 9)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL10
+STM32_ADC_CHANNEL(3, 10)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL11
+STM32_ADC_CHANNEL(3, 11)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL12
+STM32_ADC_CHANNEL(3, 12)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL13
+STM32_ADC_CHANNEL(3, 13)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL14
+STM32_ADC_CHANNEL(3, 14)
+#endif
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3_CHANNEL15
+STM32_ADC_CHANNEL(3, 15)
+#endif
+
+//-----------------------------------------------------------------------------
+// End of adc3.inl
diff --git a/ecos/packages/devs/adc/cortexm/stm32/current/src/adc_stm32.c b/ecos/packages/devs/adc/cortexm/stm32/current/src/adc_stm32.c
new file mode 100644
index 0000000..5a7a0e6
--- /dev/null
+++ b/ecos/packages/devs/adc/cortexm/stm32/current/src/adc_stm32.c
@@ -0,0 +1,631 @@
+//==========================================================================
+//
+// adc_stm32.c
+//
+// ADC driver for STM32 on chip ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Simon Kallweit <simon.kallweit@intefo.ch>
+// Contributors:
+// Date: 2009-02-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_adc_cortexm_stm32.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/io/adc.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+//-----------------------------------------------------------------------------
+// Diagnostic support
+// Switch the #if to 1 to generate some diagnostic messages.
+
+#ifdef CYGPKG_DEVS_ADC_CORTEXM_STM32_TRACE
+# include <cyg/infra/diag.h>
+# define adc_diag( __fmt, ... ) diag_printf("ADC: %30s[%4d]: " __fmt, __FUNCTION__, __LINE__, ## __VA_ARGS__ );
+#else
+# define adc_diag( __fmt, ... )
+#endif
+
+
+//-----------------------------------------------------------------------------
+// STM32 ADC device setup
+
+typedef struct stm32_adc_setup {
+ CYG_ADDRESS adc_base; // ADC registers base address
+ CYG_ADDRESS dma_base; // DMA registers base address
+ cyg_vector_t dma_int_vector; // DMA interrupt vector
+ cyg_priority_t dma_int_pri; // DMA interrupt priority
+ cyg_uint8 dma_channel; // DMA channel to use
+ CYG_ADDRESS tim_base; // Timer registers base address
+ const cyg_uint32 *pins; // ADC associated GPIO pins
+ cyg_uint8 extsel; // ADC EXTSEL value (timer event)
+ cyg_uint32 sample_time; // ADC sampling time in us
+ cyg_uint32 adc_clkena; // ADC clock enable
+ cyg_uint32 tim_clkena; // Timer clock enable
+} stm32_adc_setup;
+
+//-----------------------------------------------------------------------------
+// STM32 ADC device
+
+typedef struct stm32_adc_info {
+ const stm32_adc_setup *setup; // ADC setup
+ cyg_handle_t dma_int_handle; // DMA interrupt handle
+ cyg_interrupt dma_int_data; // DMA interrupt data
+ cyg_uint16 *dma_buf; // DMA buffer
+ cyg_adc_channel *chan[18]; // Channel references by channel no
+ cyg_uint32 chan_mask; // Channel mask
+} stm32_adc_info;
+
+//-----------------------------------------------------------------------------
+// API function call forward references
+
+static bool stm32_adc_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo stm32_adc_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+
+static void stm32_adc_enable(cyg_adc_channel *chan);
+static void stm32_adc_disable(cyg_adc_channel *chan);
+static void stm32_adc_set_rate(cyg_adc_channel *chan, cyg_uint32 rate);
+
+static cyg_uint32 stm32_dma_isr(cyg_vector_t vector, cyg_addrword_t data);
+static void stm32_dma_dsr(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+
+static void stm32_adc_init_clock(void);
+static void stm32_adc_init_device(cyg_adc_device *device);
+static void stm32_adc_update_sequence(cyg_adc_device *device);
+
+CYG_ADC_FUNCTIONS(stm32_adc_funs,
+ stm32_adc_enable,
+ stm32_adc_disable,
+ stm32_adc_set_rate);
+
+//-----------------------------------------------------------------------------
+// STM32 ADC channel instance macro
+
+#define STM32_ADC_CHANNEL(_device_, _chan_) \
+CYG_ADC_CHANNEL( \
+ stm32_adc##_device_##_channel##_chan_, \
+ _chan_, \
+ CYGDAT_DEVS_ADC_CORTEXM_STM32_ADC##_device_##_CHANNEL##_chan_##_BUFSIZE,\
+ &stm32_adc_device##_device_ \
+); \
+DEVTAB_ENTRY( \
+ stm32_adc##_device_##_channel##_chan_##_device, \
+ CYGDAT_DEVS_ADC_CORTEXM_STM32_ADC##_device_##_CHANNEL##_chan_##_NAME, \
+ 0, \
+ &cyg_io_adc_devio, \
+ stm32_adc_init, \
+ stm32_adc_lookup, \
+ &stm32_adc##_device_##_channel##_chan_ \
+);
+
+//-----------------------------------------------------------------------------
+// STM32 ADC device instances
+
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC1
+#include "adc1.inl"
+#endif
+
+#ifdef CYGHWR_DEVS_ADC_CORTEXM_STM32_ADC3
+#include "adc3.inl"
+#endif
+
+static cyg_bool initialized;
+static cyg_uint32 adc_clock;
+
+__externC cyg_uint32 hal_stm32_pclk1;
+__externC cyg_uint32 hal_stm32_pclk2;
+
+//-----------------------------------------------------------------------------
+// This function is called from the device IO infrastructure to initialize the
+// device. It should perform any work needed to start up the device, short of
+// actually starting the generation of samples. This function will be called
+// for each channel, so if there is initialization that only needs to be done
+// once, such as creating and interrupt object, then care should be taken to do
+// this. This function should also call cyg_adc_device_init() to initialize the
+// generic parts of the driver.
+
+static bool
+stm32_adc_init(struct cyg_devtab_entry *tab)
+{
+ cyg_adc_channel *chan = (cyg_adc_channel *) tab->priv;
+ cyg_adc_device *device = chan->device;
+ stm32_adc_info *info = device->dev_priv;
+
+ adc_diag("Initializing device\n");
+
+ // Initialize ADC clock
+ if (!initialized) {
+ stm32_adc_init_clock();
+ initialized = true;
+ }
+
+ // Keep reference to channel
+ info->chan[chan->channel] = chan;
+
+ if (!info->dma_int_handle) {
+ // Initialize ADC device
+ stm32_adc_init_device(device);
+
+ // Set default rate
+ stm32_adc_set_rate(chan, chan->device->config.rate);
+
+ // Initialize DMA interrupt
+ cyg_drv_interrupt_create(info->setup->dma_int_vector,
+ info->setup->dma_int_pri,
+ (cyg_addrword_t) device,
+ &stm32_dma_isr,
+ &stm32_dma_dsr,
+ &info->dma_int_handle,
+ &info->dma_int_data);
+ cyg_drv_interrupt_attach(info->dma_int_handle);
+ cyg_drv_interrupt_unmask(info->setup->dma_int_vector);
+ }
+
+ // Initialize generic parts of ADC device
+ cyg_adc_device_init(device);
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// This function is called when a client looks up or opens a channel. It should
+// call cyg_adc_channel_init() to initialize the generic part of the channel.
+// It should also perform any operations needed to start the channel generating
+// samples.
+
+static Cyg_ErrNo
+stm32_adc_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ cyg_adc_channel *chan = (cyg_adc_channel *) (*tab)->priv;
+ stm32_adc_info *info = chan->device->dev_priv;
+ cyg_uint32 cr;
+
+ adc_diag("Opening device\n");
+
+ // Configure the input pin, if available
+ if (info->setup->pins[chan->channel] != CYGHWR_HAL_STM32_GPIO_NONE)
+ CYGHWR_HAL_STM32_GPIO_SET(info->setup->pins[chan->channel]);
+
+ // Activate temperature and VREF if necessary
+ if (chan->channel >= 16) {
+ HAL_READ_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+ cr |= CYGHWR_HAL_STM32_ADC_CR2_TSVREFE;
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+ }
+
+ // Initialize generic parts of the channel
+ cyg_adc_channel_init(chan);
+
+ // The generic ADC manual says: When a channel is first looked up or
+ // opened, then it is automatically enabled and samples start to
+ // accumulate - so we start the channel now
+ chan->enabled = true;
+ stm32_adc_enable(chan);
+
+ return ENOERR;
+}
+
+//-----------------------------------------------------------------------------
+// This function is called from the generic ADC package to enable the channel
+// in response to a CYG_IO_SET_CONFIG_ADC_ENABLE config operation. It should
+// take any steps needed to start the channel generating samples
+
+static void
+stm32_adc_enable(cyg_adc_channel *chan)
+{
+ stm32_adc_info *info = chan->device->dev_priv;
+ cyg_uint32 cr;
+ cyg_bool start;
+
+ adc_diag("Enabling channel\n");
+
+ start = !info->chan_mask;
+
+ // Update the scanning sequence
+ info->chan_mask |= (1 << chan->channel);
+ stm32_adc_update_sequence(chan->device);
+
+ // Start scanning when first channel was activated
+ if (start) {
+ // Enable timer
+ adc_diag("Starting scanning\n");
+ HAL_READ_UINT32(info->setup->tim_base + CYGHWR_HAL_STM32_TIM_CR1, cr);
+ cr |= CYGHWR_HAL_STM32_TIM_CR1_CEN;
+ HAL_WRITE_UINT32(info->setup->tim_base + CYGHWR_HAL_STM32_TIM_CR1, cr);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// This function is called from the generic ADC package to enable the channel
+// in response to a CYG_IO_SET_CONFIG_ADC_DISABLE config operation. It should
+// take any steps needed to stop the channel generating samples.
+
+static void
+stm32_adc_disable(cyg_adc_channel *chan)
+{
+ stm32_adc_info *info = chan->device->dev_priv;
+ cyg_uint32 cr;
+
+ adc_diag("Disabling channel\n");
+
+ // Update scanning sequence
+ info->chan_mask &= ~(1 << chan->channel);
+ stm32_adc_update_sequence(chan->device);
+
+ // Stop scanning when no channel is active
+ if (!info->chan_mask) {
+ // Disable timer
+ adc_diag("Stopping scanning\n");
+ HAL_READ_UINT32(info->setup->tim_base + CYGHWR_HAL_STM32_TIM_CR1, cr);
+ cr &= ~CYGHWR_HAL_STM32_TIM_CR1_CEN;
+ HAL_WRITE_UINT32(info->setup->tim_base + CYGHWR_HAL_STM32_TIM_CR1, cr);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// This function is called from the generic ADC package to enable the channel
+// in response to a CYG_IO_SET_CONFIG_ADC_RATE config operation. It should take
+// any steps needed to change the sample rate of the channel, or of the entire
+// device. We use a timer channel to generate the interrupts for sampling the
+// analog channels
+
+static void
+stm32_adc_set_rate( cyg_adc_channel *chan, cyg_uint32 rate)
+{
+ cyg_adc_device *device = chan->device;
+ stm32_adc_info *info = device->dev_priv;
+ cyg_uint32 clock;
+ cyg_uint32 period, prescaler;
+ cyg_uint32 cr;
+
+ adc_diag("Setting rate to %d\n", rate);
+
+ device->config.rate = rate;
+
+ clock = hal_stm32_timer_clock(info->setup->tim_base);
+
+ period = clock / rate;
+ prescaler = (period / 0x10000) + 1;
+ period = period / prescaler;
+
+ HAL_WRITE_UINT32(info->setup->tim_base + CYGHWR_HAL_STM32_TIM_PSC,
+ prescaler - 1);
+ HAL_WRITE_UINT32(info->setup->tim_base + CYGHWR_HAL_STM32_TIM_ARR,
+ period - 1);
+
+ // Reinitialize timer
+ cr = CYGHWR_HAL_STM32_TIM_EGR_UG;
+ HAL_WRITE_UINT32(info->setup->tim_base + CYGHWR_HAL_STM32_TIM_EGR, cr);
+}
+
+//-----------------------------------------------------------------------------
+// This function is the ISR attached to the ADC device's DMA channel interrupt
+// vector. It is responsible for reading samples from the DMA buffer and
+// passing them on to the generic layer.
+
+static cyg_uint32
+stm32_dma_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_adc_device *device = (cyg_adc_device *) data;
+ stm32_adc_info *info = (stm32_adc_info *) device->dev_priv;
+ cyg_uint32 chan_active = info->chan_mask;
+ cyg_uint16 *sample = info->dma_buf;
+ cyg_adc_channel **chan = info->chan;
+ cyg_uint32 isr;
+ cyg_uint32 res = CYG_ISR_HANDLED;
+
+ HAL_READ_UINT32(info->setup->dma_base + CYGHWR_HAL_STM32_DMA_ISR, isr);
+ if (!(isr & CYGHWR_HAL_STM32_DMA_ISR_MASK(info->setup->dma_channel)))
+ return 0;
+
+ while (chan_active) {
+ if (chan_active & 0x1)
+ res |= cyg_adc_receive_sample(*chan, *sample++ & 0xfff);
+ chan_active >>= 1;
+ chan++;
+ }
+
+ HAL_WRITE_UINT32(info->setup->dma_base + CYGHWR_HAL_STM32_DMA_IFCR,
+ CYGHWR_HAL_STM32_DMA_IFCR_MASK(info->setup->dma_channel));
+
+ cyg_drv_interrupt_acknowledge(vector);
+
+ return res;
+}
+
+//-----------------------------------------------------------------------------
+// This function is the DSR attached to the ADC device's DMA channel interrupt
+// vector. It is called by the kernel if the ISR return value contains the
+// CYG_ISR_CALL_DSR bit. It needs to call cyg_adc_wakeup() for each channel
+// that has its wakeup field set.
+
+static void
+stm32_dma_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_adc_device *device = (cyg_adc_device *) data;
+ stm32_adc_info *info = (stm32_adc_info *) device->dev_priv;
+ cyg_uint32 chan_active = info->chan_mask;
+ cyg_adc_channel **chan = info->chan;
+
+ while (chan_active) {
+ if (chan_active & 0x1)
+ if ((*chan)->wakeup)
+ cyg_adc_wakeup(*chan);
+ chan_active >>= 1;
+ chan++;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Initializes the ADC system clock.
+
+static void
+stm32_adc_init_clock(void)
+{
+ CYG_ADDRESS rcc = CYGHWR_HAL_STM32_RCC;
+ cyg_uint32 cfgr;
+
+ adc_diag("Initializing ADC system clock\n");
+
+ HAL_READ_UINT32(rcc + CYGHWR_HAL_STM32_RCC_CFGR, cfgr);
+ cfgr &= ~CYGHWR_HAL_STM32_RCC_CFGR_ADCPRE_XXX;
+
+#if CYGNUM_DEVS_ADC_CORTEXM_STM32_CLOCK_DIV == 2
+ cfgr |= CYGHWR_HAL_STM32_RCC_CFGR_ADCPRE_2;
+ adc_clock = hal_stm32_pclk2 / 2;
+#elif CYGNUM_DEVS_ADC_CORTEXM_STM32_CLOCK_DIV == 4
+ cfgr |= CYGHWR_HAL_STM32_RCC_CFGR_ADCPRE_4;
+ adc_clock = hal_stm32_pclk2 / 4;
+#elif CYGNUM_DEVS_ADC_CORTEXM_STM32_CLOCK_DIV == 6
+ cfgr |= CYGHWR_HAL_STM32_RCC_CFGR_ADCPRE_6;
+ adc_clock = hal_stm32_pclk2 / 6;
+#elif CYGNUM_DEVS_ADC_CORTEXM_STM32_CLOCK_DIV == 8
+ cfgr |= CYGHWR_HAL_STM32_RCC_CFGR_ADCPRE_8;
+ adc_clock = hal_stm32_pclk2 / 8;
+#endif
+
+ HAL_WRITE_UINT32(rcc + CYGHWR_HAL_STM32_RCC_CFGR, cfgr);
+}
+
+//-----------------------------------------------------------------------------
+// Initializes an ADC device.
+
+static void
+stm32_adc_init_device(cyg_adc_device *device)
+{
+ stm32_adc_info *info = device->dev_priv;
+ cyg_uint32 cr;
+ cyg_uint64 tmp;
+ cyg_uint32 cycles;
+ cyg_uint32 smpr;
+ int i;
+
+ static const cyg_uint32 cycles_table[] =
+ { 15, 75, 135, 285, 415, 555, 715, 2395 };
+
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( info->setup->adc_clkena );
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( info->setup->tim_clkena );
+
+ // Make sure ADC is powered on
+ cr = CYGHWR_HAL_STM32_ADC_CR2_ADON;
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+
+ // Reset calibration
+ cr |= CYGHWR_HAL_STM32_ADC_CR2_RSTCAL;
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+ do {
+ HAL_READ_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+ } while (cr & CYGHWR_HAL_STM32_ADC_CR2_RSTCAL);
+
+ // Do calibration
+ cr |= CYGHWR_HAL_STM32_ADC_CR2_CAL;
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+ do {
+ HAL_READ_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+ } while (cr & CYGHWR_HAL_STM32_ADC_CR2_CAL);
+
+ // Power off ADC
+ cr &= ~CYGHWR_HAL_STM32_ADC_CR2_ADON;
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+
+ // Enable external triggering and DMA
+ cr |= CYGHWR_HAL_STM32_ADC_CR2_DMA |
+ CYGHWR_HAL_STM32_ADC_CR2_EXTTRIG |
+ CYGHWR_HAL_STM32_ADC_CR2_EXTSEL(info->setup->extsel);
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+
+ // Enable scanning
+ cr = CYGHWR_HAL_STM32_ADC_CR1_SCAN;
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR1, cr);
+
+
+ // Set timer direction = down, clock divider = 1
+ cr = CYGHWR_HAL_STM32_TIM_CR1_DIR | CYGHWR_HAL_STM32_TIM_CR1_CKD_1;
+ HAL_WRITE_UINT32(info->setup->tim_base + CYGHWR_HAL_STM32_TIM_CR1, cr);
+
+ // Enable generation of TRGO event
+ cr = CYGHWR_HAL_STM32_TIM_CR2_MMS_UPDATE;
+ HAL_WRITE_UINT32(info->setup->tim_base + CYGHWR_HAL_STM32_TIM_CR2, cr);
+
+
+ // Setup DMA channel
+ // Ensure that the DMA clocks are enabled.
+ if (info->setup->dma_base == CYGHWR_HAL_STM32_DMA1)
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( CYGHWR_HAL_STM32_DMA1_CLOCK );
+ else
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( CYGHWR_HAL_STM32_DMA2_CLOCK );
+
+ HAL_WRITE_UINT32(info->setup->dma_base +
+ CYGHWR_HAL_STM32_DMA_CPAR(info->setup->dma_channel),
+ info->setup->adc_base + CYGHWR_HAL_STM32_ADC_DR);
+ HAL_WRITE_UINT32(info->setup->dma_base +
+ CYGHWR_HAL_STM32_DMA_CMAR(info->setup->dma_channel),
+ (CYG_ADDRESS) info->dma_buf);
+ HAL_WRITE_UINT32(info->setup->dma_base +
+ CYGHWR_HAL_STM32_DMA_CNDTR(info->setup->dma_channel),
+ 0);
+ HAL_WRITE_UINT32(info->setup->dma_base +
+ CYGHWR_HAL_STM32_DMA_CCR(info->setup->dma_channel),
+ CYGHWR_HAL_STM32_DMA_CCR_TCIE |
+ CYGHWR_HAL_STM32_DMA_CCR_TEIE |
+ CYGHWR_HAL_STM32_DMA_CCR_CIRC |
+ CYGHWR_HAL_STM32_DMA_CCR_MINC |
+ CYGHWR_HAL_STM32_DMA_CCR_PSIZE16 |
+ CYGHWR_HAL_STM32_DMA_CCR_MSIZE16);
+
+ // Compute duration of a single cycle in pico-seconds
+ tmp = 1000000000000LL / adc_clock;
+ // Compute tenths of cycles for target sample time
+ tmp = (info->setup->sample_time * 1000000 * 10) / tmp;
+ cycles = tmp;
+
+ adc_diag("Setting ADC sample time to %d us (%d.%d cycles)\n",
+ info->setup->sample_time, cycles / 10, cycles % 10);
+
+ // Find best matching SMPR value
+ if (cycles > cycles_table[7]) {
+ adc_diag("ADC sample time too long\n");
+ smpr = 7;
+ } else {
+ for (smpr = 7; smpr > 0; smpr--)
+ if (cycles > cycles_table[smpr])
+ break;
+ }
+
+ // Expand SMPR value to all channels
+ for (i = 0; i < 10; i++)
+ smpr |= smpr << 3;
+
+ // Set sampling time
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_SMPR1, smpr);
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_SMPR2, smpr);
+}
+
+//-----------------------------------------------------------------------------
+// Updates the sequence for the regular group. ADC and DMA are disabled during
+// the update. The sequence registers and DMA count registers are rewritten.
+// Note: As the regular group consists of 16 channels max, we cannot activate
+// the theoretical maximum of 18 channels (analog ins + temperature/VREF).
+
+static void
+stm32_adc_update_sequence(cyg_adc_device *device)
+{
+ stm32_adc_info *info = device->dev_priv;
+ int i;
+ int count = 0;
+ cyg_uint32 cr;
+ cyg_uint32 sqr1 = 0;
+ cyg_uint32 sqr2 = 0;
+ cyg_uint32 sqr3 = 0;
+
+ adc_diag("Updating regular group\n");
+
+ // Disable ADC
+ HAL_READ_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+ cr &= ~CYGHWR_HAL_STM32_ADC_CR2_ADON;
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+
+ // Disable DMA
+ HAL_READ_UINT32(info->setup->dma_base +
+ CYGHWR_HAL_STM32_DMA_CCR(info->setup->dma_channel), cr);
+ cr &= ~CYGHWR_HAL_STM32_DMA_CCR_EN;
+ HAL_WRITE_UINT32(info->setup->dma_base +
+ CYGHWR_HAL_STM32_DMA_CCR(info->setup->dma_channel), cr);
+
+ // Initialize scanning sequence (regular group)
+ for (i = 0; i < 18; i++) {
+ if (!(info->chan_mask & (1 << i)))
+ continue;
+
+ if (count < 6) {
+ sqr3 |= CYGHWR_HAL_STM32_ADC_SQRx_SQ(count, i);
+ } else if (count < 12) {
+ sqr2 |= CYGHWR_HAL_STM32_ADC_SQRx_SQ(count - 6, i);
+ } else if (count < 16) {
+ sqr1 |= CYGHWR_HAL_STM32_ADC_SQRx_SQ(count - 12, i);
+ } else {
+ CYG_FAIL("Too many active channels\n");
+ }
+ count++;
+ }
+
+ sqr1 |= CYGHWR_HAL_STM32_ADC_SQR1_L(count - 1);
+
+ adc_diag("sqr1: %p sqr2: %p sqr3: %p\n",
+ (void *) sqr1, (void *) sqr2, (void *) sqr3);
+
+ // Write sequence registers
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_SQR1, sqr1);
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_SQR2, sqr2);
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_SQR3, sqr3);
+
+ // Update DMA
+ HAL_WRITE_UINT32(info->setup->dma_base +
+ CYGHWR_HAL_STM32_DMA_CNDTR(info->setup->dma_channel),
+ count);
+
+ // Enable DMA
+ HAL_READ_UINT32(info->setup->dma_base +
+ CYGHWR_HAL_STM32_DMA_CCR(info->setup->dma_channel), cr);
+ cr |= CYGHWR_HAL_STM32_DMA_CCR_EN;
+ HAL_WRITE_UINT32(info->setup->dma_base +
+ CYGHWR_HAL_STM32_DMA_CCR(info->setup->dma_channel), cr);
+
+ // Enable ADC
+ HAL_READ_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+ cr |= CYGHWR_HAL_STM32_ADC_CR2_ADON;
+ HAL_WRITE_UINT32(info->setup->adc_base + CYGHWR_HAL_STM32_ADC_CR2, cr);
+}
+
+//-----------------------------------------------------------------------------
+// End of adc_stm32.c
diff --git a/ecos/packages/devs/adc/synth/current/ChangeLog b/ecos/packages/devs/adc/synth/current/ChangeLog
new file mode 100644
index 0000000..c0f8049
--- /dev/null
+++ b/ecos/packages/devs/adc/synth/current/ChangeLog
@@ -0,0 +1,35 @@
+2009-03-05 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * cdl/adc_synth.cdl:
+ * cdl/adc_synth.c:
+ Fixed some typos.
+
+2009-02-27 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * cdl/adc_synth.cdl
+ * src/adc_synth.c
+ Synthetic ADC driver package created.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/adc/synth/current/cdl/adc_synth.cdl b/ecos/packages/devs/adc/synth/current/cdl/adc_synth.cdl
new file mode 100644
index 0000000..ac471f7
--- /dev/null
+++ b/ecos/packages/devs/adc/synth/current/cdl/adc_synth.cdl
@@ -0,0 +1,158 @@
+# ====================================================================
+#
+# adc_synth.cdl
+#
+# eCos Synthetic ADC configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Simon Kallweit <simon.kallweit@intefo.ch>
+# Contributors:
+# Date: 2009-02-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_ADC_SYNTH {
+ display "Synthetic ADC device driver"
+
+ parent CYGPKG_IO_ADC_DEVICES
+ active_if CYGPKG_IO_ADC_DEVICES
+ active_if CYGPKG_HAL_SYNTH
+ requires {CYGNUM_IO_ADC_SAMPLE_SIZE >= CYGNUM_DEVS_ADC_SYNTH_SAMPLE_SIZE}
+ description "
+ This option enables the ADC device drivers for Synthetic target."
+
+ include_dir cyg/io
+ compile -library=libextras.a adc_synth.c
+
+ cdl_interface CYGINT_DEVS_ADC_SYNTH_CHANNELS {
+ display "Number of ADC channels"
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_SYNTH_SAMPLE_SIZE {
+ display "Sample size"
+ flavor data
+ legal_values 1 to 32
+ default_value 16
+ description "
+ Sample size provided by the ADC channels."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_SYNTH_DEFAULT_RATE {
+ display "Default sample rate"
+ flavor data
+ legal_values 1 to 10000
+ default_value 100
+ description "
+ The driver will be initialized with the default sample rate.
+ If you raise the default sample rate you might need to increase
+ the buffer size for each channel."
+ }
+
+ # Support 16 channels
+ for { set ::channel 0 } { $::channel < 16 } { incr ::channel } {
+
+ cdl_component CYGHWR_DEVS_ADC_SYNTH_CHANNEL[set ::channel] {
+ display "ADC channel [set ::channel]"
+ flavor none
+ implements CYGINT_DEVS_ADC_SYNTH_CHANNELS
+ description "
+ If the application needs to access the ADC
+ channel [set ::channel] via an eCos ADC driver then
+ this option should be enabled."
+
+ cdl_option CYGDAT_DEVS_ADC_SYNTH_CHANNEL[set ::channel]_NAME {
+ display "Device name"
+ flavor data
+ default_value [format {"\"/dev/adc0%d\""} $::channel]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_SYNTH_CHANNEL[set ::channel]_BUFSIZE {
+ display "Size of data buffer"
+ flavor data
+ legal_values 1 to 65536
+ default_value 128
+ description "
+ This option controls the number of samples the
+ buffer can store. The required RAM is = size of
+ data buffer * size of sample."
+ }
+
+ cdl_option CYGDAT_DEVS_ADC_SYNTH_CHANNEL[set ::channel]_SOURCE {
+ display "Channel source"
+ flavor data
+ legal_values { "CONST" "RANDOM" "FILE" }
+ default_value { "CONST" }
+ description "
+ This option controls the sample source of the virtual ADC
+ channel. CONST mode always returns a constant sample value.
+ RANDOM mode returns random samples. FILE returns samples as
+ read by a file on the host."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_SYNTH_CHANNEL[set ::channel]_CONST_VALUE {
+ display "Constant sample value"
+ flavor data
+ default_value 0
+ description "
+ Constant sample value returned when CONST mode is selected."
+ }
+
+ cdl_option CYGDAT_DEVS_ADC_SYNTH_CHANNEL[set ::channel]_FILENAME {
+ display "Sample data filename"
+ flavor data
+ default_value [format {"\"adc0%d\""} $::channel]
+ description "
+ Filename of sample data file used in FILE mode."
+ }
+
+ cdl_option CYGNUM_DEVS_ADC_SYNTH_CHANNEL[set ::channel]_MODE {
+ display "Channel mode"
+ flavor data
+ calculated CYGDAT_DEVS_ADC_SYNTH_CHANNEL[set ::channel]_SOURCE == { "CONST" } ? 0 : \
+ CYGDAT_DEVS_ADC_SYNTH_CHANNEL[set ::channel]_SOURCE == { "RANDOM" } ? 1 : \
+ CYGDAT_DEVS_ADC_SYNTH_CHANNEL[set ::channel]_SOURCE == { "FILE" } ? 2 : -1
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/adc/synth/current/src/adc_synth.c b/ecos/packages/devs/adc/synth/current/src/adc_synth.c
new file mode 100644
index 0000000..42ddab2
--- /dev/null
+++ b/ecos/packages/devs/adc/synth/current/src/adc_synth.c
@@ -0,0 +1,482 @@
+//==========================================================================
+//
+// adc_synth.c
+//
+// ADC driver for Synthetic ADC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Simon Kallweit <simon.kallweit@intefo.ch>
+// Contributors:
+// Date: 2009-02-27
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/devs_adc_synth.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/io/adc.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+//-----------------------------------------------------------------------------
+// Diagnostic support
+// Switch the #if to 1 to generate some diagnostic messages.
+
+#if 0
+#include <cyg/infra/diag.h>
+#define adc_diag( __fmt, ... ) diag_printf("ADC: %30s[%4d]: " __fmt, __FUNCTION__, __LINE__, ## __VA_ARGS__ );
+#else
+#define adc_diag( __fmt, ... )
+#endif
+
+#define NUM_CHANNELS 16
+
+#define MODE_CONST 0
+#define MODE_RANDOM 1
+#define MODE_FILE 2
+
+#define SAMPLE_BITS ((1 << CYGNUM_DEVS_ADC_SYNTH_SAMPLE_SIZE) - 1)
+
+//-----------------------------------------------------------------------------
+// Synthetic ADC channel
+
+typedef struct synth_adc_channel_info {
+ cyg_uint32 mode; // Channel mode
+ cyg_uint32 const_value; // Const sample value
+ char *filename; // Sampling data filename
+
+ int fd; // File descriptor of sample file
+ cyg_uint32 num_samples; // Number of samples in the file
+ cyg_adc_sample_t *base; // Base address of mapped sample file
+ cyg_adc_sample_t *sample; // Current sample
+
+ cyg_adc_sample_t (*get_sample)(cyg_adc_channel *chan);
+} synth_adc_channel_info;
+
+//-----------------------------------------------------------------------------
+// Synthetic ADC device
+
+typedef struct synth_adc_info {
+ synth_adc_channel_info *chan_info; // Channel infos
+ cyg_adc_channel *chan[NUM_CHANNELS]; // Channel references
+ cyg_uint32 chan_mask; // Active channels
+ cyg_handle_t alarm_handle; // Alarm handle
+ cyg_alarm alarm_data; // Alarm data
+ cyg_tick_count_t alarm_interval; // Alarm interval in ticks
+ cyg_uint32 alarm_samples; // Number of samples per tick
+} synth_adc_info;
+
+//-----------------------------------------------------------------------------
+// API function call forward references
+
+static bool synth_adc_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo synth_adc_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+
+static void synth_adc_enable(cyg_adc_channel *chan);
+static void synth_adc_disable(cyg_adc_channel *chan);
+static void synth_adc_set_rate(cyg_adc_channel *chan, cyg_uint32 rate);
+
+static void alarm_handler(cyg_handle_t alarm, cyg_addrword_t data);
+
+static cyg_adc_sample_t synth_adc_get_sample_const(cyg_adc_channel *chan);
+static cyg_adc_sample_t synth_adc_get_sample_random(cyg_adc_channel *chan);
+static cyg_adc_sample_t synth_adc_get_sample_file(cyg_adc_channel *chan);
+
+static cyg_uint32 rand(void);
+
+CYG_ADC_FUNCTIONS(synth_adc_funs,
+ synth_adc_enable,
+ synth_adc_disable,
+ synth_adc_set_rate);
+
+//-----------------------------------------------------------------------------
+// Synthetic ADC channel info macro
+
+#define SYNTH_ADC_CHANNEL_INFO(_chan_) \
+{ \
+ .mode = CYGNUM_DEVS_ADC_SYNTH_CHANNEL##_chan_##_MODE, \
+ .const_value = CYGNUM_DEVS_ADC_SYNTH_CHANNEL##_chan_##_CONST_VALUE, \
+ .filename = CYGDAT_DEVS_ADC_SYNTH_CHANNEL##_chan_##_FILENAME, \
+}
+
+//-----------------------------------------------------------------------------
+// Synthetic ADC channel instance macro
+
+#define SYNTH_ADC_CHANNEL(_chan_) \
+CYG_ADC_CHANNEL( \
+ synth_adc_channel##_chan_, \
+ _chan_, \
+ CYGNUM_DEVS_ADC_SYNTH_CHANNEL##_chan_##_BUFSIZE, \
+ &synth_adc_device \
+); \
+DEVTAB_ENTRY( \
+ synth_adc_channel##_chan_##_device, \
+ CYGDAT_DEVS_ADC_SYNTH_CHANNEL##_chan_##_NAME, \
+ 0, \
+ &cyg_io_adc_devio, \
+ synth_adc_init, \
+ synth_adc_lookup, \
+ &synth_adc_channel##_chan_ \
+);
+
+//-----------------------------------------------------------------------------
+// Synthetic ADC device instance
+
+static synth_adc_channel_info synth_adc_channel_infos[NUM_CHANNELS] = {
+ SYNTH_ADC_CHANNEL_INFO(0),
+ SYNTH_ADC_CHANNEL_INFO(1),
+ SYNTH_ADC_CHANNEL_INFO(2),
+ SYNTH_ADC_CHANNEL_INFO(3),
+ SYNTH_ADC_CHANNEL_INFO(4),
+ SYNTH_ADC_CHANNEL_INFO(5),
+ SYNTH_ADC_CHANNEL_INFO(6),
+ SYNTH_ADC_CHANNEL_INFO(7),
+ SYNTH_ADC_CHANNEL_INFO(8),
+ SYNTH_ADC_CHANNEL_INFO(9),
+ SYNTH_ADC_CHANNEL_INFO(10),
+ SYNTH_ADC_CHANNEL_INFO(11),
+ SYNTH_ADC_CHANNEL_INFO(12),
+ SYNTH_ADC_CHANNEL_INFO(13),
+ SYNTH_ADC_CHANNEL_INFO(14),
+ SYNTH_ADC_CHANNEL_INFO(15),
+};
+
+static synth_adc_info synth_adc_info0 = {
+ .chan_info = synth_adc_channel_infos,
+};
+
+CYG_ADC_DEVICE(synth_adc_device,
+ &synth_adc_funs,
+ &synth_adc_info0,
+ CYGNUM_DEVS_ADC_SYNTH_DEFAULT_RATE);
+
+SYNTH_ADC_CHANNEL(0)
+SYNTH_ADC_CHANNEL(1)
+SYNTH_ADC_CHANNEL(2)
+SYNTH_ADC_CHANNEL(3)
+SYNTH_ADC_CHANNEL(4)
+SYNTH_ADC_CHANNEL(5)
+SYNTH_ADC_CHANNEL(6)
+SYNTH_ADC_CHANNEL(7)
+SYNTH_ADC_CHANNEL(8)
+SYNTH_ADC_CHANNEL(9)
+SYNTH_ADC_CHANNEL(10)
+SYNTH_ADC_CHANNEL(11)
+SYNTH_ADC_CHANNEL(12)
+SYNTH_ADC_CHANNEL(13)
+SYNTH_ADC_CHANNEL(14)
+SYNTH_ADC_CHANNEL(15)
+
+
+//-----------------------------------------------------------------------------
+// This function is called from the device IO infrastructure to initialize the
+// device. It should perform any work needed to start up the device, short of
+// actually starting the generation of samples. This function will be called
+// for each channel, so if there is initialization that only needs to be done
+// once, such as creating and interrupt object, then care should be taken to do
+// this. This function should also call cyg_adc_device_init() to initialize the
+// generic parts of the driver.
+
+static bool
+synth_adc_init(struct cyg_devtab_entry *tab)
+{
+ static cyg_bool initialized = false;
+ cyg_adc_channel *chan = (cyg_adc_channel *) tab->priv;
+ cyg_adc_device *device = chan->device;
+ synth_adc_info *info = device->dev_priv;
+ synth_adc_channel_info *chan_info = &info->chan_info[chan->channel];
+ cyg_handle_t counter;
+
+ adc_diag("Initializing device\n");
+
+ // Initialize channel
+ info->chan[chan->channel] = chan;
+ switch (chan_info->mode) {
+ case MODE_CONST:
+ chan_info->get_sample = synth_adc_get_sample_const;
+ break;
+ case MODE_RANDOM:
+ chan_info->get_sample = synth_adc_get_sample_random;
+ break;
+ case MODE_FILE:
+ chan_info->get_sample = synth_adc_get_sample_file;
+ break;
+ }
+
+ // Set default rate
+ if (!initialized) {
+ // Initialize alarm
+ cyg_clock_to_counter(cyg_real_time_clock(), &counter);
+ cyg_alarm_create(counter, alarm_handler, (cyg_addrword_t) device,
+ &info->alarm_handle, &info->alarm_data);
+
+ synth_adc_set_rate(chan, chan->device->config.rate);
+ initialized = true;
+ }
+
+ // Initialize generic parts of ADC device
+ cyg_adc_device_init(device);
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// This function is called when a client looks up or opens a channel. It should
+// call cyg_adc_channel_init() to initialize the generic part of the channel.
+// It should also perform any operations needed to start the channel generating
+// samples.
+
+static Cyg_ErrNo
+synth_adc_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ cyg_adc_channel *chan = (cyg_adc_channel *) (*tab)->priv;
+ synth_adc_info *info = chan->device->dev_priv;
+ synth_adc_channel_info *chan_info = &info->chan_info[chan->channel];
+
+ adc_diag("Opening device\n");
+
+ // When this channel is in file mode, initialize file access
+ if (chan_info->mode == MODE_FILE) {
+ struct cyg_hal_sys_new_stat stat;
+
+ // Open the file
+ chan_info->fd = cyg_hal_sys_open(chan_info->filename,
+ CYG_HAL_SYS_O_RDONLY, 0);
+ if (chan_info->fd == -ENOENT) {
+ adc_diag("Cannot open sampling file '%s' for channel '%s'\n",
+ chan_info->filename, (*tab)->name);
+ CYG_FAIL("Cannot open sampling file\n");
+ }
+
+ // Get file size
+ if (cyg_hal_sys_newfstat(chan_info->fd, &stat) != 0) {
+ CYG_FAIL("Cannot stat sampling file\n");
+ }
+ chan_info->num_samples = stat.st_size / sizeof(cyg_adc_sample_t);
+ if (chan_info->num_samples <= 0)
+ CYG_FAIL("Sampling file too small\n");
+
+ // Memory map
+ chan_info->base = (cyg_adc_sample_t *) cyg_hal_sys_mmap(
+ NULL,
+ chan_info->num_samples * sizeof(cyg_adc_sample_t),
+ CYG_HAL_SYS_PROT_READ,
+ CYG_HAL_SYS_MAP_SHARED,
+ chan_info->fd,
+ 0);
+ if (chan_info->base == (void *) -1)
+ CYG_FAIL("Cannot memory map sampling file\n");
+ chan_info->sample = chan_info->base;
+
+ adc_diag("Mapped to %p\n", chan_info->base);
+ }
+
+ // Initialize generic parts of the channel
+ cyg_adc_channel_init(chan);
+
+ // The generic ADC manual says: When a channel is first looked up or
+ // opened, then it is automatically enabled and samples start to
+ // accumulate - so we start the channel now
+ chan->enabled = true;
+ synth_adc_enable(chan);
+
+ return ENOERR;
+}
+
+//-----------------------------------------------------------------------------
+// This function is called from the generic ADC package to enable the channel
+// in response to a CYG_IO_SET_CONFIG_ADC_ENABLE config operation. It should
+// take any steps needed to start the channel generating samples
+
+static void
+synth_adc_enable(cyg_adc_channel *chan)
+{
+ synth_adc_info *info = chan->device->dev_priv;
+ cyg_bool start;
+
+ adc_diag("Enabling channel\n");
+
+ start = !info->chan_mask;
+ info->chan_mask |= (1 << chan->channel);
+
+ // Start scanning when first channel was activated
+ if (start) {
+ // Enable timer
+ adc_diag("Starting scanning\n");
+ cyg_alarm_initialize(info->alarm_handle,
+ cyg_current_time() + info->alarm_interval,
+ info->alarm_interval);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// This function is called from the generic ADC package to enable the channel
+// in response to a CYG_IO_SET_CONFIG_ADC_DISABLE config operation. It should
+// take any steps needed to stop the channel generating samples.
+
+static void
+synth_adc_disable(cyg_adc_channel *chan)
+{
+ synth_adc_info *info = chan->device->dev_priv;
+
+ adc_diag("Disabling channel\n");
+
+ info->chan_mask &= ~(1 << chan->channel);
+
+ // Stop scanning when no channel is active
+ if (!info->chan_mask) {
+ // Disable timer
+ adc_diag("Stopping scanning\n");
+ cyg_alarm_disable(info->alarm_handle);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// This function is called from the generic ADC package to enable the channel
+// in response to a CYG_IO_SET_CONFIG_ADC_RATE config operation. It should take
+// any steps needed to change the sample rate of the channel, or of the entire
+// device. We use a timer channel to generate the interrupts for sampling the
+// analog channels
+
+static void
+synth_adc_set_rate(cyg_adc_channel *chan, cyg_uint32 rate)
+{
+ cyg_adc_device *device = chan->device;
+ synth_adc_info *info = device->dev_priv;
+ cyg_uint64 interval;
+
+ adc_diag("Setting rate to %d\n", rate);
+
+ interval = 1000000000000LL / rate;
+ interval /= (CYGNUM_HAL_RTC_NUMERATOR / CYGNUM_HAL_RTC_DENOMINATOR);
+
+ if (interval > 1000) {
+ info->alarm_interval = interval / 1000;
+ info->alarm_samples = 1;
+ } else {
+ info->alarm_interval = 1;
+ info->alarm_samples = 1000 / interval;
+ }
+
+ if (info->chan_mask)
+ cyg_alarm_initialize(info->alarm_handle,
+ cyg_current_time() + info->alarm_interval,
+ info->alarm_interval);
+
+ device->config.rate = rate;
+}
+
+static void
+alarm_handler(cyg_handle_t alarm, cyg_addrword_t data)
+{
+ cyg_adc_device *device = (cyg_adc_device *) data;
+ synth_adc_info *info = device->dev_priv;
+ cyg_adc_channel *chan;
+ synth_adc_channel_info *chan_info;
+ cyg_uint32 active_mask;
+ int i, j;
+
+ if (!info->chan_mask)
+ return;
+
+ active_mask = info->chan_mask;
+
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ if (active_mask & 0x01) {
+ chan = info->chan[i];
+ chan_info = &info->chan_info[chan->channel];
+ for (j = 0; j < info->alarm_samples; j++)
+ cyg_adc_receive_sample(chan, chan_info->get_sample(chan));
+ cyg_adc_wakeup(info->chan[i]);
+ }
+ active_mask >>= 1;
+ }
+}
+
+static cyg_adc_sample_t
+synth_adc_get_sample_const(cyg_adc_channel *chan)
+{
+ synth_adc_info *info = chan->device->dev_priv;
+ synth_adc_channel_info *chan_info = &info->chan_info[chan->channel];
+
+ return chan_info->const_value;
+}
+
+static cyg_adc_sample_t
+synth_adc_get_sample_random(cyg_adc_channel *chan)
+{
+ return rand() & SAMPLE_BITS;
+}
+
+static cyg_adc_sample_t
+synth_adc_get_sample_file(cyg_adc_channel *chan)
+{
+ synth_adc_info *info = chan->device->dev_priv;
+ synth_adc_channel_info *chan_info = &info->chan_info[chan->channel];
+ cyg_adc_sample_t sample;
+
+ sample = *chan_info->sample++;
+ if (chan_info->sample >= chan_info->base + chan_info->num_samples)
+ chan_info->sample = chan_info->base;
+
+ return sample;
+}
+
+//-----------------------------------------------------------------------------
+// Simple random number generator
+
+static cyg_uint32 rand(void)
+{
+ static cyg_uint32 seed;
+
+ seed = (seed * 1103515245) + 12345; // permutate seed
+
+ return seed;
+}
+
diff --git a/ecos/packages/devs/can/arm/at91/at91sam7/current/ChangeLog b/ecos/packages/devs/can/arm/at91/at91sam7/current/ChangeLog
new file mode 100644
index 0000000..e43fdf0
--- /dev/null
+++ b/ecos/packages/devs/can/arm/at91/at91sam7/current/ChangeLog
@@ -0,0 +1,36 @@
+2012-01-25 Bernard Fouché <bernard.fouche@kuantic.com>
+
+ * src/can_at91sam7.c: CYGNUM_CAN_EVENT_OVERRUN_RX_HW instead of
+ CYGNUM_CAN_EVENT_OVERRUN_RX. CYGNUM_CAN_MODE_LISTEN_ONLY_ENTER &
+ CYGNUM_CAN_MODE_LISTEN_ONLY_EXIT return -EINVAL. [ Bugzilla 1001453 ]
+
+2007-03-23 Uwe Kindler <uwe_kindler@web.de>
+
+ * AT91SAM7 CAN driver package created
+ * cdl/can_at91sam7.cdl
+ * include/can_at91sam7.inl
+ * src/can_at91sam7.c
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/can/arm/at91/at91sam7/current/cdl/can_at91sam7.cdl b/ecos/packages/devs/can/arm/at91/at91sam7/current/cdl/can_at91sam7.cdl
new file mode 100644
index 0000000..cded440
--- /dev/null
+++ b/ecos/packages/devs/can/arm/at91/at91sam7/current/cdl/can_at91sam7.cdl
@@ -0,0 +1,216 @@
+# ====================================================================
+#
+# can_at91sam7.cdl
+#
+# eCos AT91SAM7 CAN module configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors:
+# Date: 2007-02-10
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_CAN_AT91SAM7 {
+ display "Atmel AT91SAM7 CAN device drivers"
+ parent CYGPKG_IO_CAN_DEVICES
+ active_if CYGPKG_IO_CAN
+ active_if CYGPKG_HAL_ARM_AT91SAM7
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ description "
+ This option enables the CAN device drivers for the
+ Atmel AT91SAM7."
+ compile -library=libextras.a can_at91sam7.c
+ define_proc {
+ puts $::cdl_system_header "/***** CAN driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_CAN_DEVICE_HEADER <pkgconf/devs_can_at91sam7.h>"
+ puts $::cdl_system_header "#define CYGDAT_IO_CAN_DEVICE_INL <cyg/io/can_at91sam7.inl>"
+ puts $::cdl_system_header "/***** CAN driver proc output end *****/"
+ }
+
+ cdl_interface CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS {
+ display "AT91SAM7 CAN Channel"
+ flavor bool
+ description "
+ This interface is implemented for each single CAN channnel
+ of an AT91SAM7 chip and counts the number of available
+ channels."
+ }
+
+
+ # Support up one on-chip CAN module. The number may vary between
+ # processor variants so it is easy to update this here
+ for { set ::sam7can 0 } { $::sam7can < 1 } { incr ::sam7can } {
+
+ cdl_interface CYGINT_DEVS_CAN_AT91SAM7_CAN[set ::sam7can] {
+ display "Platform provides CAN [set ::sam7can]"
+ flavor bool
+ description "
+ This interface will be implemented if the specific AT91SAM7
+ processor being used has on-chip CAN [set ::sam7can], and if
+ that CAN module is accessible on the target hardware."
+ }
+
+ cdl_component CYGPKG_DEVS_CAN_AT91SAM7_CAN[set ::sam7can] {
+ display "Allow access to the on-chip CAN [set ::sam7can] via a CAN driver"
+ flavor bool
+ active_if CYGINT_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]
+ default_value 1
+ implements CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS
+ implements CYGINT_IO_CAN_TIMESTAMP
+ implements CYGINT_IO_CAN_RUNTIME_MBOX_CFG
+ implements CYGINT_IO_CAN_REMOTE_BUF
+ implements CYGINT_IO_CAN_AUTOBAUD
+ description "
+ If the application needs to access the on-chip CAN module [set ::sam7can]
+ via an eCos CAN driver then this option should be enabled."
+
+ cdl_option CYGPKG_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_NAME {
+ display "Device name for CAN module [set ::sam7can]"
+ flavor data
+ default_value [format {"\"/dev/can%d\""} $::sam7can]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_KBAUD {
+ display "Default baud rate for CAN module [set ::sam7can]"
+ flavor data
+ default_value 100
+ legal_values { 10 20 50 100 125 250 500 800 1000 "AUTO"}
+ description "This option determines the initial baud rate in KBaud for
+ CAN module [set ::sam7can]"
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_QUEUESIZE_TX {
+ display "Size of TX Queue for the CAN module [set ::sam7can] driver"
+ flavor data
+ default_value 8
+ legal_values 1 to 64
+ description "
+ The CAN device driver will run in interrupt mode and will
+ perform buffering of outgoing data. This option controls the number
+ of CAN messages the TX queue can store."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_QUEUESIZE_RX {
+ display "Size of RX Queue for the CAN module [set ::sam7can] driver"
+ flavor data
+ default_value 32
+ legal_values 8 to 128
+ description "
+ The CAN device driver will run in interrupt mode and will
+ perform buffering of incoming data. This option controls the number
+ of CAN events the RX queue can store."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_ISR_PRIORITY {
+ display "Interrupt priority"
+ flavor data
+ default_value 4
+ legal_values 0 to 7
+ description "
+ Interrupt priority CAN module [set ::sam7can]. Each interrupt source
+ has a programmable priority level of 0 to 7. Level 7 is the
+ highest priority and level 0 the lowest."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_DEFAULT_TX_MBOX {
+ display "Default TX message box"
+ flavor data
+ calculated 7
+ description "
+ By default one message buffer will be used for message transmission.
+ This option selects one of the 8 CAN message buffers for
+ transmission."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_STD_MBOXES {
+ display "11 Bit standard ID msg. buffers"
+ flavor booldata
+ implements CYGINT_IO_CAN_STD_CAN_ID
+ default_value 3
+ legal_values 1 to 7
+ requires CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_STD_MBOXES + CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_EXT_MBOXES < 8
+ description "
+ The CAN module provides 8 message buffers. One message buffer
+ is reserved for message transmission. The remaining 7 buffers are
+ available for reception of messages. This configuration option
+ defines the number of message boxes for reception of CAN messages
+ with standard identifier. This configuration option does not matter
+ when you configure message filters at runtime. Only if the CAN
+ modul is configured to receive all available CAN identifiers,
+ then this configuration option is important. If you get
+ RX overrun events, you should raise the number of message boxes or
+ lower the CAN baud rate."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_EXT_MBOXES {
+ display "29 Bit extended ID msg. buffers"
+ flavor booldata
+ implements CYGINT_IO_CAN_EXT_CAN_ID
+ default_value 4
+ legal_values 1 to 7
+ requires CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_STD_MBOXES + CYGNUM_DEVS_CAN_AT91SAM7_CAN[set ::sam7can]_EXT_MBOXES < 8
+ description "
+ The CAN module provides 8 message buffers. One message buffer
+ is reserved for message transmission. The remaining 7 buffers are
+ available for reception of messages. This configuration option
+ defines the number of message boxes for reception of CAN messages
+ with extended identifier. This configuration option does not matter
+ when you configure message filters at runtime. Only if the FlexCAN
+ modul is configured to receive all available CAN identifiers,
+ then this configuration option is important. If you get
+ RX overrun events, you should raise the number of message boxes or
+ lower the CAN baud rate."
+ }
+ }
+ }
+
+ cdl_option CYGDBG_DEVS_CAN_AT91SAM7_DEBUG {
+ display "Support printing debug information"
+ default_value 0
+ description "
+ Check this box to turn ON debug options for AT91SAM7 CAN device driver."
+ }
+}
diff --git a/ecos/packages/devs/can/arm/at91/at91sam7/current/include/can_at91sam7.inl b/ecos/packages/devs/can/arm/at91/at91sam7/current/include/can_at91sam7.inl
new file mode 100644
index 0000000..a16f2fc
--- /dev/null
+++ b/ecos/packages/devs/can/arm/at91/at91sam7/current/include/can_at91sam7.inl
@@ -0,0 +1,185 @@
+#ifndef CYGONCE_CAN_AT91SAM7_H
+#define CYGONCE_CAN_AT91SAM7_H
+//==========================================================================
+//
+// devs/can/arm/at91sam7x/current/include/can_at91sam7.inl
+//
+// CAN message macros for Atmel AT91SAM7X CAN driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-02-08
+// Purpose: Support AT91SAM7X on-chip CAN moduls
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDE
+//==========================================================================
+#include <pkgconf/devs_can_at91sam7.h>
+
+
+//==========================================================================
+// DATA TYPES
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// We define our own CAN message data type here. This structure needs less
+// memory than the common CAN message defined by IO layer. This is important
+// because the AT91SAM7 contains only 64 KBytes RAM memory
+//
+typedef struct st_at91sam7_can_message
+{
+ cyg_can_msg_data data;// 8 data bytes
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ cyg_uint32 id; // also extended identifiers (29 Bit) are supported
+ cyg_uint8 ctrl;// control stores extended flag, rtr flag and dlc
+#else
+ //
+ // only standard identifiers are supported - we need only 11 bit of
+ // the data word to store the identifier. So we have 5 bit left to store
+ // the the rtr flag and the dlc flag. We do not need the IDE flag because
+ // only standard identifiers are supported
+ //
+ cyg_uint16 id;
+#endif
+} at91sam7_can_message;
+
+
+//--------------------------------------------------------------------------
+// We also define an own event structure here to store the received events
+// This event structure uses the device CAN message structure and
+// 16 Bit value for timestamps
+//
+typedef struct st_at91sam7_can_event
+{
+ cyg_uint16 flags;
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+ cyg_uint16 timestamp;
+#endif
+ at91sam7_can_message msg;
+} at91sam7_can_event;
+
+
+
+//==========================================================================
+// DEFINES
+//==========================================================================
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+//
+// If we use extended identifier then we store the message parameters
+// into control word
+//
+#define AT91SAM7_CAN_SET_DLC(_msg_, _dlc_) ((_msg_).ctrl = (_dlc_)) // this also clears the ctrl
+#define AT91SAM7_CAN_SET_EXT(_msg_) ((_msg_).ctrl |= 0x01 << 4)
+#define AT91SAM7_CAN_SET_RTR(_msg_) ((_msg_).ctrl |= 0x01 << 5)
+
+#define AT91SAM7_CAN_GET_DLC(_msg_) ((_msg_).ctrl & 0x0F)
+#define AT91SAM7_CAN_IS_EXT(_msg_) ((((_msg_).ctrl >> 4) & 0x01) != 0)
+#define AT91SAM7_CAN_IS_RTR(_msg_) ((((_msg_).ctrl >> 5) & 0x01) != 0)
+#define AT91SAM7_CAN_GET_ID(_msg_) ((_msg_).id & CYG_CAN_EXT_ID_MASK)
+#else // CYGOPT_IO_CAN_EXT_CAN_ID
+//
+// We use only standard identifiers and we can store the message parameters
+// into the upper 5 bits of the 16 bit id field (only 11 bits are required for
+// standard frames
+//
+#define AT91SAM7_CAN_SET_DLC(_msg_, _dlc_) ((_msg_).id |= (_dlc_) << 11)
+#define AT91SAM7_CAN_SET_EXT(_msg_) // we do not need to support this flag - only std IDs supported
+#define AT91SAM7_CAN_SET_RTR(_msg_) ((_msg_).id |= 0x01 << 15)
+
+#define AT91SAM7_CAN_GET_DLC(_msg_) (((_msg_).id >> 11) & 0x0F)
+#define AT91SAM7_CAN_IS_EXT(_msg_) 0 // we do not support extended identifiers so this is always false
+#define AT91SAM7_CAN_IS_RTR(_msg_) ((((_msg_).id >> 15) & 0x01) != 0)
+#define AT91SAM7_CAN_GET_ID(_msg_) ((_msg_).id & CYG_CAN_STD_ID_MASK)
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+
+
+//---------------------------------------------------------------------------
+// The foolowing macros are required for CAN devicedriver. We define our own
+// CAN messaeg and event structures and therefore we also need to define the
+// two message conversion macros that translate out message/event into the
+// standard CAN message/event
+//
+#define CYG_CAN_MSG_T at91sam7_can_message
+#define CYG_CAN_EVENT_T at91sam7_can_event
+
+//
+// We need to copy the timestamp field only if timestamps are supported by
+// driver
+//
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+#define CYG_CAN_READ_TIMESTAMP(_ioevent_ptr_, _devevent_ptr_) ((_ioevent_ptr_)->timestamp = (_devevent_ptr_)->timestamp)
+#else
+#define CYG_CAN_READ_TIMESTAMP(_ioevent_ptr_, _devevent_ptr_)
+#endif
+
+
+#define CYG_CAN_WRITE_MSG(_devmsg_ptr_, _iomsg_ptr_) \
+CYG_MACRO_START \
+ (_devmsg_ptr_)->data = (_iomsg_ptr_)->data; \
+ (_devmsg_ptr_)->id = (_iomsg_ptr_)->id; \
+ AT91SAM7_CAN_SET_DLC(*(_devmsg_ptr_), (_iomsg_ptr_)->dlc); \
+ if (CYGNUM_CAN_ID_EXT == (_iomsg_ptr_)->ext) {AT91SAM7_CAN_SET_EXT(*(_devmsg_ptr_));} \
+ if (CYGNUM_CAN_FRAME_RTR == (_iomsg_ptr_)->rtr) {AT91SAM7_CAN_SET_RTR(*(_devmsg_ptr_));} \
+CYG_MACRO_END
+
+
+#define CYG_CAN_READ_EVENT(_ioevent_ptr_, _devevent_ptr_) \
+CYG_MACRO_START \
+ (_ioevent_ptr_)->flags = (_devevent_ptr_)->flags; \
+ (_ioevent_ptr_)->msg.data = (_devevent_ptr_)->msg.data; \
+ (_ioevent_ptr_)->msg.id = AT91SAM7_CAN_GET_ID((_devevent_ptr_)->msg); \
+ (_ioevent_ptr_)->msg.dlc = AT91SAM7_CAN_GET_DLC((_devevent_ptr_)->msg); \
+ if (AT91SAM7_CAN_IS_EXT((_devevent_ptr_)->msg)) { \
+ (_ioevent_ptr_)->msg.ext = CYGNUM_CAN_ID_EXT; } \
+ else { \
+ (_ioevent_ptr_)->msg.ext = CYGNUM_CAN_ID_STD; } \
+ if (AT91SAM7_CAN_IS_RTR((_devevent_ptr_)->msg)) { \
+ (_ioevent_ptr_)->msg.rtr = CYGNUM_CAN_FRAME_RTR; } \
+ else { \
+ (_ioevent_ptr_)->msg.rtr = CYGNUM_CAN_FRAME_DATA; } \
+ CYG_CAN_READ_TIMESTAMP(_ioevent_ptr_, _devevent_ptr_); \
+CYG_MACRO_END
+
+//---------------------------------------------------------------------------
+#endif // CYGONCE_CAN_AT91SAM7_H
diff --git a/ecos/packages/devs/can/arm/at91/at91sam7/current/src/can_at91sam7.c b/ecos/packages/devs/can/arm/at91/at91sam7/current/src/can_at91sam7.c
new file mode 100644
index 0000000..f334bf0
--- /dev/null
+++ b/ecos/packages/devs/can/arm/at91/at91sam7/current/src/can_at91sam7.c
@@ -0,0 +1,1594 @@
+//==========================================================================
+//
+// devs/can/arm/at91sam7x/current/src/can_at91sam7x.c
+//
+// CAN driver for Atmel AT91SAM7X microcontrollers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-01-06
+// Purpose: Support at91sam7 on-chip CAN moduls
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/io_can.h>
+#include <pkgconf/io.h>
+#include <pkgconf/devs_can_at91sam7.h>
+
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/can.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/hal/hal_diag.h>
+#include <cyg/infra/cyg_ass.h>
+
+
+//===========================================================================
+// DEFINES
+//===========================================================================
+
+//
+// Support debug output if this option is enabled in CDL file
+//
+#ifdef CYGDBG_DEVS_CAN_AT91SAM7_DEBUG
+#define AT91SAM7_DBG_PRINT diag_printf
+#else
+#define AT91SAM7_DBG_PRINT( fmt, ... )
+#endif
+
+
+//
+// we define our own set of register bits in order to be independent from
+// platform specific names
+//
+
+//---------------------------------------------------------------------------
+// Mailbox bits
+//
+#define BIT_MB0 (0x01 << 0)
+#define BIT_MB1 (0x01 << 1)
+#define BIT_MB2 (0x01 << 2)
+#define BIT_MB3 (0x01 << 3)
+#define BIT_MB4 (0x01 << 4)
+#define BIT_MB5 (0x01 << 5)
+#define BIT_MB6 (0x01 << 6)
+#define BIT_MB7 (0x01 << 7)
+
+
+//---------------------------------------------------------------------------
+// CAN Mode Register bits (CAN_MR)
+//
+#define MR_CAN_ENABLE (0x01 << 0)
+#define MR_LOW_POWER (0x01 << 1)
+#define MR_AUTOBAUD (0x01 << 2)
+#define MR_OVERLOAD (0x01 << 3)
+#define MR_TIMESTAMP_EOF (0x01 << 4)
+#define MR_TIME_TRIG (0x01 << 5)
+#define MR_TIMER_FREEZE (0x01 << 6)
+#define MR_DISABLE_REPEAT (0x01 << 7)
+
+
+//---------------------------------------------------------------------------
+// CAN Interrupt Enable/Disable, Mask and Status Register bits (CAN_IER, CAN_IDR, CAN_IMR)
+//
+#define INT_ERR_ACTIVE (0x01 << 16)
+#define INT_WARN (0x01 << 17)
+#define INT_ERR_PASSIVE (0x01 << 18)
+#define INT_BUS_OFF (0x01 << 19)
+#define INT_SLEEP (0x01 << 20)
+#define INT_WAKEUP (0x01 << 21)
+#define INT_TMR_OVF (0x01 << 22)
+#define INT_TIMESTAMP (0x01 << 23)
+#define INT_CRC_ERR (0x01 << 24)
+#define INT_STUFF_ERR (0x01 << 25)
+#define INT_ACKN_ERR (0x01 << 26)
+#define INT_FORM_ERR (0x01 << 27)
+#define INT_BIT_ERR (0x01 << 28)
+#define INT_MB 0xFF // message box intterupt (mbox 1 - 8)
+#define INT_MB_RX 0x7F // rx message box interrupts
+#define INT_MB_TX 0x80 // tx message box interrupts
+
+//
+// We do not enable INT_WARN by default because this flug is buggy and causes interrupts
+// event if no counter reached warning level.
+//
+#define INT_ALL_ERR (INT_CRC_ERR | INT_STUFF_ERR | INT_ACKN_ERR | INT_FORM_ERR | INT_BIT_ERR)
+#define INT_DEFAULT (INT_ERR_PASSIVE | INT_BUS_OFF | INT_SLEEP | INT_WAKEUP | INT_ALL_ERR)
+
+
+//
+// these bits are only in status register (CAN_SR)
+//
+#define SR_RX_BUSY (0x01 << 29)
+#define SR_TX_BUSY (0x01 << 30)
+#define SR_OVL_BUSY (0x01 << 31)
+
+
+//---------------------------------------------------------------------------
+// CAN Baudrate Register (CAN_BR)
+//
+#define BR_PHASE2_BITMASK 0x00000007
+#define BR_PHASE1_BITMASK 0x00000070
+#define BR_PROPAG_BITMASK 0x00000700
+#define BR_SJW_BITMASK 0x00003000
+#define BR_BRP_BITMASK 0x007F0000
+#define BR_SMP_BITMASK 0x01000000
+
+
+//---------------------------------------------------------------------------
+// CAN Error Counter Register (CAN_ECR)
+//
+#define ECR_GET_TEC(_ecr_) (((_ecr_) >> 16) & 0xFF)
+#define ECR_GET_REC(_ecr_) ((_ecr_) & 0xFF)
+
+
+//---------------------------------------------------------------------------
+// CAN Transfer Command Resgister (CAN_TCR)
+//
+#define TCR_TMR_RESET 0x80000000
+
+
+//---------------------------------------------------------------------------
+// CAN Message Mode Register (CAN_MMRx)
+//
+#define MMR_TIMEMARK_BITMASK 0x0000FFFF
+#define MMR_PRIOR_BITMASK 0x000F0000
+
+#define MMR_MB_SHIFTER 24
+#define MMR_MB_TYPE_BITMASK (0x07 << MMR_MB_SHIFTER) // mask the mot bits
+#define MMR_MB_TYPE_DISABLED (0x00 << MMR_MB_SHIFTER) // message box disabled
+#define MMR_MB_TYPE_RX (0x01 << MMR_MB_SHIFTER) // rx message box
+#define MMR_MB_TYPE_RX_OVW (0x02 << MMR_MB_SHIFTER) // rx message box with overwrite
+#define MMR_MB_TYPE_TX (0x03 << MMR_MB_SHIFTER) // tx message box
+#define MMR_MB_TYPE_CONSUME (0x04 << MMR_MB_SHIFTER) // consumer - receives RTR and sends its content
+#define MMR_MB_TYPE_PRODUCE (0x05 << MMR_MB_SHIFTER) // producer - sends a RTR and waits for answer
+#define MMR_MB_GET_TYPE(_mb_) ((_mb_) & MMR_MB_TYPE_BITMASK)
+
+//---------------------------------------------------------------------------
+// CAN Message Acceptance Mask/ID Register (CAN_MAMx, CAN_MIDx)
+//
+#define MID_MIDvB_BITMASK 0x0003FFFF
+#define MID_MIDvA_BITMASK 0x1FFC0000
+#define MID_MIDE 0x20000000
+#define MID_MIDvA_SHIFTER 18
+#define MID_SET_STD(_id_) (((_id_) << MID_MIDvA_SHIFTER) & MID_MIDvA_BITMASK)
+#define MID_SET_EXT(_id_) ((_id_) | MID_MIDE)
+#define MAM_SET_STD ((((0x7FF << MID_MIDvA_SHIFTER) & MID_MIDvA_BITMASK) | MID_MIDE))
+#define MAM_SET_EXT 0xFFFFFFFF
+#define MID_GET_STD(_mid_) (((_mid_) >> MID_MIDvA_SHIFTER) & CYG_CAN_STD_ID_MASK)
+#define MID_GET_EXT(_mid_) ((_mid_) & CYG_CAN_EXT_ID_MASK)
+
+
+//---------------------------------------------------------------------------
+// CAN Message Status Register (CAN_MSRx)
+//
+#define MSR_TIMESTAMP 0x0000FFFF
+#define MSR_DLC 0x000F0000
+#define MSR_RTR 0x00100000
+#define MSR_MSG_ABORT 0x00400000
+#define MSR_RDY 0x00800000
+#define MSR_MSG_IGNORED 0x01000000
+#define MSR_DLC_SHIFTER 16
+#define MSR_DLC_GET(_msr_) (((_msr_) >> 16) & 0x0F)
+
+//---------------------------------------------------------------------------
+// CAN Message Control Register (CAN_MCRx)
+//
+#define MCR_DLC 0x000F0000 // MDLC
+#define MCR_RTR 0x00100000 // MRTR
+#define MCR_MSG_ABORT 0x00400000 // MACR
+#define MCR_TRANSFER_CMD 0x00800000 // MTCR
+#define MCR_DLC_SHIFTER 16
+#define MCR_DLC_CREATE(_len_) ((_len_) << MCR_DLC_SHIFTER)
+
+//---------------------------------------------------------------------------
+// CAN Module Register Layout
+//
+#define CANREG_MR 0x0000
+#define CANREG_IER 0x0004
+#define CANREG_IDR 0x0008
+#define CANREG_IMR 0x000C
+#define CANREG_SR 0x0010
+#define CANREG_BR 0x0014
+#define CANREG_TIM 0x0018
+#define CANREG_TIMESTAMP 0x001C
+#define CANREG_ECR 0x0020
+#define CANREG_TCR 0x0024
+#define CANREG_ACR 0x0028
+
+#define CANREG_MB_BASE 0x0200
+
+//
+// Register layout of message box relativ to base register of a certain
+// message box
+//
+#define CANREG_MMR 0x0000
+#define CANREG_MAM 0x0004
+#define CANREG_MID 0x0008
+#define CANREG_MFID 0x000C
+#define CANREG_MSR 0x0010
+#define CANREG_MDL 0x0014
+#define CANREG_MDH 0x0018
+#define CANREG_MCR 0x001C
+
+
+#define AT91SAM7_CAN_PERIPHERAL_ID 15
+#define CAN_MBOX_MIN 0
+#define CAN_MBOX_MAX 7
+#define CAN_MBOX_CNT 8
+#define CAN_MBOX_RX_MIN 0
+#define CAN_MBOX_RX_MAX (CAN_MBOX_MAX - 1) // one message box is tx
+#define CAN_MBOX_RX_CNT (CAN_MBOX_CNT - 1) // one message box is tx
+
+#define CAN_MR(_extra_) (CAN_BASE(_extra_) + CANREG_MR)
+#define CAN_IER(_extra_) (CAN_BASE(_extra_) + CANREG_IER)
+#define CAN_IDR(_extra_) (CAN_BASE(_extra_) + CANREG_IDR)
+#define CAN_IMR(_etxra_) (CAN_BASE(_extra_) + CANREG_IMR)
+#define CAN_SR(_etxra_) (CAN_BASE(_extra_) + CANREG_SR)
+#define CAN_BR(_etxra_) (CAN_BASE(_extra_) + CANREG_BR)
+#define CAN_TIM(_etxra_) (CAN_BASE(_extra_) + CANREG_TIM)
+#define CAN_TIMESTAMP(_etxra_) (CAN_BASE(_extra_) + CANREG_TIMESTAMP)
+#define CAN_ECR(_etxra_) (CAN_BASE(_extra_) + CANREG_ECR)
+#define CAN_TCR(_etxra_) (CAN_BASE(_extra_) + CANREG_TCR)
+#define CAN_ACR(_etxra_) (CAN_BASE(_extra_) + CANREG_ACR)
+
+//
+// Message box registers
+//
+#define CAN_MB_BASE(_extra_) (CAN_BASE(_extra_) + CANREG_MB_BASE)
+#define CAN_MB_MMR(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MMR)
+#define CAN_MB_MAM(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MAM)
+#define CAN_MB_MID(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MID)
+#define CAN_MB_MFID(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MFID)
+#define CAN_MB_MSR(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MSR)
+#define CAN_MB_MDL(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MDL)
+#define CAN_MB_MDH(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MDH)
+#define CAN_MB_MCR(_extra_, _mb_) (CAN_MB_BASE(_extra_) + 0x0020 * (_mb_) + CANREG_MCR)
+
+
+//---------------------------------------------------------------------------
+// Optimize for the case of a single CAN channel, while still allowing
+// multiple channels. At the moment only AT91SAM7 controllers with one
+// CAN channel are known.
+//
+#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1
+
+#define CAN_PID(_extra_) AT91SAM7_CAN_PERIPHERAL_ID
+#define CAN_ISRVEC(_extra_) CAN_PID(_extra_)
+#define CAN_ISRPRIO(_extra_) CYGNUM_DEVS_CAN_AT91SAM7_CAN0_ISR_PRIORITY
+#define CAN_BASE(_extra_) AT91_CAN
+#define CAN_DECLARE_INFO(_chan_)
+#define CAN_MBOX_TX(_extra_) CYGNUM_DEVS_CAN_AT91SAM7_CAN0_DEFAULT_TX_MBOX
+#define CAN_MBOX_STD_CNT(_extra_) CYGNUM_DEVS_CAN_AT91SAM7_CAN0_STD_MBOXES
+#define CAN_MBOX_EXT_CNT(_extra_) CYGNUM_DEVS_CAN_AT91SAM7_CAN0_EXT_MBOXES
+#define CAN_MBOX_RX_ALL_CNT(_extra) (CAN_MBOX_STD_CNT(_extra_) + CAN_MBOX_EXT_CNT(_extra_))
+
+#ifndef CYGNUM_DEVS_CAN_AT91SAM7_CAN0_STD_MBOXES
+#define CYGNUM_DEVS_CAN_AT91SAM7_CAN0_STD_MBOXES 0
+#endif
+
+#ifndef CYGNUM_DEVS_CAN_AT91SAM7_CAN0_EXT_MBOXES
+#define CYGNUM_DEVS_CAN_AT91SAM7_CAN0_EXT_MBOXES 0
+#endif
+
+#else // #if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1
+
+#define CAN_PID(_extra_) ((_extra_)->isrvec)
+#define CAN_ISRVEC(_extra_) ((_extra_)->isrvec)
+#define CAN_ISRPRIO(_extra_) ((_extra_)->isrprio)
+#define CAN_BASE(_extra_) ((_extra_)->base)
+#define CAN_DECLARE_INFO(_chan_) at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+#define CAN_MBOX_TX(_extra_) 7 // normally it is always the last mailbox
+#define CAN_MBOX_STD_CNT(_extra_) ((_extra_)->mboxes_std_cnt)
+#define CAN_MBOX_EXT_CNT(_extra_) ((_extra_)->mboxes_ext_cnt)
+#define CAN_MBOX_RX_ALL_CNT(_extra) ((_extra_)->mboxes_rx_all_cnt)
+
+#endif // #if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct at91sam7_can_info_t
+{
+ cyg_interrupt interrupt;
+ cyg_handle_t interrupt_handle;
+ cyg_uint32 stat; // buffers status register value between ISR and DSR
+ cyg_uint8 free_mboxes; // number of free message boxes for msg filters and rtr buffers
+ bool rx_all; // true if reception of call can messages is active
+ cyg_can_state state; // state of CAN controller
+
+#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS > 1
+ cyg_uint32 base; // Per-bus h/w details
+ cyg_uint8 isrpri; // ISR priority
+ cyg_uint8 isrvec; // ISR vector (peripheral id)
+ cyg_uint8 mboxes_std_cnt; // contains number of standard message boxes available
+ cyg_uint8 mboxes_ext_cnt; // number of message boxes with ext id
+ cyg_uint8 mboxes_rx_all_cnt;// number of all available mboxes
+#endif
+} at91sam7_can_info_t;
+
+
+//
+// at91sam7 info initialisation
+//
+#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS > 1
+#define AT91SAM7_CAN_INFO(_l, _base, _isrpri, _isrvec, _std_mboxes, _ext_mboxes) \
+at91sam7_can_info_t _l { \
+ state : CYGNUM_CAN_STATE_STOPPED, \
+ base : (_base), \
+ isrpri : (_isrpri), \
+ isrvec : (_isrvec), \
+ mboxes_std_cnt : (_std_mboxes), \
+ mboxes_ext_cnt : (_ext_mboxes), \
+ mboxes_rx_all_cnt : ((_std_mboxes) + (_ext_mboxes)), \
+};
+#else
+#define AT91SAM7_CAN_INFO(_l) \
+at91sam7_can_info_t _l = { \
+ state : CYGNUM_CAN_STATE_STOPPED, \
+};
+#endif
+
+
+//===========================================================================
+// GLOBAL DATA
+//===========================================================================
+#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS > 1
+//
+// ToDo - Initialisation of individual CAN channels if more than one channel
+// is supported
+//
+#else // CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1
+//
+// Only one single CAN channel supported by SAM7 chip
+//
+AT91SAM7_CAN_INFO(at91sam7_can0_info);
+#endif
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+//
+// Macro for creation of CAN_BR value for baudrate tbl
+//
+
+#define CAN_BR_TBL_ENTRY(_brp_, _propag_, _phase1_, _phase2_, _sjw_) \
+ ((_brp_ << 16) | (_propag_ << 8) | (_phase2_) | (_phase1_ << 4) | (_sjw_ << 12))
+
+//
+// Table with register values for baudrates at main clock of 48 MHz
+//
+static const cyg_uint32 at91sam7_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY(0xef, 0x07, 0x07, 0x02, 0), // 10 kbaud
+ CAN_BR_TBL_ENTRY(0x95, 0x04, 0x07, 0x01, 0), // 20 kbaud
+ CAN_BR_TBL_ENTRY(0x3b, 0x04, 0x07, 0x01, 0), // 50 kbaud
+ CAN_BR_TBL_ENTRY(0x1d, 0x04, 0x07, 0x01, 0), // 100 kbaud
+ CAN_BR_TBL_ENTRY(0x17, 0x04, 0x07, 0x01, 0), // 125 kbaud
+ CAN_BR_TBL_ENTRY(0x0b, 0x04, 0x07, 0x01, 0), // 250 kbaud
+ CAN_BR_TBL_ENTRY(0x05, 0x04, 0x07, 0x01, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY(0x03, 0x03, 0x07, 0x01, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY(0x02, 0x04, 0x07, 0x01, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY(0x00, 0x00, 0x00, 0x00, 0), // Autobaud
+};
+
+//
+// Macro fills baudrate register value depending on selected baudrate
+// For a standard AT91 clock speed of 48 MHz we provide a pre calculated
+// baudrate table. If the board uses another clock speed, then the platform
+// HAL needs to provide an own HAL_AT91SAM7_GET_CAN_BR() macro that returns
+// valid baudrate register values
+//
+#ifdef CYGNUM_HAL_ARM_AT91_CLOCK_SPEED_48000000
+#define HAL_AT91SAM7_GET_CAN_BR(_baudrate_, _br_) \
+CYG_MACRO_START \
+ _br_ = at91sam7_br_tbl[(_baudrate_) - CYGNUM_CAN_KBAUD_10]; \
+CYG_MACRO_END
+#endif
+
+
+//===========================================================================
+// PROTOTYPES
+//===========================================================================
+
+//--------------------------------------------------------------------------
+// Device driver interface functions
+//
+static bool at91sam7_can_init(struct cyg_devtab_entry* devtab_entry);
+static Cyg_ErrNo at91sam7_can_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name);
+static Cyg_ErrNo at91sam7_can_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
+static Cyg_ErrNo at91sam7_can_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
+static bool at91sam7_can_putmsg(can_channel *priv, CYG_CAN_MSG_T *pmsg, void *pdata);
+static bool at91sam7_can_getevent(can_channel *priv, CYG_CAN_EVENT_T *pevent, void *pdata);
+static void at91sam7_can_start_xmit(can_channel* chan);
+static void at91sam7_can_stop_xmit(can_channel* chan);
+
+
+//--------------------------------------------------------------------------
+// ISRs and DSRs
+//
+static cyg_uint32 at91sam7_can_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void at91sam7_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+
+//--------------------------------------------------------------------------
+// Private utility functions
+//
+static bool at91sam7_can_config_channel(can_channel* chan, cyg_can_info_t* config, cyg_bool init);
+static bool at91sam7_can_set_baud(can_channel *chan, cyg_can_baud_rate_t *baudrate);
+static void at91sam7_can_mbox_config_rx_all(can_channel *chan);
+static void at91sam7_can_setup_mbox(can_channel *chan, // channel
+ cyg_uint8 mbox, // message box number (0 -7)
+ cyg_uint32 mid, // message identifier
+ cyg_uint32 mam, // acceptance mask for this message box
+ cyg_uint32 rxtype); // RX or RX with overwrite are valid values
+static void at91sam7_enter_lowpower_mode(can_channel *chan);
+static void at91sam7_start_module(can_channel *chan);
+static cyg_can_state at91sam7_get_state(at91sam7_can_info_t *info);
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+static void at91sam7_can_config_rx_none(can_channel *chan);
+static Cyg_ErrNo at91sam7_can_set_config_msgbuf(can_channel *chan, cyg_can_msgbuf_cfg *buf);
+#endif
+
+
+
+
+//===========================================================================
+// GENERIC CAN IO DATA INITIALISATION
+//===========================================================================
+CAN_LOWLEVEL_FUNS(at91sam7_can_lowlevel_funs,
+ at91sam7_can_putmsg,
+ at91sam7_can_getevent,
+ at91sam7_can_get_config,
+ at91sam7_can_set_config,
+ at91sam7_can_start_xmit,
+ at91sam7_can_stop_xmit
+ );
+
+
+CYG_CAN_EVENT_T at91sam7_can0_rxbuf[CYGNUM_DEVS_CAN_AT91SAM7_CAN0_QUEUESIZE_RX]; // buffer for RX can events
+CYG_CAN_MSG_T at91sam7_can0_txbuf[CYGNUM_DEVS_CAN_AT91SAM7_CAN0_QUEUESIZE_TX]; // buffer for TX can messages
+
+
+CAN_CHANNEL_USING_INTERRUPTS(at91sam7_can0_chan,
+ at91sam7_can_lowlevel_funs,
+ at91sam7_can0_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_AT91SAM7_CAN0_KBAUD),
+ at91sam7_can0_txbuf, CYGNUM_DEVS_CAN_AT91SAM7_CAN0_QUEUESIZE_TX,
+ at91sam7_can0_rxbuf, CYGNUM_DEVS_CAN_AT91SAM7_CAN0_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(at91sam7_can_devtab,
+ CYGPKG_DEVS_CAN_AT91SAM7_CAN0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ at91sam7_can_init,
+ at91sam7_can_lookup, // CAN driver may need initializing
+ &at91sam7_can0_chan
+ );
+
+
+//===========================================================================
+// IMPLEMENTATION
+//===========================================================================
+
+
+
+//===========================================================================
+/// First initialisation and reset of CAN modul.
+//===========================================================================
+static bool at91sam7_can_init(struct cyg_devtab_entry* devtab_entry)
+{
+ can_channel *chan = (can_channel*)devtab_entry->priv;
+ at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+
+#ifdef CYGDBG_IO_INIT
+ diag_printf("AT91 CAN init\n");
+#endif
+ cyg_drv_interrupt_create(CAN_ISRVEC(info),
+ CAN_ISRPRIO(info), // Priority
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ at91sam7_can_ISR,
+ at91sam7_can_DSR,
+ &info->interrupt_handle,
+ &info->interrupt);
+ cyg_drv_interrupt_attach(info->interrupt_handle);
+ cyg_drv_interrupt_unmask(CAN_ISRVEC(info));
+
+ return at91sam7_can_config_channel(chan, &chan->config, true);
+}
+
+
+//===========================================================================
+// Lookup the device and return its handle
+//===========================================================================
+static Cyg_ErrNo at91sam7_can_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name)
+{
+ can_channel* chan = (can_channel*) (*tab)->priv;
+ CAN_DECLARE_INFO(chan);
+
+ chan->callbacks->can_init(chan);
+ HAL_WRITE_UINT32(CAN_IER(info), INT_DEFAULT); // enable wakeup and error interrupts
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, 1 << CAN_PID(info)); // Enable the peripheral clock to the device
+
+ //
+ // It is important to setup the message buffer configuration after enabling the
+ // peripheral clock. This is nowhere documented in the at91sam7 hardware manual.
+ // If the message buffer configuration is set before the peripheral clock is
+ // enabled, then message buffers that receive extended frames might not work
+ // properly
+ //
+ at91sam7_can_mbox_config_rx_all(chan);
+
+ return ENOERR;
+}
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Setup AT91SAM7 CAN module in a state where all message boxes are disabled
+// After this callit is possible to add single message buffers and filters
+//===========================================================================
+static void at91sam7_can_config_rx_none(can_channel *chan)
+{
+ at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+ cyg_uint8 i;
+
+ //
+ // setup all RX messages moxes into a disabled state and disable all
+ // interrupts - maybe we have to abort pending transfers before $$$$
+ //
+ HAL_WRITE_UINT32(CAN_IDR(info), INT_MB_RX);
+ for (i = 0; i < CAN_MBOX_RX_CNT; ++i)
+ {
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, i), MMR_MB_TYPE_DISABLED); // first disable message box
+ }
+
+ info->free_mboxes = CAN_MBOX_RX_CNT;
+ info->rx_all = false;
+}
+
+
+//===========================================================================
+// Add single message filter - setupm message box and enable interrupt
+//===========================================================================
+static void at91sam7_can_add_rx_filter(can_channel *chan, cyg_uint8 mbox, cyg_can_message *msg)
+{
+ CAN_DECLARE_INFO(chan);
+
+ if (msg->ext)
+ {
+ at91sam7_can_setup_mbox(chan, mbox, MID_SET_EXT(msg->id), MAM_SET_EXT, MMR_MB_TYPE_RX);
+ }
+ else
+ {
+ at91sam7_can_setup_mbox(chan, mbox, MID_SET_STD(msg->id), MAM_SET_STD, MMR_MB_TYPE_RX);
+ }
+ HAL_WRITE_UINT32(CAN_IER(info), 0x01 << mbox);
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Allocate message box
+// Try to find a free message box and return its ID
+//===========================================================================
+static cyg_int8 at91sam7_can_alloc_mbox(at91sam7_can_info_t *info)
+{
+ cyg_uint8 i;
+ cyg_int8 res = CYGNUM_CAN_MSGBUF_NA;
+
+ if (info->free_mboxes)
+ {
+ for (i = (CAN_MBOX_RX_CNT - info->free_mboxes); i <= CAN_MBOX_RX_MAX; ++i)
+ {
+ cyg_uint32 mmr;
+ HAL_READ_UINT32(CAN_MB_MMR(info, i), mmr);
+ if ((mmr & MMR_MB_TYPE_BITMASK) == MMR_MB_TYPE_DISABLED)
+ {
+ info->free_mboxes--;
+ res = i;
+ break;
+ }
+ }
+ } // if (info->free_mboxes)
+
+ return res;
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+#ifdef CYGOPT_IO_CAN_REMOTE_BUF
+//===========================================================================
+// Setup a RTR response message box
+//===========================================================================
+static bool at91sam7_can_setup_rtrmbox(can_channel *chan,
+ cyg_uint32 mbox,
+ cyg_can_message *pmsg,
+ bool init)
+{
+ CAN_DECLARE_INFO(chan);
+ cyg_uint32 mcr;
+
+ //
+ // To prevent concurrent access with the internal CAN core, the application
+ // must disable the mailbox before writing to CAN_MIDx registers - so we
+ // do this here
+ //
+ if (init)
+ {
+ if (pmsg->ext)
+ {
+ at91sam7_can_setup_mbox(chan, mbox, MID_SET_EXT(pmsg->id), MAM_SET_EXT, MMR_MB_TYPE_PRODUCE);
+ }
+ else
+ {
+ at91sam7_can_setup_mbox(chan, mbox, MID_SET_STD(pmsg->id), MAM_SET_STD, MMR_MB_TYPE_PRODUCE);
+ }
+ HAL_WRITE_UINT32(CAN_IER(info), 0x01 << mbox); // enable interrupt
+ }
+ else
+ {
+ cyg_uint32 msr;
+ //
+ // Check if this message box is ready for transmission or if it still transmits
+ // a message - we read the MSR register to check the ready flag
+ //
+ HAL_READ_UINT32(CAN_MB_MSR(info, mbox), msr);
+ if (!(msr & MSR_RDY))
+ {
+ AT91SAM7_DBG_PRINT("(RTR) !MSR_RDY\n");
+ return false;
+ }
+ }
+
+ HAL_WRITE_UINT32(CAN_MB_MDL(info, mbox), pmsg->data.dwords[0]); // set data
+ HAL_WRITE_UINT32(CAN_MB_MDH(info, mbox), pmsg->data.dwords[1]); // set data
+ mcr = (pmsg->dlc << MCR_DLC_SHIFTER) | MCR_TRANSFER_CMD; // set data lengt and transfer request
+ HAL_WRITE_UINT32(CAN_MB_MCR(info, mbox), mcr); // transfer request
+ return true;
+}
+#endif // CYGOPT_IO_CAN_REMOTE_BUF
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Configure message buffers
+//===========================================================================
+static Cyg_ErrNo at91sam7_can_set_config_msgbuf(can_channel *chan, cyg_can_msgbuf_cfg *buf)
+{
+ Cyg_ErrNo res = ENOERR;
+ at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+
+ switch (buf->cfg_id)
+ {
+ //
+ // clear all message filters and remote buffers - prepare for message buffer
+ // configuration
+ //
+ case CYGNUM_CAN_MSGBUF_RESET_ALL :
+ {
+ at91sam7_can_config_rx_none(chan);
+ }
+ break;
+
+ //
+ // setup AT91SAM7 CAN module for reception of all standard and extended messages
+ //
+ case CYGNUM_CAN_MSGBUF_RX_FILTER_ALL :
+ {
+ if (!info->rx_all) // if rx_all is enabled we do not need to do anything
+ {
+ at91sam7_can_mbox_config_rx_all(chan); // setup RX all state
+ }
+ }
+ break;
+
+ //
+ // add single message filter, message with filter ID will be received
+ //
+ case CYGNUM_CAN_MSGBUF_RX_FILTER_ADD :
+ {
+ cyg_can_filter *filter = (cyg_can_filter*) buf;
+
+ //
+ // if AT91SAM7 CAN module is configured to receive all messages then
+ // it is not allowed to add single message filters because then more
+ // than one message buffer would receive the same CAN id
+ //
+ if (info->rx_all)
+ {
+ return -EPERM;
+ }
+
+ //
+ // try to allocate a free message box - if we have a free one
+ // then we can prepare the message box for reception of the
+ // desired message id
+ //
+ filter->handle = at91sam7_can_alloc_mbox(info);
+ if (filter->handle > CYGNUM_CAN_MSGBUF_NA)
+ {
+ at91sam7_can_add_rx_filter(chan, filter->handle, &filter->msg);
+ }
+ }
+ break; //CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
+
+
+#ifdef CYGOPT_IO_CAN_REMOTE_BUF
+ //
+ // Try to add a new RTR response message buffer for automatic transmisson
+ // of data frame on reception of a remote frame
+ //
+ case CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD :
+ {
+ cyg_can_remote_buf *rtr_buf = (cyg_can_remote_buf*) buf;
+ rtr_buf->handle = at91sam7_can_alloc_mbox(info);
+
+ if (rtr_buf->handle > CYGNUM_CAN_MSGBUF_NA)
+ {
+ //
+ // if we have a free message buffer then we setup this buffer
+ // for remote frame reception
+ //
+ at91sam7_can_setup_rtrmbox(chan, rtr_buf->handle, &rtr_buf->msg, true);
+ }
+ }
+ break;
+
+ //
+ // write data into remote response buffer
+ //
+ case CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE :
+ {
+ cyg_can_remote_buf *rtr_buf = (cyg_can_remote_buf*) buf;
+ //
+ // If we have a valid rtr buf handle then we can store data into
+ // rtr message box
+ //
+ if ((rtr_buf->handle >= 0) && (rtr_buf->handle <= CAN_MBOX_RX_MAX))
+ {
+ if (!at91sam7_can_setup_rtrmbox(chan, rtr_buf->handle, &rtr_buf->msg, false))
+ {
+ res = -EAGAIN;
+ }
+ }
+ else
+ {
+ res = -EINVAL;
+ }
+ }
+ break;
+#endif // #ifdef CYGOPT_IO_CAN_REMOTE_BUF
+ } // switch (buf->cfg_id)
+
+ return res;
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+//===========================================================================
+// Read state of CAN controller
+// The CAN state variable for each channel is modiefied by DSR so if we
+// read the state we need to lock DSRs to protect the data access
+//===========================================================================
+static cyg_can_state at91sam7_get_state(at91sam7_can_info_t *info)
+{
+ cyg_can_state result;
+
+ cyg_drv_dsr_lock();
+ result = info->state;
+ cyg_drv_dsr_unlock();
+
+ return result;
+}
+
+
+//===========================================================================
+// Enter low power mode
+// Before stopping the CAN clock (PMC), the CAN Controller must be in
+// Low-power Mode to complete the current transfer. After restarting the
+// clock, the application must disable the Low-power Mode of the
+// CAN controller. If the power mode is entered, a sleep interrupt is
+// generated.
+//===========================================================================
+static void at91sam7_enter_lowpower_mode(can_channel *chan)
+{
+ CAN_DECLARE_INFO(chan);
+
+
+ cyg_uint32 mr;
+ HAL_READ_UINT32(CAN_MR(info), mr);
+ HAL_WRITE_UINT32(CAN_MR(info), mr | MR_LOW_POWER);
+ HAL_WRITE_UINT32(CAN_IER(info), INT_SLEEP);
+}
+
+
+//===========================================================================
+// Start CAN module (or leave the low power mode)
+// If the CAN module is in STANDBY state then we enable the module clock
+// and leave the low power mode by clearing the low power flag.
+//===========================================================================
+static void at91sam7_start_module(can_channel *chan)
+{
+ CAN_DECLARE_INFO(chan);
+ cyg_uint32 mr;
+
+ HAL_WRITE_UINT32(CAN_IER(info), INT_DEFAULT); // enable wakeup interrupt
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, 1 << CAN_PID(info)); // restart peripheral clock
+ HAL_READ_UINT32(CAN_MR(info), mr);
+ mr &= ~MR_LOW_POWER ;
+ HAL_WRITE_UINT32(CAN_MR(info), mr | MR_CAN_ENABLE); // clear the low power flag to leave standby
+}
+
+//===========================================================================
+// Change device configuration
+//===========================================================================
+static Cyg_ErrNo at91sam7_can_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+
+ switch (key)
+ {
+ //
+ // Setup a new CAN configuration. This will i.e. setup a new baud rate
+ //
+ case CYG_IO_SET_CONFIG_CAN_INFO:
+ {
+ cyg_can_info_t* config = (cyg_can_info_t*) buf;
+ if (*len < sizeof(cyg_can_info_t))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_info_t);
+ if (!at91sam7_can_config_channel(chan, config, false))
+ {
+ return -EINVAL;
+ }
+ }
+ break;
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ //
+ // configure message buffers
+ //
+ case CYG_IO_SET_CONFIG_CAN_MSGBUF :
+ {
+ cyg_can_msgbuf_cfg *msg_buf = (cyg_can_msgbuf_cfg *)buf;
+
+ if (*len != sizeof(cyg_can_msgbuf_cfg))
+ {
+ return -EINVAL;
+ }
+
+ res = at91sam7_can_set_config_msgbuf(chan, msg_buf);
+ }
+ break;
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+ //
+ // Change CAN state of AT91SAM7 CAN module
+ //
+ case CYG_IO_SET_CONFIG_CAN_MODE :
+ {
+ cyg_can_mode *can_mode = (cyg_can_mode*) buf;
+
+ if (*len != sizeof(cyg_can_mode))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_mode);
+
+ //
+ // decide what to do acording to mode
+ //
+ switch (*can_mode)
+ {
+ //
+ // The controller does not support a stopped and standby state so we
+ // simply enter the low power state here. This state is also safe for
+ // message buffer configuration
+ //
+ case CYGNUM_CAN_MODE_STOP : at91sam7_enter_lowpower_mode(chan); break;
+ case CYGNUM_CAN_MODE_START : at91sam7_start_module(chan); break;
+ case CYGNUM_CAN_MODE_STANDBY : at91sam7_enter_lowpower_mode(chan); break;
+ case CYGNUM_CAN_MODE_CONFIG : at91sam7_enter_lowpower_mode(chan); break;
+ case CYGNUM_CAN_MODE_LISTEN_ONLY_ENTER: return -EINVAL;
+ case CYGNUM_CAN_MODE_LISTEN_ONLY_EXIT: return -EINVAL;
+ }
+ }
+ break; // case CYG_IO_SET_CONFIG_CAN_MODE :
+ } // switch (key)
+
+ return res;
+}
+
+
+//===========================================================================
+// Query device configuration
+//===========================================================================
+static Cyg_ErrNo at91sam7_can_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+ at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+
+ switch(key)
+ {
+ //
+ // query state of CAN controller
+ //
+ case CYG_IO_GET_CONFIG_CAN_STATE :
+ {
+ cyg_can_state *can_state = (cyg_can_state*) buf;
+
+ if (*len != sizeof(cyg_can_state))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_state);
+ *can_state = at91sam7_get_state(info);
+ }
+ break;
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ //
+ // Query message box information - returns available and free message
+ // boxes
+ //
+ case CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO :
+ {
+ cyg_can_msgbuf_info *mbox_info = (cyg_can_msgbuf_info*) buf;
+
+ if (*len != sizeof(cyg_can_msgbuf_info))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_msgbuf_info);
+
+ mbox_info->count = CAN_MBOX_RX_CNT;
+ mbox_info->free = info->free_mboxes;
+ }
+ break;
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+ //
+ // Query hardware description of FlexCAN device driver
+ //
+ case CYG_IO_GET_CONFIG_CAN_HDI :
+ {
+ cyg_can_hdi *hdi = (cyg_can_hdi *)buf;
+ //
+ // comes from high level driver so we do not need to
+ // check buffer size here
+ //
+ hdi->support_flags = CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE
+ | CYGNUM_CAN_HDI_FULLCAN
+ | CYGNUM_CAN_HDI_AUTBAUD;
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+ hdi->support_flags |= CYGNUM_CAN_HDI_TIMESTAMP;
+#endif
+ }
+ break;
+
+ default :
+ res = -EINVAL;
+ }// switch(key)
+
+ return res;
+}
+
+
+//===========================================================================
+// Send single message
+//===========================================================================
+static bool at91sam7_can_putmsg(can_channel *priv, CYG_CAN_MSG_T *pmsg, void *pdata)
+{
+ CAN_DECLARE_INFO(priv);
+ cyg_uint32 msr;
+ cyg_uint32 mcr = 0;
+
+ //
+ // First check if this message box is ready fro transmission or if it still transmits
+ // a message - we read the MSR register to check the ready flag
+ //
+ HAL_READ_UINT32(CAN_MB_MSR(info, CAN_MBOX_TX(info)), msr);
+ if (!(msr & MSR_RDY))
+ {
+ AT91SAM7_DBG_PRINT("!MSR_RDY\n");
+ return false;
+ }
+
+ //
+ // To prevent concurrent access with the internal CAN core, the application must disable
+ // the mailbox before writing to CAN_MIDx registers - so we do this now
+ //
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, CAN_MBOX_TX(info)), MMR_MB_TYPE_DISABLED);
+
+ //
+ // Setup the message identifier - this depends on the frame type (standard or extended)
+ //
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (AT91SAM7_CAN_IS_EXT(*pmsg))
+ {
+ HAL_WRITE_UINT32(CAN_MB_MID(info, CAN_MBOX_TX(info)),
+ pmsg->id | MID_MIDE); // set extended message id
+ }
+ else
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ HAL_WRITE_UINT32(CAN_MB_MID(info, CAN_MBOX_TX(info)),
+ (pmsg->id << MID_MIDvA_SHIFTER) & MID_MIDvA_BITMASK); // set standard message id
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+ }
+
+ HAL_WRITE_UINT32(CAN_MB_MDL(info, CAN_MBOX_TX(info)), pmsg->data.dwords[0]); // set data
+ HAL_WRITE_UINT32(CAN_MB_MDH(info, CAN_MBOX_TX(info)), pmsg->data.dwords[1]); // set data
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, CAN_MBOX_TX(info)), MMR_MB_TYPE_TX); // reenable the message box
+ mcr = (AT91SAM7_CAN_GET_DLC(*pmsg) << MCR_DLC_SHIFTER) | MCR_TRANSFER_CMD; // set data lengt and transfer request
+
+ if (AT91SAM7_CAN_IS_RTR(*pmsg))
+ {
+ mcr |= MCR_RTR;
+ }
+
+ HAL_WRITE_UINT32(CAN_MB_MCR(info, CAN_MBOX_TX(info)), mcr);
+ return true;
+}
+
+
+//===========================================================================
+// Read event from device driver
+//===========================================================================
+static bool at91sam7_can_getevent(can_channel *chan, CYG_CAN_EVENT_T *pevent, void *pdata)
+{
+ at91sam7_can_info_t *info = (at91sam7_can_info_t *)chan->dev_priv;
+ cyg_uint32* pstat = (cyg_uint32 *)pdata;
+ cyg_uint8 mboxflags = (*pstat & INT_MB_RX);
+ cyg_uint8 mbox = 0;
+ bool res = true;
+
+ //
+ // First check if a message box interrupt occured if a message box interrupt
+ // occured process the lowest message box that caused an interrupt
+ //
+ if (mboxflags)
+ {
+ cyg_uint32 msr;
+ cyg_uint32 mid;
+ cyg_uint32 mmr;
+
+ while (!(mboxflags & 0x01))
+ {
+ mboxflags >>= 1;
+ mbox++;
+ }
+
+ //
+ // If the message box that caused the interrupt is an PRODUCER message box,
+ // then we received an remote request message, if not, then this is a normal
+ // RX message
+ //
+ HAL_READ_UINT32(CAN_MB_MMR(info, mbox), mmr);
+ HAL_READ_UINT32(CAN_MB_MSR(info, mbox), msr);
+ *pstat &= ~(0x01 << mbox); // clear flag
+
+ if (MMR_MB_GET_TYPE(mmr) != MMR_MB_TYPE_PRODUCE)
+ {
+ HAL_READ_UINT32(CAN_MB_MID(info, mbox), mid);
+ pevent->flags |= CYGNUM_CAN_EVENT_RX;
+ if (msr & MSR_MSG_IGNORED)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_OVERRUN_RX_HW;
+ }
+
+ //
+ // It is important to set the DLC first because this also clears the ctrl
+ // field if extended identifiers are supported
+ //
+ AT91SAM7_CAN_SET_DLC(pevent->msg, MSR_DLC_GET(msr));
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (mid & MID_MIDE)
+ {
+ pevent->msg.id = MID_GET_EXT(mid);
+ AT91SAM7_CAN_SET_EXT(pevent->msg);
+ }
+ else
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ pevent->msg.id = MID_GET_STD(mid);
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+ }
+
+ if (msr & MSR_RTR)
+ {
+ AT91SAM7_CAN_SET_RTR(pevent->msg);
+ }
+ else
+ {
+ HAL_READ_UINT32(CAN_MB_MDL(info, mbox), pevent->msg.data.dwords[0]);
+ HAL_READ_UINT32(CAN_MB_MDH(info, mbox), pevent->msg.data.dwords[1]);
+ }
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+ pevent->timestamp = msr & MSR_TIMESTAMP;
+#endif
+
+ HAL_WRITE_UINT32(CAN_MB_MCR(info, mbox), MCR_TRANSFER_CMD); // transfer request
+ AT91SAM7_DBG_PRINT("RXID: %x\n", AT91SAM7_CAN_GET_ID(pevent->msg));
+ } // if (!(mbox & info->rtr_mboxes)
+ else
+ {
+ HAL_WRITE_UINT32(CAN_MB_MCR(info, mbox), (msr & MSR_DLC) | MCR_TRANSFER_CMD); // transfer request
+ //
+ // We do not need to store an event into receive queue if the stat field does
+ // not contain any further event flags. If stat is empty we can set res
+ // to false and no event will bestore
+ //
+ res = !(*pstat == 0);
+ }
+
+ HAL_WRITE_UINT32(CAN_IER(info), 0x01 << mbox); // enable interruptfor this message box
+ } // if (mboxflags)
+
+ //
+ // Now check if additional events occured
+ //
+ if (*pstat)
+ {
+ if (*pstat & INT_WAKEUP)
+ {
+ AT91SAM7_DBG_PRINT("WAKE\n");
+ pevent->flags |= CYGNUM_CAN_EVENT_LEAVING_STANDBY;
+ *pstat &= ~INT_WAKEUP;
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ }
+
+ if (*pstat & INT_ERR_PASSIVE)
+ {
+ AT91SAM7_DBG_PRINT("ERRP\n");
+ pevent->flags |= CYGNUM_CAN_EVENT_ERR_PASSIVE;
+ *pstat &= ~INT_ERR_PASSIVE;
+ info->state = CYGNUM_CAN_STATE_ERR_PASSIVE;
+ HAL_WRITE_UINT32(CAN_IER(info), INT_WAKEUP);
+ }
+
+ if (*pstat & INT_WARN)
+ {
+ //
+ // check which counter reached its warning level (> 96)
+ //
+ cyg_uint8 ecr;
+ HAL_READ_UINT32(CAN_ECR(info), ecr);
+ if (ECR_GET_REC(ecr) > 96)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_WARNING_RX;
+ AT91SAM7_DBG_PRINT("WARN TX\n");
+ }
+ if (ECR_GET_TEC(ecr) > 96)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_WARNING_TX;
+ AT91SAM7_DBG_PRINT("WARN RX\n");
+ }
+ *pstat &= ~INT_WARN;
+ info->state = CYGNUM_CAN_STATE_BUS_WARN;
+ HAL_WRITE_UINT32(CAN_IER(info), INT_ERR_PASSIVE | INT_BUS_OFF);
+ }
+
+ if (*pstat & INT_BUS_OFF)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_BUS_OFF;
+ AT91SAM7_DBG_PRINT("BOFF\n");
+ *pstat &= ~INT_BUS_OFF;
+ info->state = CYGNUM_CAN_STATE_BUS_OFF;
+ HAL_WRITE_UINT32(CAN_IER(info), INT_WAKEUP);
+ }
+
+ if (*pstat & INT_SLEEP)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_ENTERING_STANDBY;
+ AT91SAM7_DBG_PRINT("SLEEP\n");
+ *pstat &= ~INT_SLEEP;
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCDR, 1 << CAN_PID(info)); // disable module clock
+ info->state = CYGNUM_CAN_STATE_STANDBY; // set state variable
+ HAL_WRITE_UINT32(CAN_IER(info), INT_WAKEUP); // enable wakeup interrupt
+ }
+
+ if (*pstat & (INT_CRC_ERR | INT_STUFF_ERR | INT_ACKN_ERR | INT_FORM_ERR | INT_BIT_ERR))
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_CAN_ERR;
+ AT91SAM7_DBG_PRINT("CERR\n");
+ *pstat &= ~(INT_CRC_ERR | INT_STUFF_ERR | INT_ACKN_ERR | INT_FORM_ERR | INT_BIT_ERR);
+ }
+ } // if (*pstat)
+
+ return res;
+}
+
+
+//===========================================================================
+// Kick transmitter
+//===========================================================================
+static void at91sam7_can_start_xmit(can_channel* chan)
+{
+ CAN_DECLARE_INFO(chan);
+
+ AT91SAM7_DBG_PRINT("start_xmit\n");
+ cyg_drv_dsr_lock();
+ HAL_WRITE_UINT32(CAN_IER(info), 0x01 << CAN_MBOX_TX(info)); // enable tx interrupt
+ cyg_drv_dsr_unlock();
+}
+
+
+//===========================================================================
+// Stop transmitter
+//===========================================================================
+static void at91sam7_can_stop_xmit(can_channel* chan)
+{
+ CAN_DECLARE_INFO(chan);
+
+ HAL_WRITE_UINT32(CAN_IDR(info), 0x01 << CAN_MBOX_TX(info)); // disable tx interrupt
+ AT91SAM7_DBG_PRINT("stop_xmit\n");
+}
+
+
+//===========================================================================
+// Configure can channel
+//===========================================================================
+static bool at91sam7_can_config_channel(can_channel* chan, cyg_can_info_t* config, cyg_bool init)
+{
+ CAN_DECLARE_INFO(chan);
+ cyg_uint32 temp32;
+ bool res = true;
+
+ if (init)
+ {
+ //
+ // If the platform that uses the driver needs to do some platform specific
+ // initialisation steps, it can do it inside of this macro. I.e. some platforms
+ // need to setup the CAN transceiver properly here (this is necessary for the
+ // Atmel AT91SAM7X-EK)
+ //
+#if CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1 && defined(HAL_AT91SAM7_CAN0_PLF_INIT)
+ HAL_AT91SAM7_CAN0_PLF_INIT();
+#else // CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS > 1
+#if defined(CYGPKG_DEVS_CAN_AT91SAM7_CAN0) && defined(HAL_AT91SAM7_CAN0_PLF_INIT)
+ if (info == &at91sam7_can0_info) {
+ HAL_AT91SAM7_CAN0_PLF_INIT();
+ }
+#endif // defined(CYGPKG_DEVS_CAN_AT91SAM7_CAN0) && defined(HAL_AT91SAM7_CAN0_PLF_INIT)
+#if defined(CYGPKG_DEVS_CAN_AT91SAM7_CAN1) && defined(HAL_AT91SAM7_CAN1_PLF_INIT)
+ if (info == &at91sam7_can1_info) {
+ HAL_AT91SAM7_CAN1_PLF_INIT();
+ }
+#endif // defined(CYGPKG_DEVS_CAN_AT91SAM7_CAN0) && defined(HAL_AT91SAM7_CAN0_PLF_INIT)
+#endif // CYGINT_DEVS_CAN_AT91SAM7_CAN_CHANNELS == 1
+
+ HAL_WRITE_UINT32(CAN_IDR(info), 0xFFFFFFFF); // disable all interrupts
+ HAL_WRITE_UINT32(CAN_MR(info), 0x00); // disable CAN module
+ HAL_ARM_AT91_PIO_CFG(AT91_CAN_CANRX); // Enable the CAN module to drive the CAN port pins
+ HAL_ARM_AT91_PIO_CFG(AT91_CAN_CANTX);
+
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, CAN_MBOX_TX(info)), MMR_MB_TYPE_DISABLED); // first disable tx message box
+ HAL_WRITE_UINT32(CAN_MB_MAM(info, CAN_MBOX_TX(info)), 0x00000000); // set acceptance mask once
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, CAN_MBOX_TX(info)), MMR_MB_TYPE_TX); // setup as tx message box
+
+ HAL_WRITE_UINT32(CAN_MR(info), MR_CAN_ENABLE); // enable CAN module
+
+ //
+ // The device should go into error active state right after enabling it
+ //
+ HAL_READ_UINT32(CAN_SR(info), temp32);
+ if (!(temp32 & INT_ERR_ACTIVE))
+ {
+ res = false;
+ }
+ } // if (init)
+
+ res = at91sam7_can_set_baud(chan, &config->baud); // set baudrate
+
+ //
+ // store new config values
+ //
+ if (config != &chan->config)
+ {
+ chan->config = *config;
+ }
+
+ return res;
+}
+
+
+//===========================================================================
+// Low level interrupt handler
+//===========================================================================
+static cyg_uint32 at91sam7_can_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ at91sam7_can_info_t * const info = (at91sam7_can_info_t *)chan->dev_priv;
+ cyg_uint32 sr;
+ cyg_uint32 imr;
+
+
+ HAL_READ_UINT32(CAN_IMR(info), imr);
+ HAL_READ_UINT32(CAN_SR(info), sr);
+ AT91SAM7_DBG_PRINT("CAN_ISR SR %x\n", sr);
+ sr &= imr;
+ HAL_WRITE_UINT32(CAN_IDR(info), sr);
+
+ info->stat |= sr;
+ cyg_drv_interrupt_acknowledge(vector);
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// High level interrupt handler
+//===========================================================================
+static void at91sam7_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ at91sam7_can_info_t * const info = (at91sam7_can_info_t *)chan->dev_priv;
+ cyg_uint32 stat = 0;
+
+ do
+ {
+ //
+ // If a number of events occured then we process all events now in
+ // in this DSR the get_event() function clears the flags in the stat
+ // field
+ //
+ while (stat)
+ {
+ if (stat & (0x01 << CAN_MBOX_TX(info)))
+ {
+ AT91SAM7_DBG_PRINT("TX_DSR\n");
+ chan->callbacks->xmt_msg(chan, 0); // send next message
+ stat &= ~INT_MB_TX; // clear flag
+ }
+ else if (stat)
+ {
+ AT91SAM7_DBG_PRINT("EVENT_DSR\n");
+ chan->callbacks->rcv_event(chan, &stat);
+ }
+ }
+
+ //
+ // We check, if a new event occured while we processed other events. If new events
+ // occured, then we process the new events
+ //
+ cyg_drv_interrupt_mask(vector);
+ stat = info->stat;
+ info->stat = 0;
+ cyg_drv_interrupt_unmask(vector);
+ } while (stat);
+}
+
+
+//===========================================================================
+// Set baudrate of certain can channel
+//===========================================================================
+static bool at91sam7_can_set_baud(can_channel *chan, cyg_can_baud_rate_t *baudrate)
+{
+ bool res = true;
+ cyg_uint32 mrbck;
+ cyg_uint32 canbr;
+ CAN_DECLARE_INFO(chan);
+
+
+#ifdef CYGOPT_IO_CAN_AUTOBAUD
+ if (CYGNUM_CAN_KBAUD_AUTO == *baudrate)
+ {
+ cyg_can_baud_rate_t i;
+ cyg_uint8 j;
+ cyg_uint32 sr;
+
+ res = false;
+ for (i = CYGNUM_CAN_KBAUD_10; i <= CYGNUM_CAN_KBAUD_1000; ++i)
+ {
+ HAL_AT91SAM7_GET_CAN_BR(i, canbr);
+ if (0 == canbr)
+ {
+ continue;
+ }
+
+ HAL_READ_UINT32(CAN_SR(info), sr);
+ HAL_WRITE_UINT32(CAN_MR(info), 0); // disable the module
+ HAL_WRITE_UINT32(CAN_BR(info), canbr); // write baudrate register
+ HAL_WRITE_UINT32(CAN_MR(info), MR_CAN_ENABLE | MR_AUTOBAUD); // enable controller in auto aud mode
+ for(j = 0; j < 200; ++j)
+ {
+ HAL_DELAY_US(1000); // wait at least 11 bit times for synchronization
+ }
+ HAL_READ_UINT32(CAN_SR(info), sr); // read status register
+ if (!(sr & INT_ALL_ERR) && (sr & INT_WAKEUP))
+ {
+ HAL_WRITE_UINT32(CAN_MR(info), 0); // disable the module
+ HAL_WRITE_UINT32(CAN_MR(info), MR_CAN_ENABLE); // enable controller
+ *baudrate = i; // store baudrate
+ return true;
+ } // if (!(sr & INT_ALL_ERR))
+ }
+ }
+ else
+#endif // CYGOPT_IO_CAN_AUTOBAUD
+ {
+ //
+ // Get bit timings from HAL because bit timings depend on sysclock
+ // For main clock of 48 MHz this macro is implemented in this device
+ // driver. If the macro fills the canbr value with 0 then the baudrate
+ // is not supported and the function returns false
+ //
+ HAL_AT91SAM7_GET_CAN_BR(*baudrate, canbr);
+ if (0 == canbr)
+ {
+ return false;
+ }
+
+ //
+ // Any modificatons to the baudrate register must be done while CAN
+ // module is disabled. So we first disable CAN module, then we set
+ // baudrate and then we reenable the CAN module by setting the CAN enable
+ // flag
+ //
+ HAL_READ_UINT32(CAN_MR(info), mrbck); // backup value of mode register
+ HAL_WRITE_UINT32(CAN_MR(info), mrbck &~MR_CAN_ENABLE); // disable controller
+ HAL_WRITE_UINT32(CAN_BR(info), canbr); // write baudrate register
+
+ //
+ // Now restore the previous state - if the module was started then
+ // it will no be started again, if it was stopped, then it remains stopped
+ //
+ HAL_WRITE_UINT32(CAN_MR(info), mrbck);
+ }
+
+ return res;
+}
+
+
+//===========================================================================
+// Setup one single message box for reception of can message
+//===========================================================================
+static void at91sam7_can_setup_mbox(can_channel *chan, cyg_uint8 mbox, cyg_uint32 mid, cyg_uint32 mam, cyg_uint32 rxtype)
+{
+ CAN_DECLARE_INFO(chan);
+ CYG_ASSERT(mbox < 7, "invalid rx mbox number");
+
+
+ //
+ // To prevent concurrent access with the internal CAN core, the application
+ // must disable the mailbox before writing to CAN_MIDx registers - so we
+ // do this here
+ //
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, mbox), MMR_MB_TYPE_DISABLED); // first disable message box
+ HAL_WRITE_UINT32(CAN_MB_MAM(info, mbox), mam); // set acceptance mask
+ HAL_WRITE_UINT32(CAN_MB_MID(info, mbox), mid); // set message identifier
+ HAL_WRITE_UINT32(CAN_MB_MMR(info, mbox), rxtype); // setup message box as rx message box (with or without overwrite)
+ HAL_WRITE_UINT32(CAN_MB_MCR(info, mbox), MCR_TRANSFER_CMD); // transfer request - we do not enable interrupts here
+}
+
+
+//===========================================================================
+// Configure message boxes for reception of any CAN message
+//===========================================================================
+static void at91sam7_can_mbox_config_rx_all(can_channel *chan)
+{
+ at91sam7_can_info_t * const info = (at91sam7_can_info_t *)chan->dev_priv;
+ cyg_uint8 i;
+ cyg_uint8 mbox_int_mask = 0;
+ cyg_uint8 mbox_rx_all_cnt = CAN_MBOX_RX_ALL_CNT(info);
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ cyg_uint8 last_std_rx_mbox = CAN_MBOX_STD_CNT(info) - 1;
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ cyg_uint8 last_ext_rx_mbox = mbox_rx_all_cnt - 1;
+#endif// CYGOPT_IO_CAN_EXT_CAN_ID
+
+ //
+ // Now setup all rx message boxes. One message box (the last one - no 8) is
+ // used for transmission so we have 7 message boxes for reception of can messages
+ // We setup the message boxes 0 - 5 as RX mboxes and message box 6 as RX mbox with
+ // overwrite.
+ //
+ for (i = 0; i < mbox_rx_all_cnt; ++i)
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ if (i < CAN_MBOX_STD_CNT(info))
+ {
+ //
+ // setup message boxes for standard frames
+ //
+ if (i < last_std_rx_mbox)
+ {
+ at91sam7_can_setup_mbox(chan, i, 0, MID_MIDE, MMR_MB_TYPE_RX);
+ }
+ else
+ {
+ at91sam7_can_setup_mbox(chan, i, 0, MID_MIDE, MMR_MB_TYPE_RX_OVW);
+ }
+ }
+ else
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ //
+ // setup message boxes for extended frames
+ //
+ if (i < last_ext_rx_mbox)
+ {
+ at91sam7_can_setup_mbox(chan, i, MID_MIDE, MID_MIDE, MMR_MB_TYPE_RX);
+ }
+ else
+ {
+ at91sam7_can_setup_mbox(chan, i, MID_MIDE, MID_MIDE, MMR_MB_TYPE_RX_OVW);
+ }
+#endif// CYGOPT_IO_CAN_EXT_CAN_ID
+ } // if (i < CAN_MBOX_STD_CNT(info))
+
+ mbox_int_mask = (mbox_int_mask << 1) | 0x01; // enable interrupt
+ } // for (i = 0; i < CAN_MBOX_RX_CNT; ++i)*/
+
+ info->free_mboxes = CAN_MBOX_RX_CNT - mbox_rx_all_cnt;
+ info->rx_all = true;
+ HAL_WRITE_UINT32(CAN_IER(info), mbox_int_mask); // Now finally enable the interrupts for als RX mboxes
+}
+
+
+//---------------------------------------------------------------------------
+// EOF can_at91am7.c
diff --git a/ecos/packages/devs/can/arm/at91/at91sam7/current/tests/can_test_aux.inl b/ecos/packages/devs/can/arm/at91/at91sam7/current/tests/can_test_aux.inl
new file mode 100644
index 0000000..2bb2e07
--- /dev/null
+++ b/ecos/packages/devs/can/arm/at91/at91sam7/current/tests/can_test_aux.inl
@@ -0,0 +1,147 @@
+//==========================================================================
+//
+// can_test_aux.inl
+//
+// CAN test auxiliary functions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Auxiliary functions for CAN driver tests
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// PRINT CAN EVENT
+//===========================================================================
+void print_can_msg(cyg_can_message *pmsg, char *pMsg)
+{
+ char *pmsg_str;
+ static char* msg_tbl[] =
+ {
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X %02X]\n"
+ };
+
+ if (pmsg->rtr)
+ {
+ diag_printf("%s [ID:%03X] [RTR:%d] [EXT:%d] [DLC:%d]\n",
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->dlc);
+
+ return;
+ }
+
+ if (pmsg->dlc > 8)
+ {
+ pmsg_str = msg_tbl[8];
+ }
+ else
+ {
+ pmsg_str = msg_tbl[pmsg->dlc];
+ }
+
+ diag_printf(pmsg_str,
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->data.bytes[0],
+ pmsg->data.bytes[1],
+ pmsg->data.bytes[2],
+ pmsg->data.bytes[3],
+ pmsg->data.bytes[4],
+ pmsg->data.bytes[5],
+ pmsg->data.bytes[6],
+ pmsg->data.bytes[7]);
+}
+
+
+//===========================================================================
+// PRINT CAN EVENT FLAGS
+//===========================================================================
+void print_can_flags(cyg_uint16 flags, char *pMsg)
+{
+ char *pmsg_str;
+ cyg_uint8 i ;
+ static char* msg_tbl[] =
+ {
+ "RX ",
+ "TX ",
+ "WRX ",
+ "WTX ",
+ "ERRP ",
+ "BOFF ",
+ "OVRX ",
+ "OVTX ",
+ "CERR ",
+ "LSTY ",
+ "ESTY ",
+ "ALOS ",
+ "DEVC ",
+ "PHYF ",
+ "PHYH ",
+ "PHYL "
+ };
+ i = 0;
+ while (flags && (i < 16))
+ {
+ if (flags & 0x0001)
+ {
+ pmsg_str = msg_tbl[i];
+ diag_printf(pmsg_str);
+ }
+ flags >>=1;
+ i++;
+ }
+
+ diag_printf("\n");
+}
+
+//---------------------------------------------------------------------------
+// end of can_test_aux.inl
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/ChangeLog b/ecos/packages/devs/can/arm/lpc2xxx/current/ChangeLog
new file mode 100644
index 0000000..cc0b854
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/ChangeLog
@@ -0,0 +1,152 @@
+2013-09-17 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/can_lpc2xxx.cdl: Add CYGHWR_DEVS_CAN_LPC2XXX_BUSOFF_WORKAROUND
+ to enable conditional Bus-Off reset mode workaround. [Bug 1001897]
+ * src/can_lpc2xxx.c: Add function lpc2xxx_reset_error_counters to
+ reset TX and RX error counters to certain values. Function
+ lpc2xxx_start_module now clears both error counters. Add some
+ LPC2XXX_DBG_PRINT statements to lpc2xxx_can_getevent function. Add
+ function lpc2xxx_print_status to ease printing status register
+ content. If a bus error condition occures (ICR_BUS_ERR) the function
+ lpc2xxx_can_getevent now clears the error counters to prevent error
+ ISR from blocking application and to support recovery from bus off
+ condition if option CYGHWR_DEVS_CAN_LPC2XXX_BUSOFF_WORKAROUND is
+ enabled.
+
+2013-09-11 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/can_accfilt_lpc2xxx.c, src/can_lpc2xxx.c: Fix a compile issue of
+ the lpc2xxx driver that only occurs if support for extended 29-bit CAN
+ identifiers is enabled and support for message filtering is disabled.
+ [ Bugzilla 1001901 ]
+
+2013-08-29 Uwe Kindler <uwe_kindler@web.de>
+
+ * includes/can_lpc2xxx_baudrates.h: Added baudrate table for CAN clock
+ of 14.745600 MHz. [ Bugzilla 1001900 ]
+
+2013-06-24 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/can_lpc2xxx.c: Add support for new config key
+ CYG_IO_GET_CONFIG_CAN_ERR_COUNTERS.
+
+2013-05-06 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/can_lpc2xxx.c: Changed return code for message filter
+ configuration to -ENOSPC if no filters are available to match
+ documentation change.
+
+2012-01-25 Bernard Fouché <bernard.fouche@kuantic.com>
+
+ * Changes made to support CAN IO package update:
+ * cdl/can_lpc2xxx.cdl: CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
+ replaced by CYG_IO_SET_CONFIG_CAN_RANGE_FILTER.
+ * include/can_lpc2xxx.h: Commented out unused and not implemented
+ things.
+ * src/can_lpc2xxx.c: CYGNUM_CAN_EVENT_OVERRUN_RX_HW instead of
+ CYGNUM_CAN_EVENT_OVERRUN_RX. CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
+ replaced by CYG_IO_SET_CONFIG_CAN_RANGE_FILTER. can_lpc2xxx.h not
+ required any more. CYGNUM_CAN_MODE_LISTEN_ONLY_ENTER &
+ CYGNUM_CAN_MODE_LISTEN_ONLY_EXIT return -EINVAL.
+ [ Bugzilla 1001453 ]
+
+2008-07-21 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/can_lpc2xxx.cdl: Added CYGOPT_DEVS_CAN_LPC2XXX_ALIE to make
+ arbitration lost interrupt optional. Added option
+ CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY to configure the interrupt
+ priority for global CAN interrupt in LPC24xx variants.
+
+ * include/can_lpc2xxx_baudrates.h: Replaced CYGNUM_CAN_LPC2XXX_VPB_CLK
+ by CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK because newer variants like LPC24xx
+ do not have a global VPB_CLK.
+
+ * src/can_accfilt_lpc2xxx.c: Adjusted LPC2XXX_CAN_FIRST_IN_LUT to
+ be 0 for LPC24xxx variants. Added macro CAN_CHAN_NO_LUT(_info_) to
+ abstract channel numbering from acceptance filter code.
+
+ * src/can_lpc2xxx.c: Removed icr data field from lpc2xxx_can_info_st
+ structure because it is not required any longer. A lot of small
+ modifications to make the driver usable with newer LPC2xxx variants like
+ LPC24xx. ISR and DSR code changed - instead of disabling interrupts in
+ IER register they are disabled in VIC by using cyg_drv_interrupt_mask()
+ function calls. Added global CAN ISR and DSR for LPC24xx variants
+ (they do not support individual interrupt vectors for RX and TX
+ interrupts). Moved LUT error checking code from ISR into DSR to keep
+ ISR as short as possible and made LUT error checking code optional.
+
+2008-05-23 Alexey Shusharin <mrfinch@mail.ru>
+
+ * cdl/can_lpc2xxx.cdl: add CAN interrupt priorities
+
+ * src/can_lpc2xxx.c: add CAN interrupt priorities,
+ repair "chan" definition missing in rx_ISR
+
+ * src/can_accfilt_lpc2xxx.c: add various types of CAN controllers
+ numbering (depends on LPC2XXX version)
+
+2007-08-17 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+
+ * src/can_lpc2xxx.c: The definition of "info" is missing when only
+ one CAN channel is configured.
+
+2007-08-17 Uwe Kindler <uwe_kindler@web.de>
+
+ * include/can_lpc2xxx_baudrates.h: Removed all prefixed zeros from
+ baudrate table entries (they aren't intended to be interpreted as
+ octal)
+
+ * tests/can_baudrates.c
+ tests/can_busload.c
+ tests/can_rx_tx.c: removed #include pkgconf/devs_can_loop.h
+
+2007-08-02 Alexey Shusharin <mrfinch@mail.ru>
+
+ * src/can_lpc2xxx.c: Added acknowledging call in rx interrupt
+ (self-reception part)
+
+2007-07-07 Alexey Shusharin <mrfinch@mail.ru>
+
+ * cdl/can_lpx2xxx.cdl: Option
+ CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION added for enabling
+ self reception requests instead of transmission requests.
+
+ * src/can_lpc2xxx.c: Some small bugs fixed. Added support for LUT
+ error. Support for self transmission request added. Debug output
+ improved.
+
+ * src/can_accfilt_lpc2xxx.c: Added support for baudrates of 10kbaud
+ and 20 kbaud at clock speed of 60 MHz
+
+2007-07-01 Uwe Kindler <uwe_kindler@web.de>
+
+ * LPC2xxx CAN driver package created
+ * cdl/can_lpc2xxx.cdl
+ * include/can_lpc2xxx.h
+ * include/can_lpc2xxx_baudrates.h
+ * src/can_lpc2xxx.c
+ * src/can_accfilt_lpc2xxx.c
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/cdl/can_lpc2xxx.cdl b/ecos/packages/devs/can/arm/lpc2xxx/current/cdl/can_lpc2xxx.cdl
new file mode 100644
index 0000000..712a300
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/cdl/can_lpc2xxx.cdl
@@ -0,0 +1,424 @@
+# ====================================================================
+#
+# can_lpc2xxx.cdl
+#
+# eCos LPC2xxx CAN module configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors:
+# Date: 2007-02-10
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_CAN_LPC2XXX {
+ display "Philips LPC2xxx CAN device drivers"
+ parent CYGPKG_IO_CAN_DEVICES
+ active_if CYGPKG_IO_CAN
+ active_if CYGPKG_HAL_ARM_LPC2XXX || CYGPKG_HAL_ARM_LPC24XX
+ requires CYGPKG_ERROR
+
+ implements CYGINT_IO_CAN_STD_CAN_ID
+ implements CYGINT_IO_CAN_EXT_CAN_ID
+
+ include_dir cyg/io
+ description "
+ This option enables the CAN device drivers for the
+ Philips LPC2XXX."
+ compile -library=libextras.a can_lpc2xxx.c
+ define_proc {
+ puts $::cdl_system_header "/***** CAN driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_CAN_DEVICE_HEADER <pkgconf/devs_can_lpc2xxx.h>"
+ puts $::cdl_system_header "/***** CAN driver proc output end *****/"
+ }
+
+ cdl_component CYGOPT_DEVS_CAN_LPC2XXX_RUNTIME_ACCFILT {
+ display "Acceptance filter runtime configuration"
+ flavor bool
+ implements CYGINT_IO_CAN_RUNTIME_MBOX_CFG
+ description "
+ The LPC2xxx CAN module supports a global acceptance
+ filter. Enabling this option provides support for runtime
+ configuration of this acceptance filter. If each CAN
+ channel should receive all CAN messages and individual
+ message filtering is not required then disable this option
+ to eliminate almost the complete acceptance filter code
+ and to decrease code size. If this option is disabled the
+ option CYGOPT_IO_CAN_RUNTIME_MBOX_CFG is not available and
+ the configuration key CYG_IO_SET_CONFIG_CAN_MSGBUF is not
+ supported by this driver."
+
+ cdl_option CYGOPT_DEVS_CAN_RANGE_FILTERING_CFG_KEYS {
+ display "Range filtering"
+ flavor bool
+ default_value 0
+ description "
+ The common CAN I/O layer supports setup of single
+ message filters for reception of single CAN
+ messages. The global LPC2xxx acceptance filter
+ supports not only single message filters but also
+ message ranges. A message range is defined by a
+ lower bound CAN identifier and an upper bound CAN
+ identifier. The acceptance filter will accept all
+ messages within this range of CAN identifiers. The
+ acceptance filter supports a number of message
+ ranges for each CAN channel."
+ }
+
+ cdl_option CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP {
+ display "LUT Error Support"
+ flavor bool
+ default_value 0
+ description "
+ The CAN module contains a look-up table for
+ acceptance filtering of incoming CAN messages. The
+ look-up table indicates errors in the LUT error
+ registers. If this option is enabled, additional
+ error check code is executed if an interrupt is
+ serviced. Normally the acceptance filter code should
+ fill the look-up table properly and no LUT error
+ should ever occur. You need to decide if LUT error
+ checking is required for your application because it
+ adds some bytes of code and slows down the ISR/DSR
+ handling a little bit because of the additional code
+ that need to be executed."
+ }
+ }
+
+
+ cdl_option CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION {
+ display "Use Self Reception Request command"
+ flavor bool
+ active_if CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION < 4
+ default_value 0
+ description "
+ Enable this option for using work-around of problem with
+ receiving messages while arbitration is lost. If this work
+ around is used each transmitted CAN message will be
+ received. This will produce additional RX interrupts an
+ requires additional time for processing these interrupts
+ and for filtering of received messages.
+
+ The errata sheet tells the following about this issue:
+ Introduction: The CAN module can lose arbitration to
+ another CAN node during an attempt to transmit a CAN
+ message. The message of the CAN node the arbitration was
+ lost to is supposed to be received correctly by the CAN
+ module.
+
+ Problem: Messages might not be received correctly if
+ during a CAN Transmission the CAN bus arbitration is lost
+ to another CAN node.
+
+ Work-around: Use the Self Reception Request command
+ instead of the Transmission Request command. However, it
+ has to be taken into account that now all transmitted
+ messages may be received if not prevented by appropriate
+ Acceptance Filter settings. (Don't set up Acceptance
+ Filter Message Identifiers for the messages you are
+ transmitting yourself.)."
+ }
+
+ cdl_option CYGOPT_DEVS_CAN_LPC2XXX_ALIE {
+ display "Arbitration lost interrupt enable"
+ flavor bool
+ default_value 0
+ description "
+ If the CAN controller loses arbitration while attempting to
+ transmit a message, an interrupt can be triggered. Normally
+ this is no real error condition and it is not necessary to
+ propagate these events to upper layers. But you can enable
+ this option if you want to check for arbitration lost events."
+ }
+
+ cdl_option CYGDBG_DEVS_CAN_LPC2XXX_DEBUG {
+ display "Support printing debug information"
+ default_value 0
+ description "
+ Check this box to turn ON debug options for LPC2XXXX
+ CAN device driver."
+ }
+
+ # Support up to 4 on-chip CAN modules. The number may vary between
+ # processor variants so it is easy to update this here
+ for { set ::channel 0 } { $::channel < 4 } { incr ::channel } {
+
+ cdl_interface CYGINT_DEVS_CAN_LPC2XXX_CAN[set ::channel] {
+ display "Platform provides CAN [set ::channel]"
+ flavor bool
+ description "
+ This interface will be implemented if the specific LPC2xxx
+ processor being used has on-chip CAN [set ::channel], and if
+ that CAN module is accessible on the target hardware."
+ }
+
+ cdl_component CYGPKG_DEVS_CAN_LPC2XXX_CAN[set ::channel] {
+ display "Allow access to the on-chip CAN [set ::channel] via a CAN driver"
+ flavor bool
+ active_if CYGINT_DEVS_CAN_LPC2XXX_CAN[set ::channel]
+ implements CYGINT_IO_CAN_CHANNELS
+ default_value 1
+ description "
+ If the application needs to access the on-chip CAN
+ module [set ::channel] via an eCos CAN driver then
+ this option should be enabled."
+
+ cdl_option CYGPKG_DEVS_CAN_LPC2XXX_CAN[set ::channel]_NAME {
+ display "Device name for CAN module [set ::channel]"
+ flavor data
+ default_value [format {"\"/dev/can%d\""} $::channel]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_KBAUD {
+ display "Default baud rate for CAN module [set ::channel]"
+ flavor data
+ default_value 100
+ legal_values { 10 20 50 100 125 250 500 800 1000 "AUTO"}
+ description "
+ This option determines the initial baud rate in
+ KBaud for CAN module [set ::channel]"
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_QUEUESIZE_TX {
+ display "Size of TX Queue for the CAN module [set ::channel] driver"
+ flavor data
+ default_value 32
+ legal_values 1 to 1024
+ description "
+ The CAN device driver will run in interrupt mode
+ and will perform buffering of outgoing data. This
+ option controls the number of CAN messages the TX
+ queue can store."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_QUEUESIZE_RX {
+ display "Size of RX Queue for the CAN module [set ::channel] driver"
+ flavor data
+ default_value 64
+ legal_values 8 to 4096
+ description "
+ The CAN device driver will run in interrupt mode
+ and will perform buffering of incoming data. This
+ option controls the number of CAN events the RX
+ queue can store."
+ }
+
+ cdl_option CYGOPT_DEVS_CAN_LPC2XXX_CAN[set ::channel]_ACCFILT_STARTUP_CFG {
+ display "Acceptance filter startup configuration"
+ flavor data
+ legal_values {"RX_ALL" "RX_NONE"}
+ default_value {"RX_ALL"}
+ active_if CYGOPT_DEVS_CAN_LPC2XXX_RUNTIME_ACCFILT
+ description "
+ Normally the acceptance filter will be configured
+ at startup time to receive all available CAN
+ messages. The application can setup single message
+ filters during runtime later. If RX_NONE is
+ selected then the acceptance filter for this
+ channel is configured to receive no CAN message
+ identifier."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_RX_INT_PRIORITY {
+ display "Priority level of CAN module [set ::channel] receive interrupt"
+ flavor data
+ active_if CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION < 4
+ default_value 16
+ legal_values 0 to 16
+ description "
+ This option sets CAN module [set ::channel]
+ device receive interrupt priority level. We
+ support up to 17 interrupt levels. Interrupts
+ 0 - 15 are vectored interrupt
+ requests. Priority 16 indicates a non vectored
+ IRQ. Vectored IRQs have the higher priority
+ then non vectored IRQs and slot 0 has the
+ highest priority and slot 15 has the lowest."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_CAN[set ::channel]_TX_INT_PRIORITY {
+ display "Priority level of CAN module [set ::channel] transmit interrupt"
+ flavor data
+ active_if CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION < 4
+ default_value 16
+ legal_values 0 to 16
+ description "
+ This option sets CAN module [set ::channel]
+ device transmit interrupt priority level. We
+ support up to 17 interrupt levels. Interrupts
+ 0 - 15 are vectored interrupt
+ requests. Priority 16 indicates a non vectored
+ IRQ. Vectored IRQs have the higher priority
+ then non vectored IRQs and slot 0 has the
+ highest priority and slot 15 has the lowest."
+ }
+ }
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_ERR_INT_PRIORITY {
+ display "Priority level of CAN error interrupt"
+ flavor data
+ active_if CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION < 4
+ default_value 16
+ legal_values 0 to 16
+ description "
+ This option sets CAN device error interrupt priority level.
+ We support up to 17 interrupt levels. Interrupts 0 - 15
+ are vectored interrupt requests. Priority 16 indicates a
+ non vectored IRQ. Vectored IRQs have the higher priority
+ then non vectored IRQs and slot 0 has the highest priority
+ and slot 15 has the lowest."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY {
+ display "Priority level of all CAN interrupts"
+ flavor data
+ active_if CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION >= 4
+ default_value 15
+ legal_values 0 to 15
+ description "
+ The LPC24xx family uses one single interrupt vector for
+ all CAN interrupts of all CAN channels. This if very
+ different from former LPC2xxx variants where each CAN
+ channels has its own interrupt vectors for transmit
+ and receive interrupts. There are 16 priority
+ levels, corresponding to the values 0 through 15 decimal,
+ of which 15 is the lowest priority. The reset value of
+ these interrupt priority registers defaults all interrupts
+ to the lowest priority 15, allowing a single write to
+ elevate the priority of an individual interrupt."
+ }
+
+ # Enable this by default for "LPX22xx" parts only.
+ cdl_option CYGHWR_DEVS_CAN_LPC2XXX_BUSOFF_WORKAROUND {
+ display "Bus-Off Reset Mode workaround"
+ flavor bool
+ default_value { CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION == 2 }
+ description "
+ If the Transmit Error counter contains 255 and another
+ error occurs, the CAN Controller is forced into a state
+ called Bus-Off. In this state, the following register bits
+ and register values are set: BS (Bus Off Set) in CANxSR, BEI
+ (Bus Error Interrupt) and EI (Error Warning Interrupt) in
+ CANxICR, RM (Reset Mode) in CANxMOD, Transmit Error Counter
+ is set to 127, Receive Error Counter is cleared.
+ On some chips RM (Reset Mode) is not set and RX / TX error
+ counters are not cleared. This may lead to a permanent
+ re-calling of the Bus-Off error ISR which in turn may block
+ the application code from running. If this workaround is
+ active, the Bus-Off error ISR sets RM (Reset Mode), clears
+ RX / TX error counters."
+ }
+
+ cdl_option CYGPKG_DEVS_CAN_LPC2XXX_TESTS {
+ display "CAN LPC2xxx device driver tests"
+ flavor data
+ no_define
+ calculated { "tests/can_busload tests/can_rx_tx" }
+ description "
+ This option specifies the set of tests for the LPC2xxx
+ CAN device driver."
+ }
+
+ cdl_option CYGBLD_DEVS_CAN_LPC2XXX_EXTRA_TESTS {
+ display "Build extra CAN tests"
+ default_value 0
+ no_define
+ description "
+ This option enables the building of some extra tests which
+ can be used when testing / debugging the LPC2xxx CAN driver. These
+ are not built by default since they do not use the dedicated
+ testing infrastructure. All tests require a properly configured
+ CAN network with a second CAN node that can send and receive
+ CAN messages."
+
+ make -priority 320 {
+ <PREFIX>/bin/can_multichan_rx : <PACKAGE>/tests/can_multichan_rx.c
+ @sh -c "mkdir -p tests $(dir $@)"
+ $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_multichan_rx.o $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+ @tail -n +2 deps.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm deps.tmp
+ $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_multichan_rx.o
+ }
+
+ make -priority 320 {
+ <PREFIX>/bin/can_multichan_tx : <PACKAGE>/tests/can_multichan_tx.c
+ @sh -c "mkdir -p tests $(dir $@)"
+ $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_multichan_tx.o $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+ @tail -n +2 deps.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm deps.tmp
+ $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_multichan_tx.o
+ }
+
+ make -priority 320 {
+ <PREFIX>/bin/can_baudrates : <PACKAGE>/tests/can_baudrates.c
+ @sh -c "mkdir -p tests $(dir $@)"
+ $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_baudrates.o $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+ @tail -n +2 deps.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm deps.tmp
+ $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_baudrates.o
+ }
+
+ make -priority 320 {
+ <PREFIX>/bin/can_extended_cfg : <PACKAGE>/tests/can_extended_cfg.c
+ @sh -c "mkdir -p tests $(dir $@)"
+ $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_extended_cfg.o $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+ @tail -n +2 deps.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm deps.tmp
+ $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_extended_cfg.o
+ }
+ }
+}
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/include/can_lpc2xxx.h b/ecos/packages/devs/can/arm/lpc2xxx/current/include/can_lpc2xxx.h
new file mode 100644
index 0000000..db59920
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/include/can_lpc2xxx.h
@@ -0,0 +1,92 @@
+#ifndef CYGONCE_CAN_LPC2XXX_H
+#define CYGONCE_CAN_LPC2XXX_H
+//==========================================================================
+//
+// devs/can/arm/lpc2xxx/current/include/can_lpc2xxx.h
+//
+// Extended configuration option for LPC2xxx CAN driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-02-08
+// Purpose: Extended configuration options for LPC2xxx CAN driver
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// DEFINES
+//==========================================================================
+//
+// The LPC2XXX supports enhanced configuration options that are not supported
+// be the generic CAN I/O layer. Be careful with using this extension
+// because they may reduce portability of your application
+//
+
+//--------------------------------------------------------------------------
+// Message filter configuration
+//
+//#define CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP CYG_IO_SET_CONFIG_CAN_ABORT + 0x10 // add message filter group
+
+
+//--------------------------------------------------------------------------
+// Mode setup of LPC2XXX
+//
+// NOT IMPLEMENTED!
+//#define CYGNUM_CAN_MODE_LPC2XXX_LISTEN_ONLY 0x80 // set controller in listen only mode
+
+
+//==========================================================================
+// DATA TYPES
+//==========================================================================
+//
+// structure for configuration of message filter groups
+//
+//typedef struct cyg_can_filtergroup_cfg_st
+//{
+// cyg_can_id_type ext;
+// cyg_uint32 lower_id_bound;
+// cyg_uint32 upper_id_bound;
+//} cyg_can_filtergroup_cfg;
+
+
+//---------------------------------------------------------------------------
+#endif // CYGONCE_CAN_LPC2XXX_H
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/include/can_lpc2xxx_baudrates.h b/ecos/packages/devs/can/arm/lpc2xxx/current/include/can_lpc2xxx_baudrates.h
new file mode 100644
index 0000000..fa99777
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/include/can_lpc2xxx_baudrates.h
@@ -0,0 +1,238 @@
+#ifndef CYGONCE_CAN_LPC2XXX_BAUDRATES_H
+#define CYGONCE_CAN_LPC2XXX_BAUDRATES_H
+//==========================================================================
+//
+// devs/can/arm/lpc2xxx/current/include/can_lpc2xxx_baudrates.h
+//
+// Precalculated values for bit timing register
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-07-01
+// Purpose: Precalculated bit timing values for various baudrates
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//
+// Macro for creation of CAN_BR value for baudrate tbl
+//
+#define CAN_BR_TBL_ENTRY(_brp_, _tseg1_, _tseg2_, _sjw_, _sam_) \
+ ((_sam_ << 23) | (_tseg2_ << 20) | (_tseg1_ << 16) | (_sjw_ << 14) | (_brp_))
+
+
+#ifndef CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK
+#error "CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK not defined"
+#endif
+//==========================================================================
+// BAUDRATES
+//==========================================================================
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 60000000
+//
+// Table with register values for baudrates at peripheral clock of 60 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY(300, 15, 2, 0, 1), // 10 kbaud
+ CAN_BR_TBL_ENTRY(150, 15, 2, 0, 1), // 20 kbaud
+ CAN_BR_TBL_ENTRY(59, 15, 2, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY(39, 11, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY(29, 12, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY(14, 12, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 7, 11, 1, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 4, 11, 1, 0, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY( 3, 11, 1, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 60000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 30000000
+//
+// Table with register values for baudrates at peripheral clock of 30 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 10 kbaud - not supported
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 20 kbaud - not supported
+ CAN_BR_TBL_ENTRY(59, 15, 2, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY(39, 11, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY(29, 12, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY(14, 12, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 7, 11, 1, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 4, 11, 1, 0, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY( 3, 11, 1, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 30000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 15000000
+//
+// Table with register values for baudrates at peripheral clock of 15 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY(59, 15, 7, 0, 1), // 10 kbaud
+ CAN_BR_TBL_ENTRY(49, 11, 1, 0, 1), // 20 kbaud
+ CAN_BR_TBL_ENTRY(19, 11, 1, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY( 9, 11, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY( 7, 11, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY( 3, 11, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 1, 11, 1, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 800 kbaud - not supported
+ CAN_BR_TBL_ENTRY( 0, 11, 1, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 15000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 48000000
+//
+// Table with register values for baudrates at peripheral clock of 48 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 10 kbaud - not supported
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 20 kbaud - not supported
+ CAN_BR_TBL_ENTRY(59, 12, 1, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY(29, 12, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY(23, 12, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY(11, 12, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 5, 12, 1, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 3, 11, 1, 0, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY( 2, 12, 1, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 48000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 24000000
+//
+// Table with register values for baudrates at peripheral clock of 24 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // 10 kbaud - not supported
+ CAN_BR_TBL_ENTRY(59, 15, 2, 0, 1), // 20 kbaud
+ CAN_BR_TBL_ENTRY(29, 12, 1, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY(14, 12, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY(11, 12, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY( 5, 12, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 2, 12, 1, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 1, 11, 1, 0, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY( 1, 5, 0, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 24000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 12000000
+//
+// Table with register values for baudrates at peripheral clock of 12 MHz
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ CAN_BR_TBL_ENTRY(59, 15, 2, 0, 1), // 10 kbaud - not supported
+ CAN_BR_TBL_ENTRY(39, 11, 1, 0, 1), // 20 kbaud
+ CAN_BR_TBL_ENTRY(14, 12, 1, 0, 1), // 50 kbaud
+ CAN_BR_TBL_ENTRY( 7, 11, 1, 0, 1), // 100 kbaud
+ CAN_BR_TBL_ENTRY( 5, 12, 1, 0, 1), // 125 kbaud
+ CAN_BR_TBL_ENTRY( 2, 12, 1, 0, 1), // 250 kbaud
+ CAN_BR_TBL_ENTRY( 2, 05, 0, 0, 0), // 500 kbaud
+ CAN_BR_TBL_ENTRY( 0, 11, 1, 0, 0), // 800 kbaud
+ CAN_BR_TBL_ENTRY( 0, 9, 0, 0, 0), // 1000 kbaud
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 12000000
+
+#if CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 14745600
+#warning "You can't get exactly the desired CAN bus speeds with the specified CAN clock of 14.7456 MHz"
+//
+// Table with register values for baudrates at peripheral clock of 14.7456 MHz
+// The clock of 14.7456 MHz is not suited for a good CAN bitrate timing because
+// you can't get exactly the desired CAN bus speed with the specified CAN
+// clock frequency. Be sure to check the error values behind the table entries.
+// Settings leading to speed deviations of more than 1.5% should be discarded.
+//
+static const cyg_uint32 lpc2xxx_br_tbl[] =
+{
+ //----------brp tseg1 tseg2 sjw sam ------------
+ CAN_BR_TBL_ENTRY(58, 20, 2, 0, 1), // 10 kbaud - Timing Error 0.030%
+ CAN_BR_TBL_ENTRY(66, 8, 0, 0, 1), // 20 kbaud - Timing Error -0.038%
+ CAN_BR_TBL_ENTRY(13, 17, 1, 0, 1), // 50 kbaud - Timing Error -0.310%
+ CAN_BR_TBL_ENTRY( 6, 17, 1, 0, 1), // 100 kbaud - Timing Error -0.310%
+ CAN_BR_TBL_ENTRY(12, 6, 0, 0, 1), // 125 kbaud - Timing Error -0.825%
+ CAN_BR_TBL_ENTRY( 5, 7, 0, 0, 1), // 250 kbaud - Timing Error 1.696%
+ CAN_BR_TBL_ENTRY( 2, 7, 0, 0, 0), // 500 kbaud - Timing Error 1.696%
+ CAN_BR_TBL_ENTRY( 1, 6, 0, 0, 0), // 800 kbaud - Timing Error -2.4%
+ CAN_BR_TBL_ENTRY( 0, 11, 1, 0, 0), // 1000 kbaud - Timing Error 1.696%
+ CAN_BR_TBL_ENTRY( 0, 0, 0, 0, 0), // Autobaud - not supported
+};
+#define HAL_LPC2XXX_BAUD_TBL_DEFINED 1
+#endif // CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK == 14745600
+
+
+//==========================================================================
+// BIT TIMING MACRO
+//==========================================================================
+//
+// Macro fills baudrate register value depending on selected baudrate
+// For several LPC2XXX peripheral clock speeds we provide a pre calculated
+// baudrate table. If the board uses another clock speed, then the platform
+// HAL needs to provide an own HAL_LPC2XXX_GET_CAN_BR() macro that returns
+// valid baudrate register values or it needs to patch this file with
+// an additional table for the desired clock speed
+//
+//
+// If a certain baudrate is not supported, then this macro shall return
+// 0 as the baudrate register value
+//
+#ifdef HAL_LPC2XXX_BAUD_TBL_DEFINED
+#define HAL_LPC2XXX_GET_CAN_BR(_baudrate_, _br_) \
+CYG_MACRO_START \
+ _br_ = lpc2xxx_br_tbl[(_baudrate_) - CYGNUM_CAN_KBAUD_10]; \
+CYG_MACRO_END
+#endif // HAL_LPC2XXX_BAUD_TBL_DEFINED
+
+//-------------------------------------------------------------------------
+#endif // #ifndef CYGONCE_CAN_LPC2XXX_BAUDRATES_H
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c b/ecos/packages/devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c
new file mode 100644
index 0000000..d3c365d
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c
@@ -0,0 +1,1009 @@
+//==========================================================================
+//
+// devs/can/arm/lpc2xxx/current/src/can_accfilt_lpc2xxx.c
+//
+// Acceptance filter management for LPC2xxx CAN driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-05-28
+// Purpose: Support LPC2xxx on-chip CAN acceptance filters
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//===========================================================================
+// Data types
+//===========================================================================
+//
+// Acceptance filter entry
+//
+typedef struct lpc2xxx_accfilt_entry
+{
+ cyg_uint32 data; // the value inclusive channel number
+ cyg_uint32 id;
+ cyg_uint32 lower_id_bound;
+ cyg_uint32 upper_id_bound;
+ cyg_uint8 channel_no;
+} lpc2xxx_accfilt_entry_t;
+
+
+//===========================================================================
+// Declarations
+//===========================================================================
+//--------------------------------------------------------------------------
+// On no-suffix and /00 devices, the CAN controllers are numbered 1 to n
+// (n = 2 or 4) in the LUT tables. However, on /01 devices, the CAN controllers
+// are numbered 0 to nâ1 in the LUT tables.
+//
+// On the LPC2468 the LUT channel numbers are also numbered from 0 - 4.
+//
+#if defined(CYGHWR_HAL_ARM_LPC2XXX_SUFFIX_01) || (CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION == 4)
+# define LPC2XXX_CAN_FIRST_IN_LUT (0)
+#else
+# define LPC2XXX_CAN_FIRST_IN_LUT (1)
+#endif
+
+//
+// This macro calculates the chanel number from the channel info. The channel
+// number is numbered from 0 - 3 but in the LUT the channel number may differ
+// depending on the device suffix. For some devices the channel number in
+// LUT are numbered 0 - 3 and for other devices the channels in LUT are
+// numbered 1 - 4. This macro abstrats this fact from the acceptance filter
+// code
+//
+#define CAN_CHAN_NO_LUT(_info_) (CAN_CHAN_NO(_info_) + LPC2XXX_CAN_FIRST_IN_LUT)
+
+//--------------------------------------------------------------------------
+// Lowlevel acceptance filter access
+//
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+static bool lpc2xxx_can_accfilt_add(lpc2xxx_can_info_t *info,
+ cyg_uint32 lower_id,
+ cyg_uint32 upper_id,
+ cyg_can_id_type ext);
+void lpc2xxx_can_accfilt_ram_insert_entry(cyg_uint32 TableAddress, cyg_uint16 EntryNo);
+void lpc2xxx_can_accfilt_ram_remove_entry(cyg_uint32 TableAddress, cyg_uint16 EntryNo);
+void lpc2xxx_can_accfilt_remove_all_ctrl_entries(lpc2xxx_can_info_t *info);
+#else
+static void lpc2xxx_can_accfilt_simple_rx_all(void);
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+void lpc2xxx_can_accfilt_reset(void);
+
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+void lpc2xxx_can_accfilt_dbg_dump(void);
+void lpc2xxx_can_reg_dump(struct cyg_devtab_entry* devtab_entry);
+#endif
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Calculate address of entry in certain table
+//===========================================================================
+static cyg_uint32 lpc2xxx_can_accfilt_calc_entry_address(cyg_uint32 TableAddressRegister, cyg_uint16 EntryNo)
+{
+ cyg_uint32 EntryAddress = 0xFFFFFFFF;
+ cyg_uint32 TableAddress;
+
+ HAL_READ_UINT32(TableAddressRegister, TableAddress);
+ switch (TableAddressRegister)
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ case CAN_ACCFILT_SFF_SA:
+ EntryAddress = ((EntryNo / 2) << 2) + TableAddress;
+ break;
+
+ case CAN_ACCFILT_SFF_GRP_SA:
+ EntryAddress = TableAddress + (EntryNo << 2);
+ break;
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ case CAN_ACCFILT_EFF_SA:
+ EntryAddress = TableAddress + (EntryNo << 2);
+ break;
+
+ case CAN_ACCFILT_EFF_GRP_SA:
+ EntryAddress = TableAddress + (EntryNo << 3);
+ break;
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ default:
+ CYG_ASSERT(0, "Wrong TableAddressRegister");
+ }
+
+ return EntryAddress;
+}
+
+
+//===========================================================================
+// Remove one single entry from acceptance filter table
+//===========================================================================
+void lpc2xxx_can_accfilt_ram_remove_entry(cyg_uint32 Table, cyg_uint16 EntryNo)
+{
+ cyg_int32 remove_address = lpc2xxx_can_accfilt_calc_entry_address(Table, EntryNo);
+ cyg_int32 entry_address;
+ lsc_buf_t lsc_val;
+ cyg_uint8 entry_size = sizeof(cyg_uint32);
+ cyg_uint32 sff_sa;
+ cyg_uint32 sff_grp_sa;
+ cyg_uint32 eff_sa;
+ cyg_uint32 eff_grp_sa;
+ cyg_int32 end_of_table;
+
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, sff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+
+ //
+ // Do not try to remove from an empty table
+ //
+ if (!end_of_table)
+ {
+ return;
+ }
+
+ entry_address = remove_address;
+
+ if ((remove_address < eff_grp_sa) && (CAN_ACCFILT_EFF_GRP_SA != Table))
+ {
+ if ((remove_address < eff_sa) && (CAN_ACCFILT_EFF_SA != Table))
+ {
+ if ((remove_address < sff_grp_sa) && (CAN_ACCFILT_SFF_GRP_SA != Table))
+ {
+ lsc_buf_t nextval;
+
+ if (EntryNo % 2)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + remove_address, lsc_val.dword);
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + remove_address + sizeof(cyg_uint32), nextval.dword);
+ lsc_val.column.upper = nextval.column.lower;
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ //
+ // Start copy immediatelly after removed entry
+ //
+ while (entry_address < sff_grp_sa)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, lsc_val.dword);
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address + sizeof(cyg_uint32), nextval.dword);
+ lsc_val.column.lower = lsc_val.column.upper;
+ lsc_val.column.upper = nextval.column.lower;
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, lsc_val.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ //
+ // now check if the lower identifier is disabled - if it is disabled, then
+ // also the upper identifier is invalid and we can remove the entry completely
+ // if the lower identifier is not disabled, then it is valid and we need
+ // to disable the upper identifier because it contains an invalid entry
+ //
+ if (lsc_val.column.lower & ACCFILT_STD_DIS)
+ {
+ sff_grp_sa -= sizeof(cyg_uint32);
+ entry_address = sff_grp_sa;
+ }
+ else
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32), lsc_val.dword);
+ lsc_val.column.upper = 0xffff;
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32), lsc_val.dword);
+ entry_size = 0; // we do not need to remove anything
+ }
+ } // if (pLine < pStdGrpStart)
+
+ eff_sa -= entry_size;
+ } // if (pLine < pExtIdStart)
+
+ eff_grp_sa -= entry_size;
+ } // if (pLine < pExtGrpStart)
+
+ //
+ // If no entry was removed then we can leave immediately without changing any
+ // table pointers because we only did a change inside the sff table
+ //
+ if (!entry_size)
+ {
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif
+ return;
+ }
+
+ if (CAN_ACCFILT_EFF_GRP_SA == Table)
+ {
+ //
+ // If we are in the area of extended groups then we need to remove
+ // 2 lines because lower and upper identifier need 1 line each
+ //
+ entry_size += sizeof(cyg_uint32);
+ }
+
+ end_of_table -= entry_size;
+
+ //
+ // Move all entries one or two dword downwards - that means we remove a line
+ //
+ while (entry_address < end_of_table)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address + entry_size, lsc_val.dword);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, lsc_val.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, sff_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif
+}
+
+//===========================================================================
+// Insert one empty line into ram - all entries behind this line will be
+// moved one entry upwards
+//===========================================================================
+void lpc2xxx_can_accfilt_ram_insert_entry(cyg_uint32 Table, cyg_uint16 EntryNo)
+{
+ cyg_int16 insert_address = lpc2xxx_can_accfilt_calc_entry_address(Table, EntryNo);
+ cyg_int16 entry_address;
+ cyg_int16 copy_start = insert_address;
+ lsc_buf_t lsc_val;
+ cyg_uint8 entry_size = sizeof(cyg_uint32);
+ cyg_uint32 sff_sa;
+ cyg_uint32 sff_grp_sa;
+ cyg_uint32 eff_sa;
+ cyg_uint32 eff_grp_sa;
+ cyg_uint32 end_of_table;
+
+
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, sff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+
+ if ((insert_address <= eff_grp_sa) && (CAN_ACCFILT_EFF_GRP_SA != Table))
+ {
+ if ((insert_address <= eff_sa) && (CAN_ACCFILT_EFF_SA != Table))
+ {
+ if ((insert_address <= sff_grp_sa) && (CAN_ACCFILT_SFF_GRP_SA != Table))
+ {
+ //
+ // If we are in the range of standard identifiers then we need to
+ // do some special copy procedure for this area because a standard entry
+ // is only 2 byte long. Copy only til start of area with standard groups
+ //
+ if (sff_grp_sa)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32), lsc_val.dword); // read last entry
+ //
+ // now check if the upper identifier is disabled - if it is disabled, then
+ // we have an odd number of std ids in the list. Then we do not need to
+ // insert a new line - we simply need to copy all entries 2 bytes upwards
+ // that means we only need to change the std id area and do not need to touch
+ // any other filter id area.
+ // If the last entry is not disabled, then we have a valid filter here.
+ // Then we need to insert a complete new line, that means we also have to move
+ // all following entries and filter tables one dword upwards.
+ //
+ if (lsc_val.words.low & ACCFILT_STD_DIS)
+ {
+ copy_start = end_of_table + sizeof(cyg_uint32); // we do not need to insert a new line and do not copy anything
+ entry_size = 0;
+ }
+ }
+
+ if (entry_size)
+ {
+ copy_start = sff_grp_sa; // copy everything behind std id group
+ sff_grp_sa += entry_size;
+ }
+ } // if (pLine < pStdGrpStart)
+
+ eff_sa += entry_size;
+ } // if (pLine < pExtIdStart)
+
+ eff_grp_sa += entry_size;
+ } // if (pLine < pExtGrpStart)
+
+ if (CAN_ACCFILT_EFF_GRP_SA == Table)
+ {
+ //
+ // If we are in the area of extended groups then we need to insert
+ // 2 lines because lower and upper identifier need 1 line each
+ //
+ entry_size += sizeof(cyg_uint32); // one entry is 2 dword long
+ }
+
+ entry_address = end_of_table - sizeof(cyg_uint32);
+ end_of_table += entry_size; // add one additional entry
+
+ //
+ // Move all entries one or two dwords upwards - that means we insert a new empty line
+ //
+ while (entry_address >= copy_start)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address, lsc_val.dword);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address + entry_size, lsc_val.dword);
+ entry_address -= sizeof(cyg_uint32);
+ }
+
+ //
+ // For the std ID area we need a special procedure
+ //
+ if (CAN_ACCFILT_SFF_SA == Table)
+ {
+ lsc_buf_t preval;
+ //
+ // Start copy with last entry of std id table
+ //
+ entry_address = sff_grp_sa - sizeof(cyg_uint32);
+
+ while (entry_address > insert_address)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address, lsc_val.dword);
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address - sizeof(cyg_uint32), preval.dword);
+ lsc_val.column.upper = lsc_val.column.lower;
+ lsc_val.column.lower = preval.column.upper;
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)entry_address, lsc_val.dword);
+ entry_address -= sizeof(cyg_uint32);
+ }
+
+ //
+ // If we insert an entry into the lower column, then we need to move the
+ // content of the lower column into the upper column
+ //
+ if (!(EntryNo % 2))
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)insert_address, lsc_val.dword);
+ lsc_val.column.upper = lsc_val.column.lower;
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + (cyg_uint32)insert_address, lsc_val.dword);
+ }
+
+ //
+ // If we inserted a new line, then we have an odd number of identifiers now
+ // and need to disable the last (the upper) entry
+ //
+ if (entry_size)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32) , lsc_val.dword);
+ lsc_val.column.upper = 0xFFFF; // disable the entry
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + sff_grp_sa - sizeof(cyg_uint32) , lsc_val.dword);
+ }
+ }
+
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, sff_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa);
+ HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+}
+
+
+//===========================================================================
+// Query number of entries in a certain table
+//===========================================================================
+static cyg_uint16 lpc2xxx_can_accfilt_get_table_entries(cyg_uint32 TableStartAddress)
+{
+ cyg_uint32 start;
+ cyg_uint32 end;
+
+ switch (TableStartAddress)
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ case CAN_ACCFILT_SFF_SA:
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, start);
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, end);
+ if (end - start)
+ {
+ lsc_buf_t data;
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + end - sizeof(cyg_uint32), data.dword);
+ if (data.column.upper & ACCFILT_STD_DIS)
+ {
+ return (((end - start) >> 1) - 1);
+ }
+ }
+ return (end - start) >> 1;
+
+ case CAN_ACCFILT_SFF_GRP_SA:
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, start);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, end);
+ return (end - start) >> 2;
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ case CAN_ACCFILT_EFF_SA:
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, start);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, end);
+ return (end - start) >> 2;
+
+ case CAN_ACCFILT_EFF_GRP_SA:
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, start);
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end);
+ return (end - start) >> 3;
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ default:
+ CYG_FAIL("Invalid identifier table address");
+ return 0;
+ } // switch (TableStartAddress)
+}
+
+//===========================================================================
+// Query certain entry from table
+//===========================================================================
+static void lpc2xxx_can_accfilt_get_entry(cyg_uint32 TableStartAddress, cyg_uint16 EntryNo, lpc2xxx_accfilt_entry_t *pEntry)
+{
+ cyg_uint32 EntryAddress = lpc2xxx_can_accfilt_calc_entry_address(TableStartAddress, EntryNo);
+ lsc_buf_t Data;
+
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress, Data.dword);
+ pEntry->data = Data.dword;
+ switch (TableStartAddress)
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ case CAN_ACCFILT_SFF_SA:
+ {
+ cyg_uint16 column;
+ if (EntryNo % 2)
+ {
+ column = Data.column.upper;
+ }
+ else
+ {
+ column = Data.column.lower;
+ }
+ pEntry->id = ACCFILT_STD_GET_ID(column);
+ pEntry->channel_no = ACCFILT_STD_GET_CTRL(column);
+ }
+ break;
+
+ case CAN_ACCFILT_SFF_GRP_SA:
+ pEntry->lower_id_bound = ACCFILT_STD_GET_ID(Data.column.lower);
+ pEntry->upper_id_bound = ACCFILT_STD_GET_ID(Data.column.upper);
+ pEntry->channel_no = ACCFILT_STD_GET_CTRL(Data.column.lower);
+ break;
+#endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ case CAN_ACCFILT_EFF_SA:
+ pEntry->id = ACCFILT_EXT_GET_ID(Data.dword);
+ pEntry->channel_no = ACCFILT_EXT_GET_CTRL(Data.dword);
+ break;
+
+ case CAN_ACCFILT_EFF_GRP_SA:
+ pEntry->lower_id_bound = ACCFILT_EXT_GET_ID(Data.dword);
+ pEntry->channel_no = ACCFILT_EXT_GET_CTRL(Data.dword);
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE+ EntryAddress + sizeof(cyg_uint32), Data.dword);
+ pEntry->upper_id_bound = ACCFILT_EXT_GET_ID(Data.dword);
+ break;
+#endif // #ifedf CYGOPT_IO_CAN_EXT_CAN_ID
+ default:
+ CYG_FAIL("Invalid identifier table address");
+ } // switch ()
+}
+
+
+//===========================================================================
+// Set certain entry in table
+//===========================================================================
+static void lpc2xxx_can_accfilt_set_entry(cyg_uint32 TableStartAddress, cyg_uint16 EntryNo, lpc2xxx_accfilt_entry_t *pEntry)
+{
+ cyg_uint32 EntryAddress = lpc2xxx_can_accfilt_calc_entry_address(TableStartAddress, EntryNo);
+ lsc_buf_t Data;
+
+ switch (TableStartAddress)
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ case CAN_ACCFILT_SFF_SA:
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress, Data.dword);
+ if (EntryNo % 2)
+ {
+ Data.column.upper = (pEntry->channel_no << 13) | (pEntry->id & ACCFILT_STD_ID_MASK);
+ }
+ else
+ {
+ Data.column.lower = (pEntry->channel_no << 13) | (pEntry->id & ACCFILT_STD_ID_MASK);
+ }
+ }
+ break;
+
+ case CAN_ACCFILT_SFF_GRP_SA:
+ Data.column.lower = (pEntry->channel_no << 13) | (pEntry->lower_id_bound & ACCFILT_STD_ID_MASK);
+ Data.column.upper = (pEntry->channel_no << 13) | (pEntry->upper_id_bound & ACCFILT_STD_ID_MASK);
+ break;
+#endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ case CAN_ACCFILT_EFF_SA:
+ Data.dword = (pEntry->channel_no << 29) | (pEntry->id & ACCFILT_EXT_ID_MASK);
+ break;
+
+ case CAN_ACCFILT_EFF_GRP_SA:
+ {
+ lsc_buf_t Data2;
+
+ Data.dword = (pEntry->channel_no << 29) | (pEntry->lower_id_bound & ACCFILT_EXT_ID_MASK);
+ Data2.dword = (pEntry->channel_no << 29) | (pEntry->upper_id_bound & ACCFILT_EXT_ID_MASK);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress + sizeof(cyg_uint32), Data2.dword);
+ }
+ break;
+#endif // #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+
+ default:
+ CYG_FAIL("Invalid identifier table address");
+ } // switch ()
+
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + EntryAddress, Data.dword);
+}
+
+
+//===========================================================================
+// Add one entry to acceptance filter RAM
+// If upper ID is > lower ID then we have to add a group filter - else we
+// have to add a single message filter here
+//===========================================================================
+static bool lpc2xxx_can_accfilt_add(lpc2xxx_can_info_t *info,
+ cyg_uint32 lower_id,
+ cyg_uint32 upper_id,
+ cyg_can_id_type ext)
+{
+ cyg_uint32 accfilt_bck; // acceptance filter backup
+ cyg_uint32 end_of_table;
+ cyg_uint32 table;
+ lpc2xxx_accfilt_entry_t entry;
+ lpc2xxx_accfilt_entry_t new_entry;
+
+
+ //
+ // first step: disable acceptance filter and prepare it for modification
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS);
+
+ //
+ // Check if table is full
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+ if (end_of_table >= ACCFILT_RAM_SIZE)
+ {
+ return false;
+ }
+
+ new_entry.id = lower_id;
+ new_entry.lower_id_bound = lower_id;
+ new_entry.upper_id_bound = upper_id;
+
+ //
+ // Here we rely on the ISR vector ordering for calculation of channel number
+ // Maybe this is not the right way for newer LPC parts
+ //
+ new_entry.channel_no = CAN_CHAN_NO_LUT(info);
+
+ //
+ // If lower_id == upper_id then we know that we have to setup a single message filter
+ // here. If it is not equal the it is group of identifiers to receive
+ //
+ if ((lower_id == upper_id) || (lower_id > upper_id))
+ {
+ //
+ // setup single message filter (standard or extended) here
+ //
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (ext)
+ {
+ table = CAN_ACCFILT_EFF_SA;
+ }
+ else
+#endif // #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ table = CAN_ACCFILT_SFF_SA;
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+ }
+ }
+ else
+ {
+ //
+ // setup single message filter (standard or extended) here
+ //
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (ext)
+ {
+ table = CAN_ACCFILT_EFF_GRP_SA;
+ }
+ else
+#endif // #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ table = CAN_ACCFILT_SFF_GRP_SA;
+#endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ }
+ }
+
+ cyg_uint16 entries = lpc2xxx_can_accfilt_get_table_entries(table);
+ cyg_uint16 i;
+
+
+ for (i = 0; i < entries; ++i)
+ {
+ lpc2xxx_can_accfilt_get_entry(table, i, &entry);
+
+ if (entry.channel_no > new_entry.channel_no)
+ {
+ break;
+ }
+
+ if ((entry.channel_no == new_entry.channel_no)
+ && (entry.id > new_entry.id))
+ {
+ break;
+ }
+ } // for (i = 0; i < entries; ++i)
+
+ lpc2xxx_can_accfilt_ram_insert_entry(table, i);
+ lpc2xxx_can_accfilt_set_entry(table, i, &new_entry);
+
+ //
+ // finally restore the previous state of the acceptance filter
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+ return true;
+}
+
+
+//===========================================================================
+// Remove all entries from a certain controller
+//===========================================================================
+void lpc2xxx_can_accfilt_remove_all_ctrl_entries(lpc2xxx_can_info_t *info)
+{
+ cyg_uint32 accfilt_bck; // acceptance filter backup
+ cyg_uint16 i;
+ cyg_uint16 entries;
+ cyg_uint32 TableStartAddress = CAN_ACCFILT_SFF_SA;
+ lpc2xxx_accfilt_entry_t Entry;
+ cyg_uint8 channel_no = CAN_CHAN_NO_LUT(info);
+ cyg_uint16 entry_idx;
+
+ //
+ // first step: disable acceptance filter and prepare it for modification
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS);
+
+ //
+ // now remove all entries for a certain controller
+ //
+ for (TableStartAddress = CAN_ACCFILT_SFF_SA; TableStartAddress < CAN_ACCFILT_ENDOFTABLE; TableStartAddress += 4)
+ {
+ entries = lpc2xxx_can_accfilt_get_table_entries(TableStartAddress);
+ entry_idx = 0;
+ for (i = 0; i < entries; ++i)
+ {
+ lpc2xxx_can_accfilt_get_entry(TableStartAddress, entry_idx, &Entry);
+ if (Entry.channel_no == channel_no)
+ {
+ lpc2xxx_can_accfilt_ram_remove_entry(TableStartAddress, entry_idx);
+ }
+ else
+ {
+ entry_idx++;
+ }
+ } // for (i = 0; i < entries; ++i)
+ } // for (TableStartAddress = CAN_ACCFILT_SFF_SA ...
+
+ //
+ // finally restore the previous state of the acceptance filter
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+#ifndef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Setup reception of all CAN identifiers
+// If runtime acceptance filter configuration is not required then we simply
+// setup the acceptance filter here to receive all CAN identifiers
+//===========================================================================
+static void lpc2xxx_can_accfilt_simple_rx_all(void)
+{
+ cyg_uint32 regval;
+
+ //
+ // First check if it is really necessary to setup filters. If end of table is
+ // != 0 then the acceptance filter is already setup properly
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, regval);
+ if (regval)
+ {
+ return;
+ }
+
+ cyg_uint32 accfilt_bck; // acceptance filter backup
+ cyg_uint8 i = 0; // loop counter
+ lsc_buf_t accfilt_entry; // std group entry
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ cyg_uint8 std_address = 0; // std group entry address
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ cyg_uint8 ext_address = LPC2XXX_INIT_CNT << 2;
+#endif
+#else
+ cyg_uint8 ext_address = 0;
+#endif
+
+ //
+ // first step: disable acceptance filter and prepare it for modification
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS);
+
+ //
+ // Write table start adresses - we use only standard group and extended filter
+ // group
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, ext_address);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, ext_address);
+
+ //
+ // Now loop through all active CAN channels and setup the acceptance filter for
+ // each channel to receive all standard and extended CAN identifiers
+ //
+ while (lpc2xxx_global_can_info.active_channels[i])
+ {
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)lpc2xxx_global_can_info.active_channels[i++]->dev_priv;
+ cyg_uint8 channel_no = CAN_CHAN_NO_LUT(info);
+
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ accfilt_entry.column.lower = (channel_no << 13) | (0x000 & ACCFILT_STD_ID_MASK);
+ accfilt_entry.column.upper = (channel_no << 13) | (0x7FF & ACCFILT_STD_ID_MASK);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + std_address, accfilt_entry.dword);
+ std_address += sizeof(cyg_uint32);
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ accfilt_entry.dword = (channel_no << 29) | (0x00000000 & ACCFILT_EXT_ID_MASK);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + ext_address, accfilt_entry.dword);
+ ext_address += sizeof(cyg_uint32);
+ accfilt_entry.dword = (channel_no << 29) | (0x1FFFFFFF & ACCFILT_EXT_ID_MASK);
+ HAL_WRITE_UINT32(CAN_ACCFILT_RAM_BASE + ext_address, accfilt_entry.dword);
+ ext_address += sizeof(cyg_uint32);
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ } // while (lpc2xxx_global_can_info.active_channels[i])
+
+ //
+ // finally store end of table value and restore the previous state of the
+ // acceptance filter
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, ext_address);
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+//===========================================================================
+// Reset acceptance filter to poweron defaults
+//===========================================================================
+void lpc2xxx_can_accfilt_reset(void)
+{
+ cyg_uint32 accfilt_bck; // acceptance filter backup
+ //
+ // first step: disable acceptance filter and prepare it for modification
+ //
+ HAL_READ_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF | AFMR_BYPASS);
+
+ //
+ // Now write zero to all addresses of acceptance filter table
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_SFF_GRP_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_EFF_GRP_SA, 0);
+ HAL_WRITE_UINT32(CAN_ACCFILT_ENDOFTABLE, 0);
+
+ //
+ // finally restore the previous state of the acceptance filter
+ //
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, accfilt_bck);
+}
+
+
+//===========================================================================
+// Dump content of acceptance filter lookup table
+//===========================================================================
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+void lpc2xxx_can_accfilt_dbg_dump(void)
+{
+ cyg_uint32 sff_sa;
+ cyg_uint32 sff_grp_sa;
+ cyg_uint32 eff_sa;
+ cyg_uint32 eff_grp_sa;
+ cyg_uint32 end_of_table;
+ cyg_uint32 entry_address;
+ lsc_buf_t data;
+
+
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_SA, sff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_SFF_GRP_SA, sff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_GRP_SA, eff_grp_sa);
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+
+ entry_address = sff_sa;
+
+ //
+ // Print lookup table registers
+ //
+ diag_printf("\n\nDUMP CAN ACCEPTANCE FILTER REGISTERS\n");
+ diag_printf("----------------------------------------\n");
+ diag_printf("SFF_sa:\t\t0x%08x\n", sff_sa);
+ diag_printf("SFF_GRP_sa:\t0x%08x\n", sff_grp_sa);
+ diag_printf("EFF_sa:\t\t0x%08x\n", eff_sa);
+ diag_printf("EFF_GRP_sa:\t0x%08x\n", eff_grp_sa);
+ diag_printf("EOT:\t\t0x%08x\n", end_of_table);
+
+ //
+ // Print table of standard identifiers
+ //
+ diag_printf("\n\nDUMP CAN LOOKUP TABLE RAM");
+ diag_printf("\nSFF_sa\t\tcolumn_lower\tcolumn_upper\traw_data\n");
+ diag_printf("----------------------------------------------------------\n");
+ while (entry_address < sff_grp_sa)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword);
+ diag_printf("0x%04x:\t\t0x%x\t\t0x%x\t\t0x%x\n", entry_address, data.column.lower, data.column.upper, data.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ //
+ // Print table of standard identifier groups
+ //
+ diag_printf("\nSFF_GRP_sa\tcolumn_lower\tcolumn_upper\traw_data\n");
+ diag_printf("----------------------------------------------------------\n");
+ while (entry_address < eff_sa)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword);
+ diag_printf("0x%04x:\t\t0x%x\t\t0x%x\t\t0x%x\n", entry_address, data.column.lower, data.column.upper, data.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ //
+ // Print table of extended identifiers
+ //
+ diag_printf("\nEFF_sa\t\t-\t\t-\t\traw_data\n");
+ diag_printf("----------------------------------------------------------\n");
+ while (entry_address < eff_grp_sa)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword);
+ diag_printf("0x%04x:\t\t\t\t\t\t0x%x\n", entry_address, data.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+
+ //
+ // Print table of extended identifier groups
+ //
+ diag_printf("\nEFF_GRP_sa\t-\t\t-\t\traw_data\n");
+ diag_printf("----------------------------------------------------------\n");
+ while (entry_address < end_of_table)
+ {
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + entry_address, data.dword);
+ diag_printf("0x%04x:\t\t\t\t\t\t0x%x\n", entry_address, data.dword);
+ entry_address += sizeof(cyg_uint32);
+ }
+}
+#endif // CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+
+//===========================================================================
+// Dump content of acceptance filter lookup table
+//===========================================================================
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+void lpc2xxx_can_reg_dump(struct cyg_devtab_entry* devtab_entry)
+{
+ can_channel *chan = (can_channel*)devtab_entry->priv;
+ cyg_uint32 reg_val;
+ CAN_DECLARE_INFO(chan);
+
+ chan = chan; // avoid compiler warnings for unused variables
+ //
+ // Print table of extended identifier groups
+ //
+ diag_printf("\n\nCAN REGISTER DUMP\n");
+ diag_printf("\nRegister\tValue\n");
+ diag_printf("----------------------------------------------------------\n");
+ HAL_READ_UINT32(CAN_CTRL_MOD(info), reg_val);
+ diag_printf("CANMOD\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_CMR(info), reg_val);
+ diag_printf("CANCMR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_GSR(info), reg_val);
+ diag_printf("CANGSR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_ICR(info), reg_val);
+ diag_printf("CANICR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_IER(info), reg_val);
+ diag_printf("CANIER\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_BTR(info), reg_val);
+ diag_printf("CANBTR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_EWL(info), reg_val);
+ diag_printf("CANEWL\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_SR(info), reg_val);
+ diag_printf("CANSR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_RFS(info), reg_val);
+ diag_printf("CANRFS\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_RID(info), reg_val);
+ diag_printf("CANRID\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_RDA(info), reg_val);
+ diag_printf("CANRDA\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CTRL_RDB(info), reg_val);
+ diag_printf("CANRDB\t\t0x%08x\n", reg_val);
+
+ diag_printf("\n\nCAN CENTRAL REGISTER DUMP\n");
+ diag_printf("\nRegister\tValue\n");
+ diag_printf("----------------------------------------------------------\n");
+ HAL_READ_UINT32(CAN_CENTRAL_TXSR, reg_val);
+ diag_printf("CANTxSR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CENTRAL_RXSR, reg_val);
+ diag_printf("CANRxSR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_CENTRAL_MSR, reg_val);
+ diag_printf("CANMSR\t\t0x%08x\n", reg_val);
+
+ diag_printf("\n\nCAN ACCEPTANCE FILTER REGISTER DUMP\n");
+ diag_printf("\nRegister\tValue\n");
+ diag_printf("----------------------------------------------------------\n");
+ HAL_READ_UINT32(CAN_ACCFILT_AFMR, reg_val);
+ diag_printf("AFMR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR, reg_val);
+ diag_printf("LUTERR\t\t0x%08x\n", reg_val);
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR_ADDR, reg_val);
+ diag_printf("LUTERRADDR\t0x%08x\n", reg_val);
+}
+#endif // #ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+
+//---------------------------------------------------------------------------
+// EOF can_accfilt_lpc2xxx.c
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c b/ecos/packages/devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c
new file mode 100644
index 0000000..f219853
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c
@@ -0,0 +1,2294 @@
+//==========================================================================
+//
+// devs/can/arm/lpc2xxx/current/src/can_lpc2xxx.c
+//
+// CAN driver for LPC2xxx microcontrollers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-04-09
+// Purpose: Support LPC2xxx on-chip CAN moduls
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/io_can.h>
+#include <pkgconf/io.h>
+#include <pkgconf/devs_can_lpc2xxx.h>
+
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/hal/hal_diag.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/can.h>
+#include <cyg/io/can_lpc2xxx_baudrates.h>
+
+
+
+
+//===========================================================================
+// DEFINES
+//===========================================================================
+//
+// Check if the macro HAL_LPC2XXX_GET_CAN_BR is provided
+//
+#ifndef HAL_LPC2XXX_GET_CAN_BR
+#error "Macro HAL_LPC2XXX_GET_CAN_BR() missing"
+#endif
+
+//
+// Support debug output if this option is enabled in CDL file
+//
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+#define LPC2XXX_DBG_PRINT diag_printf
+#else
+#define LPC2XXX_DBG_PRINT( fmt, ... )
+#endif
+
+
+//---------------------------------------------------------------------------
+// we define our own set of register bits in order to be independent from
+// platform specific names
+//
+
+//---------------------------------------------------------------------------
+// Memory map of CAN block
+//
+#define CAN_ACCFILT_RAM_BASE 0xE0038000
+#define CAN_ACCFILT_REG_BASE 0xE003C000
+#define CAN_CENTRAL_REG_BASE 0xE0040000
+#define CAN_CTRL_1_REG_BASE 0xE0044000
+#define CAN_CTRL_2_REG_BASE 0xE0048000
+#define CAN_CTRL_3_REG_BASE 0xE004C000
+#define CAN_CTRL_4_REG_BASE 0xE0050000
+
+
+//---------------------------------------------------------------------------
+// CAN Acceptance Filter register layout
+//
+#define CAN_ACCFILT_AFMR (CAN_ACCFILT_REG_BASE + 0x0000)
+#define CAN_ACCFILT_SFF_SA (CAN_ACCFILT_REG_BASE + 0x0004)
+#define CAN_ACCFILT_SFF_GRP_SA (CAN_ACCFILT_REG_BASE + 0x0008)
+#define CAN_ACCFILT_EFF_SA (CAN_ACCFILT_REG_BASE + 0x000C)
+#define CAN_ACCFILT_EFF_GRP_SA (CAN_ACCFILT_REG_BASE + 0x0010)
+#define CAN_ACCFILT_ENDOFTABLE (CAN_ACCFILT_REG_BASE + 0x0014)
+#define CAN_ACCFILT_LUT_ERR_ADDR (CAN_ACCFILT_REG_BASE + 0x0018)
+#define CAN_ACCFILT_LUT_ERR (CAN_ACCFILT_REG_BASE + 0x001C)
+
+//---------------------------------------------------------------------------
+// CAN_ACCFILT_AFMR Bits
+//
+#define AFMR_OFF 0x00000001 // 1 = Acceptance filter is not operational
+#define AFMR_BYPASS 0x00000002 // 1 = all Rx messages are accepted on enabled CAN controllers.
+#define AFMR_FULLCAN 0x00000004 // 1 = FullCAN mode
+#define AFMR_ON 0x00000000 // Acceptance filter on
+#define ACCFILT_RAM_SIZE 2048 // size of acceptance filter ram
+
+
+//---------------------------------------------------------------------------
+// Acceptance filter tool macros
+//
+#define ACCFILT_STD_ID_MASK 0x7FF
+#define ACCFILT_EXT_ID_MASK 0x1FFFFFFF
+#define ACCFILT_STD_DIS 0x1000
+#define ACCFILT_STD_CTRL_MASK 0xE000
+#define ACCFILT_EXT_CTRL_MASK 0xE0000000
+#define ACCFILT_STD_GET_CTRL(_entry_) (((_entry_) >> 13) & 0x7)
+#define ACCFILT_STD_GET_CTRL_LOWER(_entry_) (((_entry_) >> 29) & 0x7)
+#define ACCFILT_STD_GET_CTRL_UPPER(_entry_) (((_entry_) >> 13) & 0x7)
+#define ACCFILT_STD_GET_ID(_entry_) ((_entry_) & ACCFILT_STD_ID_MASK)
+#define ACCFILT_EXT_GET_ID(_entry_) ((_entry_) & ACCFILT_EXT_ID_MASK)
+#define ACCFILT_EXT_GET_CTRL(_entry_) (((_entry_) >> 29) & 0x7)
+#define ACCFILT_EXT_SET_CTRL(_entry_, _ctrl_) ((_entry_ & 0xE0000000) | ((_ctrl_) << 29))
+
+
+//---------------------------------------------------------------------------
+// CAN Central CAN Registers register layout
+//
+#define CAN_CENTRAL_TXSR (CAN_CENTRAL_REG_BASE + 0x0000)
+#define CAN_CENTRAL_RXSR (CAN_CENTRAL_REG_BASE + 0x0004)
+#define CAN_CENTRAL_MSR (CAN_CENTRAL_REG_BASE + 0x0008)
+
+
+//---------------------------------------------------------------------------
+// CAN Controller register offsets
+// Registers are offsets from base CAN module control register
+//
+#define CANREG_MOD 0x0000
+#define CANREG_CMR 0x0004
+#define CANREG_GSR 0x0008
+#define CANREG_ICR 0x000C
+#define CANREG_IER 0x0010
+#define CANREG_BTR 0x0014
+#define CANREG_EWL 0x0018
+#define CANREG_SR 0x001C
+#define CANREG_RFS 0x0020
+#define CANREG_RID 0x0024
+#define CANREG_RDA 0x0028
+#define CANREG_RDB 0x002C
+#define CANREG_TFI1 0x0030
+#define CANREG_TID1 0x0034
+#define CANREG_TDA1 0x0038
+#define CANREG_TDB1 0x003C
+#define CANREG_TFI2 0x0040
+#define CANREG_TID2 0x0044
+#define CANREG_TDA2 0x0048
+#define CANREG_TDB2 0x004C
+#define CANREG_TFI3 0x0050
+#define CANREG_TID3 0x0054
+#define CANREG_TDA3 0x0058
+#define CANREG_TDB3 0x005C
+
+
+//---------------------------------------------------------------------------
+// CAN Controller register layout
+//
+#define CAN_CTRL_MOD(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_MOD)
+#define CAN_CTRL_CMR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_CMR)
+#define CAN_CTRL_GSR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_GSR)
+#define CAN_CTRL_ICR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_ICR)
+#define CAN_CTRL_IER(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_IER)
+#define CAN_CTRL_BTR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_BTR)
+#define CAN_CTRL_EWL(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_EWL)
+#define CAN_CTRL_SR(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_SR)
+#define CAN_CTRL_RFS(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RFS)
+#define CAN_CTRL_RID(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RID)
+#define CAN_CTRL_RDA(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RDA)
+#define CAN_CTRL_RDB(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_RDB)
+#define CAN_CTRL_TFI1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TFI1)
+#define CAN_CTRL_TID1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TID1)
+#define CAN_CTRL_TDA1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDA1)
+#define CAN_CTRL_TDB1(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDB1)
+#define CAN_CTRL_TFI2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TFI2)
+#define CAN_CTRL_TID2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TID2)
+#define CAN_CTRL_TDA2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDA2)
+#define CAN_CTRL_TDB2(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDB2)
+#define CAN_CTRL_TFI3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TFI3)
+#define CAN_CTRL_TID3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TID3)
+#define CAN_CTRL_TDA3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDA3)
+#define CAN_CTRL_TDB3(_extra_) (CAN_CTRL_BASE(_extra_) + CANREG_TDB3)
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_ICR register bits
+//
+#define ICR_RX 0x00000001
+#define ICR_TX1 0x00000002
+#define ICR_ERR_WARN 0x00000004
+#define ICR_DATA_OVR 0x00000008
+#define ICR_WAKE_UP 0x00000010
+#define ICR_ERR_PASSIVE 0x00000020
+#define ICR_ARBITR_LOST 0x00000040
+#define ICR_BUS_ERR 0x00000080
+#define ICR_ID_READY 0x00000100
+#define ICR_TX2 0x00000200
+#define ICR_TX3 0x00000400
+#define ICR_LUT_ERR 0x00000800
+#define ICR_GET_ERRBIT(_icr_) (((_icr_) >> 16) & 0x1F)
+#define ICR_ERR_DIRECTION 0x00200000
+#define ICR_GET_ERRCODE(_icr_) (((_icr_) >> 22) & 0x03)
+#define ICR_GET_ALCBIT(_icr_) (((_icr_) >> 24) & 0x1F)
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_ALIE
+#define CAN_ALL_ERR_INT (ICR_ERR_PASSIVE | ICR_ARBITR_LOST | ICR_BUS_ERR | ICR_ERR_WARN)
+#else
+#define CAN_ALL_ERR_INT (ICR_ERR_PASSIVE | ICR_BUS_ERR | ICR_ERR_WARN)
+#endif
+#define CAN_MISC_INT (CAN_ALL_ERR_INT | ICR_WAKE_UP)
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_ICR register bits
+//
+#define ICR_ERRCODE_BIT_ERR 0x00
+#define ICR_ERRCODE_FORM_ERR 0x01
+#define ICR_ERRCODE_STUFF_ERR 0x02
+#define ICR_ERRCODE_OTHER_ERR 0x03
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_RFS register bits
+//
+#define RFS_ACCFILT_INDEX_MASK 0x000003FF
+#define RFS_RECEIVED_IN_BYPASS_MODE 0x00000400
+#define RFS_DLC_MASK 0x000F0000
+#define RFS_RTR 0x40000000
+#define RFS_EXT 0x80000000
+#define RFS_GET_DLC(_regval_) (((_regval_) >> 16) & 0xF)
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_CMR register bits
+//
+#define CMR_TX_REQ 0x00000001
+#define CMR_TX_ABORT 0x00000002
+#define CMR_RX_RELEASE_BUF 0x00000004
+#define CMR_CLEAR_DATA_OVR 0x00000008
+#define CMR_SELF_RX_REQ 0x00000010
+#define CMR_SEND_TX_BUF1 0x00000020
+#define CMR_SEND_TX_BUF2 0x00000040
+#define CMR_SEND_TX_BUF3 0x00000080
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_TFI register bits
+//
+#define TFI_PRIO_MASK 0x000000FF
+#define TFI_DLC_MASK 0x000F0000
+#define TFI_DLC_RTR 0x40000000
+#define TFI_DLC_EXT 0x80000000
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_MOD register bits
+//
+#define CANMOD_OPERATIONAL 0x00000000
+#define CANMOD_RESET 0x00000001
+#define CANMOD_LISTEN_ONLY 0x00000002
+#define CANMOD_SELF_TEST 0x00000004
+#define CANMOD_TX_BUF_CFG 0x00000008
+#define CANMOD_SLEEP 0x00000010
+#define CANMOD_REV_POLARITY 0x00000020
+#define CANMOD_TEST 0x00000040
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_IER register bits
+//
+#define IER_RX 0x00000001
+#define IER_TX1 0x00000002
+#define IER_ERR_WARN 0x00000004
+#define IER_DATA_OVR 0x00000008
+#define IER_WAKE_UP 0x00000010
+#define IER_ERR_PASSIVE 0x00000020
+#define IER_ARBITR_LOST 0x00000040
+#define IER_BUS_ERR 0x00000080
+#define IER_ID_READY 0x00000100
+#define IER_TX2 0x00000200
+#define IER_TX3 0x00000400
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_GSR register bits
+//
+#define GSR_RX_MSG_AVAILABLE 0x00000001
+#define GSR_DATA_OVR 0x00000002
+#define GSR_TX_NOT_PENDING 0x00000004
+#define GSR_ALL_TX_COMPLETE 0x00000008
+#define GSR_RECEIVING_ACTIVE 0x00000010
+#define GSR_SENDING_ACTIVE 0x00000020
+#define GSR_ERR 0x00000040
+#define GSR_BUS_OFF 0x00000080
+#define GSR_RXERR_CNT(_reg_) (((_reg_) >> 16) & 0xFF)
+#define GSR_TXERR_CNT(_reg_) (((_reg_) >> 24) & 0xFF)
+
+
+//---------------------------------------------------------------------------
+// CAN_CTRL_SR register bits
+//
+#define SR_RX_MSG_AVAILABLE 0x01
+#define SR_DATA_OVR 0x02
+#define SR_TX_BUF_WRITE_OK 0x04 // TBS1, TBS2, TBS3 (Bit 2, 10, 18)
+#define SR_TX_COMPLETE 0x08 // TCS1, TCS2, TCS3 (Bit 3, 11, 19)
+#define SR_RECEIVING_ACTIVE 0x10
+#define SR_SENDING_ACTIVE 0x20 // TS1, TS2, TS3 (5, 13, 21)
+#define SR_ERR 0x40
+#define SR_BUS_OFF 0x80
+
+
+//---------------------------------------------------------------------------
+// Optimize for the case of a single CAN channel, while still allowing
+// multiple channels.
+//
+#if CYGINT_IO_CAN_CHANNELS == 1
+#define CAN_CTRL_BASE(_extra_) CAN_CTRL_SINGLETON_BASE
+#define CAN_ISRVEC(_extra_) CAN_SINGLETON_ISRVEC
+#define CAN_CHAN_NO(_extra_) CAN_SINGLETON_CHAN_NO
+#define CAN_DECLARE_INFO(_chan_)
+#define CAN_DECLARE_CHAN(_data_)
+#else
+#define CAN_CTRL_BASE(_extra_) ((_extra_)->base)
+#define CAN_ISRVEC(_extra_) ((_extra_)->isrvec)
+#define CAN_CHAN_NO(_extra_) ((_extra_)->chan_no)
+#define CAN_DECLARE_INFO(_chan_) lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+#define CAN_DECLARE_CHAN(_data_) can_channel *chan = (can_channel *)data;
+#endif // CYGINT_IO_CAN_CHANNELS == 1
+
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN0_ACCFILT_STARTUP_CFG_RX_ALL
+#define CAN0_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
+#else
+#define CAN0_FLAG_STARTUP_ACCFILT_SETUP 0x00
+#endif
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN1_ACCFILT_STARTUP_CFG_RX_ALL
+#define CAN1_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
+#else
+#define CAN1_FLAG_STARTUP_ACCFILT_SETUP 0x00
+#endif
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN2_ACCFILT_STARTUP_CFG_RX_ALL
+#define CAN2_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
+#else
+#define CAN2_FLAG_STARTUP_ACCFILT_SETUP 0x00
+#endif
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_CAN3_ACCFILT_STARTUP_CFG_RX_ALL
+#define CAN3_FLAG_STARTUP_ACCFILT_SETUP INFO_FLAG_STARTUP_RX_ALL
+#else
+#define CAN3_FLAG_STARTUP_ACCFILT_SETUP 0x00
+#endif
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+//
+// Structure stores LPC2xxx CAN channel related stuff
+//
+
+// If we use Self Reception Request command instead of the Transmission Request
+// we must add last transmit message id in order to reject it in rx_ISR
+// There are two last_tx_id because tx interrupt (and so transmission of next
+// message) happens before rx interrupt (which uses last_tx_id for rejecting))
+
+// Format of last_tx_id:
+// (bits: 28:0-ID, 29-Validation, 30-RTR, 31-EXT)
+// if last_tx_id == 0xFFFFFFFF (Validation == 1) then last id is not valid
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_IDMASK 0x1FFFFFFF
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_FLMASK 0xC0000000
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID 0xFFFFFFFF
+
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_DECL cyg_uint8 last_tx_index; \
+ cyg_uint32 last_tx_id[2];
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_INIT last_tx_index : 0, \
+ last_tx_id : {LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID, LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID},
+#else
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_DECL
+ #define LPC2XXX_CAN_INFO_LAST_TX_ID_INIT
+#endif
+
+typedef struct lpc2xxx_can_info_st
+{
+//
+// Newer LPC2xxx variants like the LPC2468 do not support per channel
+// interrupts. They provide only one single interrupt vector for all
+// CAN interrupts
+//
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ cyg_interrupt tx_interrupt;
+ cyg_handle_t tx_interrupt_handle;
+ cyg_uint8 tx_interrupt_priority;
+ cyg_interrupt rx_interrupt;
+ cyg_handle_t rx_interrupt_handle;
+ cyg_uint8 rx_interrupt_priority;
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ cyg_can_state state; // state of CAN controller
+ cyg_uint8 flags; // flags indicating several states
+ LPC2XXX_CAN_INFO_LAST_TX_ID_DECL // last transmitted messages ids
+#if CYGINT_IO_CAN_CHANNELS > 1
+ cyg_uint32 base; // Per-bus h/w details
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ cyg_uint8 isrvec; // ISR vector (peripheral id)
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ cyg_uint8 chan_no; // number of CAN channel
+#endif // CYGINT_IO_CAN_CHANNELS > 1
+} lpc2xxx_can_info_t;
+
+
+#define INFO_FLAG_RX_ALL 0x01 // this bit indicates that channel receives all CAN messages - no filtering active
+#define INFO_FLAG_STARTUP_RX_ALL 0x02 // this bit indicates filter state at startup
+
+
+//
+// lpc2xxx info initialisation
+//
+#define LPC2XXX_CTRL_NOT_INITIALIZED 0xFF
+
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+#if CYGINT_IO_CAN_CHANNELS > 1
+#define LPC2XXX_CAN_INFO(_l, _base, _isrvec, _chan_no_, _tx_priority, _rx_priority, _flags) \
+lpc2xxx_can_info_t _l = { \
+ state : LPC2XXX_CTRL_NOT_INITIALIZED, \
+ base : (_base), \
+ isrvec : (_isrvec), \
+ chan_no : (_chan_no_), \
+ tx_interrupt_priority : (_tx_priority), \
+ rx_interrupt_priority : (_rx_priority), \
+ flags : (_flags), \
+ LPC2XXX_CAN_INFO_LAST_TX_ID_INIT \
+};
+#else // CYGINT_IO_CAN_CHANNELS == 1
+#define LPC2XXX_CAN_INFO(_l, _tx_priority, _rx_priority, _flags) \
+lpc2xxx_can_info_t _l = { \
+ state : CYGNUM_CAN_STATE_STOPPED, \
+ tx_interrupt_priority : (_tx_priority), \
+ rx_interrupt_priority : (_rx_priority), \
+ flags : (_flags), \
+ LPC2XXX_CAN_INFO_LAST_TX_ID_INIT \
+};
+#endif // CYGINT_IO_CAN_CHANNELS == 1
+#else // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+//
+// Newer devices support only one global CAN interrupt. We do not need
+// per channel interrupt data an ignore the values during initialisation
+//
+#if CYGINT_IO_CAN_CHANNELS > 1
+#define LPC2XXX_CAN_INFO(_l, _base, _isrvec, _chan_no_, _tx_priority, _rx_priority, _flags) \
+lpc2xxx_can_info_t _l = { \
+ state : LPC2XXX_CTRL_NOT_INITIALIZED, \
+ base : (_base), \
+ chan_no : (_chan_no_), \
+ flags : (_flags), \
+ LPC2XXX_CAN_INFO_LAST_TX_ID_INIT \
+};
+#else // CYGINT_IO_CAN_CHANNELS == 1
+#define LPC2XXX_CAN_INFO(_l, _tx_priority, _rx_priority, _flags) \
+lpc2xxx_can_info_t _l = { \
+ state : CYGNUM_CAN_STATE_STOPPED, \
+ flags : (_flags), \
+ LPC2XXX_CAN_INFO_LAST_TX_ID_INIT \
+};
+#endif // CYGINT_IO_CAN_CHANNELS == 1
+
+//
+// The following defines are only dummies required for proper
+// initialisation of can channel data structures
+//
+#define CYGNUM_HAL_INTERRUPT_CAN1_TX
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY
+#define CYGNUM_HAL_INTERRUPT_CAN2_TX
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY
+#define CYGNUM_HAL_INTERRUPT_CAN3_TX
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY
+#define CYGNUM_HAL_INTERRUPT_CAN4_TX
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY
+#define CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+
+
+//
+// Acceptance filter data
+//
+typedef struct lpc2xxx_global_can_info_st
+{
+ cyg_interrupt interrupt; // common CAN interrupt
+ cyg_handle_t interrupt_handle; // common CAN interrupt handle
+ cyg_uint16 free_filters; // number of free message filter
+#if CYGINT_IO_CAN_CHANNELS > 1 // optimize for single channel
+ cyg_uint8 init_cnt; // counts number of initialized channels
+ can_channel* active_channels[5]; // stores pointers to active channels - the last entry is just a delimiter
+#else // CYGINT_IO_CAN_CHANNELS > 1
+ can_channel* active_channels[1]; // optimize for one single channel
+#endif // CYGINT_IO_CAN_CHANNELS > 1
+} lpc2xxx_global_can_info_t;
+
+
+#if CYGINT_IO_CAN_CHANNELS > 1
+#define LPC2XXX_GET_CAN_CHANNEL(_can_info_, _chan_no_) ((can_channel*)(_can_info_).active_channels[_chan_no_])
+#define LPC2XXX_INIT_CNT lpc2xxx_global_can_info.init_cnt
+#else
+#define LPC2XXX_GET_CAN_CHANNEL(_can_info_, _chan_no_) ((can_channel*)(_can_info_).active_channels[0])
+#define LPC2XXX_INIT_CNT 1
+#endif
+
+//
+// The number of available message filters depends on the size of the
+// acceptance filter RAM and on the size of one entry. The size of
+// one entry is 4 byte (standard ID only 2 byte, extended groups 8 byte)
+//
+#define ACCFILT_COMMON_ENTRY_SIZE 4
+#define LPC2XXX_CAN_MSG_FILTERS_MAX (ACCFILT_RAM_SIZE / ACCFILT_COMMON_ENTRY_SIZE)
+lpc2xxx_global_can_info_t lpc2xxx_global_can_info =
+{
+ .free_filters = LPC2XXX_CAN_MSG_FILTERS_MAX,
+#if CYGINT_IO_CAN_CHANNELS > 1 // optimize for single channel
+ .init_cnt = 0,
+ .active_channels = {0, 0, 0, 0, 0},
+#endif // #if CYGINT_IO_CAN_CHANNELS > 1
+};
+
+
+
+//
+// Data type for access of single bytes/words of an dword value
+//
+typedef union lsc_buf_u
+{
+ cyg_uint8 bytes[4];
+ struct
+ {
+ cyg_uint16 low;
+ cyg_uint16 high;
+ } words;
+
+ struct
+ {
+ cyg_uint16 upper; // uppper column of acceptance filter ram
+ cyg_uint16 lower; // lower column of acceptance filter ram
+ } column;
+
+ cyg_uint32 dword;
+} lsc_buf_t;
+
+
+//===========================================================================
+// GLOBAL DATA
+//===========================================================================
+#if CYGINT_IO_CAN_CHANNELS > 1
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+LPC2XXX_CAN_INFO(lpc2xxx_can0_info,
+ CAN_CTRL_1_REG_BASE,
+ CYGNUM_HAL_INTERRUPT_CAN1_TX,
+ 0,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY,
+ CAN0_FLAG_STARTUP_ACCFILT_SETUP);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+LPC2XXX_CAN_INFO(lpc2xxx_can1_info,
+ CAN_CTRL_2_REG_BASE,
+ CYGNUM_HAL_INTERRUPT_CAN2_TX,
+ 1,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY,
+ CAN1_FLAG_STARTUP_ACCFILT_SETUP);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+LPC2XXX_CAN_INFO(lpc2xxx_can2_info,
+ CAN_CTRL_3_REG_BASE,
+ CYGNUM_HAL_INTERRUPT_CAN3_TX,
+ 2,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY,
+ CAN2_FLAG_STARTUP_ACCFILT_SETUP);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+LPC2XXX_CAN_INFO(lpc2xxx_can3_info,
+ CAN_CTRL_4_REG_BASE,
+ CYGNUM_HAL_INTERRUPT_CAN4_TX,
+ 3,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY,
+ CAN3_FLAG_STARTUP_ACCFILT_SETUP);
+#endif
+#else // CYGINT_IO_CAN_CHANNELS == 1
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+LPC2XXX_CAN_INFO(lpc2xxx_can0_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN0_RX_INT_PRIORITY,
+ CAN0_FLAG_STARTUP_ACCFILT_SETUP);
+#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_1_REG_BASE
+#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN1_TX
+#define CAN_SINGLETON_CHAN_NO 0
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+LPC2XXX_CAN_INFO(lpc2xxx_can1_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN1_RX_INT_PRIORITY,
+ CAN1_FLAG_STARTUP_ACCFILT_SETUP);
+#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_2_REG_BASE
+#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN2_TX
+#define CAN_SINGLETON_CHAN_NO 1
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+LPC2XXX_CAN_INFO(lpc2xxx_can2_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN2_RX_INT_PRIORITY,
+ CAN2_FLAG_STARTUP_ACCFILT_SETUP);
+#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_3_REG_BASE
+#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN3_TX
+#define CAN_SINGLETON_CHAN_NO 2
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+LPC2XXX_CAN_INFO(lpc2xxx_can3_info,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_TX_INT_PRIORITY,
+ CYGNUM_DEVS_CAN_LPC2XXX_CAN3_RX_INT_PRIORITY,
+ CAN3_FLAG_STARTUP_ACCFILT_SETUP);
+#define CAN_CTRL_SINGLETON_BASE CAN_CTRL_4_REG_BASE
+#define CAN_SINGLETON_ISRVEC CYGNUM_HAL_INTERRUPT_CAN4_TX
+#define CAN_SINGLETON_CHAN_NO 3
+#endif
+
+#endif // #if CYGINT_IO_CAN_CHANNELS > 1
+
+
+//===========================================================================
+// PROTOTYPES
+//===========================================================================
+
+//--------------------------------------------------------------------------
+// Device driver interface functions
+//
+static bool lpc2xxx_can_init(struct cyg_devtab_entry* devtab_entry);
+static Cyg_ErrNo lpc2xxx_can_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name);
+static Cyg_ErrNo lpc2xxx_can_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
+static Cyg_ErrNo lpc2xxx_can_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
+static bool lpc2xxx_can_putmsg(can_channel *priv, CYG_CAN_MSG_T *pmsg, void *pdata);
+static bool lpc2xxx_can_getevent(can_channel *priv, CYG_CAN_EVENT_T *pevent, void *pdata);
+static void lpc2xxx_can_start_xmit(can_channel* chan);
+static void lpc2xxx_can_stop_xmit(can_channel* chan);
+
+
+//--------------------------------------------------------------------------
+// ISRs and DSRs
+//
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+static cyg_uint32 lpc2xxx_can_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void lpc2xxx_can_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static cyg_uint32 lpc2xxx_can_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void lpc2xxx_can_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+static cyg_uint32 lpc2xxx_can_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void lpc2xxx_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+
+//--------------------------------------------------------------------------
+// Private utility functions
+//
+static bool lpc2xxx_can_config_channel(can_channel* chan, cyg_can_info_t* config, cyg_bool init);
+static bool lpc2xxx_can_set_baud(can_channel *chan, cyg_can_baud_rate_t *baudrate);
+static Cyg_ErrNo lpc2xxx_enter_lowpower_mode(can_channel *chan);
+static void lpc2xxx_start_module(can_channel *chan);
+static cyg_can_state lpc2xxx_get_state(lpc2xxx_can_info_t *info);
+static void lpc2xxx_set_state(lpc2xxx_can_info_t *info, cyg_can_state state);
+
+
+//--------------------------------------------------------------------------
+// Message box configuration
+//
+static void lpc2xxx_can_config_rx_all(can_channel *chan);
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+static void lpc2xxx_can_config_rx_none(can_channel *chan);
+static bool lpc2xxx_can_add_rx_filter(lpc2xxx_can_info_t *info, cyg_can_filter *filter);
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+#include "can_accfilt_lpc2xxx.c"
+
+//===========================================================================
+// GENERIC CAN IO DATA INITIALISATION
+//===========================================================================
+CAN_LOWLEVEL_FUNS(lpc2xxx_can_lowlevel_funs,
+ lpc2xxx_can_putmsg,
+ lpc2xxx_can_getevent,
+ lpc2xxx_can_get_config,
+ lpc2xxx_can_set_config,
+ lpc2xxx_can_start_xmit,
+ lpc2xxx_can_stop_xmit
+ );
+
+
+//---------------------------------------------------------------------------
+// CAN channel 0
+//
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+CYG_CAN_EVENT_T lpc2xxx_can0_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_RX]; // buffer for RX can events
+CYG_CAN_MSG_T lpc2xxx_can0_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_TX]; // buffer for TX can messages
+
+
+CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can0_chan,
+ lpc2xxx_can_lowlevel_funs,
+ lpc2xxx_can0_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD),
+ lpc2xxx_can0_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_TX,
+ lpc2xxx_can0_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(lpc2xxx_can0_devtab,
+ CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ lpc2xxx_can_init,
+ lpc2xxx_can_lookup, // CAN driver may need initializing
+ &lpc2xxx_can0_chan
+ );
+#endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+
+
+//---------------------------------------------------------------------------
+// CAN channel 1
+//
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+CYG_CAN_EVENT_T lpc2xxx_can1_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_RX]; // buffer for RX can events
+CYG_CAN_MSG_T lpc2xxx_can1_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_TX]; // buffer for TX can messages
+
+
+CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can1_chan,
+ lpc2xxx_can_lowlevel_funs,
+ lpc2xxx_can1_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD),
+ lpc2xxx_can1_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_TX,
+ lpc2xxx_can1_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN1_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(lpc2xxx_can1_devtab,
+ CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ lpc2xxx_can_init,
+ lpc2xxx_can_lookup, // CAN driver may need initializing
+ &lpc2xxx_can1_chan
+ );
+#endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+
+
+//---------------------------------------------------------------------------
+// CAN channel 2
+//
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+CYG_CAN_EVENT_T lpc2xxx_can2_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_RX]; // buffer for RX can events
+CYG_CAN_MSG_T lpc2xxx_can2_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_TX]; // buffer for TX can messages
+
+
+CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can2_chan,
+ lpc2xxx_can_lowlevel_funs,
+ lpc2xxx_can2_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN2_KBAUD),
+ lpc2xxx_can2_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_TX,
+ lpc2xxx_can2_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN2_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(lpc2xxx_can2_devtab,
+ CYGPKG_DEVS_CAN_LPC2XXX_CAN2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ lpc2xxx_can_init,
+ lpc2xxx_can_lookup, // CAN driver may need initializing
+ &lpc2xxx_can2_chan
+ );
+#endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+
+
+//---------------------------------------------------------------------------
+// CAN channel 3
+//
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+CYG_CAN_EVENT_T lpc2xxx_can3_rxbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_RX]; // buffer for RX can events
+CYG_CAN_MSG_T lpc2xxx_can3_txbuf[CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_TX]; // buffer for TX can messages
+
+
+CAN_CHANNEL_USING_INTERRUPTS(lpc2xxx_can3_chan,
+ lpc2xxx_can_lowlevel_funs,
+ lpc2xxx_can3_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LPC2XXX_CAN3_KBAUD),
+ lpc2xxx_can3_txbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_TX,
+ lpc2xxx_can3_rxbuf, CYGNUM_DEVS_CAN_LPC2XXX_CAN3_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(lpc2xxx_can3_devtab,
+ CYGPKG_DEVS_CAN_LPC2XXX_CAN3_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ lpc2xxx_can_init,
+ lpc2xxx_can_lookup, // CAN driver may need initializing
+ &lpc2xxx_can3_chan
+ );
+#endif // CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+
+
+//===========================================================================
+// IMPLEMENTATION
+//===========================================================================
+
+
+
+//===========================================================================
+/// First initialisation and reset of CAN modul.
+//===========================================================================
+static bool lpc2xxx_can_init(struct cyg_devtab_entry* devtab_entry)
+{
+ can_channel *chan = (can_channel*)devtab_entry->priv;
+ bool res;
+
+#ifdef CYGDBG_IO_INIT
+ diag_printf("LPC2XXX CAN init\n");
+#endif
+
+ //
+ // Newer LPC2xxx variants do not support individual interrupt
+ // sources for CAN on chip peripherals
+ //
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+ //
+ // Create TX interrupt
+ //
+ cyg_drv_interrupt_create(CAN_ISRVEC(info),
+ info->tx_interrupt_priority,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ lpc2xxx_can_tx_ISR,
+ lpc2xxx_can_tx_DSR,
+ &info->tx_interrupt_handle,
+ &info->tx_interrupt);
+ cyg_drv_interrupt_attach(info->tx_interrupt_handle);
+ cyg_drv_interrupt_unmask(CAN_ISRVEC(info));
+
+ //
+ // Create RX interrupt
+ //
+ cyg_drv_interrupt_create(CAN_ISRVEC(info) + 6,
+ info->rx_interrupt_priority,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ lpc2xxx_can_rx_ISR,
+ lpc2xxx_can_rx_DSR,
+ &info->rx_interrupt_handle,
+ &info->rx_interrupt);
+ cyg_drv_interrupt_attach(info->rx_interrupt_handle);
+ cyg_drv_interrupt_unmask(CAN_ISRVEC(info) + 6);
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+
+ //
+ // Now create and enable global CAN interrupt. This interrupt is
+ // global for all channels and so we need to call it only one times -
+ // when the first channel is initialized
+ //
+#if CYGINT_IO_CAN_CHANNELS > 1
+ if (!lpc2xxx_global_can_info.init_cnt)
+#endif // #if CYGINT_IO_CAN_CHANNELS > 1
+ {
+ //
+ // Create err interrupt
+ //
+ cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_CAN,
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ CYGNUM_DEVS_CAN_LPC2XXX_ERR_INT_PRIORITY,
+#else // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY,
+#endif // CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+ 0, // Data item passed to interrupt handler
+ lpc2xxx_can_ISR,
+ lpc2xxx_can_DSR,
+ &lpc2xxx_global_can_info.interrupt_handle,
+ &lpc2xxx_global_can_info.interrupt);
+ cyg_drv_interrupt_attach(lpc2xxx_global_can_info.interrupt_handle);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_CAN);
+ }
+
+ res = lpc2xxx_can_config_channel(chan, &chan->config, true);
+#if CYGINT_IO_CAN_CHANNELS > 1
+ lpc2xxx_global_can_info.active_channels[lpc2xxx_global_can_info.init_cnt++] = chan;
+#else // CYGINT_IO_CAN_CHANNELS > 1
+ lpc2xxx_global_can_info.active_channels[0] = chan;
+#endif
+ return res;
+}
+
+
+//===========================================================================
+// Configure can channel
+//===========================================================================
+static bool lpc2xxx_can_config_channel(can_channel* chan, cyg_can_info_t* config, cyg_bool init)
+{
+ CAN_DECLARE_INFO(chan);
+ bool res = true;
+
+ if (init)
+ {
+ //
+ // In case platform needs extra initialization (i.e. setup of
+ // CAN transceivers) it should implement this macro
+ //
+#ifdef CYGPRI_IO_CAN_LPC2XXX_PLF_INIT_HOOK
+ CYGPRI_IO_CAN_LPC2XXX_PLF_INIT_HOOK(chan, config);
+#endif
+
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_OFF); // Acceptance Filter Mode Register = off
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET); // Go into reset mode
+ HAL_WRITE_UINT32(CAN_CTRL_IER(info), 0); // disable all interrupts
+ HAL_WRITE_UINT32(CAN_CTRL_GSR(info), 0); // Clear Status register - clears error counters
+
+ //
+ // Perform platform/variant specific initialisation here.
+ // The variant/ platform should setup the pin configuration to support
+ // CAN here
+ //
+ HAL_LPC2XXX_INIT_CAN(CAN_CHAN_NO(info));
+
+ //
+ // If this is the first channel to initialize then we reset the CAN
+ // registers and setup the CAN I/O pins
+ //
+#if CYGINT_IO_CAN_CHANNELS > 1
+ if (!lpc2xxx_global_can_info.init_cnt)
+#endif // #if CYGINT_IO_CAN_CHANNELS > 1
+ {
+ lpc2xxx_can_accfilt_reset();
+ }
+ } // if (init)
+
+ res = lpc2xxx_can_set_baud(chan, &config->baud); // set baudrate
+ // $$$$ enable receive interrupt?
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_OPERATIONAL); // enter normal operating mode
+
+ //
+ // store new config values
+ //
+ if (config != &chan->config)
+ {
+ chan->config = *config;
+ }
+
+ return res;
+}
+
+
+//===========================================================================
+// Set baudrate of certain can channel
+//===========================================================================
+static bool lpc2xxx_can_set_baud(can_channel *chan, cyg_can_baud_rate_t *baudrate)
+{
+ bool res = true;
+ cyg_uint32 canbtr;
+ cyg_uint32 canmod;
+ CAN_DECLARE_INFO(chan);
+
+ //
+ // Get bit timings from HAL because bit timings depend on sysclock
+ // If the macro fills the canbtr value with 0 then the baudrate
+ // is not supported and the function returns false
+ //
+ HAL_LPC2XXX_GET_CAN_BR(*baudrate, canbtr);
+ if (0 == canbtr)
+ {
+ return false;
+ }
+
+ //
+ // Any modificatons to the baudrate register must be done while CAN
+ // module is in reset mode. So we first set the CAN module in reset
+ // mode, then we set baudrate and then we restore content of CANMOD
+ // register
+ //
+ HAL_READ_UINT32(CAN_CTRL_MOD(info), canmod); // backup canmod register
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET); // Go into reset mode
+ HAL_WRITE_UINT32(CAN_CTRL_BTR(info), canbtr); // write baudrate value
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), canmod); // restore previous value
+
+ return res;
+}
+
+
+//===========================================================================
+// Lookup the device and return its handle
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_can_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name)
+{
+ can_channel* chan = (can_channel*) (*tab)->priv;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+ cyg_uint32 regval;
+
+ chan->callbacks->can_init(chan);
+
+ //
+ // If runtime acceptance filter configuration is supported then we only
+ // configure RX ALL if the user selected the RX ALL setup in config utility
+ //
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ if (info->flags & INFO_FLAG_STARTUP_RX_ALL)
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ {
+ lpc2xxx_can_config_rx_all(chan);
+ }
+
+ HAL_WRITE_UINT32(CAN_ACCFILT_AFMR, AFMR_ON); // Activate acceptance filter
+ HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
+ regval = regval | IER_RX | CAN_MISC_INT; // enable all interrupts
+ HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval);
+
+ return ENOERR;
+}
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Setup LPC2XXX CAN module in a state where all message boxes are disabled
+// After this call it is possible to add single message buffers and filters
+//===========================================================================
+static void lpc2xxx_can_config_rx_none(can_channel *chan)
+{
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ //
+ // Remove all acceptance filters
+ // $$$$ maybe we should also abort any pending transfers and
+ // disable receive interrupts ?
+ //
+ lpc2xxx_can_accfilt_remove_all_ctrl_entries(info);
+ info->flags &= ~INFO_FLAG_RX_ALL;
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif
+}
+
+
+//===========================================================================
+// Add one single message filter to acceptance filter
+//===========================================================================
+static bool lpc2xxx_can_add_rx_filter(lpc2xxx_can_info_t *info, cyg_can_filter *filter)
+{
+ bool res;
+
+ res = lpc2xxx_can_accfilt_add(info, filter->msg.id, 0, filter->msg.ext);
+ if (!res)
+ {
+ filter->handle = CYGNUM_CAN_MSGBUF_NA;
+ }
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif
+ return res;
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Configure message buffers
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_can_config_msgbuf(can_channel *chan, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+ cyg_can_msgbuf_cfg *msg_buf = (cyg_can_msgbuf_cfg *)buf;
+
+ if (*len != sizeof(cyg_can_msgbuf_cfg))
+ {
+ return -EINVAL;
+ }
+
+ switch (msg_buf->cfg_id)
+ {
+ //
+ // clear all message filters and remote buffers - prepare for message buffer
+ // configuration
+ //
+ case CYGNUM_CAN_MSGBUF_RESET_ALL :
+ {
+ lpc2xxx_can_config_rx_none(chan);
+ }
+ break;
+
+ //
+ // setup driver for reception of all standard and extended messages
+ //
+ case CYGNUM_CAN_MSGBUF_RX_FILTER_ALL :
+ {
+ if (!(info->flags & INFO_FLAG_RX_ALL)) // if rx_all is enabled we do not need to do anything
+ {
+ lpc2xxx_can_config_rx_all(chan); // setup RX all state
+ }
+ }
+ break;
+
+ //
+ // add single message filter, message with filter ID will be received
+ //
+ case CYGNUM_CAN_MSGBUF_RX_FILTER_ADD :
+ {
+ cyg_can_filter *filter = (cyg_can_filter*) buf;
+
+ //
+ // if the acceptance filter is configured to receive all messages then
+ // it is not allowed to add single message filters because then more
+ // than one acceptance filter would receive the same CAN id
+ //
+ if (info->flags & INFO_FLAG_RX_ALL)
+ {
+ return -EPERM;
+ }
+
+ //
+ // try to allocate a free acceptance filter entry - if we have a free one
+ // then we can prepare the acceptance filter table for reception of
+ // this message
+ //
+ if (!lpc2xxx_can_add_rx_filter(info, filter))
+ {
+ return -ENOSPC;
+ }
+ }
+ break; //CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
+
+
+#ifdef CYGOPT_IO_CAN_REMOTE_BUF
+ //
+ // Try to add a new RTR response message buffer for automatic
+ // transmission of data frame on reception of a remote frame
+ //
+ case CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD :
+ {
+ // $$$$ TODO implement remote response buffers in software
+ return -ENOSUPP;
+ }
+ break;
+
+ //
+ // write data into remote response buffer
+ //
+ case CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE :
+ {
+ // $$$$ TODO implement remote response buffers in software
+ return -ENOSUPP;
+ }
+ break;
+#endif // #ifdef CYGOPT_IO_CAN_REMOTE_BUF
+ default:
+ return -EINVAL;
+ } // switch (buf->cfg_id)
+
+ return res;
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+//===========================================================================
+// Read state of CAN controller
+// The CAN state variable for each channel is modified by DSR so if we
+// read the state we need to lock DSRs to protect the data access
+//===========================================================================
+static cyg_can_state lpc2xxx_get_state(lpc2xxx_can_info_t *info)
+{
+ cyg_can_state result;
+
+ cyg_drv_dsr_lock();
+ result = info->state;
+ cyg_drv_dsr_unlock();
+
+ return result;
+}
+
+
+//===========================================================================
+// Set state of CAN controller
+// The CAN state variable for each channel is modified by DSR so if we
+// write the state we need to lock DSRs to protect the data access
+//===========================================================================
+static void lpc2xxx_set_state(lpc2xxx_can_info_t *info, cyg_can_state state)
+{
+ cyg_drv_dsr_lock();
+ info->state = state;
+ cyg_drv_dsr_unlock();
+}
+
+
+//===========================================================================
+// Enter low power mode
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_enter_lowpower_mode(can_channel *chan)
+{
+ cyg_uint32 regval;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ //
+ // Before we enter low power mode, we have to enable wake up interrupt
+ // Normally this interrupt is always enabled so we do not need to do
+ // anything here
+ //
+ HAL_READ_UINT32(CAN_CTRL_MOD(info), regval);
+
+ //
+ // Software can only set SM when RM in the CAN Mode register is 0
+ //
+ if (regval & CANMOD_RESET)
+ {
+ return -EPERM;
+ }
+
+ //regval &= CANMOD_SLEEP;
+ lpc2xxx_set_state(info, CYGNUM_CAN_STATE_STANDBY);
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_SLEEP);
+ return ENOERR;
+}
+
+
+#ifdef CYGHWR_DEVS_CAN_LPC2XXX_BUSOFF_WORKAROUND
+//===========================================================================
+// Reset error counters to the given values
+//===========================================================================
+static void lpc2xxx_reset_error_counters(lpc2xxx_can_info_t *info,
+ cyg_uint8 rx_errcnt, cyg_uint8 tx_errcnt)
+{
+ lsc_buf_t data;
+ cyg_uint32 regval;
+ HAL_READ_UINT32(CAN_CTRL_MOD(info), regval);
+
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET);
+ HAL_READ_UINT32(CAN_CTRL_GSR(info), data.dword);
+ data.bytes[2] = rx_errcnt; // reset RX error counter
+ data.bytes[3] = tx_errcnt; // reset TX error counter to 0
+ HAL_WRITE_UINT32(CAN_CTRL_GSR(info), data.dword);
+
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), regval);
+}
+#endif // #ifdef CYGHWR_DEVS_CAN_LPC2XXX_BUSOFF_WORKAROUND
+
+
+//===========================================================================
+// Start CAN module - set CANMOD operational and enable all interrupts
+//===========================================================================
+static void lpc2xxx_start_module(can_channel *chan)
+{
+ lsc_buf_t data;
+ cyg_uint32 regval;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ // before we start CAN module, we clear both error counters to start
+ // with a clean error counter state
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET);
+ HAL_READ_UINT32(CAN_CTRL_GSR(info), data.dword);
+ data.bytes[2] = 0; // reset RX error counter to 0
+ data.bytes[3] = 0; // reset TX error counter to 0
+ HAL_WRITE_UINT32(CAN_CTRL_GSR(info), data.dword);
+
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_OPERATIONAL);
+ //
+ // The interrupt enable register is also modified by ISR and DSR so
+ // we need to protect acces here
+ //
+ cyg_drv_isr_lock();
+ HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
+ regval = regval | IER_RX | CAN_MISC_INT; // enable all interrupts
+ HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval);
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ cyg_drv_isr_unlock();
+}
+
+
+//===========================================================================
+// Enter reset mode
+//===========================================================================
+static void lpc2xxx_enter_reset_mode(can_channel *chan)
+{
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ info->state = CYGNUM_CAN_STATE_STOPPED;
+ HAL_WRITE_UINT32(CAN_CTRL_MOD(info), CANMOD_RESET);
+}
+
+
+#ifdef CYGOPT_DEVS_CAN_RANGE_FILTERING_CFG_KEYS
+//===========================================================================
+// Add message filter group
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_can_config_accfilt_group(can_channel *chan, const void* buf, cyg_uint32* len)
+{
+ bool res;
+ cyg_can_filter_range_cfg *filter_grp = (cyg_can_filter_range_cfg *)buf;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+
+ if (*len != sizeof(cyg_can_filter_range_cfg))
+ {
+ return -EINVAL;
+ }
+
+ if (filter_grp->lower_id_bound >= filter_grp->upper_id_bound)
+ {
+ return -EINVAL;
+ }
+
+ //
+ // if the acceptance filter is configured to receive all messages then
+ // it is not allowed to add single message filter groups because then more
+ // than one acceptance filter would receive the same CAN id
+ //
+ if (info->flags & INFO_FLAG_RX_ALL)
+ {
+ return -EPERM;
+ }
+
+ res = lpc2xxx_can_accfilt_add(info,
+ filter_grp->lower_id_bound,
+ filter_grp->upper_id_bound,
+ filter_grp->ext);
+
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif
+ return res ? ENOERR : -ENOSPC;
+}
+#endif // CYGOPT_DEVS_CAN_RANGE_FILTERING_CFG_KEYS
+
+
+//===========================================================================
+// Change device configuration
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_can_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+
+ switch (key)
+ {
+ //
+ // Setup a new CAN configuration. This will i.e. setup a new baud rate
+ //
+ case CYG_IO_SET_CONFIG_CAN_INFO:
+ {
+ cyg_can_info_t* config = (cyg_can_info_t*) buf;
+ if (*len < sizeof(cyg_can_info_t))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_info_t);
+ if (!lpc2xxx_can_config_channel(chan, config, false))
+ {
+ return -EINVAL;
+ }
+ }
+ break;
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ //
+ // configure message buffers
+ //
+ case CYG_IO_SET_CONFIG_CAN_MSGBUF :
+ {
+ res = lpc2xxx_can_config_msgbuf(chan, buf, len);
+ }
+ break;
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+#ifdef CYGOPT_DEVS_CAN_RANGE_FILTERING_CFG_KEYS
+ //
+ // Add message filter group to acceptance filter
+ //
+ case CYG_IO_SET_CONFIG_CAN_RANGE_FILTER :
+ {
+ return lpc2xxx_can_config_accfilt_group(chan, buf, len);
+ }
+ break;
+#endif // CYGOPT_DEVS_CAN_RANGE_FILTERING_CFG_KEYS
+
+ //
+ // Change CAN state of CAN module
+ //
+ case CYG_IO_SET_CONFIG_CAN_MODE :
+ {
+ cyg_can_mode *can_mode = (cyg_can_mode*) buf;
+
+ if (*len != sizeof(cyg_can_mode))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_mode);
+
+ //
+ // decide what to do according to mode
+ //
+ switch (*can_mode)
+ {
+ //
+ // The controller does not support a stopped and standby state so we
+ // simply enter the low power state here. This state is also safe for
+ // message buffer configuration
+ //
+ case CYGNUM_CAN_MODE_STOP : lpc2xxx_enter_reset_mode(chan); break;
+ case CYGNUM_CAN_MODE_START : lpc2xxx_start_module(chan); break;
+ case CYGNUM_CAN_MODE_STANDBY : lpc2xxx_enter_lowpower_mode(chan); break;
+ case CYGNUM_CAN_MODE_CONFIG : lpc2xxx_enter_reset_mode(chan); break;
+ case CYGNUM_CAN_MODE_LISTEN_ONLY_ENTER: return -EINVAL;
+ case CYGNUM_CAN_MODE_LISTEN_ONLY_EXIT: return -EINVAL;
+ }
+ }
+ break; // case CYG_IO_SET_CONFIG_CAN_MODE :
+ //
+ // Unknown config key - indicate this by returning -EINVAL
+ //
+ default:
+ return -EINVAL;
+ } // switch (key)
+
+ return res;
+}
+
+
+//===========================================================================
+// Query device configuration
+//===========================================================================
+static Cyg_ErrNo lpc2xxx_can_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ switch(key)
+ {
+ //
+ // query state of CAN controller
+ //
+ case CYG_IO_GET_CONFIG_CAN_STATE :
+ {
+ cyg_can_state *can_state = (cyg_can_state*) buf;
+
+ if (*len != sizeof(cyg_can_state))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_state);
+ *can_state = lpc2xxx_get_state(info);
+ }
+ break;
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+ //
+ // Query message box information - returns available and free message
+ // boxes
+ //
+ case CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO :
+ {
+ cyg_can_msgbuf_info *mbox_info = (cyg_can_msgbuf_info*) buf;
+
+ if (*len != sizeof(cyg_can_msgbuf_info))
+ {
+ return -EINVAL;
+ }
+ cyg_uint32 end_of_table;
+ *len = sizeof(cyg_can_msgbuf_info);
+
+ HAL_READ_UINT32(CAN_ACCFILT_ENDOFTABLE, end_of_table);
+ mbox_info->count = LPC2XXX_CAN_MSG_FILTERS_MAX;
+ mbox_info->free = (ACCFILT_RAM_SIZE - end_of_table) / ACCFILT_COMMON_ENTRY_SIZE;
+ }
+ break;
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+ //
+ // Query hardware description of LPC2xxx CAN device driver
+ //
+ case CYG_IO_GET_CONFIG_CAN_HDI :
+ {
+ cyg_can_hdi *hdi = (cyg_can_hdi *)buf;
+ //
+ // comes from high level driver so we do not need to
+ // check buffer size here
+ //
+ hdi->support_flags = CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE
+ | CYGNUM_CAN_HDI_FULLCAN;
+ }
+ break;
+
+ //
+ // Read error counters from device hardware
+ //
+ case CYG_IO_GET_CONFIG_CAN_ERR_COUNTERS :
+ {
+ lsc_buf_t data;
+ cyg_can_err_count_info* err_info = (cyg_can_err_count_info*)buf;
+ HAL_READ_UINT32(CAN_CTRL_GSR(info), data.dword);
+ err_info->rx_err_count = data.bytes[2];
+ err_info->tx_err_count = data.bytes[3];
+ *len = sizeof(cyg_can_err_count_info);
+ }
+ break;
+
+ default :
+ res = -EINVAL;
+ }// switch(key)
+
+ return res;
+}
+
+
+//===========================================================================
+// Send single message
+//===========================================================================
+static bool lpc2xxx_can_putmsg(can_channel *chan, CYG_CAN_MSG_T *pmsg, void *pdata)
+{
+ cyg_uint32 regval;
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *) chan->dev_priv;
+#else
+ CAN_DECLARE_INFO(info);
+#endif
+
+ //
+ // We use only one single transmit buffer of the three available buffers
+ // We use buffer 1 (buffer 2 and 3 are unused)
+ //
+ // The errata sheet tells the following about the transmit buffers:
+ // Problem: The Triple Transmit Buffer function cannot be used.
+ // Work-around: Use any one Transmit buffer only (Use either Transmit Buffer 1,
+ // Transmit Buffer 2 or Transmit Buffer 3 exclusively). The buffer you decided
+ // to use should be loaded only when there is no pending transmission.
+ //
+ HAL_READ_UINT32(CAN_CTRL_SR(info), regval);
+ if (!(regval & SR_TX_BUF_WRITE_OK))
+ {
+ return false;
+ }
+
+ regval = pmsg->dlc << 16;
+ if (pmsg->rtr)
+ {
+ regval |= TFI_DLC_RTR;
+ }
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (pmsg->ext)
+ {
+ regval |= TFI_DLC_EXT;
+ }
+#endif // #define CYGOPT_IO_CAN_EXT_CAN_ID
+ HAL_WRITE_UINT32(CAN_CTRL_TFI1(info), regval); // write DLC
+ HAL_WRITE_UINT32(CAN_CTRL_TID1(info), pmsg->id); // write ID
+ HAL_WRITE_UINT32(CAN_CTRL_TDA1(info), pmsg->data.dwords[0]); // write first 4 data bytes
+ HAL_WRITE_UINT32(CAN_CTRL_TDB1(info), pmsg->data.dwords[1]); // write second 4 data bytes
+
+ //
+ // Request transmission of message
+ // The errata sheet tells the following about tx request:
+ // Introduction: The CAN module can lose arbitration to another CAN node during an
+ // attempt to transmit a CAN message. The message of the CAN node the arbitration was
+ // lost to is supposed to be received correctly by the CAN module.
+ // Problem: Messages might not be received correctly if during a CAN Transmission the
+ // CAN bus arbitration is lost to another CAN node.
+ // Work-around: Use the Self Reception Request command instead of the Transmission
+ // Request command. However, it has to be taken into account that now all transmitted
+ // messages may be received if not prevented by appropriate Acceptance Filter settings.
+ // (Don't set up Acceptance Filter Message Identifiers for the messages you are
+ // transmitting yourself.)
+ //
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
+ // Calc last_tx_id
+ regval = pmsg->id | (regval & LPC2XXX_CAN_INFO_LAST_TX_ID_FLMASK);
+
+ // Save last message id to next last_tx_id
+ info->last_tx_index = info->last_tx_index == 0 ? 1 : 0;
+ info->last_tx_id[info->last_tx_index] = regval;
+
+ // Write self transmission request
+ HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_SELF_RX_REQ | CMR_SEND_TX_BUF1);
+#else
+ // Write transmission request
+ HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_TX_REQ | CMR_SEND_TX_BUF1);
+#endif
+
+ return true;
+}
+
+
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+//===========================================================================
+// Print status registers
+// This function is only here for debugging purposes to ease printing
+// of status register content
+//===========================================================================
+static void lpc2xxx_print_status(lpc2xxx_can_info_t *info)
+{
+ cyg_uint32 regval;
+ lsc_buf_t data;
+
+ HAL_READ_UINT32(CAN_CTRL_MOD(info), regval);
+ LPC2XXX_DBG_PRINT("CANREG_MOD: 0x%08x\n", regval);
+
+ HAL_READ_UINT32(CAN_CTRL_GSR(info), data.dword);
+ LPC2XXX_DBG_PRINT("RXERR: %d\n", data.bytes[2]);
+ LPC2XXX_DBG_PRINT("TXERR: %d\n", data.bytes[3]);
+}
+#endif
+
+
+//===========================================================================
+// Read event from device driver
+//===========================================================================
+static bool lpc2xxx_can_getevent(can_channel *chan, CYG_CAN_EVENT_T *pevent, void *pdata)
+{
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+ bool res = true;
+ cyg_uint32 regval;
+ cyg_uint32 event = *((cyg_uint32*)pdata);
+ lsc_buf_t data;
+
+ //
+ // Handle RX event
+ //
+ if (event & ICR_RX)
+ {
+ cyg_uint32 id;
+
+ pevent->flags |= CYGNUM_CAN_EVENT_RX;
+ HAL_READ_UINT32(CAN_CTRL_RFS(info), regval);
+ HAL_READ_UINT32(CAN_CTRL_RID(info), id);
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (regval & RFS_EXT)
+ {
+ pevent->msg.ext = CYGNUM_CAN_ID_EXT;
+ pevent->msg.id = id & 0x1FFFFFFF;
+ }
+ else
+#endif // #define CYGOPT_IO_CAN_EXT_CAN_ID
+ {
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ pevent->msg.ext = CYGNUM_CAN_ID_STD;
+ pevent->msg.id = id & 0x7FF;
+#endif // #ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ } // if (regval & RFS_EXT)
+
+ if (regval & RFS_RTR)
+ {
+ pevent->msg.rtr = CYGNUM_CAN_FRAME_RTR;
+ }
+ else
+ {
+ pevent->msg.rtr = CYGNUM_CAN_FRAME_DATA;
+ HAL_READ_UINT32(CAN_CTRL_RDA(info), pevent->msg.data.dwords[0]);
+ HAL_READ_UINT32(CAN_CTRL_RDB(info), pevent->msg.data.dwords[1]);
+ } //if (regval & RFS_RTR)
+ pevent->msg.dlc = RFS_GET_DLC(regval);
+ //
+ // Release the message buffer. Now this buffer can receive the next message
+ //
+ HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_RX_RELEASE_BUF);
+
+ //
+ // Now check if an data overrun occurred - a message was lost
+ // because the preceding message to this CAN controller was not read
+ // and released quickly enough. After reading the status we clear
+ // the overrun bit
+ //
+ HAL_READ_UINT32(CAN_CTRL_GSR(info), regval);
+ if (regval & GSR_DATA_OVR)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_OVERRUN_RX_HW;
+ HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_CLEAR_DATA_OVR);
+ }
+ }
+
+ //
+ // Handle TX events
+ //
+#ifndef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ if (event & ICR_TX1)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_TX;
+ }
+#endif
+
+ //
+ // Handle all other events
+ //
+ if (event & (CAN_MISC_INT | ICR_LUT_ERR))
+ {
+ HAL_READ_UINT32(CAN_CTRL_GSR(info), data.dword);
+
+ //
+ // 1: Error Warning Interrupt -- this bit is set on every change (set or clear) of the Error
+ // Status or Bus Status bit in CANSR, if the EIE bit in CAN is 1 at the time of the
+ // change.
+ //
+ if (event & ICR_ERR_WARN)
+ {
+ //
+ // If one of the warning counters is above 96 then the controller is in bus warning
+ // state. If both counters are below 96 the this interrupt indicates that the
+ // controller has left the bus warning state and is error active again
+ //
+ if (data.bytes[2] >= 96)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_WARNING_RX;
+ info->state = CYGNUM_CAN_STATE_BUS_WARN;
+ LPC2XXX_DBG_PRINT("CYGNUM_CAN_EVENT_WARNING_RX counter (%d) (%p)\n", data.bytes[2], (void*) chan);
+ }
+ else if (data.bytes[3] >= 96)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_WARNING_TX;
+ info->state = CYGNUM_CAN_STATE_BUS_WARN;
+ LPC2XXX_DBG_PRINT("CYGNUM_CAN_EVENT_WARNING_TX counter (%d) (%p)\n", data.bytes[3], (void*) chan);
+ }
+ else
+ {
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ LPC2XXX_DBG_PRINT("CYGNUM_CAN_STATE_ACTIVE (%p)\n", (void*) chan);
+ }
+ LPC2XXX_DBG_PRINT("ICR_ERR_WARN (%p)\n", (void*) chan);
+ }
+
+ //
+ // 1: Wake-Up Interrupt: this bit is set if the CAN controller is sleeping and bus activity
+ // is detected, if the WUIE bit in CANIE is 1.
+ //
+ if (event & ICR_WAKE_UP)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_LEAVING_STANDBY;
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ LPC2XXX_DBG_PRINT("ICR_WAKE_UP (%p)\n", (void*) chan);
+ }
+
+ //
+ // Error Passive Interrupt -- this bit is set if the EPIE bit in CANIE is 1, and the CAN
+ // controller switches between Error Passive and Error Active mode in either
+ // direction. We have to check if the ERR bit is set in global status register.
+ // If it is set, then it is a switch to error passive else it is a switch to
+ // error active state
+ //
+ if (event & ICR_ERR_PASSIVE)
+ {
+ if (data.dword & GSR_ERR)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_ERR_PASSIVE;
+ info->state = CYGNUM_CAN_STATE_ERR_PASSIVE;
+ LPC2XXX_DBG_PRINT("CYGNUM_CAN_EVENT_ERR_PASSIVE (%p)\n", (void*) chan);
+ }
+ else
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_ERR_ACTIVE;
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ LPC2XXX_DBG_PRINT("CYGNUM_CAN_EVENT_ERR_ACTIVE (%p)\n", (void*) chan);
+ }
+ LPC2XXX_DBG_PRINT("ICR_ERR_PASSIVE (%p)\n", (void*) chan);
+ }
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_ALIE
+ //
+ // Arbitration Lost Interrupt -- this bit is set if the ALIE bit in CANIE is 1, and the
+ // CAN controller loses arbitration while attempting to transmit.
+ //
+ if (event & ICR_ARBITR_LOST)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_ARBITRATION_LOST;
+ LPC2XXX_DBG_PRINT("ICR_ARBITR_LOST (%p)\n", (void*) chan);
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_ALIE
+
+ //
+ // 1: Bus Error Interrupt -- this bit is set if the BEIE bit in CANIE
+ // is 1, and the CAN controller detects an error on the bus.
+ //
+ if (event & ICR_BUS_ERR)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_BUS_OFF;
+ LPC2XXX_DBG_PRINT("ICR_BUS_ERR (%p)\n", (void*) chan);
+
+#ifdef CYGHWR_DEVS_CAN_LPC2XXX_BUSOFF_WORKAROUND
+ //
+ // we do exactly here, what is written in the user manual
+ // 1. we go into reset mode
+ // 2. we clear the RX error counter and set the TX error counter
+ // to 127
+ // 3. we clear the reset mode
+ // This ensures, that this ISR does not fire again and again and
+ // blocks the application while the bus off condition is active.
+ // Setting the TX error counter to 127 ensures that the controller
+ // is in TX error passive mode and that it does not flood the CAN
+ // bus with error messages. This makes it possible for the
+ // controller to properly recover from a bus off condition
+ //
+ lpc2xxx_reset_error_counters(info, 0, 127);
+#endif
+ }
+
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ //
+ // LUT error interrupt -- this bit is set if bit 0 in LUTerr is 1 and LUTerrAd
+ // points to entry in filter table for this CAN controller
+ //
+ if(event & ICR_LUT_ERR)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_FILTER_ERR;
+ LPC2XXX_DBG_PRINT("ICR_LUT_ERR (%p)\n", (void*) chan);
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+
+ } // if (event & (CAN_MISC_INT | ICR_LUT_ERR))
+
+ return res;
+}
+
+
+//===========================================================================
+// Kick transmitter
+//===========================================================================
+static void lpc2xxx_can_start_xmit(can_channel* chan)
+{
+ cyg_uint32 regval;
+ CAN_DECLARE_INFO(chan);
+
+ LPC2XXX_DBG_PRINT("start_xmit (%p)\n", (void*) chan);
+
+ cyg_drv_dsr_lock();
+ HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
+ regval |= IER_TX1; // enable tx interrupt for tx buf 1
+ HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval);
+ cyg_drv_dsr_unlock();
+
+ //
+ // kick transmitter
+ //
+ chan->callbacks->xmt_msg(chan, 0); // Kick transmitter (if necessary)
+}
+
+
+//===========================================================================
+// Stop transmitter
+//===========================================================================
+static void lpc2xxx_can_stop_xmit(can_channel* chan)
+{
+ cyg_uint32 regval;
+ CAN_DECLARE_INFO(chan);
+
+ LPC2XXX_DBG_PRINT("stop_xmit (%p)\n", (void*) chan);
+
+ cyg_drv_dsr_lock();
+ HAL_READ_UINT32(CAN_CTRL_IER(info), regval);
+ regval &= ~IER_TX1; // disable tx interrupt for tx buf 1
+ HAL_WRITE_UINT32(CAN_CTRL_IER(info), regval);
+ cyg_drv_dsr_unlock();
+}
+
+
+#ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+//===========================================================================
+// Low level transmit interrupt handler
+//===========================================================================
+static cyg_uint32 lpc2xxx_can_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ //
+ // Now read input capture register - this clears all interrupt bits in this
+ // register and also acknowledges the interrupt - any further processing is done
+ // by the DSR
+ //
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+ LPC2XXX_DBG_PRINT("tx_ISR (%p)\n", (void*) data);
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// High level transmit interrupt handler
+//===========================================================================
+static void lpc2xxx_can_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ cyg_uint32 regval;
+ CAN_DECLARE_INFO(chan);
+
+ //
+ // First read the ICR register to acknowledge all interrupts and
+ // get all captured interrupts
+ //
+ HAL_READ_UINT32(CAN_CTRL_ICR(info), regval);
+
+ //
+ // If TX events are supported then only call the rcv_event() callback
+ // if any other event occurred - pass the event field to the getevent function
+ // to indicate the events
+ //
+#ifndef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ if (regval & ~ICR_TX1)
+#endif
+ {
+ chan->callbacks->rcv_event(chan, &regval);
+ }
+
+ //
+ // Now transmit next message and reenable interrupts
+ //
+ chan->callbacks->xmt_msg(chan, 0); // send next message
+ LPC2XXX_DBG_PRINT("tx_DSR (%p)\n", (void*) data);
+ cyg_drv_interrupt_unmask(vector);
+}
+
+
+//===========================================================================
+// Low level receive interrupt handler
+//===========================================================================
+static cyg_uint32 lpc2xxx_can_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_USE_SELF_RECEPTION
+ cyg_uint32 regval;
+ can_channel* chan = (can_channel*)data;
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *) chan->dev_priv;
+ cyg_uint32 id;
+ cyg_uint32 index;
+
+ // We have to reject self tx message, so read message id
+ HAL_READ_UINT32(CAN_CTRL_RID(info), id);
+ HAL_READ_UINT32(CAN_CTRL_RFS(info), regval);
+ id |= (regval & LPC2XXX_CAN_INFO_LAST_TX_ID_FLMASK);
+
+ // Test message id
+ for(index = 0; index < 2; index++)
+ {
+ if(id == info->last_tx_id[index])
+ {
+ // Clear last_tx_id
+ info->last_tx_id[index] = LPC2XXX_CAN_INFO_LAST_TX_ID_NOVALID;
+
+ // Clear receive buffer
+ HAL_WRITE_UINT32(CAN_CTRL_CMR(info), CMR_RX_RELEASE_BUF);
+
+ // Acknowledge a vector
+ cyg_drv_interrupt_acknowledge(vector);
+
+ // Exit without calling DSR
+ LPC2XXX_DBG_PRINT("self_rx_ISR (%p)\n", (void*) data);
+ return CYG_ISR_HANDLED;
+ }
+ }
+#endif
+
+ //
+ // The ISR only disables and acknowledges the RX interrupt
+ // any further processing is done by DSR. We also need to mask the
+ // global CAN status interrupt here because the interrupt flag
+ // in ICR is not cleared yet and may still cause a status
+ // interrupt
+ //
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+ LPC2XXX_DBG_PRINT("rx_ISR (%p)\n", (void*) data);
+
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// High level receive interrupt handler
+//===========================================================================
+static void lpc2xxx_can_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ cyg_uint32 icr = ICR_RX;
+
+ //
+ // Read the event, the receive buffer will be released by the
+ // get_event() function
+ //
+ chan->callbacks->rcv_event(chan, &icr);
+ LPC2XXX_DBG_PRINT("rx_DSR (%p)\n", (void*) data);
+ cyg_drv_interrupt_unmask(vector);
+}
+
+
+
+//===========================================================================
+// status ISR handler
+//===========================================================================
+static cyg_uint32 lpc2xxx_can_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ //
+ // Acknowledge and disable the interrupt - any further processing is
+ // done by the DSR
+ //
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+ LPC2XXX_DBG_PRINT("err_ISR\n");
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// status ISR handler
+//===========================================================================
+static void lpc2xxx_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ // If we use acceptance filter we can get LUT error
+ cyg_uint32 luterr;
+ cyg_uint8 luterr_chan0 = 0; // Init to avoid warnings
+ cyg_uint8 luterr_chan1 = 0; // Init to avoid warnings
+
+ // Read LUT error flag
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR, luterr);
+
+ if (luterr & 1)
+ {
+ cyg_uint32 lutaddr;
+ cyg_uint32 eff_sa;
+ lsc_buf_t errentry;
+
+ // Read address of failed entry (it clears interrupt flag)
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR_ADDR, lutaddr);
+
+ // Read address of extended id individual table
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+
+ // Read error entry
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + lutaddr, errentry.dword);
+
+ // If err entry from standard id tables then read two
+ // controllers numbers
+ if(lutaddr < eff_sa)
+ {
+ // Calc CAN controllers numbers
+ luterr_chan0 = (cyg_uint8) ACCFILT_STD_GET_CTRL_UPPER(errentry.dword);
+
+ if(errentry.column.lower & ACCFILT_STD_DIS)
+ {
+ luterr_chan1 = luterr_chan0;
+ }
+ else
+ {
+ luterr_chan1 = (cyg_uint8) ACCFILT_STD_GET_CTRL_LOWER(errentry.dword);
+ }
+ }
+ else
+ {
+ // Calc CAN controller number
+ luterr_chan0 = luterr_chan1 = (cyg_uint8) ACCFILT_EXT_GET_CTRL(errentry.dword);
+ }
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+
+ //
+ // Loop through all channels - we need to do this only if we have more
+ // than one channel so we can optimize here for single channel
+ //
+ cyg_uint8 i = 0;
+#if CYGINT_IO_CAN_CHANNELS > 1
+ while (lpc2xxx_global_can_info.active_channels[i])
+#endif
+ {
+ cyg_uint32 regval;
+ can_channel *chan = LPC2XXX_GET_CAN_CHANNEL(lpc2xxx_global_can_info, i++);
+ CAN_DECLARE_INFO(chan);
+
+ HAL_READ_UINT32(CAN_CTRL_ICR(info), regval);
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ // Set ICR_LUT_ERR flag only for controller which cause LUT error
+ if ((luterr & 1) && ((luterr_chan0 == i) || (luterr_chan1 == i)))
+ {
+ regval |= ICR_LUT_ERR;
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ regval &= CAN_MISC_INT; // don't care about RX and TX events here
+ if (regval)
+ {
+ chan->callbacks->rcv_event(chan, &regval);
+ }
+ } // while (lpc2xxx_global_can_info.active_channels[i])
+
+ LPC2XXX_DBG_PRINT("err_DSR\n");
+ cyg_drv_interrupt_unmask(vector);
+}
+#else // #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+
+
+//===========================================================================
+// Global CAN interrupt handler
+//===========================================================================
+static cyg_uint32 lpc2xxx_can_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ //
+ // Disable interrupts, the DSR will enable it as soon as it processed
+ // the current interrupt
+ //
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+ LPC2XXX_DBG_PRINT("CAN_ISR\n");
+ return CYG_ISR_CALL_DSR;
+}
+
+//===========================================================================
+// Global CAN DSR
+//===========================================================================
+static void lpc2xxx_can_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ // If we use acceptance filter we can get LUT error
+ cyg_uint32 luterr;
+ cyg_uint8 luterr_chan0 = 0xFF; // Init to avoid warnings
+ cyg_uint8 luterr_chan1 = 0xFF; // Init to avoid warnings
+
+ // Read LUT error flag
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR, luterr);
+
+ if (luterr & 1)
+ {
+ cyg_uint32 lutaddr;
+ cyg_uint32 eff_sa;
+ lsc_buf_t errentry;
+
+ // Read address of failed entry (it clears interrupt flag)
+ HAL_READ_UINT32(CAN_ACCFILT_LUT_ERR_ADDR, lutaddr);
+
+ // Read address of extended id individual table
+ HAL_READ_UINT32(CAN_ACCFILT_EFF_SA, eff_sa);
+
+ // Read error entry
+ HAL_READ_UINT32(CAN_ACCFILT_RAM_BASE + lutaddr, errentry.dword);
+
+ // If errentry from standard id tables then read two controllers numbers
+ if(lutaddr < eff_sa)
+ {
+ // Calc CAN controllers numbers
+ luterr_chan0 = (cyg_uint8) ACCFILT_STD_GET_CTRL_UPPER(errentry.dword);
+
+ if(errentry.column.lower & ACCFILT_STD_DIS)
+ {
+ luterr_chan1 = luterr_chan0;
+ }
+ else
+ {
+ luterr_chan1 = (cyg_uint8) ACCFILT_STD_GET_CTRL_LOWER(errentry.dword);
+ }
+ }
+ else
+ {
+ // Calc CAN controller number
+ luterr_chan0 = luterr_chan1 = (cyg_uint8) ACCFILT_EXT_GET_CTRL(errentry.dword);
+ }
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+
+ //
+ // Walk through list of active CAN channels and process interrupts
+ // of all channels - we need to loop only if we have more than one CAN channel so
+ // we can optimize for single CAN channel here
+ //
+#if CYGINT_IO_CAN_CHANNELS > 1
+ cyg_uint8 i = 0;
+ while (lpc2xxx_global_can_info.active_channels[i])
+#endif // CYGINT_IO_CAN_CHANNELS > 1
+ {
+ cyg_uint32 icr;
+ can_channel *chan = LPC2XXX_GET_CAN_CHANNEL(lpc2xxx_global_can_info, i++);
+ CAN_DECLARE_INFO(chan);
+
+ HAL_READ_UINT32(CAN_CTRL_ICR(info), icr); // this read clears ICR
+#ifdef CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ // Set ICR_LUT_ERR flag only for controller which cause LUT error
+ if ((luterr_chan0 == i) || (luterr_chan1 == i))
+ {
+ icr |= ICR_LUT_ERR;
+ }
+#endif // CYGOPT_DEVS_CAN_LPC2XXX_LUT_ERR_SUPP
+ //
+ // If TX events are supported then we simply call the rcv_event()
+ // callback to store the event. If TX events are not supported then
+ // we only call the rcv_event() function if any other interrupt than
+ // the TX interrupt was captured
+ //
+#ifndef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ if (icr & ~ICR_TX1)
+#endif // CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ {
+ chan->callbacks->rcv_event(chan, &icr);
+ }
+ //
+ // If this was an TX interrupt then transmit next message now
+ //
+ if (icr & ICR_TX1)
+ {
+ chan->callbacks->xmt_msg(chan, 0); // send next message
+ }
+ } // while (lpc2xxx_global_can_info.active_channels[i])
+ LPC2XXX_DBG_PRINT("CAN_DSR\n");
+ cyg_drv_interrupt_unmask(vector);
+}
+#endif // #ifndef CYGNUM_DEVS_CAN_LPC2XXX_INT_PRIORITY
+
+
+#ifdef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Configure message boxes for reception of any CAN message
+//===========================================================================
+static void lpc2xxx_can_config_rx_all(can_channel *chan)
+{
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+ //
+ // First clear all acceptance filter entries and then insert the
+ // two RX all groups
+ //
+ lpc2xxx_can_config_rx_none(chan);
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ lpc2xxx_can_accfilt_add(info, 0x000, 0x7FF, CYGNUM_CAN_ID_STD);
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ lpc2xxx_can_accfilt_add(info, 0x000, 0x1FFFFFFF, CYGNUM_CAN_ID_EXT);
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+
+ info->flags |= INFO_FLAG_RX_ALL;
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif // CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+#ifndef CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+//===========================================================================
+// Configure message boxes for reception of any CAN message
+//===========================================================================
+static void lpc2xxx_can_config_rx_all(can_channel *chan)
+{
+ lpc2xxx_can_info_t *info = (lpc2xxx_can_info_t *)chan->dev_priv;
+
+ lpc2xxx_can_accfilt_simple_rx_all();
+ info->flags |= INFO_FLAG_RX_ALL;
+
+#ifdef CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+ lpc2xxx_can_accfilt_dbg_dump();
+#endif // CYGDBG_DEVS_CAN_LPC2XXX_DEBUG
+}
+#endif // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+
+
+//---------------------------------------------------------------------------
+// EOF can_lpc2xxx.c
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_baudrates.c b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_baudrates.c
new file mode 100644
index 0000000..fe81ac5
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_baudrates.c
@@ -0,0 +1,230 @@
+//==========================================================================
+//
+// can_baudrates.c
+//
+// CAN test of all supported baudrates
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-06-26
+// Description: CAN LPC2xxx baudrate test
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN;
+
+
+//
+// The table of baudrates to test
+//
+static cyg_can_baud_rate_t baudrate_tbl[9] =
+{
+ CYGNUM_CAN_KBAUD_10,
+ CYGNUM_CAN_KBAUD_20,
+ CYGNUM_CAN_KBAUD_50,
+ CYGNUM_CAN_KBAUD_100,
+ CYGNUM_CAN_KBAUD_125,
+ CYGNUM_CAN_KBAUD_250,
+ CYGNUM_CAN_KBAUD_500,
+ CYGNUM_CAN_KBAUD_800,
+ CYGNUM_CAN_KBAUD_1000,
+};
+
+//
+// String table forprinting supported baudrates
+//
+static char* baudrate_strings_tbl[9] =
+{
+ "10",
+ "20",
+ "50",
+ "100",
+ "125",
+ "250",
+ "500",
+ "800",
+ "1000",
+};
+
+
+//===========================================================================
+// Thread 0
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event;
+ cyg_uint32 i;
+ cyg_can_info_t can_info;
+
+ diag_printf("\n\nWhen the LPC2xxx driver selects a new baudrate then you need\n"
+ "to setup your hardware to the new baudrate and send one CAN\n"
+ "single CAN standard message.\n");
+ //
+ // Test all supported baudrates
+ //
+ for (i = 0; i < 9; ++i)
+ {
+ diag_printf("\n\nBaudrate: %s Kbaud\n", baudrate_strings_tbl[i]);
+ can_info.baud = baudrate_tbl[i];
+ len = sizeof(can_info);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_CAN_INFO, &can_info, &len))
+ {
+ diag_printf("not supported\n");
+ continue;
+ }
+ else
+ {
+ diag_printf("waiting for CAN message...\n");
+ }
+
+ len = sizeof(rx_event);
+ //
+ // First receive CAN event from real CAN hardware
+ //
+ len = sizeof(rx_event);
+ if (ENOERR != cyg_io_read(hCAN, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from channel 0");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "RX chan 1:");
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+ CYG_TEST_FAIL_FINISH("Rx message expected");
+ }
+ } // for (i = 0; i < 9; ++i)
+
+ CYG_TEST_PASS_FINISH("CAN baudrate test OK");
+}
+
+
+//===========================================================================
+// Entry point
+//===========================================================================
+void cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver channel 1
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME, &hCAN))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 0");
+ }
+
+ //
+ // create the main thread
+ //
+ cyg_thread_create(5, can0_thread,
+ (cyg_addrword_t) 0,
+ "can_tx_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_busload.c
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_busload.c b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_busload.c
new file mode 100644
index 0000000..33a9082
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_busload.c
@@ -0,0 +1,252 @@
+//==========================================================================
+//
+// can_busload.c
+//
+// CAN bus load test
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-06-26
+// Description: CAN bus load test
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// We need two CAN channels
+#if defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN0) && defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN1)
+
+
+// The same baud rates are required because we send from one channel to the other one
+#if CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD == CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD
+
+
+// We need a large RX buffer
+#ifdef CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_RX_1024
+
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN_Tbl[2];
+
+
+//===========================================================================
+// Thread 0
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_message tx_msg;
+ cyg_can_event rx_event;
+ cyg_uint32 i;
+ cyg_uint32 rx_msg_cnt = 0;
+
+
+ //
+ // Prepeare message - we use a data length of 0 bytes here. Each received message
+ // causes an iterrupt. The shortest message is a 0 data byte message. This will generate
+ // the highest interrupt rate
+ //
+ CYG_CAN_MSG_SET_PARAM(tx_msg, 0, CYGNUM_CAN_ID_STD, 0, CYGNUM_CAN_FRAME_DATA);
+
+ //
+ // Now send 1024 CAN messages as fast as possible to stress the receiver of CAN
+ // channel 1
+ //
+ for (i = 0; i< 1024; ++i)
+ {
+ tx_msg.id = i;
+ len = sizeof(tx_msg);
+ if (ENOERR != cyg_io_write(hCAN_Tbl[1], &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to channel 0");
+ }
+ }
+
+ //
+ // Now try to receive all 1024 CAN messages. If all messages are received
+ // and no overrun occured then the message processing is fast enought
+ //
+ while (1)
+ {
+ len = sizeof(rx_event);
+ //
+ // First receive CAN event from real CAN hardware
+ //
+ len = sizeof(rx_event);
+ if (ENOERR != cyg_io_read(hCAN_Tbl[0], &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from channel 1");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "RX chan 1:");
+ rx_msg_cnt++;
+ if (rx_msg_cnt == 1024)
+ {
+ CYG_TEST_PASS_FINISH("CAN load test OK");
+ }
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+ if (rx_event.flags & CYGNUM_CAN_EVENT_OVERRUN_RX)
+ {
+ CYG_TEST_FAIL_FINISH("RX overrun for channel 1");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_ERR_PASSIVE)
+ {
+ CYG_TEST_FAIL_FINISH("Channel 1 error passive event");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_BUS_OFF)
+ {
+ CYG_TEST_FAIL_FINISH("Channel 1 bus off event");
+ }
+ }
+ } // while (1)
+}
+
+
+//===========================================================================
+// Entry point
+//===========================================================================
+void cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver channel 1
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME, &hCAN_Tbl[0]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 0");
+ }
+
+
+ //
+ // open CAN device driver channel 2
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME, &hCAN_Tbl[1]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 1");
+ }
+
+ //
+ // create the main thread
+ //
+ cyg_thread_create(5, can0_thread,
+ (cyg_addrword_t) 0,
+ "can_tx_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+#else // CYGNUM_DEVS_CAN_LPC2XXX_CAN0_QUEUESIZE_RX_1024
+#define N_A_MSG "Channel 0 needs RX buffer size for 1024 events"
+#endif
+
+#else // CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD == CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD
+#define N_A_MSG "Baudrate of channel 0 and 1 need to be equal"
+#endif
+
+#else // defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN0) && defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN1)
+#define N_A_MSG "Needs support for CAN channel 1 and 2"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_busload.c
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_extended_cfg.c b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_extended_cfg.c
new file mode 100644
index 0000000..8e2f336
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_extended_cfg.c
@@ -0,0 +1,251 @@
+//==========================================================================
+//
+// can_extended_cfg.c
+//
+// Test of extended CAN configuration keys for LPC2xxx CAN driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2006-06-20
+// Description: LPC2xxx CAN extended configuration test
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_RUNTIME_MBOX_CFG)
+#include "can_test_aux.inl"
+
+#if defined(CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS)
+#include <cyg/io/can_lpc2xxx.h>
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN0;
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event;
+ cyg_can_filtergroup_cfg acc_filt_grp;
+ cyg_can_msgbuf_cfg msgbox_cfg;
+
+ //
+ // First we reset message buffer configuration - this is mandatory bevore starting
+ // message buffer runtime configuration. This call clears/frees all message buffers
+ // The CAN controller cannot receive any further CAN message after this call
+ //
+ msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+ len = sizeof(msgbox_cfg);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&msgbox_cfg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error resetting message buffer configuration of /dev/can0");
+ }
+
+ //
+ // Now we setup two different acceptance filter groups. Acceptance filter
+ // groups are not part of the CAN I/O layer and are a LPC2xxx specific
+ // feature. You should not use appcetance filter groups if you would like
+ // to code portable eCos CAN applications
+ //
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ acc_filt_grp.ext = CYGNUM_CAN_ID_STD;
+ acc_filt_grp.lower_id_bound = 0x100;
+ acc_filt_grp.upper_id_bound = 0x110;
+ len = sizeof(acc_filt_grp);
+
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP ,&acc_filt_grp, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error adding filter group to /dev/can0");
+ }
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ acc_filt_grp.ext = CYGNUM_CAN_ID_EXT;
+ acc_filt_grp.lower_id_bound = 0x2000;
+ acc_filt_grp.upper_id_bound = 0x2200;
+ len = sizeof(acc_filt_grp);
+
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_LPC2XXX_ACCFILT_GROUP ,&acc_filt_grp, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error adding filter group to /dev/can0");
+ }
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+ diag_printf("\n\nNow try to send CAN messages. The device should only\n"
+ "receive standard messages identifiers in the range of 0x100\n"
+ "to 0x110 and/or extended identifiers in the range 0x2000 to\n"
+ "0x2200. As soon as a standard message with ID 0x110 or an\n"
+ "extended message with ID 0x2200 arrives, the test finishes\n\n");
+
+ while (1)
+ {
+ len = sizeof(rx_event);
+
+ if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "");
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ if (rx_event.msg.id == 0x110)
+ {
+ CYG_TEST_PASS_FINISH("LPC2xxx CAN message filter group test OK");
+ }
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (rx_event.msg.id == 0x2200)
+ {
+ CYG_TEST_PASS_FINISH("LPC2xxx CAN message filter group test OK");
+ }
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+
+ if (((rx_event.msg.id > 0x110) && (rx_event.msg.id < 0x2000))
+ || (rx_event.msg.id > 0x2200))
+ {
+ CYG_TEST_FAIL_FINISH("Received CAN identifier outside filter group bounds");
+ }
+ }
+ }
+ } // while (1)
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ //
+ // create the thread that accesses the CAN device driver
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGOPT_DEVS_CAN_LPC2XXX_EXTENDED_CFG_KEYS
+#define N_A_MSG "Needs support for extended LPC2xxx CAN configuration keys"
+#endif
+
+#else // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
+#define N_A_MSG "Needs CAN message box runtime confuguration support"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF flexcan_remote.c
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_multichan_rx.c b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_multichan_rx.c
new file mode 100644
index 0000000..0537245
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_multichan_rx.c
@@ -0,0 +1,338 @@
+//==========================================================================
+//
+// can_multichan_rx.c
+//
+// CAN RX test for multiple CAN channels
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-06-26
+// Description: CAN RX test for multiple CAN controller channels
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_SUPPORT_NONBLOCKING)
+
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN_Tbl[4];
+
+
+//===========================================================================
+// Setup acceptance filter
+//===========================================================================
+void can_setup_channel(cyg_io_handle_t hCAN, unsigned char Channel)
+{
+ cyg_uint32 len;
+ cyg_can_msgbuf_cfg msgbox_cfg;
+ cyg_uint8 i;
+ cyg_uint32 blocking;
+
+ //
+ // First we reset message buffer configuration - this is mandatory bevore starting
+ // message buffer runtime configuration. This call clears/frees all message buffers
+ // The CAN controller cannot receive any further CAN message after this call
+ //
+ msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+ len = sizeof(msgbox_cfg);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&msgbox_cfg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error resetting message buffer configuration of /dev/can0");
+ }
+
+ //
+ // Now setup 10 message filters for this channel
+ //
+ for (i = 0; i < 10; ++i)
+ {
+ cyg_can_filter rx_filter;
+
+ rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD;
+ rx_filter.msg.id = Channel * 0x100 + i;
+ rx_filter.msg.ext = CYGNUM_CAN_ID_STD;
+
+ len = sizeof(rx_filter);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config");
+ }
+ else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle)
+ {
+ CYG_TEST_FAIL_FINISH("Error setting up message filter");
+ }
+ }
+
+ //
+ // Now set driver into nonblocking mode because the receiver thread will
+ // receive the messages from all channels
+ //
+ blocking = 0;
+ len = sizeof(blocking);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_READ_BLOCKING ,&blocking, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error setting channel into nonblocking mode");
+ }
+
+ //
+ // If timeouts are supported we need to setup a timeout value of 0 because
+ // the driver should return immediatelly if no message is available
+ //
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMEOUTS
+ cyg_can_timeout_info_t timeouts;
+
+ timeouts.rx_timeout = 0;
+ timeouts.tx_timeout = 0;
+ len = sizeof(timeouts);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_CAN_TIMEOUT ,&timeouts, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error setting timeout for channel");
+ }
+#endif
+}
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_uint8 i = 0;
+
+ //
+ // Check that all cannels have the same baudrate
+ //
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+ can_setup_channel(hCAN_Tbl[0], 0);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+ can_setup_channel(hCAN_Tbl[1], 1);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+ can_setup_channel(hCAN_Tbl[2], 2);
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+ can_setup_channel(hCAN_Tbl[3], 3);
+#endif
+
+ diag_printf("\n\nThis test uses all available CAN channels for reception\n"
+ "of CAN standard messages. The following messages will be received:\n\n");
+
+ for (i = 0; i < 4; ++i)
+ {
+ if (hCAN_Tbl[i])
+ {
+ diag_printf("CAN channel %d: msg: 0x%03x - 0x%03x\n", i, i * 0x100, i * 0x100 + 9);
+ }
+ }
+
+ diag_printf("\n\nYou can stop this test by sending a message with ID 0xX09\n");
+
+ while (1)
+ {
+ for (i = 0; i < 4; ++i)
+ {
+ if (hCAN_Tbl[i])
+ {
+ Cyg_ErrNo ret;
+ cyg_can_event rx_event;
+
+ len = sizeof(rx_event);
+ ret = cyg_io_read(hCAN_Tbl[i], &rx_event, &len);
+ if ((ret == -EAGAIN) || (ret == -EINTR))
+ {
+ continue;
+ }
+
+ if (ENOERR != ret)
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from channel");
+ }
+ else
+ {
+ diag_printf("Channel %d events: ", i);
+ print_can_flags(rx_event.flags, "");
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "");
+ if ((rx_event.msg.id & 9) == 9)
+ {
+ CYG_TEST_PASS_FINISH("LPC2xxx CAN multi channel RX test OK");
+ }
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ }
+ } // if (hCAN_Tbl[i])
+ } // for (i = 0; i < 4; ++i)
+ } // while (1)
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME, &hCAN_Tbl[0]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 0");
+ }
+#else
+ hCAN_Tbl[0] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME, &hCAN_Tbl[1]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 1");
+ }
+#else
+ hCAN_Tbl[1] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN2_NAME, &hCAN_Tbl[2]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 2");
+ }
+#else
+ hCAN_Tbl[2] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN3_NAME, &hCAN_Tbl[3]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 3");
+ }
+#else
+ hCAN_Tbl[3] = 0;
+#endif
+
+ //
+ // create the thread that accesses the CAN device driver
+ //
+ cyg_thread_create(4, can_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+#else // CYGOPT_IO_CAN_SUPPORT_NONBLOCKING
+#define N_A_MSG "Needs support for nonblocking calls"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_multichan_rx.c
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_multichan_tx.c b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_multichan_tx.c
new file mode 100644
index 0000000..a9daa4b
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_multichan_tx.c
@@ -0,0 +1,291 @@
+//==========================================================================
+//
+// can_multichan_tx.c
+//
+// CAN TX test for multiple CAN channels
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-06-26
+// Description: CAN TX test for multiple CAN controller channels
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can_thread;
+thread_data_t can0_thread_data;
+cyg_io_handle_t hCAN_Tbl[4];
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_message tx_msg;
+ cyg_can_info_t can_info;
+ cyg_can_baud_rate_t baud;
+ cyg_uint8 i = 0;
+ cyg_uint8 j = 0;
+
+ //
+ // Check that all cannels have the same baudrate
+ //
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+ len = sizeof(can_info);
+ if (ENOERR != cyg_io_get_config(hCAN_Tbl[0], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 0");
+ }
+ else
+ {
+ baud = can_info.baud;
+ ++i;
+ }
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+ len = sizeof(can_info);
+ if (ENOERR != cyg_io_get_config(hCAN_Tbl[1], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 1");
+ }
+ else
+ {
+ if (i && (baud != can_info.baud))
+ {
+ CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 0 and 1");
+ }
+ baud = can_info.baud;
+ ++i;
+ }
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+ len = sizeof(can_info);
+ if (ENOERR != cyg_io_get_config(hCAN_Tbl[2], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 2");
+ }
+ else
+ {
+ if (i && (baud != can_info.baud))
+ {
+ CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 1 and 2");
+ }
+ baud = can_info.baud;
+ ++i;
+ }
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+ len = sizeof(can_info);
+ if (ENOERR != cyg_io_get_config(hCAN_Tbl[3], CYG_IO_GET_CONFIG_CAN_INFO, &can_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading baudrate of CAN channel 3");
+ }
+ else
+ {
+ if (i && (baud != can_info.baud))
+ {
+ CYG_TEST_FAIL_FINISH("Error - different baudrates for CAN channel 2 and 3");
+ }
+ baud = can_info.baud;
+ ++i;
+ }
+#endif
+
+ diag_printf("\n\nYou should no receive 4 CAN messages from each active CAN channel\n");
+
+ //
+ // Now each CAN channel sends 10 CAN messages
+ //
+ for (i = 0; i < 4; ++i)
+ {
+ if (hCAN_Tbl[i])
+ {
+ CYG_CAN_MSG_SET_PARAM(tx_msg, i * 0x100, CYGNUM_CAN_ID_STD, 4, CYGNUM_CAN_FRAME_DATA);
+ tx_msg.data.dwords[0] = 0;
+ tx_msg.data.dwords[1] = 0;
+ char err_msg[64];
+ diag_snprintf(err_msg, sizeof(err_msg), "Error sending TX using CAN channel %d", i);
+ for (j = 0; j < 4; ++j)
+ {
+ tx_msg.id = i * 0x100 + j;
+ tx_msg.data.bytes[0] = j;
+ len = sizeof(tx_msg);
+ if (ENOERR != cyg_io_write(hCAN_Tbl[i], &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH(err_msg);
+ }
+ }
+ } // if (hCAN_Tbl[i])
+ } // for (i = 0; i < 4; ++i)
+
+ CYG_TEST_PASS_FINISH("LPC2xxx CAN multi channel TX test OK");
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN0
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME, &hCAN_Tbl[0]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 0");
+ }
+#else
+ hCAN_Tbl[0] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN1
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME, &hCAN_Tbl[1]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 1");
+ }
+#else
+ hCAN_Tbl[1] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN2
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN2_NAME, &hCAN_Tbl[2]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 2");
+ }
+#else
+ hCAN_Tbl[2] = 0;
+#endif
+
+#ifdef CYGPKG_DEVS_CAN_LPC2XXX_CAN3
+ //
+ // open CAN device driver
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN3_NAME, &hCAN_Tbl[3]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 3");
+ }
+#else
+ hCAN_Tbl[3] = 0;
+#endif
+
+ //
+ // create the thread that accesses the CAN device driver
+ //
+ cyg_thread_create(4, can_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_multichan_tx.c
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_rx_tx.c b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_rx_tx.c
new file mode 100644
index 0000000..f2f5856
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_rx_tx.c
@@ -0,0 +1,348 @@
+//==========================================================================
+//
+// can_rx_tx.c
+//
+// CAN RX / TX test
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2007-06-26
+// Description: CAN RX/TX test for 2 CAN channels
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// We need two CAN channels
+#if defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN0) && defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN1)
+
+
+// The same baud rates are required because we send from one channel to the other one
+#if CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD == CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD
+
+
+// We need the loop can driver
+#if defined(CYGPKG_DEVS_CAN_LOOP)
+#include <pkgconf/devs_can_loop.h>
+
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can_tx_thread;
+thread_data_t can0_thread_data;
+cyg_thread_entry_t can_rx_thread;
+thread_data_t can1_thread_data;
+cyg_io_handle_t hCAN_Tbl[2];
+cyg_io_handle_t hLoopCAN_Tbl[2];
+
+
+//===========================================================================
+// Thread 0
+//===========================================================================
+void can_rx_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event;
+ cyg_can_event loop_rx_event;
+ cyg_uint32 msg_cnt = 0;
+ cyg_uint8 i;
+
+ while (msg_cnt < 0xF0)
+ {
+
+ //
+ // First receive CAN event from real CAN hardware
+ //
+ len = sizeof(rx_event);
+ if (ENOERR != cyg_io_read(hCAN_Tbl[1], &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from channel 1");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "RX chan 1:");
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+ }
+
+ //
+ // Now receive CAN event from loop CAN driver
+ //
+ len = sizeof(loop_rx_event);
+ if (ENOERR != cyg_io_read(hLoopCAN_Tbl[1], &loop_rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from loop channel 1");
+ }
+
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "RX loop 1:");
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ else
+ {
+ print_can_flags(rx_event.flags, "");
+ }
+
+ //
+ // Chaeck message ID and DLC of HW CAN message and CAN message from loop driver
+ // booth should be the same
+ //
+ if (rx_event.msg.id != loop_rx_event.msg.id)
+ {
+ CYG_TEST_FAIL_FINISH("Received message IDs of hw CAN channel and loop CAN channel are not equal");
+ }
+
+ if (rx_event.msg.dlc != loop_rx_event.msg.dlc)
+ {
+ CYG_TEST_FAIL_FINISH("Received DLCs of hw CAN msg and loop CAN msg are not equal");
+ }
+
+ //
+ // Now check each data byte of the receive message
+ //
+ for (i = 0; i < rx_event.msg.dlc; ++i)
+ {
+ if (rx_event.msg.data.bytes[i] != loop_rx_event.msg.data.bytes[i])
+ {
+ CYG_TEST_FAIL_FINISH("Data of hw CAN msg and loop CAN msg are not equal");
+ }
+
+ if (rx_event.msg.data.bytes[i] != (i + msg_cnt))
+ {
+ CYG_TEST_FAIL_FINISH("CAN message contains unexpected data");
+ }
+ }
+
+ msg_cnt++;
+ } // while (1)
+
+ CYG_TEST_PASS_FINISH("CAN rx/tx test OK");
+}
+
+
+//===========================================================================
+// Thread 1
+//===========================================================================
+void can_tx_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_message tx_msg;
+ cyg_uint32 msg_cnt = 0;
+ cyg_uint8 i;
+
+
+ CYG_CAN_MSG_SET_PARAM(tx_msg, 0, CYGNUM_CAN_ID_STD, 0, CYGNUM_CAN_FRAME_DATA);
+
+ //
+ // Prepare CAN message with a known CAN state
+ //
+ for (i = 0; i < 8; ++i)
+ {
+ tx_msg.data.bytes[i] = i;
+ }
+
+ while (msg_cnt < 0xF0)
+ {
+ tx_msg.id = msg_cnt;
+ len = sizeof(tx_msg);
+ if (ENOERR != cyg_io_write(hCAN_Tbl[0], &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to channel 0");
+ }
+
+
+ tx_msg.id = msg_cnt;
+ len = sizeof(tx_msg);
+ if (ENOERR != cyg_io_write(hLoopCAN_Tbl[0], &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to channel 1");
+ }
+
+ //
+ // Increment data in each single data byte
+ //
+ for (i = 0; i < 8; ++i)
+ {
+ tx_msg.data.bytes[i] += 1;
+ }
+
+ msg_cnt++;
+ tx_msg.dlc = (tx_msg.dlc + 1) % 9;
+ } // while (msg_cnt < 0x100)
+}
+
+
+//===========================================================================
+// Entry point
+//===========================================================================
+void cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open CAN device driver channel 1
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN0_NAME, &hCAN_Tbl[0]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 0");
+ }
+
+
+ //
+ // open CAN device driver channel 2
+ //
+ if (ENOERR != cyg_io_lookup(CYGPKG_DEVS_CAN_LPC2XXX_CAN1_NAME, &hCAN_Tbl[1]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening CAN channel 1");
+ }
+
+ //
+ // open Loop CAN device driver channel 1
+ //
+ if (ENOERR != cyg_io_lookup(CYGDAT_DEVS_CAN_LOOP_CAN0_NAME, &hLoopCAN_Tbl[0]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening loop CAN channel 0");
+ }
+
+
+ //
+ // open Loop CAN device driver channel 2
+ //
+ if (ENOERR != cyg_io_lookup(CYGDAT_DEVS_CAN_LOOP_CAN1_NAME, &hLoopCAN_Tbl[1]))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening loop CAN channel 1");
+ }
+
+
+
+
+
+ //
+ // create the first thread that access the CAN device driver
+ //
+ cyg_thread_create(5, can_tx_thread,
+ (cyg_addrword_t) 0,
+ "can_tx_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ //
+ // create the second thread that access the CAN device driver
+ //
+ cyg_thread_create(4, can_rx_thread,
+ (cyg_addrword_t) 0,
+ "can_rx_thread",
+ (void *) can1_thread_data.stack,
+ 1024 * sizeof(long),
+ &can1_thread_data.hdl,
+ &can1_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+ cyg_thread_resume(can1_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+#else // defined(CYGPKG_DEVS_CAN_LOOP)
+#define N_A_MSG "Needs support for loop CAN device driver"
+#endif
+
+#else // CYGNUM_DEVS_CAN_LPC2XXX_CAN0_KBAUD == CYGNUM_DEVS_CAN_LPC2XXX_CAN1_KBAUD
+#define N_A_MSG "Baudrate of channel 0 and 1 need to be equal"
+#endif
+
+#else // defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN0) && defined(CYGPKG_DEVS_CAN_LPC2XXX_CAN1)
+#define N_A_MSG "Needs support for CAN channel 1 and 2"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+//---------------------------------------------------------------------------
+// EOF can_rx_tx.c
diff --git a/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_test_aux.inl b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_test_aux.inl
new file mode 100644
index 0000000..2bb2e07
--- /dev/null
+++ b/ecos/packages/devs/can/arm/lpc2xxx/current/tests/can_test_aux.inl
@@ -0,0 +1,147 @@
+//==========================================================================
+//
+// can_test_aux.inl
+//
+// CAN test auxiliary functions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Auxiliary functions for CAN driver tests
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// PRINT CAN EVENT
+//===========================================================================
+void print_can_msg(cyg_can_message *pmsg, char *pMsg)
+{
+ char *pmsg_str;
+ static char* msg_tbl[] =
+ {
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X %02X]\n"
+ };
+
+ if (pmsg->rtr)
+ {
+ diag_printf("%s [ID:%03X] [RTR:%d] [EXT:%d] [DLC:%d]\n",
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->dlc);
+
+ return;
+ }
+
+ if (pmsg->dlc > 8)
+ {
+ pmsg_str = msg_tbl[8];
+ }
+ else
+ {
+ pmsg_str = msg_tbl[pmsg->dlc];
+ }
+
+ diag_printf(pmsg_str,
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->data.bytes[0],
+ pmsg->data.bytes[1],
+ pmsg->data.bytes[2],
+ pmsg->data.bytes[3],
+ pmsg->data.bytes[4],
+ pmsg->data.bytes[5],
+ pmsg->data.bytes[6],
+ pmsg->data.bytes[7]);
+}
+
+
+//===========================================================================
+// PRINT CAN EVENT FLAGS
+//===========================================================================
+void print_can_flags(cyg_uint16 flags, char *pMsg)
+{
+ char *pmsg_str;
+ cyg_uint8 i ;
+ static char* msg_tbl[] =
+ {
+ "RX ",
+ "TX ",
+ "WRX ",
+ "WTX ",
+ "ERRP ",
+ "BOFF ",
+ "OVRX ",
+ "OVTX ",
+ "CERR ",
+ "LSTY ",
+ "ESTY ",
+ "ALOS ",
+ "DEVC ",
+ "PHYF ",
+ "PHYH ",
+ "PHYL "
+ };
+ i = 0;
+ while (flags && (i < 16))
+ {
+ if (flags & 0x0001)
+ {
+ pmsg_str = msg_tbl[i];
+ diag_printf(pmsg_str);
+ }
+ flags >>=1;
+ i++;
+ }
+
+ diag_printf("\n");
+}
+
+//---------------------------------------------------------------------------
+// end of can_test_aux.inl
diff --git a/ecos/packages/devs/can/loop/current/ChangeLog b/ecos/packages/devs/can/loop/current/ChangeLog
new file mode 100644
index 0000000..da8347e
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/ChangeLog
@@ -0,0 +1,73 @@
+2007-08-28 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * tests/can_overrun1.c (can0_thread): Fix the length of the data
+ in the message. Add a delay to allow the CAN device to process
+ the packets.
+ * test/can_txcevent.c: (can0_thread): Add a delay to allow the CAN device
+ to process the packet.s
+ * src/loop_can.c (FIFO_SIZE): Changed to one more than the TX
+ queue size. If it is less, the loopback tests don't pass because
+ packets don't get transmitted.
+
+2007-08-24 Andrew Lunn <andrew.lunn>
+
+ * doc/synth_test.ecm: Import file for running the tests on synth.
+
+2007-08-24 Alexey Shusharin <mrfinch@mail.ru>
+
+ * tests/can_callback.c: Added test of CAN callback on event
+ * cdl/can_loop.cdl: Added can_callback.c into tests list
+
+2007-08-09 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/loop_can.c: Change all CYGPKG_IO_CAN_* to CYGPKG_DEVS_CAN_*
+ so that the loopback driver gets compiled. It looks like
+ at some point in its life it used to live in io/can instead
+ of its current location in dev/can/loop.
+
+2007-03-23 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/can_loop.cd: Changed naming of various options from
+ xxx_IO_CAN_LOOP into xxx_DEVS_CAN_LOOP
+
+2007-03-23 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/can_loop.cdl: Driver now implements the interfaces
+ CYGINT_IO_CAN_TX_EVENTS, CYGINT_IO_CAN_STD_CAN_ID,
+ CYGINT_IO_CAN_EXT_CAN_ID.
+ Removed CYGPKG_IO_CAN_LOOP_CFLAGS_ADD and
+ CYGPKG_IO_CAN_LOOP_CFLAGS_REMOVE because they had no function.
+
+ * src/loop_can.c: Added missing function loop_can_get_config
+ to make the driver build properly.
+
+ * tests: Did some fixes and cleanups for all test cases to make them
+ work properly with the changes in the CAN I/O layer.
+
+2005-08-15 Uwe Kindler <uwe_kindler@web.de>
+
+ * Loopback CAN driver created
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/can/loop/current/cdl/can_loop.cdl b/ecos/packages/devs/can/loop/current/cdl/can_loop.cdl
new file mode 100644
index 0000000..14cfad5
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/cdl/can_loop.cdl
@@ -0,0 +1,140 @@
+# ====================================================================
+#
+# can_loop.cdl
+#
+# eCos CAN LOOP configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Original data: gthomas
+# Contributors:
+# Date: 2005-07-11
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_CAN_LOOP {
+ display "Loop CAN device drivers"
+
+ parent CYGPKG_IO_CAN_DEVICES
+ active_if CYGPKG_IO_CAN
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+
+ description "
+ This package contains the loop CAN device driver."
+
+ compile -library=libextras.a loop_can.c
+
+ # Support up to two CAN loop device.
+ for { set ::loopcan 0 } { $::loopcan < 2 } { incr ::loopcan } {
+
+ cdl_component CYGPKG_DEVS_CAN_LOOP_CAN[set ::loopcan] {
+ display "LOOP CAN channel [set ::loopcan] driver"
+ flavor bool
+ default_value 0
+ implements CYGINT_IO_CAN_TIMESTAMP
+ implements CYGINT_IO_CAN_TX_EVENTS
+ implements CYGINT_IO_CAN_STD_CAN_ID
+ implements CYGINT_IO_CAN_EXT_CAN_ID
+ description "
+ This option includes the CAN loop device driver for channel [set ::loopcan]."
+
+ cdl_option CYGDAT_DEVS_CAN_LOOP_CAN[set ::loopcan]_NAME {
+ display "Device name for LOOP CAN channel [set ::loopcan]"
+ flavor data
+ default_value [format {"\"/dev/can%d\""} $::loopcan]
+ description "
+ This option specifies the device name for loop CAN channel [set ::loopcan]."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LOOP_CAN[set ::loopcan]_KBAUD {
+ display "Baud rate for the LOOP CAN channel [set ::loopcan] driver"
+ flavor data
+ default_value 100
+ legal_values { 10 20 50 100 125 250 500 800 1000 }
+ description "This option determines the initial baud rate in KBaud for
+ loop CAN channel [set ::loopcan]."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LOOP_CAN[set ::loopcan]_QUEUESIZE_TX {
+ display "Size of TX Queue for loop CAN channel [set ::loopcan]"
+ flavor data
+ default_value 32
+ legal_values 16 to 512
+ description "
+ The CAN device driver will run in interrupt mode and will
+ perform buffering of outgoing data. This option controls the number
+ of CAN messages the TX queue can store."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_LOOP_CAN[set ::loopcan]_QUEUESIZE_RX {
+ display "Size of RX Queue for the loop CAN channel [set ::loopcan]"
+ flavor data
+ default_value 32
+ legal_values 16 to 512
+ description "
+ The CAN device driver will run in interrupt mode and will
+ perform buffering of incoming data. This option controls the number
+ of CAN events the RX queue can store."
+ }
+ }
+ }
+
+
+ cdl_component CYGPKG_DEVS_CAN_LOOP_OPTIONS {
+ display "CAN device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVS_CAN_LOOP_TESTS {
+ display "CAN loop device driver tests"
+ flavor data
+ calculated { "tests/can_rdwr tests/can_timeout tests/can_txevent tests/can_overrun1 tests/can_overrun2 tests/can_nonblock tests/can_callback" }
+ description "
+ This option specifies the set of tests for the CAN loop device drivers."
+ }
+ }
+}
+
+# EOF can_loop.cdl
diff --git a/ecos/packages/devs/can/loop/current/doc/README b/ecos/packages/devs/can/loop/current/doc/README
new file mode 100644
index 0000000..78195b6
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/doc/README
@@ -0,0 +1,2 @@
+The file synth_test.ecm can be used to configure a synthetic target
+work tree to enable the various options to allow the tests to be run. \ No newline at end of file
diff --git a/ecos/packages/devs/can/loop/current/doc/synth_test.ecm b/ecos/packages/devs/can/loop/current/doc/synth_test.ecm
new file mode 100644
index 0000000..634924a
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/doc/synth_test.ecm
@@ -0,0 +1,66 @@
+cdl_savefile_version 1;
+cdl_savefile_command cdl_savefile_version {};
+cdl_savefile_command cdl_savefile_command {};
+cdl_savefile_command cdl_configuration { description hardware template package };
+cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value };
+cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value };
+
+cdl_configuration eCos {
+ description "" ;
+ hardware linux ;
+ template default ;
+ package -hardware CYGPKG_HAL_SYNTH current ;
+ package -hardware CYGPKG_HAL_SYNTH_I386 current ;
+ package -hardware CYGPKG_DEVS_FLASH_SYNTH current ;
+ package -hardware CYGPKG_DEVS_ETH_ECOSYNTH current ;
+ package -hardware CYGPKG_DEVS_WATCHDOG_SYNTH current ;
+ package -hardware CYGPKG_DEVS_WALLCLOCK_SYNTH current ;
+ package -template CYGPKG_HAL current ;
+ package -template CYGPKG_IO current ;
+ package -template CYGPKG_IO_SERIAL current ;
+ package -template CYGPKG_INFRA current ;
+ package -template CYGPKG_KERNEL current ;
+ package -template CYGPKG_MEMALLOC current ;
+ package -template CYGPKG_ISOINFRA current ;
+ package -template CYGPKG_LIBC current ;
+ package -template CYGPKG_LIBC_I18N current ;
+ package -template CYGPKG_LIBC_SETJMP current ;
+ package -template CYGPKG_LIBC_SIGNALS current ;
+ package -template CYGPKG_LIBC_STARTUP current ;
+ package -template CYGPKG_LIBC_STDIO current ;
+ package -template CYGPKG_LIBC_STDLIB current ;
+ package -template CYGPKG_LIBC_STRING current ;
+ package -template CYGPKG_LIBC_TIME current ;
+ package -template CYGPKG_LIBM current ;
+ package -template CYGPKG_IO_WALLCLOCK current ;
+ package -template CYGPKG_ERROR current ;
+ package CYGPKG_IO_CAN current ;
+ package CYGPKG_DEVS_CAN_LOOP current ;
+};
+
+cdl_component CYGPKG_DEVS_CAN_LOOP_CAN0 {
+ user_value 1
+};
+
+cdl_component CYGPKG_DEVS_CAN_LOOP_CAN1 {
+ user_value 1
+};
+
+cdl_option CYGOPT_IO_CAN_TX_EVENT_SUPPORT {
+ user_value 1
+};
+
+cdl_option CYGOPT_IO_CAN_SUPPORT_NONBLOCKING {
+ user_value 1
+};
+
+cdl_option CYGOPT_IO_CAN_SUPPORT_CALLBACK {
+ user_value 1
+};
+
+cdl_component CYGOPT_IO_CAN_SUPPORT_TIMEOUTS {
+ user_value 1
+};
+
diff --git a/ecos/packages/devs/can/loop/current/src/loop_can.c b/ecos/packages/devs/can/loop/current/src/loop_can.c
new file mode 100644
index 0000000..85e4a57
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/src/loop_can.c
@@ -0,0 +1,408 @@
+//==========================================================================
+//
+// loop_can.c
+//
+// Loopback CAN device driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-07-10
+// Purpose: Loopback CAN device driver
+// Description: This device driver implements a pair of CAN lines that are
+// connected back-to-back. Data output to one will appear as
+// input on the other. This process in part driven by an alarm
+// object which provides a degree of separation between the two
+// channels.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_can.h>
+#include <pkgconf/devs_can_loop.h>
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/can.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/kernel/kapi.h>
+
+#ifdef CYGPKG_DEVS_CAN_LOOP
+
+//-------------------------------------------------------------------------
+
+extern void diag_printf(const char *fmt, ...);
+
+//-------------------------------------------------------------------------
+// Forward definitions
+
+static bool loop_can_init(struct cyg_devtab_entry *devtab_entry);
+static bool loop_can_putmsg(can_channel *priv, cyg_can_message *pmsg, void *pdata);
+static Cyg_ErrNo loop_can_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static bool loop_can_getevent(can_channel *priv, cyg_can_event *pevent, void *pdata);
+static Cyg_ErrNo loop_can_set_config(can_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static Cyg_ErrNo loop_can_get_config(can_channel *chan, cyg_uint32 key,
+ const void* buf, cyg_uint32* len);
+static void loop_can_start_xmit(can_channel *chan);
+static void loop_can_stop_xmit(can_channel *chan);
+
+static void alarm_handler(cyg_handle_t alarm, cyg_addrword_t data);
+
+
+//-------------------------------------------------------------------------
+// Alarm object for feeding data back into CAN channels
+
+static cyg_alarm alarm_obj;
+
+static cyg_handle_t alarm_handle;
+
+//-------------------------------------------------------------------------
+// Transfer FIFOs
+
+#define FIFO_SIZE 33
+
+struct fifo
+{
+ cyg_bool tx_enable;
+ volatile int head;
+ volatile int tail;
+ volatile int num;
+ volatile cyg_can_event buf[FIFO_SIZE+1];
+};
+
+static struct fifo fifo0 = { false, 0, 0, 0 }; // from CAN0 to CAN1
+static struct fifo fifo1 = { false, 0, 0, 0 }; // from CAN1 to CAN0
+
+//-------------------------------------------------------------------------
+
+#define BUFSIZE 128
+
+//-------------------------------------------------------------------------
+// Info for each serial device controlled
+
+typedef struct loop_can_info {
+ struct fifo *write_fifo;
+ struct fifo *read_fifo;
+} loop_can_info;
+
+//-------------------------------------------------------------------------
+// Callback functions exported by this driver
+CAN_LOWLEVEL_FUNS(loop_can_lowlevel_funs,
+ loop_can_putmsg,
+ loop_can_getevent,
+ loop_can_get_config,
+ loop_can_set_config,
+ loop_can_start_xmit,
+ loop_can_stop_xmit
+ );
+
+//-------------------------------------------------------------------------
+// Hardware info for each serial line
+
+#ifdef CYGPKG_DEVS_CAN_LOOP_CAN0
+static loop_can_info loop_can_info0 = {
+ &fifo0,
+ &fifo1
+};
+
+static cyg_can_message loop_can_txbuf0[CYGNUM_DEVS_CAN_LOOP_CAN0_QUEUESIZE_TX];
+static cyg_can_event loop_can_rxbuf0[CYGNUM_DEVS_CAN_LOOP_CAN0_QUEUESIZE_RX];
+#endif // CYGPKG_IO_SERIAL_LOOP_SERIAL0
+
+#ifdef CYGPKG_DEVS_CAN_LOOP_CAN1
+static loop_can_info loop_can_info1 = {
+ &fifo1,
+ &fifo0
+};
+
+static cyg_can_message loop_can_txbuf1[CYGNUM_DEVS_CAN_LOOP_CAN1_QUEUESIZE_TX];
+static cyg_can_event loop_can_rxbuf1[CYGNUM_DEVS_CAN_LOOP_CAN1_QUEUESIZE_RX];
+#endif // CYGPKG_IO_SERIAL_LOOP_SERIAL1
+
+
+
+//-------------------------------------------------------------------------
+// Channel descriptions:
+//
+#ifdef CYGPKG_DEVS_CAN_LOOP_CAN0
+CAN_CHANNEL_USING_INTERRUPTS(loop_can0_chan,
+ loop_can_lowlevel_funs,
+ loop_can_info0,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LOOP_CAN0_KBAUD),
+ loop_can_txbuf0, CYGNUM_DEVS_CAN_LOOP_CAN0_QUEUESIZE_TX,
+ loop_can_rxbuf0, CYGNUM_DEVS_CAN_LOOP_CAN0_QUEUESIZE_RX
+ );
+#endif // CYGPKG_DEVS_CAN_LOOP_CAN1
+
+#ifdef CYGPKG_DEVS_CAN_LOOP_CAN1
+CAN_CHANNEL_USING_INTERRUPTS(loop_can1_chan,
+ loop_can_lowlevel_funs,
+ loop_can_info1,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_LOOP_CAN1_KBAUD),
+ loop_can_txbuf1, CYGNUM_DEVS_CAN_LOOP_CAN1_QUEUESIZE_TX,
+ loop_can_rxbuf1, CYGNUM_DEVS_CAN_LOOP_CAN1_QUEUESIZE_RX
+ );
+#endif // CYGPKG_DEVS_CAN_LOOP_CAN1
+
+
+
+//-------------------------------------------------------------------------
+// And finally, the device table entries:
+//
+#ifdef CYGPKG_DEVS_CAN_LOOP_CAN0
+DEVTAB_ENTRY(loop_can_io0,
+ CYGDAT_DEVS_CAN_LOOP_CAN0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ loop_can_init,
+ loop_can_lookup, // CAN driver may need initializing
+ &loop_can0_chan
+ );
+#endif // CYGPKG_DEVS_CAN_LOOP_CAN0
+
+#ifdef CYGPKG_DEVS_CAN_LOOP_CAN1
+DEVTAB_ENTRY(loop_can_io1,
+ CYGDAT_DEVS_CAN_LOOP_CAN1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ loop_can_init,
+ loop_can_lookup, // CAN driver may need initializing
+ &loop_can1_chan
+ );
+#endif // CYGPKG_DEVS_CAN_LOOP_CAN1
+
+//-------------------------------------------------------------------------
+
+static bool
+loop_can_config_channel(can_channel *chan, cyg_can_info_t *new_config, bool init)
+{
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+//-------------------------------------------------------------------------
+// Function to initialize the device. Called at bootstrap time.
+
+bool loop_can_init(struct cyg_devtab_entry *tab)
+{
+ can_channel *chan = (can_channel *)tab->priv;
+
+ (chan->callbacks->can_init)(chan);
+
+ // Set up alarm for feeding data back into channels
+
+ cyg_alarm_create( cyg_real_time_clock(),
+ alarm_handler,
+ 0,
+ &alarm_handle,
+ &alarm_obj);
+
+ cyg_alarm_initialize( alarm_handle, 1, 1 );
+
+ loop_can_config_channel(chan, &chan->config, true);
+
+ return true;
+}
+
+//-------------------------------------------------------------------------
+// This routine is called when the device is "looked" up (i.e. attached)
+
+static Cyg_ErrNo
+loop_can_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ can_channel *chan = (can_channel *)(*tab)->priv;
+ (chan->callbacks->can_init)(chan);
+ return ENOERR;
+}
+
+//-------------------------------------------------------------------------
+// Return 'true' if message is sent to device
+
+bool
+loop_can_putmsg(can_channel *chan, cyg_can_message *pmsg, void *pdata)
+{
+ loop_can_info *loop_chan = (loop_can_info *)chan->dev_priv;
+
+ struct fifo *fwr = loop_chan->write_fifo;
+#ifdef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ struct fifo *frd = loop_chan->read_fifo;
+#endif
+
+ if( fwr->num == FIFO_SIZE )
+ {
+ return false;
+ }
+
+ fwr->buf[fwr->tail].msg = *pmsg;
+ fwr->buf[fwr->tail].flags = CYGNUM_CAN_EVENT_RX;
+ fwr->num++;
+ fwr->tail = (fwr->tail + 1) % FIFO_SIZE;
+
+#ifdef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ //
+ // if TX events are supported we insert a TX event into read fifo
+ //
+ if( frd->num < FIFO_SIZE )
+ {
+ frd->buf[frd->tail].msg = *pmsg;
+ frd->buf[frd->tail].flags = CYGNUM_CAN_EVENT_TX;
+ frd->num++;
+ frd->tail = (frd->tail + 1) % FIFO_SIZE;
+ }
+#endif
+
+ return true;
+}
+
+//-------------------------------------------------------------------------
+
+bool loop_can_getevent(can_channel *chan, cyg_can_event *pevent, void *pdata)
+{
+ loop_can_info *loop_chan = (loop_can_info *)chan->dev_priv;
+
+ struct fifo *frd = loop_chan->read_fifo;
+
+ while( frd->num == 0 )
+ {
+ continue;
+ }
+
+ *pevent = frd->buf[frd->head];
+
+
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+ //
+ // if timestamps are supported then we store a actual timestamp into
+ // CAN event
+ //
+ pevent->timestamp = cyg_current_time();
+#endif // CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+
+ frd->num--;
+ frd->head = (frd->head + 1) % FIFO_SIZE;
+
+ return true;
+}
+
+//-------------------------------------------------------------------------
+
+static Cyg_ErrNo
+loop_can_set_config(can_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ return ENOERR;
+}
+
+//-------------------------------------------------------------------------
+// Query device configuration
+
+static Cyg_ErrNo
+loop_can_get_config(can_channel *chan, cyg_uint32 key,
+ const void* buf, cyg_uint32* len)
+{
+ return ENOERR;
+}
+
+
+//-------------------------------------------------------------------------
+// Enable the transmitter on the device
+
+static void
+loop_can_start_xmit(can_channel *chan)
+{
+ loop_can_info *loop_chan = (loop_can_info *)chan->dev_priv;
+
+ loop_chan->write_fifo->tx_enable = true;
+
+ (chan->callbacks->xmt_msg)(chan, 0);
+}
+
+//-------------------------------------------------------------------------
+// Disable the transmitter on the device
+
+static void
+loop_can_stop_xmit(can_channel *chan)
+{
+ loop_can_info *loop_chan = (loop_can_info *)chan->dev_priv;
+
+ loop_chan->write_fifo->tx_enable = false;
+}
+
+//-------------------------------------------------------------------------
+
+static void alarm_handler(cyg_handle_t alarm, cyg_addrword_t data)
+{
+ can_channel *chan0 = &loop_can0_chan;
+ can_channel *chan1 = &loop_can1_chan;
+
+
+ while(fifo0.num )
+ {
+ (chan1->callbacks->rcv_event)(chan1, 0);
+
+ if(fifo0.tx_enable )
+ {
+ (chan0->callbacks->xmt_msg)(chan0, 0);
+ }
+ }
+
+ while(fifo1.num )
+ {
+ (chan0->callbacks->rcv_event)(chan0, 0);
+
+ if(fifo1.tx_enable )
+ {
+ (chan1->callbacks->xmt_msg)(chan1, 0);
+ }
+ } // while( fifo1.num )
+}
+
+
+#endif // CYGPKG_IO_CAN_LOOP
+
+//-------------------------------------------------------------------------
+// EOF loop_can.c
diff --git a/ecos/packages/devs/can/loop/current/tests/can_callback.c b/ecos/packages/devs/can/loop/current/tests/can_callback.c
new file mode 100644
index 0000000..528199b
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/tests/can_callback.c
@@ -0,0 +1,240 @@
+//==========================================================================
+//
+// can_callback.c
+//
+// CAN driver test of callback on event
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler, Alexey Shusharin
+// Contributors: Uwe Kindler, Alexey Shusharin
+// Date: 2007-08-23
+// Description: CAN driver test of callback on event
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_SUPPORT_CALLBACK)
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can_thread;
+thread_data_t can_thread_data;
+
+cyg_mutex_t can_lock;
+cyg_cond_t can_wait;
+
+cyg_io_handle_t hCAN0;
+cyg_io_handle_t hCAN1;
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// CALLBACK FUNCTION
+//===========================================================================
+
+static void callback_func(cyg_uint16 flags, CYG_ADDRWORD data)
+{
+ if (data == ((CYG_ADDRWORD) hCAN0) && (flags & CYGNUM_CAN_EVENT_RX))
+ {
+ // Wake up thread
+ cyg_cond_signal(&can_wait);
+ }
+}
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_callback_cfg callback_cfg;
+ cyg_can_message tx_msg;
+ cyg_bool_t wait_res;
+
+ //
+ // open CAN0 device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ //
+ // open CAN1 device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can1", &hCAN1))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can1");
+ }
+
+ //
+ // configure CAN0 callback
+ //
+ len = sizeof(callback_cfg);
+ callback_cfg.flag_mask = 0xFFFF;
+ callback_cfg.data = (CYG_ADDRWORD) hCAN0;
+ callback_cfg.callback_func = callback_func;
+
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_CALLBACK,
+ &callback_cfg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+
+ //
+ // transmit message from CAN1 to CAN0
+ //
+ tx_msg.id = 0x001;
+ tx_msg.ext = CYGNUM_CAN_ID_STD;
+ tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
+ tx_msg.dlc = 0;
+ len = sizeof(tx_msg);
+
+ if (ENOERR != cyg_io_write(hCAN1, &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing message to /dev/can1");
+ }
+
+ //
+ // Wait CAN0 callback
+ //
+ cyg_mutex_lock(&can_lock);
+
+ wait_res = cyg_cond_timed_wait(&can_wait, 100);
+
+ cyg_mutex_unlock(&can_lock);
+
+ //
+ // If result of wait is a signal operation, test is successed
+ // If timeout - test is failed, because callback_func() hasn't been
+ // called with correct parameters
+ //
+ if(wait_res)
+ {
+ CYG_TEST_PASS_FINISH("can_callback test OK");
+ }
+ else
+ {
+ CYG_TEST_FAIL_FINISH("can_callback test FAILED");
+ }
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ cyg_mutex_init(&can_lock);
+ cyg_cond_init(&can_wait, &can_lock);
+
+ //
+ // create the main thread
+ //
+ cyg_thread_create(4, can_thread,
+ (cyg_addrword_t) 0,
+ "can_thread",
+ (void *) can_thread_data.stack,
+ 1024 * sizeof(long),
+ &can_thread_data.hdl,
+ &can_thread_data.obj);
+
+ cyg_thread_resume(can_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // #if defined(CYGOPT_IO_CAN_SUPPORT_CALLBACK)
+#define N_A_MSG "Needs callback support"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF can_callback.c
diff --git a/ecos/packages/devs/can/loop/current/tests/can_nonblock.c b/ecos/packages/devs/can/loop/current/tests/can_nonblock.c
new file mode 100644
index 0000000..73d953a
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/tests/can_nonblock.c
@@ -0,0 +1,199 @@
+//==========================================================================
+//
+// can_nonblock.c
+//
+// CAN driver test of nonblocking calls
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-14
+// Description: CAN driver test of nonblocking callst
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// Package option requirements
+#if defined(CYGOPT_IO_CAN_SUPPORT_NONBLOCKING)
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+
+cyg_io_handle_t hDrvFlexCAN;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_uint32 blocking;
+ cyg_can_event rx_event;
+ Cyg_ErrNo res;
+
+ blocking = 0;
+ len = sizeof(blocking);
+ if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_READ_BLOCKING ,&blocking, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+
+ len = sizeof(rx_event);
+ res = cyg_io_read(hDrvFlexCAN, &rx_event, &len);
+
+ if (-EAGAIN == res)
+ {
+ CYG_TEST_PASS_FINISH("can_test1 test OK");
+ }
+ else if (-EINTR == res)
+ {
+ CYG_TEST_PASS_FINISH("can_test1 test OK");
+ }
+ else
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+}
+
+
+void
+cyg_start(void)
+{
+ cyg_uint32 len;
+ cyg_can_info_t can_cfg;
+
+ CYG_TEST_INIT();
+
+ //
+ // open flexcan device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hDrvFlexCAN))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ //
+ // setup CAN baudrate 250 KBaud
+ //
+ can_cfg.baud = CYGNUM_CAN_KBAUD_250;
+ len = sizeof(can_cfg);
+ if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_CAN_INFO ,&can_cfg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+
+ //
+ // create the main thread
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // #if defined(CYGOPT_IO_CAN_SUPPORT_NONBLOCKING)
+#define N_A_MSG "Needs nonblocking calls"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF can_nonblock.c
diff --git a/ecos/packages/devs/can/loop/current/tests/can_overrun1.c b/ecos/packages/devs/can/loop/current/tests/can_overrun1.c
new file mode 100644
index 0000000..8e57a74
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/tests/can_overrun1.c
@@ -0,0 +1,275 @@
+//==========================================================================
+//
+// can_overrun1.c
+//
+// Test CAN device drivers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Simple read/write test of CAN driver
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// tx event support required
+#if defined(CYGOPT_IO_CAN_TX_EVENT_SUPPORT)
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// WRITER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_io_handle_t hCAN0;
+ cyg_uint8 i;
+ cyg_uint32 len;
+ cyg_can_buf_info_t buf_info;
+ cyg_can_event rx_event;
+ cyg_can_message tx_msg =
+ {
+ 0x000, // CAN identifier
+ data :
+ {
+ {0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 }// 8 data bytes
+ },
+ CYGNUM_CAN_ID_STD, // standard frame
+ CYGNUM_CAN_FRAME_DATA, // data frame
+ 1, // data length code
+ };
+
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ len = sizeof(buf_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&buf_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ if (buf_info.rx_count > 0)
+ {
+ CYG_TEST_FAIL_FINISH("Empty RX buffer expected for /dev/can0");
+ }
+
+ //
+ // now we send exactly one CAN message more than it is space in left in buffer
+ // Because each TX message will cause a TX event in receive queue we should
+ // get a RX queue overrun
+ //
+ diag_printf("Sending %d CAN messages to /dev/can0\n", buf_info.rx_bufsize + 1);
+ for (i = 0; i <= buf_info.rx_bufsize; ++i)
+ {
+ CYG_CAN_MSG_SET_STD_ID(tx_msg, 0x000 + i);
+ CYG_CAN_MSG_SET_DATA(tx_msg, 0, i);
+ len = sizeof(tx_msg);
+
+ if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to /dev/can0");
+ }
+ else
+ {
+ print_can_msg(&tx_msg, "");
+ }
+ }
+
+ //
+ // Give the loop back driver time to process all those messages.
+ //
+ cyg_thread_delay(10);
+
+ //
+ // now check if receive queue is completely filled - that means number of rx events should
+ // be equal to RX queue size
+ //
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&buf_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ if (buf_info.rx_bufsize != buf_info.rx_count)
+ {
+ CYG_TEST_FAIL_FINISH("Number of events in /dev/can0 RX queue differs from queue size");
+ }
+
+ //
+ // Now read all events from receive queue - if everything is o.k. than the oldest
+ // event should be overwritten by the latest sent message and the last event in
+ // queue should indicate a RX overrun
+ //
+ diag_printf("\nReceiving %d CAN messages from /dev/can0\n", buf_info.rx_bufsize);
+ for (i = 0; i < buf_info.rx_bufsize; ++i)
+ {
+ len = sizeof(rx_event);
+
+ if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can1");
+ }
+ else
+ {
+ //
+ // if we received a valid TX event then we can print the message
+ //
+ if (rx_event.flags & CYGNUM_CAN_EVENT_TX)
+ {
+ print_can_msg(&rx_event.msg, "");
+ if (rx_event.msg.data.bytes[0] != (i + 1))
+ {
+ CYG_TEST_FAIL_FINISH("Received /dev/can0 TX event contains invalid data");
+ }
+ }
+ else
+ {
+ CYG_TEST_FAIL_FINISH("Unexpected CAN event for /dev/can0");
+ }
+
+ //
+ // now check if any other flag is set
+ //
+ if (rx_event.flags & CYGNUM_CAN_EVENT_OVERRUN_RX)
+ {
+ diag_printf("RX queue overrun successfully indicated for /dev/can0\n");
+ if (i < (buf_info.rx_bufsize - 1))
+ {
+ CYG_TEST_FAIL_FINISH("RX queue overrun occured too early /dev/can0");
+ }
+ else
+ {
+ CYG_TEST_PASS_FINISH("can_overrun1 test OK");
+ }
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_OVERRUN_RX)
+ }
+ } // for (i = 0; i < buf_info.rx_bufsize; ++i)
+
+ CYG_TEST_FAIL_FINISH("RX overrun expected but not received for /dev/can0");
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // create the two threads which access the CAN device driver
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+#define N_A_MSG "TX event support required for IO/CAN"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF serial4.c
diff --git a/ecos/packages/devs/can/loop/current/tests/can_overrun2.c b/ecos/packages/devs/can/loop/current/tests/can_overrun2.c
new file mode 100644
index 0000000..2318e9b
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/tests/can_overrun2.c
@@ -0,0 +1,354 @@
+//==========================================================================
+//
+// can_overrun2.c
+//
+// Test CAN device RX overrun events
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Simple read/write test of CAN driver
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+cyg_thread_entry_t can1_thread;
+thread_data_t can1_thread_data;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// WRITER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_io_handle_t hCAN0;
+ cyg_uint8 i;
+ cyg_uint32 len;
+ cyg_uint32 rx_bufsize;
+ cyg_can_buf_info_t tx_buf_info;
+ cyg_can_event rx_event;
+ cyg_can_message tx_msg =
+ {
+ 0x000, // CAN identifier
+ data :
+ {
+ {0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 }// 8 data bytes
+ },
+ CYGNUM_CAN_ID_STD, // standard frame
+ CYGNUM_CAN_FRAME_DATA, // data frame
+ 2, // data length code
+ };
+
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ len = sizeof(tx_buf_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&tx_buf_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ //
+ // Before we can write the CAN messages, we need to know the buffer size of the
+ // receiver. The receiver will tell us this buffer size with one single CAN
+ // message
+ //
+ len = sizeof(rx_event);
+
+ if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+
+ //
+ // we expect a RX event here - we treat any other flag as an error
+ //
+ if (!(rx_event.flags & CYGNUM_CAN_EVENT_RX) || (rx_event.flags & !CYGNUM_CAN_EVENT_RX))
+ {
+ CYG_TEST_FAIL_FINISH("Unexpected RX event for /dev/can0");
+ }
+
+ rx_bufsize = *((cyg_uint32 *)rx_event.msg.data.bytes);
+
+ //
+ // now we send exactly one CAN message more than there is space in the receive buffer
+ // this should cause an RX ovverun in receive buffer
+ //
+ diag_printf("/dev/can0: Sending %d CAN messages\n", rx_bufsize);
+ for (i = 0; i <= rx_bufsize; ++i)
+ {
+ //
+ // we store the message number as CAN id and in first data byte so
+ // a receiver can check this later
+ //
+ CYG_CAN_MSG_SET_STD_ID(tx_msg, 0x000 + i);
+ CYG_CAN_MSG_SET_DATA(tx_msg, 0, i);
+ len = sizeof(tx_msg);
+
+ if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to /dev/can0");
+ }
+ else
+ {
+ print_can_msg(&tx_msg, "");
+ }
+ } // for (i = 0; i <= rx_bufsize; ++i)
+
+ cyg_thread_suspend(cyg_thread_self());
+}
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can1_thread(cyg_addrword_t data)
+{
+ cyg_io_handle_t hCAN1;
+ cyg_uint8 i;
+ cyg_uint32 len;
+ cyg_can_buf_info_t rx_buf_info;
+ cyg_can_event rx_event;
+ cyg_can_message tx_msg;
+
+ if (ENOERR != cyg_io_lookup("/dev/can1", &hCAN1))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can1");
+ }
+
+ len = sizeof(rx_buf_info);
+ if (ENOERR != cyg_io_get_config(hCAN1, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&rx_buf_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can1");
+ }
+
+ //
+ // first we send the size of our receive buffer to the writer
+ // we setup tx message now
+ //
+ tx_msg.id = 0x000;
+ tx_msg.ext = CYGNUM_CAN_ID_STD;
+ tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
+ tx_msg.dlc = sizeof(rx_buf_info.rx_bufsize);
+
+ //
+ // we store size of rx buffer in CAN message. We do not need to care about
+ // endianess here because this is a loopback driver test and we will receive
+ // our own messages
+ //
+ *((cyg_uint32 *)tx_msg.data.bytes) = rx_buf_info.rx_bufsize;
+ len = sizeof(tx_msg);
+
+ //
+ // as soon as we send a CAN message, thread 0 will resume because it is waiting
+ // for a message
+ //
+ diag_printf("/dev/can1: Sending size of RX buffer %d\n", rx_buf_info.rx_bufsize);
+ if (ENOERR != cyg_io_write(hCAN1, &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to /dev/can1");
+ }
+ cyg_thread_delay(10); // let thread 0 run
+
+ //
+ // now we check if we received CAN messages - if receive buffer is not full
+ // the we have an error here because we expect a full receive buffer
+ //
+ len = sizeof(rx_buf_info);
+ if (ENOERR != cyg_io_get_config(hCAN1, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&rx_buf_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can1");
+ }
+
+ if (rx_buf_info.rx_bufsize != rx_buf_info.rx_count)
+ {
+ CYG_TEST_FAIL_FINISH("RX buffer of /dev/can1 does not contain number of expected messages");
+ }
+
+ //
+ // now we wait for messages from /dev/can0
+ //
+ diag_printf("/dev/can1: Receiving %d CAN messages\n", rx_buf_info.rx_count);
+ for (i = 0; i < rx_buf_info.rx_count; ++i)
+ {
+ len = sizeof(rx_event);
+ if (ENOERR != cyg_io_read(hCAN1, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+ else
+ {
+ if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
+ {
+ print_can_msg(&rx_event.msg, "");
+ if (rx_event.msg.data.bytes[0] != (i + 1))
+ {
+ CYG_TEST_FAIL_FINISH("Received /dev/can1 RX event contains invalid data");
+ }
+ }
+ else
+ {
+ CYG_TEST_FAIL_FINISH("Unexpected CAN event for /dev/can1");
+ }
+
+ //
+ // now check if any other flag is set
+ //
+ if (rx_event.flags & CYGNUM_CAN_EVENT_OVERRUN_RX)
+ {
+ diag_printf("RX queue overrun successfully indicated for /dev/can1\n");
+
+//
+// if TX events are supported then we have already a TX event in receive queue because
+// we sent a message and the RX queue overrun will occur one message earlier
+//
+#if defined(CYGOPT_IO_CAN_TX_EVENT_SUPPORT)
+ if (i < (rx_buf_info.rx_bufsize - 2))
+#else
+ if (i < (rx_buf_info.rx_bufsize - 1))
+#endif
+ {
+ CYG_TEST_FAIL_FINISH("RX queue overrun occured too early for /dev/can1");
+ }
+ else
+ {
+ CYG_TEST_PASS_FINISH("can_overrun2 test OK");
+ }
+ } // if (rx_event.flags & CYGNUM_CAN_EVENT_OVERRUN_RX)
+ }
+
+ }
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // create the two threads which access the CAN device driver
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_create(5, can1_thread,
+ (cyg_addrword_t) can0_thread_data.hdl,
+ "can1_thread",
+ (void *) can1_thread_data.stack,
+ 1024 * sizeof(long),
+ &can1_thread_data.hdl,
+ &can1_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+ cyg_thread_resume(can1_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF serial4.c
diff --git a/ecos/packages/devs/can/loop/current/tests/can_rdwr.c b/ecos/packages/devs/can/loop/current/tests/can_rdwr.c
new file mode 100644
index 0000000..f9e3789
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/tests/can_rdwr.c
@@ -0,0 +1,307 @@
+//==========================================================================
+//
+// can_rdwr.c
+//
+// Test CAN device drivers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Simple read/write test of CAN driver
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+cyg_thread_entry_t can1_thread;
+thread_data_t can1_thread_data;
+
+cyg_sem_t sem_wait;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// WRITER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_io_handle_t hCAN0;
+ cyg_uint8 i;
+ cyg_uint32 len;
+ cyg_can_buf_info_t tx_buf_info;
+ cyg_can_message tx_msg =
+ {
+ 0x000, // CAN identifier
+ data :
+ {
+ {0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7}, // 8 data bytes
+ },
+ CYGNUM_CAN_ID_STD, // standard frame
+ CYGNUM_CAN_FRAME_DATA, // data frame
+ 8, // data length code
+ };
+
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ len = sizeof(tx_buf_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&tx_buf_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ if (tx_buf_info.tx_bufsize < 10)
+ {
+ CYG_TEST_FAIL_FINISH("TX quesize of /dev/can0 too small for 10 CAN messages");
+ }
+
+ while (1)
+ {
+ //
+ // now we simply send 10 CAN messages and then suspend the thread
+ //
+ CYG_TEST_INFO("Thread0: Writing 10 CAN messages");
+ for (i = 0; i < 10; ++i)
+ {
+ //
+ // we store the message number as CAN id and in first data byte so
+ // a receiver can check this later
+ //
+ CYG_CAN_MSG_SET_STD_ID(tx_msg, 0x000 + i);
+ CYG_CAN_MSG_SET_DATA(tx_msg, 0, i);
+ len = sizeof(tx_msg);
+
+ if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to /dev/can0");
+ }
+ else
+ {
+ print_can_msg(&tx_msg, "");
+ }
+ } // for (i = 0; i < 10; ++i)
+
+ //
+ // Give reader thread 200 ticks time for readung all messages. The reader thread
+ // signals the semaphore if it received all transmitted messages
+ //
+ if (!cyg_semaphore_timed_wait( &sem_wait, cyg_current_time( ) + 200 ))
+ {
+ CYG_TEST_FAIL_FINISH("Waiting for reader thread timed out.");
+ }
+ else
+ {
+ CYG_TEST_PASS_FINISH("can_rdwr test OK");
+ }
+ } // while (1)
+}
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can1_thread(cyg_addrword_t data)
+{
+ cyg_io_handle_t hCAN1;
+ cyg_uint8 i;
+ cyg_uint32 len;
+ cyg_can_buf_info_t rx_buf_info;
+ cyg_can_event rx_event;
+
+ if (ENOERR != cyg_io_lookup("/dev/can1", &hCAN1))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can1");
+ }
+
+ len = sizeof(rx_buf_info);
+ if (ENOERR != cyg_io_get_config(hCAN1, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&rx_buf_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can1");
+ }
+
+ if (rx_buf_info.rx_bufsize < 10)
+ {
+ CYG_TEST_FAIL_FINISH("RX quesize of /dev/can1 too small for 10 CAN events");
+ }
+
+ while (1)
+ {
+ //
+ // now we try to read the 10 CAN messages that was sent by writer
+ // thread previously
+ //
+ CYG_TEST_INFO("Thread1: Reading 10 CAN messages");
+ for (i = 0; i < 10; ++i)
+ {
+ len = sizeof(rx_event);
+
+ if (ENOERR != cyg_io_read(hCAN1, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can1");
+ }
+
+ //
+ // we expect only RX events in this test case - so all other events
+ // cause a test fail
+ //
+ if (!(rx_event.flags & CYGNUM_CAN_EVENT_RX))
+ {
+ CYG_TEST_FAIL_FINISH("Received wrong CAN event type");
+ }
+
+ //
+ // The writer thread stored the message number in CAN id and first
+ // data byte so we can check now if we received valid data
+ //
+ if ((rx_event.msg.id != i) || (rx_event.msg.data.bytes[0] != i))
+ {
+ CYG_TEST_FAIL_FINISH("Received CAN message contains unexpected data");
+ }
+ else
+ {
+ print_can_msg(&rx_event.msg, "");
+ }
+ } //for (i = 0; i < 10; ++i)
+
+ //
+ // signal successfull reception of all messages
+ //
+ cyg_semaphore_post(&sem_wait);
+ } // while (1)
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // Initialize the wait semaphore to 0
+ //
+ cyg_semaphore_init( &sem_wait, 0 );
+
+ //
+ // create the two threads which access the CAN device driver
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_create(5, can1_thread,
+ (cyg_addrword_t) can0_thread_data.hdl,
+ "can1_thread",
+ (void *) can1_thread_data.stack,
+ 1024 * sizeof(long),
+ &can1_thread_data.hdl,
+ &can1_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+ cyg_thread_resume(can1_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF serial4.c
diff --git a/ecos/packages/devs/can/loop/current/tests/can_test_aux.inl b/ecos/packages/devs/can/loop/current/tests/can_test_aux.inl
new file mode 100644
index 0000000..2bb2e07
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/tests/can_test_aux.inl
@@ -0,0 +1,147 @@
+//==========================================================================
+//
+// can_test_aux.inl
+//
+// CAN test auxiliary functions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Auxiliary functions for CAN driver tests
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// PRINT CAN EVENT
+//===========================================================================
+void print_can_msg(cyg_can_message *pmsg, char *pMsg)
+{
+ char *pmsg_str;
+ static char* msg_tbl[] =
+ {
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X %02X]\n"
+ };
+
+ if (pmsg->rtr)
+ {
+ diag_printf("%s [ID:%03X] [RTR:%d] [EXT:%d] [DLC:%d]\n",
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->dlc);
+
+ return;
+ }
+
+ if (pmsg->dlc > 8)
+ {
+ pmsg_str = msg_tbl[8];
+ }
+ else
+ {
+ pmsg_str = msg_tbl[pmsg->dlc];
+ }
+
+ diag_printf(pmsg_str,
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->data.bytes[0],
+ pmsg->data.bytes[1],
+ pmsg->data.bytes[2],
+ pmsg->data.bytes[3],
+ pmsg->data.bytes[4],
+ pmsg->data.bytes[5],
+ pmsg->data.bytes[6],
+ pmsg->data.bytes[7]);
+}
+
+
+//===========================================================================
+// PRINT CAN EVENT FLAGS
+//===========================================================================
+void print_can_flags(cyg_uint16 flags, char *pMsg)
+{
+ char *pmsg_str;
+ cyg_uint8 i ;
+ static char* msg_tbl[] =
+ {
+ "RX ",
+ "TX ",
+ "WRX ",
+ "WTX ",
+ "ERRP ",
+ "BOFF ",
+ "OVRX ",
+ "OVTX ",
+ "CERR ",
+ "LSTY ",
+ "ESTY ",
+ "ALOS ",
+ "DEVC ",
+ "PHYF ",
+ "PHYH ",
+ "PHYL "
+ };
+ i = 0;
+ while (flags && (i < 16))
+ {
+ if (flags & 0x0001)
+ {
+ pmsg_str = msg_tbl[i];
+ diag_printf(pmsg_str);
+ }
+ flags >>=1;
+ i++;
+ }
+
+ diag_printf("\n");
+}
+
+//---------------------------------------------------------------------------
+// end of can_test_aux.inl
diff --git a/ecos/packages/devs/can/loop/current/tests/can_timeout.c b/ecos/packages/devs/can/loop/current/tests/can_timeout.c
new file mode 100644
index 0000000..7feba87
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/tests/can_timeout.c
@@ -0,0 +1,247 @@
+//==========================================================================
+//
+// can_timeout.c
+//
+// Test CAN device driver timeouts
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Timeout test of CAN device driver
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// timeout support required
+#if defined(CYGOPT_IO_CAN_SUPPORT_TIMEOUTS)
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// Measure timeout time and compare it with RX timeout value
+//===========================================================================
+void check_timeout(cyg_io_handle_t hCAN, cyg_uint32 timeout)
+{
+ cyg_can_event rx_event;
+ cyg_can_timeout_info_t timeout_info;
+ cyg_uint32 len;
+ cyg_uint32 current_time_old;
+ cyg_uint32 current_time_new;
+ cyg_int32 diff_time;
+
+
+
+ timeout_info.tx_timeout = timeout;
+ timeout_info.rx_timeout = timeout;
+ len = sizeof(timeout_info);
+ if (ENOERR != cyg_io_set_config(hCAN, CYG_IO_SET_CONFIG_CAN_TIMEOUT ,&timeout_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+
+ diag_printf("read timeout: %d\n", timeout);
+
+ //
+ // if the return code is -EINTR then we know that a timout occured. Normally the
+ // receive queue should be empty so we can expect a timeout here
+ //
+ current_time_old = (cyg_uint32)cyg_current_time();
+ len = sizeof(rx_event);
+ if (-EINTR == cyg_io_read(hCAN, &rx_event, &len))
+ {
+ current_time_new = (cyg_uint32)cyg_current_time();
+ diff_time = current_time_new - current_time_old;
+ diag_printf("measured time: %d\n\n", diff_time);
+ diff_time = diff_time - timeout;
+
+ //
+ // If the measured value is smaller then the timeout value or if
+ // the difference is > 2 the we treat this as an error
+ //
+ if ((diff_time < 0) || (diff_time > 2))
+ {
+ CYG_TEST_FAIL_FINISH("Measured timeout time differs from /dev/can0 RX timeout value.");
+ }
+ }
+ else
+ {
+ CYG_TEST_FAIL_FINISH("Timeout expected for /dev/can0");
+ }
+}
+
+//===========================================================================
+// WRITER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_io_handle_t hCAN0;
+ cyg_uint32 len;
+ cyg_uint32 blocking;
+ cyg_can_timeout_info_t timeout_info;
+
+
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ //
+ // the first thing we need to do is to switch to nonblocking calls because
+ // function calls with timeout require nonblocking calls
+ //
+ blocking = 0;
+ len = sizeof(blocking);
+ if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_READ_BLOCKING ,&blocking, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error changing config of /dev/can0");
+ }
+
+ //
+ // first we read the timeout configuration
+ //
+ len = sizeof(timeout_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_TIMEOUT ,&timeout_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ //
+ // now we check the default timeout and a number of different timeout values
+ //
+ check_timeout(hCAN0, timeout_info.rx_timeout);
+ check_timeout(hCAN0, 10);
+ check_timeout(hCAN0, 20);
+ check_timeout(hCAN0, 50);
+ check_timeout(hCAN0, 100);
+ check_timeout(hCAN0, 200);
+ check_timeout(hCAN0, 500);
+
+
+ CYG_TEST_PASS_FINISH("can_timeout test OK");
+}
+
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // create the thread which access the CAN device driver
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGOPT_IO_CAN_SUPPORT_TIMEOUTS
+#define N_A_MSG "Timeout support required for IO/CAN"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF can_timeout.c
diff --git a/ecos/packages/devs/can/loop/current/tests/can_txevent.c b/ecos/packages/devs/can/loop/current/tests/can_txevent.c
new file mode 100644
index 0000000..e2e521d
--- /dev/null
+++ b/ecos/packages/devs/can/loop/current/tests/can_txevent.c
@@ -0,0 +1,271 @@
+//==========================================================================
+//
+// can_txevent.c
+//
+// Test CAN device driver timeouts
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Timeout test of CAN device driver
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+// tx event support required
+#if defined(CYGOPT_IO_CAN_TX_EVENT_SUPPORT)
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// WRITER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_io_handle_t hCAN0;
+ cyg_uint32 len;
+ cyg_can_buf_info_t buf_info;
+ cyg_uint16 i;
+ cyg_can_event rx_event;
+ cyg_can_message tx_msg =
+ {
+ 0x000, // CAN identifier
+ data :
+ {
+ {0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 }// 8 data bytes
+ },
+ CYGNUM_CAN_ID_STD, // standard frame
+ CYGNUM_CAN_FRAME_DATA, // data frame
+ 4, // data length code
+ };
+
+
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+ //
+ // first we read the buffer info
+ //
+ len = sizeof(buf_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&buf_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ //
+ // check if buffer is really empty
+ //
+ if (buf_info.rx_count != 0)
+ {
+ CYG_TEST_FAIL_FINISH("Receive buffer of /dev/can0 is not empty.");
+ }
+
+ //
+ // now send messages - because TX events are supported each transmitted CAN message
+ // will cause a TX event that is filled into receive queue
+ //
+ diag_printf("Sending %d CAN messages to /dev/can0 \n", buf_info.rx_bufsize);
+ for (i = 0; i < buf_info.rx_bufsize; ++i)
+ {
+ CYG_CAN_MSG_SET_STD_ID(tx_msg, 0x000 + i);
+ CYG_CAN_MSG_SET_DATA(tx_msg, 0, i);
+ len = sizeof(tx_msg);
+
+ if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing to /dev/can0");
+ }
+ else
+ {
+ print_can_msg(&tx_msg, "");
+ }
+ }
+
+ //
+ // Give the loop back driver time to process all those messages.
+ //
+ cyg_thread_delay(10);
+
+ //
+ // now we read the buffer info - we expect a completely filled recieve queue
+ //
+ len = sizeof(buf_info);
+ if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_BUFFER_INFO ,&buf_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+ //
+ // if receive queue is not completely filled, then we have an error here
+ //
+ if (buf_info.rx_bufsize != buf_info.rx_count)
+ {
+ diag_printf("RX bufsize: %d events in RX buffer: %d\n", buf_info.rx_bufsize, buf_info.rx_count);
+ CYG_TEST_FAIL_FINISH("Receive queue of /dev/can0 not completely filled.");
+ }
+
+ //
+ // now we read the receive queue
+ //
+ diag_printf("Receiving %d TX events from /dev/can0 \n", buf_info.rx_count);
+ for (i = 0; i < buf_info.rx_count; ++i)
+ {
+ len = sizeof(rx_event);
+
+ if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+
+ //
+ // we expect only a set TX flag because no other events may arrive for the
+ // loopback driver
+ //
+ if (!(rx_event.flags & CYGNUM_CAN_EVENT_TX) || (rx_event.flags & !CYGNUM_CAN_EVENT_TX))
+ {
+ CYG_TEST_FAIL_FINISH("Unexpected receive event flags.");
+ }
+
+ //
+ // Now check if TX events contain valid data - we know that the ID and the first
+ // data byte contain the message number
+ //
+ if ((rx_event.msg.id != i) || (rx_event.msg.data.bytes[0] != i))
+ {
+ CYG_TEST_FAIL_FINISH("Received invalid data in TX event");
+ }
+ else
+ {
+ print_can_msg(&rx_event.msg, "");
+ }
+ } // for (i = 0; i < buf_info.rx_count; ++i)
+
+ CYG_TEST_PASS_FINISH("can_txevent test OK");
+}
+
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // create the thread which access the CAN device driver
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+#define N_A_MSG "TX event support required for IO/CAN"
+#endif
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF serial4.c
diff --git a/ecos/packages/devs/can/m68k/mcf52xx/current/ChangeLog b/ecos/packages/devs/can/m68k/mcf52xx/current/ChangeLog
new file mode 100644
index 0000000..8295490
--- /dev/null
+++ b/ecos/packages/devs/can/m68k/mcf52xx/current/ChangeLog
@@ -0,0 +1,125 @@
+2012-01-25 Bernard Fouché <bernard.fouche@kuantic.com>
+
+ * src/can_mcf52xx.c CYGNUM_CAN_EVENT_OVERRUN_RX_HW instead of
+ CYGNUM_CAN_EVENT_OVERRUN_RX. CYGNUM_CAN_MODE_LISTEN_ONLY_ENTER &
+ CYGNUM_CAN_MODE_LISTEN_ONLY_EXIT return -EINVAL.
+
+2007-03-23 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/can_mcf52xx.cdl Removed interfaces
+ CYGINT_DEVS_CAN_MCF52xx_FLEXCAN_SUPP_STD_CAN_ID and
+ CYGINT_DEVS_CAN_MCF52xx_FLEXCAN_SUPP_EXT_CAN_ID. The generic
+ CAN I/O layer provides some similar interfaces now.
+ Driver now implements the new CAN I/O interfaces
+ CYGINT_IO_CAN_TIMESTAMP, CYGINT_IO_CAN_RUNTIME_MBOX_CFG
+ CYGINT_IO_CAN_REMOTE_BUF and CYGINT_IO_CAN_TX_EVENTS,
+ CYGINT_IO_CAN_STD_CAN_ID, CYGINT_IO_CAN_EXT_CAN_ID
+ Removed make commands for removed test cases.
+ Removed cdl component CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN_OPTIONS
+ because it did not have any functionality.
+
+ * src/can_mcf52xx.c Replaced
+ CYGINT_DEVS_CAN_MCF52xx_FLEXCAN_SUPP_EXT_CAN_ID with
+ generic CAN I/O option CYGOPT_IO_CAN_EXT_CAN_ID and
+ CYGINT_DEVS_CAN_MCF52xx_FLEXCAN_SUPP_STD_CAN_ID with
+ generic CAN I/O option CYGOPT_IO_CAN_STD_CAN_ID
+ Implemented CAN mode CYGNUM_CAN_MODE_CONFIG.
+ Changed old access to CAN data (byte array) to access
+ to new cyg_can_msg_data type.
+
+ * tests/flexcan_filter: removed. This tast case is now part of
+ generic CAN I/O layer.
+
+ * tests/flexcan_load: removed. This tast case is now part of
+ generic CAN I/O layer.
+
+ * tests/flexcan_remote: removed. This tast case is now part of
+ generic CAN I/O layer.
+
+ * tets/flexcan_wake: Did some code cleaning.
+
+2006-02-15 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/can_mcf52xx.cdl Added two interfaces
+ CYGINT_DEVS_CAN_MCF52xx_FLEXCAN_SUPP_STD_CAN_ID and
+ CYGINT_DEVS_CAN_MCF52xx_FLEXCAN_SUPP_EXT_CAN_ID.
+ The number of standard and extended message boxes is now
+ configurable:
+ CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_STD_MBOXES
+ CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_EXT_MBOXES
+ Channged default TX buffer to 15.
+
+ * src/can_mcf52xx.c Added initialisation macro for second
+ FlexCAN modul. Driver partly rewritten - support of up to
+ 15 message buffers when reception of all CAN frames is
+ configured - improves performance when "bursts" of CAN
+ messages arrive. Changed message buffer configuration -
+ only the config key CYG_IO_SET_CONFIG_CAN_MSGBUF is
+ supported now. The exact configuration option is defined
+ in new data field cyg_can_msgbuf_cfg_id in cyg_can_msgbuf_cfg
+ structure.
+
+ * tests/flexcan_filter.c
+ * tests/flexcan_wake.c
+ * tests/flexcan_remote.c
+ * tests/flexcan_load.c
+ Changed message buffer configuration to support of new
+ config key CYG_IO_SET_CONFIG_CAN_MSGBUF. Removed baudrate
+ runtime configuration of 250 kBaud - now default
+ value is used.
+
+2005-09-20 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/can_mcf52xx.c Only support events of tx message buffers
+ in flexcan_getevent() if CYGOPT_IO_CAN_TX_EVENT_SUPPORT is
+ active.
+
+2005-09-11 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/can_mcf52xx.cdl Default message buffer configuration
+ changed. Message buffer 13 now is transmit message buffer.
+ Message buffers 14 and 15 are no receive message buffers
+ for all standard and extended frames.
+
+ * src/can_mcf52xx.c Driver partly rewritten. Support for message
+ filtering added. Message buffer handling added. Several bugs
+ fixed. Support added for configuration options
+ CYG_IO_SET_CONFIG_CAN_REMOTE_BUF
+ CYG_IO_SET_CONFIG_CAN_FILTER_MSG
+ CYG_IO_SET_CONFIG_CAN_FILTER_ALL
+ CYG_IO_SET_CONFIG_CAN_MODE
+ CYG_IO_GET_CONFIG_CAN_STATE
+ CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO
+ CYG_IO_GET_CONFIG_CAN_HDI
+
+ * tests/flexcan_filter.c Test of message filtering addded
+ * tests/flexcan_wake.c Test of mode setting and standby mode of
+ FlexCAN module added.
+
+2005-05-24 Uwe Kindler <uwe_kindler@web.de>
+
+ * mcf52xx FlexCAN driver package created
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/can/m68k/mcf52xx/current/cdl/can_mcf52xx.cdl b/ecos/packages/devs/can/m68k/mcf52xx/current/cdl/can_mcf52xx.cdl
new file mode 100644
index 0000000..59a9fbc
--- /dev/null
+++ b/ecos/packages/devs/can/m68k/mcf52xx/current/cdl/can_mcf52xx.cdl
@@ -0,0 +1,275 @@
+# ====================================================================
+#
+# can_mcf52xx.cdl
+#
+# eCos MCF52xx FlexCAN configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors:
+# Date: 2005-05-17
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN {
+ display "CAN driver for FlexCAN module of coldfire mcf52xx family"
+
+ parent CYGPKG_IO_CAN_DEVICES
+ active_if CYGPKG_IO_CAN
+ active_if CYGPKG_HAL_M68K_MCF52xx
+
+ requires CYGPKG_ERROR
+
+ description "
+ This package provides a generic CAN device driver for the on-chip
+ FlexCAN modules in MCF52xx ColdFire processors."
+ compile -library=libextras.a can_mcf52xx.c
+ define_proc {
+ puts $::cdl_system_header "/***** CAN driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_CAN_DEVICE_HEADER <pkgconf/devs_can_mcf52xx_flexcan.h>"
+ puts $::cdl_system_header "/***** CAN driver proc output end *****/"
+ }
+
+
+ # Support up to two on-chip FlexCAN modules. The number varies between
+ # processor variants
+ for { set ::flexcan 0 } { $::flexcan < 2 } { incr ::flexcan } {
+
+ cdl_interface CYGINT_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan] {
+ display "Platform provides FlexCAN [set ::flexcan]"
+ flavor bool
+ description "
+ This interface will be implemented if the specific coldfire
+ processor being used has an on-chip FlexCAN[set ::flexcan], and if
+ that FlexCAN is accessible on the target hardware."
+ }
+
+ cdl_component CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan] {
+ display "Allow access to the on-chip FlexCAN[set ::flexcan] via a CAN driver"
+ flavor bool
+ active_if CYGINT_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]
+ default_value 1
+ implements CYGINT_IO_CAN_TIMESTAMP
+ implements CYGINT_IO_CAN_RUNTIME_MBOX_CFG
+ implements CYGINT_IO_CAN_REMOTE_BUF
+ implements CYGINT_IO_CAN_TX_EVENTS
+
+ description "
+ If the application needs to access the on-chip FlexCAN[set ::flexcan]
+ via an eCos CAN driver then this option should be enabled."
+
+ cdl_option CYGDAT_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_NAME {
+ display "Device name for FlexCAN [set ::flexcan]"
+ flavor data
+ default_value [format {"\"/dev/can%d\""} $::flexcan]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+
+ cdl_option CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_KBAUD {
+ display "Default baud rate for FlexCAN [set ::flexcan]"
+ flavor data
+ default_value 100
+ legal_values { 10 20 50 100 125 250 500 800 1000 }
+ description "This option determines the initial baud rate in KBaud for FlexCAN [set ::flexcan]"
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_QUEUESIZE_TX {
+ display "Size of TX Queue for the FlexCAN [set ::flexcan] driver"
+ flavor data
+ default_value 64
+ legal_values 16 to 1024
+ description "
+ The CAN device driver will run in interrupt mode and will
+ perform buffering of outgoing data. This option controls the number
+ of CAN messages the TX queue can store."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_QUEUESIZE_RX {
+ display "Size of RX Queue for the FlexCAN [set ::flexcan] driver"
+ flavor data
+ default_value 128
+ legal_values 16 to 1024
+ description "
+ The CAN device driver will run in interrupt mode and will
+ perform buffering of incoming data. This option controls the number
+ of CAN events the RX queue can store."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN[set ::flexcan]_WAKEINT {
+ display "Wake interrupt priority"
+ flavor data
+ default_value is_loaded(CYGNUM_HAL_M68K_MCF52xx_ISR_DEFAULT_PRIORITY_FLEXCAN[set ::flexcan]_WAKEINT) ? \
+ CYGNUM_HAL_M68K_MCF52xx_ISR_DEFAULT_PRIORITY_FLEXCAN[set ::flexcan]_WAKEINT : \
+ CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MIN
+ legal_values CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MIN to CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MAX
+ description "
+ Interrupt priority for wake interrupt."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN[set ::flexcan]_ERRINT {
+ display "Error interrupt priority"
+ flavor data
+ default_value is_loaded(CYGNUM_HAL_M68K_MCF52xx_ISR_DEFAULT_PRIORITY_FLEXCAN[set ::flexcan]_ERRINT) ? \
+ CYGNUM_HAL_M68K_MCF52xx_ISR_DEFAULT_PRIORITY_FLEXCAN[set ::flexcan]_ERRINT : \
+ CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MIN
+ legal_values CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MIN to CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MAX
+ description "
+ Interrupt priority for error interrupt."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN[set ::flexcan]_BOFFINT {
+ display "Bus off interrupt priority"
+ flavor data
+ default_value is_loaded(CYGNUM_HAL_M68K_MCF52xx_ISR_DEFAULT_PRIORITY_FLEXCAN[set ::flexcan]_BOFFINT) ? \
+ CYGNUM_HAL_M68K_MCF52xx_ISR_DEFAULT_PRIORITY_FLEXCAN[set ::flexcan]_BOFFINT : \
+ CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MIN
+ legal_values CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MIN to CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MAX
+ description "
+ Interrupt priority for bus off interrupt."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_DEFAULT_TX_MBOX {
+ display "Default TX buffer"
+ flavor data
+ calculated 15
+ description "
+ By default one message buffer will be used for message transmission.
+ This option selects one of the 16 FlexCAN message buffers for
+ transmission."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_STD_MBOXES {
+ display "11 Bit standard ID msg. buffers"
+ flavor booldata
+ requires CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_STD_MBOXES + CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_EXT_MBOXES < 16
+ implements CYGINT_IO_CAN_STD_CAN_ID
+ default_value 7
+ legal_values 1 to 15
+ description "
+ The FlexCAN module contains 16 message buffers. One message buffer
+ is reserved for message transmission. The remaining 15 buffers are
+ available for reception of messages. This configuration option
+ defines the number of message boxes for reception of CAN messages
+ with standard identifier. This configuration option does not matter
+ when you configure message filters at runtime. Only if the FlexCAN
+ modul is configured to receive all available standard CAN identifiers
+ (0 - 0x7FF), then this configuration option is important. If you get
+ RX overrun events, you should raise the number of message boxes or
+ lower the CAN baud rate."
+ }
+
+ cdl_option CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_EXT_MBOXES {
+ display "29 Bit extended ID msg. buffers"
+ flavor booldata
+ requires CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_STD_MBOXES + CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_EXT_MBOXES < 16
+ implements CYGINT_IO_CAN_EXT_CAN_ID
+ default_value 8
+ legal_values 1 to 15
+ description "
+ The FlexCAN module contain 16 message buffers. One message buffer
+ is reserved for message transmission. The remaining 15 buffers are
+ available for reception of messages. This configuration option
+ defines the number of message boxes for reception of CAN messages
+ with extended identifier. This configuration option does not matter
+ when you configure message filters at runtime. Only if the FlexCAN
+ modul is configured to receive all available standard CAN identifiers
+ (0 - 0x7FF), then this configuration option is important. If you get
+ RX overrun events, you should raise the number of message boxes or
+ lower the CAN baud rate."
+ }
+
+ cdl_component CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]_MBOXCFG {
+ display "Message buffer configuration"
+ flavor none
+ active_if CYGINT_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]
+ description "
+ The FlexCAN module contains 16 flexible message buffers of 0-8 bytes
+ data length, each configurable as Rx or Tx, all supporting standard and
+ extended messages. At the moment a fixed configuration is used for
+ TX and RX message buffers but in future this may be configurable."
+
+
+ # Support all 16 message buffers.
+ for { set ::mbox 0 } { $::mbox < 16 } { incr ::mbox } {
+
+ cdl_option CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN[set ::flexcan]_MBOX[set ::mbox] {
+ display "Interrupt priority for message buffer [set ::mbox]"
+ flavor data
+ default_value is_loaded(CYGNUM_HAL_M68K_MCF52xx_ISR_DEFAULT_PRIORITY_FLEXCAN[set ::flexcan]_MBOX[set ::mbox]) ? \
+ CYGNUM_HAL_M68K_MCF52xx_ISR_DEFAULT_PRIORITY_FLEXCAN[set ::flexcan]_MBOX[set ::mbox] : \
+ CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MIN
+ legal_values CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MIN to CYGNUM_HAL_M68K_MCF52xx_ISR_PRIORITY_MAX
+ description "
+ Interrupt priority for message buffer [set ::mbox]. Normally this should be
+ the default interrupt priority provided by HAL."
+ }
+ }
+ }
+ }
+ }
+
+ cdl_option CYGBLD_DEVS_CAN_MCF52xx_FLEXCAN_EXTRA_TESTS {
+ display "Build extra FlexCAN tests"
+ default_value 0
+ no_define
+ description "
+ This option enables the building of some extra tests which
+ can be used when testing / debugging FlexCAN drivers. These
+ are not built by default since they do not use the dedicated
+ testing infrastructure. All tests require a properly configured
+ CAN network with a second CAN node that can send and receive
+ CAN messages."
+
+ make -priority 320 {
+ <PREFIX>/bin/flexcan_wake : <PACKAGE>/tests/flexcan_wake.c
+ @sh -c "mkdir -p tests $(dir $@)"
+ $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/flexcan_wake.o $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+ @tail -n +2 deps.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm deps.tmp
+ $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/flexcan_wake.o
+ }
+ }
+}
diff --git a/ecos/packages/devs/can/m68k/mcf52xx/current/src/can_mcf52xx.c b/ecos/packages/devs/can/m68k/mcf52xx/current/src/can_mcf52xx.c
new file mode 100644
index 0000000..1702376
--- /dev/null
+++ b/ecos/packages/devs/can/m68k/mcf52xx/current/src/can_mcf52xx.c
@@ -0,0 +1,2739 @@
+//==========================================================================
+//
+// devs/serial/m68k/flexcan/current/src/can_mcf_flexcan.c
+//
+// CAN driver for Motorola coldfire processors
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-05-12
+// Purpose: support coldfire on-chip flexcan moduls
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/io_can.h>
+#include <pkgconf/devs_can_mcf52xx_flexcan.h>
+
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/can.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_io.h>
+
+
+//===========================================================================
+// DEFINES
+//===========================================================================
+
+//
+// we define our own ste of register bits in order to be independent from
+// platform specific names
+//
+
+//---------------------------------------------------------------------------
+// MCR regsiter bits
+//
+#define FLEXCAN_MCR_STOP (0x01 << 15)
+#define FLEXCAN_MCR_FRZ (0x01 << 14)
+#define FLEXCAN_MCR_HALT (0x01 << 12)
+#define FLEXCAN_MCR_NOTRDY (0x01 << 11)
+#define FLEXCAN_MCR_WAKEMSK (0x01 << 10)
+#define FLEXCAN_MCR_SOFTRST (0x01 << 9)
+#define FLEXCAN_MCR_FRZACK (0x01 << 8)
+#define FLEXCAN_MCR_SUPV (0x01 << 7)
+#define FLEXCAN_MCR_SELFWAKE (0x01 << 6)
+#define FLEXCAN_MCR_APS (0x01 << 5)
+#define FLEXCAN_MCR_STOPACK (0x01 << 4)
+
+
+//---------------------------------------------------------------------------
+// CTRL0 register bits
+//
+#define FLEXCAN_CTRL0_BOFFMSK (0x01 << 7)
+#define FLEXCAN_CTRL0_ERRMASK (0x01 << 6)
+#define FLEXCAN_CTRL0_RXMODE (0x01 << 2)
+#define FLEXCAN_CTRL0_RXMODE_0_DOMINANT (0x00 << 2)
+#define FLEXCAN_CTRL0_RXMODE_1_DOMINANT (0x01 << 2)
+#define FLEXCAN_CTRL0_TXMODE_MASK (0x03 << 0)
+#define FLEXCAN_CTRL0_TXMODE_SHIFT 0
+#define FLEXCAN_CTRL0_TXMODE_FULL_0_DOMINANT (0x00 << 0)
+#define FLEXCAN_CTRL0_TXMODE_FULL_1_DOMINANT (0x01 << 0)
+#define FLEXCAN_CTRL0_TXMODE_OPEN_0_DOMINANT (0x02 << 0)
+
+
+//---------------------------------------------------------------------------
+// CTRL1 register bits
+//
+#define FLEXCAN_CTRL1_SAMP (0x01 << 7)
+#define FLEXCAN_CTRL1_TSYNC (0x01 << 5)
+#define FLEXCAN_CTRL1_LBUF (0x01 << 4)
+#define FLEXCAN_CTRL1_LOM (0x01 << 3)
+#define FLEXCAN_CTRL1_PROPSEG_MASK (0x07 << 0)
+#define FLEXCAN_CTRL1_PROPSEG_SHIFT 0
+
+
+//---------------------------------------------------------------------------
+// CTRL2 register bits
+//
+#define FLEXCAN_CTRL2_RJW_MASK (0x03 << 6)
+#define FLEXCAN_CTRL2_RJW_SHIFT 6
+#define FLEXCAN_CTRL2_PSEG1_MASK (0x07 << 3)
+#define FLEXCAN_CTRL2_PSEG1_SHIFT 3
+#define FLEXCAN_CTRL2_PSEG2_MASK (0x07 << 0)
+#define FLEXCAN_CTRL2_PSEG2_SHIFT 0
+
+//---------------------------------------------------------------------------
+// ESTAT register bits
+//
+#define FLEXCAN_ESTAT_BITERR_MASK (0x03 << 14)
+#define FLEXCAN_ESTAT_BITERR_SHIFT 14
+#define FLEXCAN_ESTAT_BITERR_NONE (0x00 << 14)
+#define FLEXCAN_ESTAT_BITERR_DOMINANT_RECESSIVE (0x01 << 14)
+#define FLEXCAN_ESTAT_BITERR_RECESSIVE_DOMINANT (0x02 << 14)
+#define FLEXCAN_ESTAT_ACKERR (0x01 << 13)
+#define FLEXCAN_ESTAT_CRCERR (0x01 << 12)
+#define FLEXCAN_ESTAT_FORMERR (0x01 << 11)
+#define FLEXCAN_ESTAT_STUFFERR (0x01 << 10)
+#define FLEXCAN_ESTAT_TXWARN (0x01 << 9)
+#define FLEXCAN_ESTAT_RXWARN (0x01 << 8)
+#define FLEXCAN_ESTAT_IDLE (0x01 << 7)
+#define FLEXCAN_ESTAT_TX_RX (0x01 << 6)
+#define FLEXCAN_ESTAT_FCS_MASK (0x03 << 4)
+#define FLEXCAN_ESTAT_FCS_SHIFT 4
+#define FLEXCAN_ESTAT_FCS_ERROR_ACTIVE (0x00 << 4)
+#define FLEXCAN_ESTAT_FCS_ERROR_PASSIVE (0x01 << 4)
+#define FLEXCAN_ESTAT_BOFFINT (0x01 << 2)
+#define FLEXCAN_ESTAT_ERRINT (0x01 << 1)
+#define FLEXCAN_ESTAT_WAKEINT (0x01 << 0)
+
+//
+// For receive event calls we use these two identifiers for
+// err and bus off events - message boxes use 0 - 15
+//
+#define FLEXCAN_ERR_EVENT 16
+#define FLEXCAN_BUSOFF_EVENT 17
+#define FLEXCAN_WAKE_EVENT 18
+
+//
+// Acceptance mask
+//
+#define FLEXCAN_ACCEPTANCE_MASK_RX_ALL 0x00 // receive all messages - mbox ID does not matter
+#define FLEXCAN_ACCEPTANCE_MASK_RX_ID 0x1FFFFFFF // receive only messages where ID exactly matches mbox ID
+
+
+//---------------------------------------------------------------------------
+// message buffer cfg bits
+//
+#define MBOX_RXCODE_NOT_ACTIVE 0x00
+#define MBOX_RXCODE_BUSY 0x10
+#define MBOX_RXCODE_EMPTY 0x40
+#define MBOX_RXCODE_FULL 0x20
+#define MBOX_RXCODE_OVERRUN 0x60
+
+#define MBOX_TXCODE_NOT_READY 0x80
+#define MBOX_TXCODE_TRANSMIT 0xC0
+#define MBOX_TXCODE_RESPONSE 0xA0
+
+#define MBOX_DATA_FRAME 0x00 // data frame
+#define MBOX_REMOTE_FRAME 0x01 // remote frame
+#define MBOX_STD_ID 0x00 // standard identifier
+#define MBOX_EXT_ID 0x01 // remote identifier
+#define MBOX_TX 0x08 // tx message box
+#define MBOX_RX 0x00 // rx messge box
+
+#define MBOX_CFG_IDE 0x08
+#define MBOX_CFG_RTR_EXT 0x01
+#define MBOX_CFG_RTR_STD 0x10
+#define MBOX_CFG_SSR 0x10
+#define MBOX_CFG_DLC_MASK 0x0F
+#define MBOX_CFG_STAT_MASK 0xF0
+
+
+//---------------------------------------------------------------------------
+// flexcan message buffer configuration
+//
+#define FLEXCAN_MBOX_MIN 0
+#define FLEXCAN_MBOX_MAX 15
+#define FLEXCAN_MBOX_CNT 16
+#define FLEXCAN_MBOX_TX CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_DEFAULT_TX_MBOX
+#define FLEXCAN_MBOX_RX_MIN 0
+#define FLEXCAN_MBOX_RX_MAX (FLEXCAN_MBOX_MAX - 1) // one msg box is tx
+#define FLEXCAN_MBOX_RX_CNT (FLEXCAN_MBOX_CNT - 1) // one msg box is tx
+
+
+#define FLEXCAN_CTRLSTAT_NOT_READ 0 // indicates that control status register is not read
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+//
+// Type of message buffer - required for function getevent in order to
+// identify the type of message box that cause event
+//
+typedef enum
+{
+ MBOX_STATE_DISABLED, // message box unused (free)
+ MBOX_STATE_TX, // TX message box
+ MBOX_STATE_REMOTE_TX, // remote TX msaage box (data will be sent on reception of rtr frame)
+ MBOX_STATE_RX_ALL_STD, // RX message box for standard IDs
+ MBOX_STATE_RX_ALL_EXT, // RX message box for standard IDs
+ MBOX_STATE_RX_FILT // RX message box for filter mboxes
+} flexcan_mbox_state;
+
+
+//
+// configuration info for flexcan message buffer
+//
+typedef struct flexcan_mbox_info_st
+{
+ cyg_vector_t isr_vec; // isr vector
+ int isr_priority; // isr priority
+ cyg_interrupt interrupt; // stores interrupt data
+ cyg_handle_t interrupt_handle; // stores interrupt number
+ cyg_uint8 num; // number of message buffer
+ bool busy; // if true, then transmission or reception is in progress
+ flexcan_mbox_state state; // message box state
+ cyg_uint8 ctrlstat_shadow; // shadow register of message box ctrlstat register
+} flexcan_mbox_info;
+
+//
+// Between ISR and DSR handling there is some kind of circular buffer.
+// A DSR is only invoked if no other message box invoked a DSR before
+// the DSR will read all available message buffers. This structure
+// is for exchange of information between ISR and DSR
+//
+typedef struct st_rxmbox_circbuf
+{
+ cyg_uint8 idx_rd; // the message box the DSR will read from
+ cyg_uint8 idx_wr; // the message box that will receive the next message
+ cyg_uint8 count; // the number of received message before DSR starts (number of ISR nesting)
+} flexcan_rxmbox_circbuf;
+
+//
+// flexcan interrupt (busoff, err, wake) data - stores interrupt data for
+// a non message box interrupt (bus off, err or wake interrupt)
+//
+typedef struct flexcan_int_st
+{
+ cyg_vector_t isr_vec;
+ int isr_priority;
+ cyg_interrupt interrupt;
+ cyg_handle_t interrupt_handle;
+} flexcan_int;
+
+//
+// flexcan message box initialisation
+//
+#define FLEXCAN_MBOX_INIT(_mbox0_vec, _prio, _mbox_no) { \
+ isr_vec : (_mbox0_vec) + (_mbox_no), \
+ isr_priority : (_prio), \
+ num : (_mbox_no), \
+ busy : false \
+}
+
+//
+// Interrupt initialisation
+//
+#define FLEXCAN_INT_INIT(_vec, _prio) \
+{ \
+ isr_vec : (_vec), \
+ isr_priority : (_prio) \
+}
+
+//
+// flexcan configuration
+//
+typedef struct flexcan_info
+{
+ cyg_uint8 *base; // base address of flexcan modul
+ cyg_vector_t isr_vec_mbox0; // vector number of ISR vector of first message box
+ flexcan_mbox_info mboxes[FLEXCAN_MBOX_CNT];// message boxes
+ cyg_uint32 last_tx_id; // last transmitted message identifier
+
+ flexcan_int boff_int; // bus off interrupt data
+ flexcan_int err_int; // error interrupt data
+ flexcan_int wake_int; // wake interrupt data
+
+ cyg_uint8 tx_all_mbox; // number of message box for all transmit messages
+ cyg_uint8 free_mboxes; // number of free message boxes for msg filters and rtr buffers
+ cyg_can_state state; // state of CAN controller
+
+ flexcan_rxmbox_circbuf rxmbox_std_circbuf;
+ flexcan_rxmbox_circbuf rxmbox_ext_circbuf;
+
+ cyg_uint8 mboxes_std_cnt; // contains number of standard message boxes available
+ cyg_uint8 mboxes_ext_cnt; // number of message boxes with ext id
+ cyg_uint8 mboxes_rx_all_cnt;// number of all available mboxes
+
+ bool rx_all; // true if reception of call can messages is active
+ cyg_uint16 imask_shadow; // interrupt mask shadow register
+#ifdef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ cyg_can_message last_tx_msg; // stores last transmitted message for TX events
+#endif
+
+#ifdef FLEXCAN_CAN_STATS
+ cyg_uint32 isr_count;
+ cyg_uint32 dsr_count;
+ cyg_uint32 rx_bytes;
+ cyg_uint32 tx_bytes;
+ cyg_uint32 rx_errors;
+#endif
+} flexcan_info;
+
+
+//
+// flexcan info initialisation
+//
+#define FLEXCAN_INFO(_l, \
+ _baseaddr, \
+ _isr_vec_mbox0, \
+ _mbox0_isr_prio, \
+ _mbox1_isr_prio, \
+ _mbox2_isr_prio, \
+ _mbox3_isr_prio, \
+ _mbox4_isr_prio, \
+ _mbox5_isr_prio, \
+ _mbox6_isr_prio, \
+ _mbox7_isr_prio, \
+ _mbox8_isr_prio, \
+ _mbox9_isr_prio, \
+ _mbox10_isr_prio, \
+ _mbox11_isr_prio, \
+ _mbox12_isr_prio, \
+ _mbox13_isr_prio, \
+ _mbox14_isr_prio, \
+ _mbox15_isr_prio, \
+ _boff_isr_vec, _boff_isr_prio, \
+ _err_isr_vec, _err_isr_prio, \
+ _wake_isr_vec, _wake_isr_prio, \
+ _tx_all_mbox, \
+ _std_mboxes, _ext_mboxes) \
+flexcan_info _l = { \
+ (void *)( _baseaddr), \
+ (_isr_vec_mbox0), \
+ mboxes : { \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox0_isr_prio), 0), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox1_isr_prio), 1), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox2_isr_prio), 2), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox3_isr_prio), 3), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox4_isr_prio), 4), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox5_isr_prio), 5), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox6_isr_prio), 6), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox7_isr_prio), 7), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox8_isr_prio), 8), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox9_isr_prio), 9), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox10_isr_prio),10), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox11_isr_prio),11), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox12_isr_prio),12), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox13_isr_prio),13), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox14_isr_prio),14), \
+ FLEXCAN_MBOX_INIT((_isr_vec_mbox0), (_mbox15_isr_prio),15), \
+ }, \
+ last_tx_id : 0xFFFFFFFF, \
+ boff_int : FLEXCAN_INT_INIT(_boff_isr_vec, _boff_isr_prio), \
+ err_int : FLEXCAN_INT_INIT(_err_isr_vec, _err_isr_prio), \
+ wake_int : FLEXCAN_INT_INIT(_wake_isr_vec, _wake_isr_prio), \
+ tx_all_mbox : _tx_all_mbox, \
+ free_mboxes : ((_std_mboxes) + (_ext_mboxes)), \
+ state : CYGNUM_CAN_STATE_ACTIVE, \
+ rx_all : true, \
+ mboxes_std_cnt : _std_mboxes, \
+ mboxes_ext_cnt : _ext_mboxes, \
+ mboxes_rx_all_cnt : ((_std_mboxes) + (_ext_mboxes)) \
+};
+
+
+//===========================================================================
+// GLOBAL DATA
+//===========================================================================
+//
+// Note: two levels of macro are required to get proper expansion.
+//
+#define _FLEXCAN_MBOX_INTPRIO(n) CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX##n
+#define FLEXCAN_MBOX_INTPRIO(n) _FLEXCAN_MBOX_INTPRIO(n)
+
+//
+// Define number of message boxes if they are not defined yet
+//
+#ifndef CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_STD_MBOXES
+#define CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_STD_MBOXES 0
+#endif
+#ifndef CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_EXT_MBOXES
+#define CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_EXT_MBOXES 0
+#endif
+#ifndef CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN1_STD_MBOXES
+#define CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN1_STD_MBOXES 0
+#endif
+#ifndef CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN1_EXT_MBOXES
+#define CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN1_EXT_MBOXES 0
+#endif
+
+
+#ifdef CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN0
+//
+// FlexCAN channel initialisation for FlexCAN channel 0
+//
+FLEXCAN_INFO(flexcan_can0_info,
+ HAL_MCF52xx_MBAR + HAL_MCF52xx_FLEXCAN0_BASE,
+ HAL_MCF52xx_FLEXCAN0_MBOX0_ISRVEC,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX0,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX1,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX2,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX3,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX4,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX5,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX6,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX7,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX8,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX9,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX10,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX11,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX12,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX13,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX14,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_MBOX15,
+ HAL_MCF52xx_FLEXCAN0_BOFF_ISRVEC,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_BOFFINT,
+ HAL_MCF52xx_FLEXCAN0_ERR_ISRVEC,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_ERRINT,
+ HAL_MCF52xx_FLEXCAN0_WAKE_ISRVEC,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN0_WAKEINT,
+ CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_DEFAULT_TX_MBOX,
+ CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_STD_MBOXES,
+ CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_EXT_MBOXES);
+#endif // CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN[set ::flexcan]
+
+#ifdef CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN1
+//
+// FlexCAN channel initialisation for FlexCAN channel 1
+//
+FLEXCAN_INFO(flexcan_can0_info,
+ HAL_MCF52xx_MBAR + HAL_MCF52xx_FLEXCAN0_BASE,
+ HAL_MCF52xx_FLEXCAN1_MBOX0_ISRVEC,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX0,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX1,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX2,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX3,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX4,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX5,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX6,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX7,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX8,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX9,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX10,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX11,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX12,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX13,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX14,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_MBOX15,
+ HAL_MCF52xx_FLEXCAN1_BOFF_ISRVEC,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_BOFFINT,
+ HAL_MCF52xx_FLEXCAN1_ERR_ISRVEC,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_ERRINT,
+ HAL_MCF52xx_FLEXCAN1_WAKE_ISRVEC,
+ CYGNUM_DEVS_CAN_MCF52xx_ISR_PRIORITY_FLEXCAN1_WAKEINT,
+ CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN1_DEFAULT_TX_MBOX,
+ CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN1_STD_MBOXES,
+ CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN1_EXT_MBOXES);
+#endif // CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN1
+
+//
+// message box structure for hardware access of message box
+//
+typedef struct flexcan_mbox
+{
+ cyg_uint8 timestamp;
+ cyg_uint8 ctrlstat;
+ cyg_uint16 id_hi;
+ cyg_uint16 id_lo;
+ cyg_uint8 data[8];
+ cyg_uint16 reserved;
+} flexcan_mbox;
+
+//
+// flexcan register layout for hardware register access of FlexCAN modul
+//
+typedef struct flexcan_regs
+{
+ cyg_uint16 CANMCR; // 0x00
+ cyg_uint16 reserved0[2]; // 0x02
+ cyg_uint8 CANCTRL0; // 0x06
+ cyg_uint8 CANCTRL1; // 0x07
+ cyg_uint8 PRESDIV; // 0x08
+ cyg_uint8 CANCTRL2; // 0x09
+ cyg_uint16 TIMER; // 0x0A
+ cyg_uint16 reserved1[2]; // 0x0C
+ cyg_uint16 RXGMASK_HI; // 0x10
+ cyg_uint16 RXGMASK_LO; // 0x12
+ cyg_uint16 RX14MASK_HI; // 0x14
+ cyg_uint16 RX14MASK_LO; // 0x16
+ cyg_uint16 RX15MASK_HI; // 0x18
+ cyg_uint16 RX15MASK_LO; // 0x1A
+ cyg_uint16 reserved2[2]; // 0x1C
+ cyg_uint16 ESTAT; // 0x20
+ cyg_uint16 IMASK; // 0x22
+ cyg_uint16 IFLAG; // 0x24
+ cyg_uint8 RXERRCNT; // 0x26
+ cyg_uint8 TXERRCNT; // 0x27
+ cyg_uint16 reserved3[44];// 0x28
+ flexcan_mbox mbox[16]; // 0x80
+} flexcan_regs;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+static cyg_uint16 flexcan_baud_rates[] = {
+ 0, // Unused
+ 10, // 10 kbit/s
+ 20, // 20
+ 50, // 50
+ 100, // 100
+ 125, // 125
+ 250, // 250
+ 500, // 500
+ 800, // 800
+ 1000, // 1000 kbit/s
+};
+
+
+//===========================================================================
+// PROTOTYPES
+//===========================================================================
+static bool flexcan_init(struct cyg_devtab_entry* devtab_entry);
+static Cyg_ErrNo flexcan_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name);
+static Cyg_ErrNo flexcan_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
+static Cyg_ErrNo flexcan_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len);
+static bool flexcan_putmsg(can_channel *priv, cyg_can_message *pmsg, void *pdata);
+static bool flexcan_getevent(can_channel *priv, cyg_can_event *pevent, void *pdata);
+static void flexcan_start_xmit(can_channel* chan);
+static void flexcan_stop_xmit(can_channel* chan);
+
+//
+// TX and RX ISRs and DSRs
+//
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+static cyg_uint32 flexcan_mbox_rx_std_isr(cyg_vector_t, cyg_addrword_t);
+static void flexcan_mbox_rx_std_dsr(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+static cyg_uint32 flexcan_mbox_rx_ext_isr(cyg_vector_t, cyg_addrword_t);
+static void flexcan_mbox_rx_ext_dsr(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+static cyg_uint32 flexcan_mbox_rx_filt_isr(cyg_vector_t, cyg_addrword_t);
+static cyg_uint32 flexcan_mbox_tx_isr(cyg_vector_t, cyg_addrword_t);
+static void flexcan_mbox_tx_dsr(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
+static void flexcan_mbox_rx_filt_dsr(cyg_vector_t, cyg_ucount32, cyg_addrword_t );
+
+//
+// All other flexcan interrupt handlers
+//
+static cyg_uint32 flexcan_err_isr(cyg_vector_t, cyg_addrword_t);
+static void flexcan_err_dsr(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
+static cyg_uint32 flexcan_busoff_isr(cyg_vector_t, cyg_addrword_t);
+static void flexcan_busoff_dsr(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
+static cyg_uint32 flexcan_wake_isr(cyg_vector_t, cyg_addrword_t);
+static void flexcan_wake_dsr(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
+
+//
+// Flexcan utility functions
+//
+static bool flexcan_cfg_mbox_tx(flexcan_mbox *pmbox, cyg_can_message *pmsg, bool rtr);
+static void flexcan_cfg_mbox_rx(flexcan_mbox *pmbox, cyg_can_message *pmsg, bool enable);
+static void flexcan_read_from_mbox(can_channel *chan, cyg_uint8 mbox, cyg_can_event *pevent, cyg_uint8 *ctrlstat);
+static void flexcan_set_acceptance_mask(cyg_uint16 *rxmask_reg, cyg_uint32 mask, cyg_can_id_type ext);
+static void flexcan_start_chip(can_channel *chan);
+static void flexcan_enter_standby(can_channel *chan, bool selfwake);
+static void flexcan_stop_chip(can_channel *chan);
+static void flexcan_leave_standby(can_channel *chan);
+static bool flexcan_set_baud(can_channel *chan, cyg_uint16 baudrate);
+static bool flexcan_config(can_channel* chan, cyg_can_info_t* config, cyg_bool init);
+static cyg_int8 flexcan_alloc_mbox(flexcan_info *info);
+static void flexcan_disable_mbox(can_channel *chan, cyg_uint32 mbox_id);
+static void flexcan_setup_rxmbox(can_channel *chan, cyg_uint32 mbox_id, cyg_ISR_t *isr, cyg_can_message *pmsg, bool enable, bool int_enable);
+static void flexcan_setup_txmbox(can_channel *chan, cyg_uint32 mbox_id, cyg_can_message *pmsg);
+static void flexcan_setup_rtrmbox(can_channel *chan, cyg_uint32 mbox_id, cyg_can_message *pmsg);
+static void flexcan_mboxint_enable(flexcan_info *info, cyg_uint32 mbox_id);
+static void flexcan_mboxint_disable(flexcan_info *info, cyg_uint32 mbox_id);
+static void flexcan_config_rx_all(can_channel *chan);
+static void flexcan_enable_rxmbox(can_channel *chan, cyg_uint32 mbox_id);
+
+
+CAN_LOWLEVEL_FUNS(flexcan_lowlevel_funs,
+ flexcan_putmsg,
+ flexcan_getevent,
+ flexcan_get_config,
+ flexcan_set_config,
+ flexcan_start_xmit,
+ flexcan_stop_xmit
+ );
+
+
+cyg_can_event flexcan_can0_rxbuf[CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_RX]; // buffer for 32 rx can events
+cyg_can_message flexcan_can0_txbuf[CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_TX]; // buffer for 32 tx can messageds
+
+
+CAN_CHANNEL_USING_INTERRUPTS(flexcan_can0_chan,
+ flexcan_lowlevel_funs,
+ flexcan_can0_info,
+ CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_KBAUD),
+ flexcan_can0_txbuf, CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_TX,
+ flexcan_can0_rxbuf, CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_RX
+ );
+
+
+DEVTAB_ENTRY(flexcan_devtab,
+ CYGDAT_DEVS_CAN_MCF52xx_FLEXCAN0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_can_devio,
+ flexcan_init,
+ flexcan_lookup, // CAN driver may need initializing
+ &flexcan_can0_chan
+ );
+
+
+//===========================================================================
+// Lookup the device and return its handle
+//===========================================================================
+static Cyg_ErrNo
+flexcan_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name)
+{
+ can_channel* chan = (can_channel*) (*tab)->priv;
+ (chan->callbacks->can_init)(chan);
+
+ return ENOERR;
+}
+
+
+//===========================================================================
+// Enable hardware message box for reception
+//===========================================================================
+static __inline__ void flexcan_hwmbox_enable_rx(flexcan_regs *flexcan, cyg_uint32 mbox_id)
+{
+ HAL_WRITE_UINT8(&(flexcan->mbox[mbox_id].ctrlstat), MBOX_RXCODE_EMPTY);
+}
+
+
+//===========================================================================
+// Disable hardware message box
+//===========================================================================
+static __inline__ void flexcan_hwmbox_disable(flexcan_regs *flexcan, cyg_uint32 mbox_id)
+{
+ HAL_WRITE_UINT8(&(flexcan->mbox[mbox_id].ctrlstat), MBOX_RXCODE_NOT_ACTIVE);
+}
+
+
+//===========================================================================
+// lock mbox by reading control status register
+//===========================================================================
+static __inline__ void flexcan_hwmbox_lock(flexcan_regs *flexcan, cyg_uint32 mbox_id, cyg_uint8 *pctrlstat)
+{
+ HAL_READ_UINT8(&(flexcan->mbox[mbox_id].ctrlstat), *pctrlstat); // this read will lock the mbox
+}
+
+
+//===========================================================================
+// Enable message box interrupt for one message box
+//===========================================================================
+static void flexcan_mboxint_enable(flexcan_info *info, cyg_uint32 mbox_id)
+{
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+
+ info->imask_shadow |= (0x0001 << mbox_id);
+ HAL_WRITE_UINT16(&flexcan->IMASK, info->imask_shadow);
+}
+
+
+//===========================================================================
+// Disable message box interrupt for one message box
+//===========================================================================
+static void flexcan_mboxint_disable(flexcan_info *info, cyg_uint32 mbox_id)
+{
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+
+ info->imask_shadow &= ~(0x0001 << mbox_id);
+ HAL_WRITE_UINT16(&flexcan->IMASK, info->imask_shadow);
+}
+
+
+//===========================================================================
+// Allocate message box
+// Try to find a free message box and return its ID
+//===========================================================================
+static cyg_int8 flexcan_alloc_mbox(flexcan_info *info)
+{
+ cyg_uint8 i;
+ cyg_int8 res = CYGNUM_CAN_MSGBUF_NA;
+
+ if (info->free_mboxes)
+ {
+ for (i = (FLEXCAN_MBOX_RX_CNT - info->free_mboxes); i <= FLEXCAN_MBOX_RX_MAX; ++i)
+ {
+ if (MBOX_STATE_DISABLED == info->mboxes[i].state)
+ {
+ info->free_mboxes--;
+ res = i;
+ break;
+ }
+ }
+ } // if (info->free_mboxes)
+
+ return res;
+}
+
+
+//===========================================================================
+// Enable a previously configured rx mbox - a mbox ready to recive
+//===========================================================================
+static void flexcan_enable_rxmbox(can_channel *chan,
+ cyg_uint32 mbox_id)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+
+ flexcan_hwmbox_enable_rx(flexcan, mbox_id);
+ flexcan_mboxint_enable(info, mbox_id);
+}
+
+//===========================================================================
+// Prepare message buffer filter
+// Setup a RX message box for reception of a certain CAN identifier but do
+// not enable it
+//===========================================================================
+static void flexcan_setup_rxmbox(can_channel *chan,
+ cyg_uint32 mbox_id,
+ cyg_ISR_t *isr,
+ cyg_can_message *pmsg,
+ bool enable,
+ bool int_enable)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ flexcan_mbox_info *pmbox;
+ cyg_DSR_t *dsr_func = &flexcan_mbox_rx_filt_dsr;
+
+ //
+ // Set state of message buffer accoring to ISR function that
+ // will be registered
+ //
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ if (*isr == flexcan_mbox_rx_std_isr)
+ {
+ //
+ // If we have only one single RX all message box then we use
+ // the filter ISR instead of RX all standard ISR because it
+ // is better suited for a single RX mbox
+ //
+ if (info->mboxes_std_cnt > 1)
+ {
+ info->mboxes[mbox_id].state = MBOX_STATE_RX_ALL_STD;
+ dsr_func = &flexcan_mbox_rx_std_dsr;
+ }
+ else
+ {
+ info->mboxes[mbox_id].state = MBOX_STATE_RX_FILT;
+ isr = flexcan_mbox_rx_filt_isr;
+ }
+ }
+ else
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (*isr == flexcan_mbox_rx_ext_isr)
+ {
+ //
+ // If we have only one single RX all message box then we use
+ // the filter ISR instead of RX all standard ISR because it
+ // is better suited for a single RX mbox
+ //
+ if (info->mboxes_ext_cnt > 1)
+ {
+ info->mboxes[mbox_id].state = MBOX_STATE_RX_ALL_EXT;
+ dsr_func = &flexcan_mbox_rx_ext_dsr;
+ }
+ else
+ {
+ info->mboxes[mbox_id].state = MBOX_STATE_RX_FILT;
+ isr = flexcan_mbox_rx_filt_isr;
+ }
+ }
+ else
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ if (*isr == flexcan_mbox_rx_filt_isr)
+ {
+ info->mboxes[mbox_id].state = MBOX_STATE_RX_FILT;
+ }
+ else
+ {
+ CYG_ASSERT(0, "Invalid ISR function pointer");
+ }
+
+ pmbox = &info->mboxes[mbox_id];
+ flexcan_cfg_mbox_rx(&flexcan->mbox[mbox_id], pmsg, enable);
+
+ cyg_drv_interrupt_create(pmbox->isr_vec,
+ pmbox->isr_priority,
+ (cyg_addrword_t) chan,
+ isr,
+ dsr_func,
+ &(pmbox->interrupt_handle),
+ &(pmbox->interrupt));
+ cyg_drv_interrupt_attach(pmbox->interrupt_handle);
+ cyg_drv_interrupt_unmask(pmbox->isr_vec);
+
+ //
+ // now enable interrupt for this message box - but only if we
+ // really should do it
+ //
+ if (int_enable)
+ {
+ flexcan_mboxint_enable(info, mbox_id);
+ }
+}
+
+
+//===========================================================================
+// Disable a message box - after this call a message box is available
+// again for message filters or remote buffers
+//===========================================================================
+static void flexcan_disable_mbox(can_channel *chan, cyg_uint32 mbox_id)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ flexcan_mbox_info *pmbox;
+
+ //
+ // if message box is already disabled we do not need to disable it
+ // here
+ //
+ if (MBOX_STATE_DISABLED == info->mboxes[mbox_id].state)
+ {
+ return;
+ }
+
+ HAL_WRITE_UINT8(&flexcan->mbox[mbox_id].ctrlstat, MBOX_RXCODE_NOT_ACTIVE);
+ info->mboxes[mbox_id].state = MBOX_STATE_DISABLED;
+ pmbox = &info->mboxes[mbox_id];
+
+ //
+ // now disable interrupts for this message box and free all
+ // interrupt resources
+ //
+ flexcan_mboxint_disable(info, mbox_id);
+ cyg_drv_interrupt_mask(pmbox->isr_vec);
+ cyg_drv_interrupt_detach(pmbox->interrupt_handle);
+ cyg_drv_interrupt_delete(pmbox->interrupt_handle);
+
+ info->free_mboxes++;
+}
+
+
+//===========================================================================
+// Setup a transmit message box
+//===========================================================================
+static void flexcan_setup_txmbox(can_channel *chan,
+ cyg_uint32 mbox_id,
+ cyg_can_message *pmsg)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ flexcan_mbox_info *pmbox;
+
+ info->mboxes[mbox_id].state = MBOX_STATE_TX;
+ pmbox = &info->mboxes[mbox_id];
+ flexcan_cfg_mbox_tx(&flexcan->mbox[mbox_id], pmsg, false);
+
+ //
+ // prepare message box interrupt for message box
+ //
+ cyg_drv_interrupt_create(pmbox->isr_vec,
+ pmbox->isr_priority,
+ (cyg_addrword_t) chan,
+ &flexcan_mbox_tx_isr,
+ &flexcan_mbox_tx_dsr,
+ &(pmbox->interrupt_handle),
+ &(pmbox->interrupt));
+ cyg_drv_interrupt_attach(pmbox->interrupt_handle);
+ cyg_drv_interrupt_unmask(pmbox->isr_vec);
+
+ //
+ // now enable interrupt for this message box
+ //
+ flexcan_mboxint_enable(info, mbox_id);
+}
+
+
+//===========================================================================
+// Setup a RTR response message box
+//===========================================================================
+static void flexcan_setup_rtrmbox(can_channel *chan,
+ cyg_uint32 mbox_id,
+ cyg_can_message *pmsg)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+
+ info->mboxes[mbox_id].state = MBOX_STATE_REMOTE_TX;
+ flexcan_cfg_mbox_tx(&flexcan->mbox[mbox_id], pmsg, true);
+}
+
+
+//===========================================================================
+// Setup the list of message boxes ready to receive a message
+//===========================================================================
+static void flexcan_setup_rxmbox_circbuf(flexcan_rxmbox_circbuf *pbuf)
+{
+ pbuf->count = 0;
+ pbuf->idx_rd = 0;
+ pbuf->idx_wr = 0;
+}
+
+
+//===========================================================================
+// Setup flexCAN modul for reception of any kind of message
+//===========================================================================
+static void flexcan_config_rx_all(can_channel *chan)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_int8 i;
+
+ //
+ // setup all available message boxes for reception of of messages
+ // All standard and extended message buffers will be configured
+ //
+ for (i = 0; i < info->mboxes_rx_all_cnt; ++i)
+ {
+ cyg_can_message filter_param;
+ filter_param.id = 0;
+
+ //
+ // configure message buffers for standard frames
+ //
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ if (i < info->mboxes_std_cnt)
+ {
+ filter_param.ext = CYGNUM_CAN_ID_STD;
+ flexcan_setup_rxmbox(chan, i, &flexcan_mbox_rx_std_isr, &filter_param, false, true);
+ }
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+ //
+ // configure message buffers for extended frames
+ //
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ else
+ {
+ filter_param.ext = CYGNUM_CAN_ID_EXT;
+ flexcan_setup_rxmbox(chan, i, &flexcan_mbox_rx_ext_isr, &filter_param, false, true);
+ }
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+ }
+
+ //
+ // We need to receive all available CAN messages so we have to set the acceptance filter
+ // properly
+ //
+ flexcan_set_acceptance_mask(&flexcan->RXGMASK_HI, FLEXCAN_ACCEPTANCE_MASK_RX_ALL, CYGNUM_CAN_ID_EXT);
+ flexcan_set_acceptance_mask(&flexcan->RX14MASK_HI, FLEXCAN_ACCEPTANCE_MASK_RX_ALL, CYGNUM_CAN_ID_EXT);
+ info->free_mboxes = FLEXCAN_MBOX_RX_CNT - info->mboxes_rx_all_cnt;
+ info->rx_all = true;
+
+ //
+ // now finally setup the first active message boxes and enable ist
+ //
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+ if (info->mboxes_std_cnt)
+ {
+ flexcan_setup_rxmbox_circbuf(&info->rxmbox_std_circbuf);
+ flexcan_enable_rxmbox(chan, 0);
+ }
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+ if (info->mboxes_ext_cnt)
+ {
+ flexcan_setup_rxmbox_circbuf(&info->rxmbox_ext_circbuf);
+ flexcan_enable_rxmbox(chan, info->mboxes_std_cnt);
+ }
+#endif // CYGOPT_IO_CAN_EXT_CAN_ID
+
+}
+
+//===========================================================================
+// Setup Flex CAN moduls in a state where all message boxes are disabled
+// After this call single message filters and buffers can be added
+//===========================================================================
+static void flexcan_config_rx_none(can_channel *chan)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_int8 i;
+
+ //
+ // setup all RX messages moxes into a disabled state
+ //
+ for (i = 0; i < FLEXCAN_MBOX_RX_CNT; ++i)
+ {
+ flexcan_disable_mbox(chan, i);
+ }
+
+ //
+ // If we want to receive only certain CAN identiffiers then the ID does matter and
+ // we have to setup the acceptance mask properly
+ //
+ flexcan_set_acceptance_mask(&flexcan->RXGMASK_HI, FLEXCAN_ACCEPTANCE_MASK_RX_ID, CYGNUM_CAN_ID_EXT);
+ flexcan_set_acceptance_mask(&flexcan->RX14MASK_HI, FLEXCAN_ACCEPTANCE_MASK_RX_ID, CYGNUM_CAN_ID_EXT);
+ info->free_mboxes = FLEXCAN_MBOX_RX_CNT;
+ info->rx_all = false;
+}
+
+
+//===========================================================================
+// Configure message buffers
+//===========================================================================
+static Cyg_ErrNo flexcan_set_config_msgbuf(can_channel *chan, cyg_can_msgbuf_cfg *buf)
+{
+ Cyg_ErrNo res = ENOERR;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+
+ switch (buf->cfg_id)
+ {
+ //
+ // clear all message filters and remote buffers - prepare for message buffer
+ // configuration
+ //
+ case CYGNUM_CAN_MSGBUF_RESET_ALL :
+ {
+ flexcan_config_rx_none(chan);
+ }
+ break;
+
+ //
+ // setup FlexCAN modul for reception of all standard and extended messages
+ //
+ case CYGNUM_CAN_MSGBUF_RX_FILTER_ALL :
+ {
+ if (!info->rx_all) // if rx_all is enabled we do not need to do anything
+ {
+ flexcan_config_rx_none(chan); // set into default state
+ flexcan_config_rx_all(chan); // setup RX all state
+ }
+ }
+ break;
+
+ //
+ // add single message filter, message with filter ID will be received
+ //
+ case CYGNUM_CAN_MSGBUF_RX_FILTER_ADD :
+ {
+ cyg_can_filter *filter = (cyg_can_filter*) buf;
+
+ //
+ // if FlexCAN is configured to receive all messages then it is not
+ // allowed to add single message filters because then more than
+ // one message buffer would receive the same CAN id
+ //
+ if (info->rx_all)
+ {
+ return -EPERM;
+ }
+
+ //
+ // try to allocate a free message box - if we have a free one
+ // then we can prepare the message box for reception of the
+ // desired message id
+ //
+ filter->handle = flexcan_alloc_mbox(info);
+ if (filter->handle > CYGNUM_CAN_MSGBUF_NA)
+ {
+ flexcan_setup_rxmbox(chan, filter->handle, &flexcan_mbox_rx_filt_isr, &filter->msg, true, true);
+ }
+ }
+ break; //CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
+
+ //
+ // Try to add a new RTR response message buffer for automatic transmisson
+ // of data frame on reception of a remote frame
+ //
+ case CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD :
+ {
+ cyg_can_remote_buf *rtr_buf = (cyg_can_remote_buf*) buf;
+ rtr_buf->handle = flexcan_alloc_mbox(info);
+
+ if (rtr_buf->handle > CYGNUM_CAN_MSGBUF_NA)
+ {
+ //
+ // if we have a free message buffer then we setup this buffer
+ // for remote frame reception
+ //
+ flexcan_setup_rtrmbox(chan, rtr_buf->handle, &rtr_buf->msg);
+ }
+ }
+ break;
+
+ //
+ // write data into remote response buffer
+ //
+ case CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE :
+ {
+ cyg_can_remote_buf *rtr_buf = (cyg_can_remote_buf*) buf;
+
+ //
+ // If we have a valid rtr buf handle then we can store data into
+ // rtr message box
+ //
+ if ((rtr_buf->handle >= 0) && (rtr_buf->handle <= FLEXCAN_MBOX_RX_MAX))
+ {
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ flexcan_cfg_mbox_tx(&flexcan->mbox[rtr_buf->handle], &rtr_buf->msg, true);
+ }
+ else
+ {
+ return -EINVAL;
+ }
+ }
+ break;
+ } // switch (buf->cfg_id)
+
+ return res;
+}
+
+//===========================================================================
+// Set device configuration
+//===========================================================================
+static Cyg_ErrNo
+flexcan_set_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+
+ switch(key)
+ {
+ //
+ //Setup a new CAN configuration. This will i.e. setup a new baud rate
+ //
+ case CYG_IO_SET_CONFIG_CAN_INFO:
+ {
+ cyg_can_info_t* config = (cyg_can_info_t*) buf;
+ if (*len < sizeof(cyg_can_info_t))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_info_t);
+ if (!flexcan_config(chan, config, false))
+ {
+ return -EINVAL;
+ }
+ }
+ break;
+
+ //
+ // configure message buffers
+ //
+ case CYG_IO_SET_CONFIG_CAN_MSGBUF :
+ {
+ cyg_can_msgbuf_cfg *msg_buf = (cyg_can_msgbuf_cfg *) buf;
+
+ if (*len != sizeof(cyg_can_msgbuf_cfg))
+ {
+ return -EINVAL;
+ }
+
+ flexcan_set_config_msgbuf(chan, msg_buf);
+ }
+ break;
+
+ //
+ // Change CAN state of FlexCAN modul. This function will set the FlexCAN
+ // modul into STOPPED, ACTIVE or STANDBY state
+ //
+ case CYG_IO_SET_CONFIG_CAN_MODE :
+ {
+ cyg_can_mode *can_mode = (cyg_can_mode*) buf;
+
+ if (*len != sizeof(cyg_can_mode))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_mode);
+
+ //
+ // decide what to do acording to mode
+ //
+ switch (*can_mode)
+ {
+ case CYGNUM_CAN_MODE_STOP : // stop FlexCANm modul
+ flexcan_stop_chip(chan);
+ break;
+
+ case CYGNUM_CAN_MODE_START : // start FlexCAN modul
+ flexcan_leave_standby(chan);
+ break;
+
+ case CYGNUM_CAN_MODE_STANDBY : // set FlexCAN modul into standby state
+ flexcan_enter_standby(chan, true);
+ break;
+
+ case CYGNUM_CAN_MODE_CONFIG : // stop FlexCAN modul for configuration
+ flexcan_stop_chip(chan);
+ break;
+
+ case CYGNUM_CAN_MODE_LISTEN_ONLY_ENTER:
+ case CYGNUM_CAN_MODE_LISTEN_ONLY_EXIT:
+ return -EINVAL;
+ }
+ }
+ break; // case CYG_IO_SET_CONFIG_CAN_MODE :
+ } // switch (key)
+
+ return res;
+}
+
+
+//===========================================================================
+// Query device configuration
+//===========================================================================
+static Cyg_ErrNo
+flexcan_get_config(can_channel *chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo res = ENOERR;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+
+ switch(key)
+ {
+ //
+ // query state of CAN controller
+ //
+ case CYG_IO_GET_CONFIG_CAN_STATE :
+ {
+ cyg_can_state *can_state = (cyg_can_state*) buf;
+
+ if (*len != sizeof(cyg_can_state))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_state);
+ *can_state = info->state;
+ }
+ break;
+
+ //
+ // Query message box information - returns available and free message
+ // boxes
+ //
+ case CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO :
+ {
+ cyg_can_msgbuf_info *mbox_info = (cyg_can_msgbuf_info*) buf;
+
+ if (*len != sizeof(cyg_can_msgbuf_info))
+ {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_can_msgbuf_info);
+
+ mbox_info->count = FLEXCAN_MBOX_RX_CNT;
+ mbox_info->free = info->free_mboxes;
+ }
+ break;
+
+ //
+ // Query hardware description of FlexCAN device driver
+ //
+ case CYG_IO_GET_CONFIG_CAN_HDI :
+ {
+ cyg_can_hdi *hdi = (cyg_can_hdi *)buf;
+ //
+ // comes from high level driver so we do not need to
+ // check buffer size here
+ //
+ hdi->support_flags = CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE
+ | CYGNUM_CAN_HDI_FULLCAN;
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+ hdi->support_flags |= CYGNUM_CAN_HDI_TIMESTAMP;
+#endif
+ }
+ break;
+
+ default :
+ res = -EINVAL;
+ }// switch(key)
+
+ return res;
+}
+
+
+//===========================================================================
+// Check if we received self transmitted frame
+//===========================================================================
+static bool flexcan_is_no_self_tx(cyg_can_event *pevent, flexcan_info *info, flexcan_mbox_info *pmbox)
+{
+ //
+ // If we received a self transmitted frame
+ // then this is not really an rx event and we return false. We rely on the
+ // fact here that two devices in network do not send the same identifier
+ //
+ if (pevent->msg.id == info->last_tx_id)
+ {
+ info->last_tx_id = 0xFFFFFFFF; // set last received ID to an invalid value
+ return false;
+ }
+ else
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_RX;
+
+ //
+ // check if an overun occured in this message box
+ //
+ if ((pmbox->ctrlstat_shadow & MBOX_RXCODE_OVERRUN) == MBOX_RXCODE_OVERRUN)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_OVERRUN_RX_HW;
+ }
+
+ return true;
+ }
+}
+
+
+//===========================================================================
+// Read one event from can hardware - called from high level I/O CAN driver
+//===========================================================================
+static bool flexcan_getevent(can_channel *chan, cyg_can_event *pevent, void *pdata)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ bool res = true;
+ cyg_uint16 estat;
+ cyg_uint8 event_id = *((cyg_uint8 *)pdata);
+
+ //
+ // if event_id is 0 - 15 the we have a message box event
+ //
+ if (event_id < FLEXCAN_ERR_EVENT)
+ {
+ flexcan_mbox_info *pmbox_info;
+ pmbox_info = &info->mboxes[event_id];
+
+ //
+ // Deceide what to do according to type of message box that caused this event
+ //
+ switch (pmbox_info->state)
+ {
+ //
+ // If we have an RX event then we need to read the received data from
+ // message box that caused this event and fill it into message queue of
+ // high level I/O CAN driver. We could handle this stuff in a function
+ // because it is the same like MBOX_STATE_RX_ALL_EXT but speed is more
+ // important here than codesize
+ //
+ case MBOX_STATE_RX_ALL_STD:
+ case MBOX_STATE_RX_ALL_EXT:
+ case MBOX_STATE_RX_FILT:
+ {
+ //
+ // read data from message box - during processing of this function
+ // the message box is locked and cannot receive further messages
+ //
+ flexcan_read_from_mbox(chan, event_id, pevent, &(pmbox_info->ctrlstat_shadow));
+ res = flexcan_is_no_self_tx(pevent, info, pmbox_info);
+ }
+ break;
+
+#ifdef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ //
+ // If a TX message box cause the event then we store the last transmitted
+ // message into the receive message queue
+ //
+ case MBOX_STATE_TX:
+ pevent->flags = CYGNUM_CAN_EVENT_TX;
+ pevent->msg = info->last_tx_msg;
+ break;
+#endif // CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+
+ case MBOX_STATE_REMOTE_TX:
+ break;
+
+ default:
+ res = false;
+ } // switch (pmbox->state)
+ }
+ else // (event_id >= FLEXCAN_ERR_EVENT)
+ {
+ //
+ // We have an status event - check if it is an bus off interrupt or an
+ // error interrupt and provide error information to upper layer
+ //
+ HAL_READ_UINT16(&flexcan->ESTAT, estat);
+ pevent->msg.data.bytes[0] = estat & 0xFF;
+ pevent->msg.data.bytes[1] = (estat >> 8) & 0xFF;
+ HAL_READ_UINT8(&flexcan->RXERRCNT, pevent->msg.data.bytes[2]);
+ HAL_READ_UINT8(&flexcan->TXERRCNT, pevent->msg.data.bytes[3]);
+ switch (event_id)
+ {
+ case FLEXCAN_ERR_EVENT :
+ //
+ // indicate error passive event and provide content of estat register
+ // for a more precise error information
+ //
+ if (estat & FLEXCAN_ESTAT_FCS_ERROR_PASSIVE)
+ {
+ pevent->flags = CYGNUM_CAN_EVENT_ERR_PASSIVE;
+ }
+ //
+ // If we are not in error passive state then we check if the
+ // error counters reached the warning level
+ //
+ else
+ {
+ //
+ // indicate tx error counter warning level reached
+ //
+ if (estat & FLEXCAN_ESTAT_TXWARN)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_WARNING_TX;
+ }
+
+ //
+ // indicate rx error counter warning level reached
+ //
+ if (estat & FLEXCAN_ESTAT_RXWARN)
+ {
+ pevent->flags |= CYGNUM_CAN_EVENT_WARNING_RX;
+ }
+ }
+ break;
+
+ case FLEXCAN_BUSOFF_EVENT:
+ pevent->flags = CYGNUM_CAN_EVENT_BUS_OFF;
+ break;
+
+ case FLEXCAN_WAKE_EVENT:
+ pevent->flags = CYGNUM_CAN_EVENT_LEAVING_STANDBY;
+ break;
+ } // switch (event_id)
+ }
+
+ return res;
+}
+
+
+//===========================================================================
+// Send one CAN message to CAN hardware
+//===========================================================================
+static bool flexcan_putmsg(can_channel *chan, cyg_can_message *pmsg, void *pdata)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint8 mbox = *((cyg_uint8 *)pdata);
+ flexcan_mbox_info *pmbox = &info->mboxes[mbox];
+ cyg_uint16 iflag;
+
+ HAL_READ_UINT16(&flexcan->IFLAG, iflag);
+
+ //
+ // check if device is busy sending a message
+ //
+ if (pmbox->busy)
+ {
+ //
+ // if device is busy and the interrupt flag is set, then we know
+ // that device is not busy any longer
+ //
+ if (iflag & (0x0001 << mbox))
+ {
+ HAL_WRITE_UINT16(&flexcan->IFLAG, (0x0001 << mbox));
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ pmbox->busy = true; // mark transmitter as busy
+ info->last_tx_id = pmsg->id; // store message in order to identify self recieved frames
+
+#ifdef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ info->last_tx_msg = *pmsg; // store the transmitted message for TX events
+#endif
+
+ flexcan_cfg_mbox_tx(&flexcan->mbox[mbox], pmsg, false); // send message
+
+ return true;
+}
+
+
+//===========================================================================
+// Flexcan start xmit - If the chip is in standby mode then a call to this
+// function will cause the FlexCAN modul to leave the standby mode. So
+// the output queue should be empty before entering stadby mode
+//===========================================================================
+static void flexcan_start_xmit(can_channel* chan)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ CYG_INTERRUPT_STATE saved_state;
+
+ HAL_DISABLE_INTERRUPTS(saved_state);
+
+ //
+ // if we are in standby state the we leave standby state now. This is
+ // the reason that the user should wait until the TX queue is empty before
+ // entering standby mode- or he should drain or flush the TX queue
+ //
+ if (CYGNUM_CAN_STATE_STANDBY == info->state)
+ {
+ flexcan_leave_standby(chan);
+ }
+
+ //
+ // Now enable message box 15 interrupts
+ //
+ flexcan_mboxint_enable(info, info->tx_all_mbox);
+
+ //
+ // kick transmitter
+ //
+ chan->callbacks->xmt_msg(chan, &info->tx_all_mbox); // Kick transmitter (if necessary)
+
+ HAL_RESTORE_INTERRUPTS(saved_state);
+}
+
+
+//===========================================================================
+// Flexcan stop transmission
+//===========================================================================
+static void flexcan_stop_xmit(can_channel* chan)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ CYG_INTERRUPT_STATE saved_state;
+
+ HAL_DISABLE_INTERRUPTS(saved_state);
+
+ //
+ // Now disable message box 15 interrupts
+ //
+ flexcan_mboxint_disable(info, info->tx_all_mbox);
+
+ HAL_RESTORE_INTERRUPTS(saved_state);
+}
+
+
+//===========================================================================
+// Configure flexcan channel
+//===========================================================================
+static bool flexcan_config(can_channel* chan, cyg_can_info_t* config, cyg_bool init)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint16 tmp16;
+ cyg_uint8 tmp8;
+ cyg_uint8 i;
+
+ //
+ // the first thing we need to do is to stop the chip
+ //
+ flexcan_stop_chip(chan);
+
+ //
+ // if this is the first initialisation of the FlexCAN modul we need to execute
+ // some extra steps here
+ //
+ if (init)
+ {
+#if defined(CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN0) && defined(HAL_MCF52xx_FLEXCAN0_PROC_INIT)
+ if (info == &flexcan_can0_info) {
+ HAL_MCF52xx_FLEXCAN0_PROC_INIT();
+ }
+#endif
+
+ //
+ // Issue a reset in order to go into halt mode. The reset will set the
+ // the halt bit in mcr
+ //
+ HAL_READ_UINT16(&flexcan->CANMCR, tmp16);
+ tmp16 &= ~FLEXCAN_MCR_FRZ;
+ HAL_WRITE_UINT16(&flexcan->CANMCR, tmp16);
+ tmp16 |= FLEXCAN_MCR_SOFTRST;
+ HAL_WRITE_UINT16(&flexcan->CANMCR, tmp16);
+ HAL_DELAY_US(10);
+
+ //
+ // Check reset status
+ //
+ HAL_READ_UINT16(&flexcan->CANMCR, tmp16);
+ if (tmp16 & FLEXCAN_MCR_SOFTRST)
+ {
+ return false;
+ }
+
+ //
+ // Initialize the transmit and receive pin modes
+ //
+ HAL_WRITE_UINT8(&flexcan->CANCTRL0 , (FLEXCAN_CTRL0_TXMODE_FULL_0_DOMINANT
+ | FLEXCAN_CTRL0_RXMODE_0_DOMINANT)
+ & ~FLEXCAN_CTRL0_BOFFMSK
+ & ~FLEXCAN_CTRL0_ERRMASK);
+
+ //
+ // deactivate all message buffers - this is mandatory for configuration
+ // of message buffers
+ //
+ for (i = FLEXCAN_MBOX_MIN; i <= FLEXCAN_MBOX_MAX; ++i)
+ {
+ HAL_WRITE_UINT16(&flexcan->mbox[i], MBOX_RXCODE_NOT_ACTIVE);
+ }
+
+ //
+ // mask all interrupts
+ //
+ info->imask_shadow = 0x0000;
+ HAL_WRITE_UINT16(&flexcan->IMASK, info->imask_shadow);
+ HAL_READ_UINT8(&flexcan->CANCTRL0, tmp8);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL0, tmp8 & ~(FLEXCAN_CTRL0_BOFFMSK | FLEXCAN_CTRL0_ERRMASK));
+
+ //
+ // setup bus arbitration mode - the LBUF bit defines the
+ // transmit-first scheme 0 = message buffer with lowest ID
+ // 1 = message buffer with lowest number. We use lowest ID here
+ //
+ HAL_READ_UINT8(&flexcan->CANCTRL1, tmp8);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL1, (tmp8 & ~FLEXCAN_CTRL1_LBUF));
+
+ //
+ // setup all rx message buffers
+ //
+ flexcan_config_rx_all(chan);
+
+ //
+ // bus off interrupt and error interrupt
+ //
+ HAL_READ_UINT8(&flexcan->CANCTRL0, tmp8);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL0, tmp8 | (FLEXCAN_CTRL0_BOFFMSK | FLEXCAN_CTRL0_ERRMASK));
+ } // if (init)
+
+ flexcan_set_baud(chan, config->baud); // setup baud rate
+
+ //
+ // store new config values
+ //
+ if (config != &chan->config)
+ {
+ chan->config = *config;
+ }
+ flexcan_start_chip(chan); // now we can start the chip again
+
+ return true;
+}
+
+//===========================================================================
+/// First initialisation and reset of CAN modul.
+//===========================================================================
+static bool flexcan_init(struct cyg_devtab_entry* devtab_entry)
+{
+ can_channel *chan = (can_channel*)devtab_entry->priv;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_mbox_info *pmbox;
+
+ if (!flexcan_config(chan, &chan->config, true))
+ {
+ return false;
+ }
+
+ //
+ // prepare message box interrupt for message box 15 - the tx message box
+ //
+ pmbox = &info->mboxes[info->tx_all_mbox];
+ cyg_drv_interrupt_create(pmbox->isr_vec,
+ pmbox->isr_priority,
+ (cyg_addrword_t) chan,
+ &flexcan_mbox_tx_isr,
+ &flexcan_mbox_tx_dsr,
+ &(pmbox->interrupt_handle),
+ &(pmbox->interrupt));
+ cyg_drv_interrupt_attach(pmbox->interrupt_handle);
+ cyg_drv_interrupt_unmask(pmbox->isr_vec);
+
+ //
+ // prepare error interrupt
+ //
+ cyg_drv_interrupt_create(info->err_int.isr_vec,
+ info->err_int.isr_priority,
+ (cyg_addrword_t) chan,
+ &flexcan_err_isr,
+ &flexcan_err_dsr,
+ &(info->err_int.interrupt_handle),
+ &(info->err_int.interrupt));
+ cyg_drv_interrupt_attach(info->err_int.interrupt_handle);
+ cyg_drv_interrupt_unmask(info->err_int.isr_vec);
+
+ //
+ // prepare busoff interrupt
+ //
+ cyg_drv_interrupt_create(info->boff_int.isr_vec,
+ info->boff_int.isr_priority,
+ (cyg_addrword_t) chan,
+ &flexcan_busoff_isr,
+ &flexcan_busoff_dsr,
+ &(info->boff_int.interrupt_handle),
+ &(info->boff_int.interrupt));
+ cyg_drv_interrupt_attach(info->boff_int.interrupt_handle);
+ cyg_drv_interrupt_unmask(info->boff_int.isr_vec);
+
+ //
+ // prepare wake interrupt
+ //
+ cyg_drv_interrupt_create(info->wake_int.isr_vec,
+ info->wake_int.isr_priority,
+ (cyg_addrword_t) chan,
+ &flexcan_wake_isr,
+ &flexcan_wake_dsr,
+ &(info->wake_int.interrupt_handle),
+ &(info->wake_int.interrupt));
+ cyg_drv_interrupt_attach(info->wake_int.interrupt_handle);
+ cyg_drv_interrupt_unmask(info->wake_int.isr_vec);
+
+ return true;
+}
+
+
+//===========================================================================
+// Flexcan error interrupt handler
+//===========================================================================
+static cyg_uint32 flexcan_err_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint8 ctrl0;
+ cyg_uint16 estat;
+
+ //
+ // first we disable error interrupts - DSR will reenable it later
+ //
+ HAL_READ_UINT8(&flexcan->CANCTRL0, ctrl0);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL0, ctrl0 & ~FLEXCAN_CTRL0_ERRMASK);
+
+ //
+ // for clearing the interrupt we first read the flag register as 1
+ // and then write it as 1 (and not as zero like the manual stated)
+ // we clear only the flag of this interrupt and leave all other
+ // message box interrupts untouched
+ //
+ HAL_READ_UINT16(&flexcan->ESTAT, estat);
+ HAL_WRITE_UINT16(&flexcan->ESTAT, FLEXCAN_ESTAT_ERRINT);
+
+ //
+ // On the mcf5272 there is no need to acknowledge internal
+ // interrupts, only external ones.
+ // cyg_drv_interrupt_acknowledge(vec);
+ //
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// DSR for all interrupts that are no message box interrupts
+//===========================================================================
+static void flexcan_err_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint8 ctrl0;
+ cyg_uint8 event_id = FLEXCAN_ERR_EVENT;
+
+ //
+ // signal CAN event to generic IO CAN driver - it will do any further
+ // processing
+ //
+ chan->callbacks->rcv_event(chan, &event_id);
+
+ //
+ // reenable bus off interrupts
+ //
+ HAL_READ_UINT8(&flexcan->CANCTRL0, ctrl0);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL0, ctrl0 | FLEXCAN_CTRL0_ERRMASK);
+}
+
+
+//===========================================================================
+// Bus off interrupt handler
+//===========================================================================
+static cyg_uint32 flexcan_busoff_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint8 ctrl0;
+ cyg_uint16 estat;
+
+ //
+ // first we disable bus off interrupts - DSR will reenable it later
+ //
+ HAL_READ_UINT8(&flexcan->CANCTRL0, ctrl0);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL0, ctrl0 & ~FLEXCAN_CTRL0_BOFFMSK);
+
+ //
+ // for clearing the interrupt we first read the flag register as 1
+ // and then write it as 1 (and not as zero like the manual stated)
+ // we clear only the flag of this interrupt and leave all other
+ // message box interrupts untouched
+ //
+ HAL_READ_UINT16(&flexcan->ESTAT, estat);
+ HAL_WRITE_UINT16(&flexcan->ESTAT, FLEXCAN_ESTAT_BOFFINT);
+
+ //
+ // On the mcf5272 there is no need to acknowledge internal
+ // interrupts, only external ones.
+ // cyg_drv_interrupt_acknowledge(vec);
+ //
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// DSR for all interrupts that are no message box interrupts
+//===========================================================================
+static void flexcan_busoff_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint8 ctrl0;
+ cyg_uint8 event_id = FLEXCAN_BUSOFF_EVENT;
+
+ //
+ // signal CAN event to generic IO CAN driver - it will do any further
+ // processing
+ //
+ chan->callbacks->rcv_event(chan, &event_id);
+
+ //
+ // reenable bus off interrupts
+ //
+ HAL_READ_UINT8(&flexcan->CANCTRL0, ctrl0);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL0, ctrl0 | FLEXCAN_CTRL0_BOFFMSK);
+}
+
+
+//===========================================================================
+// Bus off interrupt handler
+//===========================================================================
+static cyg_uint32 flexcan_wake_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint16 estat;
+
+ //
+ // first we disable wake interrupts - we set the mcr register to
+ // zero in order to bring it back to normal state
+ //
+ HAL_WRITE_UINT16(&flexcan->CANMCR, 0);
+
+ //
+ // for clearing the interrupt we first read the flag register as 1
+ // and then write it as 1 (and not as zero like the manual stated)
+ // we clear only the flag of this interrupt and leave all other
+ // message box interrupts untouched
+ //
+ HAL_READ_UINT16(&flexcan->ESTAT, estat);
+ HAL_WRITE_UINT16(&flexcan->ESTAT, FLEXCAN_ESTAT_WAKEINT);
+
+ //
+ // On the mcf5272 there is no need to acknowledge internal
+ // interrupts, only external ones.
+ // cyg_drv_interrupt_acknowledge(vec);
+ //
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// DSR for all interrupts that are no message box interrupts
+//===========================================================================
+static void flexcan_wake_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint8 event_id = FLEXCAN_WAKE_EVENT;
+ cyg_uint8 ctrl0;
+
+ //
+ // signal CAN event to generic IO CAN driver - it will do any further
+ // processing we will enable all other interrupts after the call to
+ // rcv_event because the user should receive this event as the first
+ // event after FlexCAN leaves standby.
+ //
+ chan->callbacks->rcv_event(chan, &event_id);
+
+ //
+ // for standby we disabled all interrut source so we have to enable
+ // it here again for normal operation
+ //
+ HAL_WRITE_UINT16(&flexcan->IMASK, info->imask_shadow);
+ HAL_READ_UINT8(&flexcan->CANCTRL0, ctrl0);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL0, ctrl0 |(FLEXCAN_CTRL0_BOFFMSK | FLEXCAN_CTRL0_ERRMASK));
+}
+
+
+//===========================================================================
+// Flexcan message box isr for rx messages if message filtering is
+// enabled
+//===========================================================================
+static cyg_uint32 flexcan_mbox_rx_filt_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint16 iflag;
+
+ //
+ // number of message box can be calculated from vector that cause
+ // interrupt - we pass this message box number as additional data to the
+ // callback because it is required in the receive event function later
+ //
+ cyg_uint8 mbox = vec - info->isr_vec_mbox0;
+
+ //
+ // first we disable interrupts of this message box - the DSR will
+ // reenable it later
+ //
+ flexcan_mboxint_disable(info, mbox);
+ info->mboxes[mbox].ctrlstat_shadow = FLEXCAN_CTRLSTAT_NOT_READ;
+
+ //
+ // for clearing the interrupt we first read the flag register as 1
+ // and then write it as 1 (and not as zero like the manual stated)
+ // we clear only the flag of this interrupt and leave all other
+ // message box interrupts untouched
+ //
+ HAL_READ_UINT16(&flexcan->IFLAG, iflag);
+ HAL_WRITE_UINT16(&flexcan->IFLAG, (0x0001 << mbox));
+
+ //
+ // On the mcf5272 there is no need to acknowledge internal
+ // interrupts, only external ones.
+ // cyg_drv_interrupt_acknowledge(vec);
+ //
+ return CYG_ISR_CALL_DSR;
+}
+
+
+#ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+//===========================================================================
+// Flexcan message box isr for extended identifiers if reception of all
+// available messages is enabled
+//===========================================================================
+static cyg_uint32 flexcan_mbox_rx_ext_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint16 iflag;
+ flexcan_rxmbox_circbuf *prx_mbox_list = &(info->rxmbox_ext_circbuf);
+
+ //
+ // number of message box can be calculated from vector that caused
+ // interrupt - we pass this message box number as additional data to the
+ // callback because it is required in the receive event function later
+ //
+ cyg_uint8 mbox = vec - info->isr_vec_mbox0;
+ if (++prx_mbox_list->count < info->mboxes_ext_cnt)
+ {
+ prx_mbox_list->idx_wr = (prx_mbox_list->idx_wr + 1) % info->mboxes_ext_cnt;
+ flexcan_hwmbox_enable_rx(flexcan, prx_mbox_list->idx_wr + info->mboxes_std_cnt);
+ flexcan_hwmbox_lock(flexcan, mbox, &(info->mboxes[mbox].ctrlstat_shadow));
+ flexcan_hwmbox_disable(flexcan, mbox); // now disable this message box - it is already locked
+ //
+ // first we disable interrupts of this message box - the DSR will
+ // reenable it later
+ //
+ flexcan_mboxint_disable(info, mbox);
+ }
+ else
+ {
+ prx_mbox_list->count = info->mboxes_ext_cnt;
+ info->mboxes[mbox].ctrlstat_shadow = FLEXCAN_CTRLSTAT_NOT_READ;
+ }
+
+ //
+ // for clearing the interrupt we first read the flag register as 1
+ // and then write it as 1 (and not as zero like the manual stated)
+ // we clear only the flag of this interrupt and leave all other
+ // message box interrupts untouched
+ //
+ HAL_READ_UINT16(&flexcan->IFLAG, iflag);
+ HAL_WRITE_UINT16(&flexcan->IFLAG, (0x0001 << mbox));
+
+ //
+ // On the mcf5272 there is no need to acknowledge internal
+ // interrupts, only external ones.
+ // cyg_drv_interrupt_acknowledge(vec); If counter of mbox list is > 1
+ // then we know that there is already a DSR running and we do not
+ // need to invoke one
+ //
+ if (prx_mbox_list->count > 1)
+ {
+ return CYG_ISR_HANDLED;
+ }
+ else
+ {
+ return CYG_ISR_CALL_DSR;
+ }
+}
+
+
+//===========================================================================
+// FlexCAN message box DSR for extended CAN frames
+//===========================================================================
+static void flexcan_mbox_rx_ext_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel * chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_rxmbox_circbuf *prx_mbox_list = &(info->rxmbox_ext_circbuf);
+ cyg_uint8 mbox;
+ cyg_uint8 mbox_cnt;
+
+ //
+ // we do not process the message box we received as event_id
+ // we take the message boxes from the ring buffer
+ //
+ do
+ {
+ cyg_drv_isr_lock();
+ mbox_cnt = --prx_mbox_list->count;
+ cyg_drv_isr_unlock();
+
+ mbox = prx_mbox_list->idx_rd + info->mboxes_std_cnt;
+ prx_mbox_list->idx_rd = (prx_mbox_list->idx_rd + 1) % info->mboxes_ext_cnt;
+ chan->callbacks->rcv_event(chan, &mbox);
+ flexcan_mboxint_enable(info, mbox);
+
+ //
+ // if the last message box is enabled, then we have to enable
+ // another one now because the last message box is filled already
+ //
+ if (mbox_cnt == (info->mboxes_ext_cnt - 1))
+ {
+ cyg_uint8 active_mbox;
+ cyg_uint8 next_mbox;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+
+ cyg_drv_isr_lock();
+ active_mbox = prx_mbox_list->idx_wr;
+ next_mbox = prx_mbox_list->idx_wr = (prx_mbox_list->idx_wr + 1) % info->mboxes_ext_cnt;
+ cyg_drv_isr_unlock();
+
+ active_mbox += info->mboxes_std_cnt;
+ next_mbox += info->mboxes_std_cnt;
+ flexcan_hwmbox_lock(flexcan, active_mbox, &(info->mboxes[active_mbox].ctrlstat_shadow));
+ flexcan_hwmbox_disable(flexcan, active_mbox); // now disable this message box - it is already locked
+ flexcan_hwmbox_enable_rx(flexcan, next_mbox);
+ }
+ }
+ while (mbox_cnt);
+}
+
+#endif // #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
+
+
+#ifdef CYGOPT_IO_CAN_STD_CAN_ID
+//===========================================================================
+// Flexcan message box isr for standard identifiers if reception of all
+// available messages is enabled
+//===========================================================================
+static cyg_uint32 flexcan_mbox_rx_std_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint16 iflag;
+ flexcan_rxmbox_circbuf *prx_mbox_list = &(info->rxmbox_std_circbuf);
+
+ //
+ // number of message box can be calculated from vector that caused
+ // interrupt - we pass this message box number as additional data to the
+ // callback because it is required in the receive event function later
+ //
+ cyg_uint8 mbox = vec - info->isr_vec_mbox0;
+ if (++prx_mbox_list->count < info->mboxes_std_cnt)
+ {
+ prx_mbox_list->idx_wr = (prx_mbox_list->idx_wr + 1) % info->mboxes_std_cnt;
+ flexcan_hwmbox_enable_rx(flexcan, prx_mbox_list->idx_wr);
+ flexcan_hwmbox_lock(flexcan, mbox, &(info->mboxes[mbox].ctrlstat_shadow));
+ flexcan_hwmbox_disable(flexcan, mbox); // now disable this message box - it is already locked
+ //
+ // first we disable interrupts of this message box - the DSR will
+ // reenable it later
+ //
+ flexcan_mboxint_disable(info, mbox);
+ }
+ else
+ {
+ prx_mbox_list->count = info->mboxes_std_cnt;
+ info->mboxes[mbox].ctrlstat_shadow = FLEXCAN_CTRLSTAT_NOT_READ;
+ }
+
+ //
+ // for clearing the interrupt we first read the flag register as 1
+ // and then write it as 1 (and not as zero like the manual stated)
+ // we clear only the flag of this interrupt and leave all other
+ // message box interrupts untouched
+ //
+ HAL_READ_UINT16(&flexcan->IFLAG, iflag);
+ HAL_WRITE_UINT16(&flexcan->IFLAG, (0x0001 << mbox));
+
+ //
+ // On the mcf5272 there is no need to acknowledge internal
+ // interrupts, only external ones.
+ // cyg_drv_interrupt_acknowledge(vec); If counter of mbox list is > 1
+ // then we know that there is already a DSR running and we do not
+ // need to invoke one
+ //
+ if (prx_mbox_list->count > 1)
+ {
+ return CYG_ISR_HANDLED;
+ }
+ else
+ {
+ return CYG_ISR_CALL_DSR;
+ }
+}
+
+
+//===========================================================================
+// Flexcan message box dsr for standard CAN frames
+//===========================================================================
+static void flexcan_mbox_rx_std_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel * chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_rxmbox_circbuf *prx_mbox_list = &(info->rxmbox_std_circbuf);
+ cyg_uint8 mbox;
+ cyg_uint8 mbox_cnt;
+
+ //
+ // we do not process the message box we received as event_id
+ // we take the message boxes from the ring buffer
+ //
+ do
+ {
+ cyg_drv_isr_lock();
+ mbox_cnt = --prx_mbox_list->count;
+ cyg_drv_isr_unlock();
+
+ mbox = prx_mbox_list->idx_rd;
+ prx_mbox_list->idx_rd = (prx_mbox_list->idx_rd + 1) % info->mboxes_std_cnt;
+ chan->callbacks->rcv_event(chan, &mbox);
+ flexcan_mboxint_enable(info, mbox);
+
+ //
+ // if the last message box is enabled, then we have to enable
+ // another one now because the last message box is filled already
+ //
+ if (mbox_cnt == (info->mboxes_std_cnt - 1))
+ {
+ cyg_uint8 active_mbox;
+ cyg_uint8 next_mbox;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+
+ cyg_drv_isr_lock();
+ active_mbox = prx_mbox_list->idx_wr;
+ next_mbox = prx_mbox_list->idx_wr = (prx_mbox_list->idx_wr + 1) % info->mboxes_ext_cnt;
+ cyg_drv_isr_unlock();
+
+ flexcan_hwmbox_lock(flexcan, active_mbox, &(info->mboxes[active_mbox].ctrlstat_shadow));
+ flexcan_hwmbox_disable(flexcan, active_mbox); // now disable this message box - it is already locked
+ flexcan_hwmbox_enable_rx(flexcan, next_mbox);
+ }
+ }
+ while (mbox_cnt);
+}
+#endif // CYGOPT_IO_CAN_STD_CAN_ID
+
+
+//===========================================================================
+// FlexCAN DSR for message filters
+//===========================================================================
+static void flexcan_mbox_rx_filt_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+
+ //
+ // number of message box can be calculated from vector that caused
+ // interrupt - we pass this message box number as additional data to the
+ // callback
+ //
+ cyg_uint8 mbox = vec - info->isr_vec_mbox0;
+
+ //
+ // signal CAN event to generic IO CAN driver - it will do any further
+ // processing
+ //
+ chan->callbacks->rcv_event(chan, &mbox);
+
+ //
+ // reenable interrupts for the message box that caused the DSR to run
+ //
+ flexcan_mboxint_enable(info, mbox);
+}
+
+//===========================================================================
+// Flexcan message box isr
+//===========================================================================
+static cyg_uint32 flexcan_mbox_tx_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint16 iflag;
+
+ // number of message box can be calculated from vector that cause
+ // interrupt - we pass this message box number as additional data to the
+ // callback
+ //
+ cyg_uint8 mbox = vec - info->isr_vec_mbox0;
+
+ //
+ // the first thing we do here is to disable this message box. we do this
+ // because if we just sent a remote transmission request with this message
+ // box then the FLEXCAN modul will automatically set up this message box
+ // for reception of the requested data frame. But we won't receive messages
+ // with the TX message box and deactivate it here immediatelly.
+ //
+ HAL_WRITE_UINT8(&flexcan->mbox[mbox].ctrlstat, MBOX_TXCODE_NOT_READY);
+
+ //
+ // first we disable interrupts of this message box - the DSR will
+ // reenable it later
+ //
+ flexcan_mboxint_disable(info, mbox);
+
+ //
+ // for clearing the interrupt we first read the flag register as 1
+ // and then write it as 1 (and not as zero like the manual stated)
+ // we clear only the flag of this interrupt and leave all other
+ // message box interrupts untouched
+ //
+ HAL_READ_UINT16(&flexcan->IFLAG, iflag);
+ HAL_WRITE_UINT16(&flexcan->IFLAG, (0x0001 << mbox));
+
+ //
+ // On the mcf5272 there is no need to acknowledge internal
+ // interrupts, only external ones.
+ // cyg_drv_interrupt_acknowledge(vec);
+ //
+ return CYG_ISR_CALL_DSR;
+}
+
+
+//===========================================================================
+// Flexcan message box dsr
+//===========================================================================
+static void flexcan_mbox_tx_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ can_channel *chan = (can_channel *)data;
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_mbox_info *pmbox;
+
+ //
+ // number of message box can be calculated from vector that caused
+ // interrupt - we pass this message box number as additional data to the
+ // callback
+ //
+ cyg_uint8 mbox = vec - info->isr_vec_mbox0;
+ pmbox = &info->mboxes[mbox];
+
+#ifdef CYGOPT_IO_CAN_TX_EVENT_SUPPORT
+ //
+ // signal CAN TX event to generic IO CAN driver - it will do any further
+ // processing
+ //
+ chan->callbacks->rcv_event(chan, &mbox);
+#endif
+
+ pmbox->busy = false;
+
+ //
+ // send next message
+ //
+ chan->callbacks->xmt_msg(chan, &mbox);
+
+ //
+ // reenable interrupts for the message box that caused the DSR to run
+ //
+ flexcan_mboxint_enable(info, mbox);
+}
+
+
+//===========================================================================
+// Start FlexCAN modul
+//===========================================================================
+static void flexcan_start_chip(can_channel *chan)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+
+ cyg_uint16 tmp16;
+
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ HAL_READ_UINT16(&flexcan->CANMCR, tmp16);
+ HAL_WRITE_UINT16(&flexcan->CANMCR, tmp16
+ & ~(FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT));
+}
+
+
+//===========================================================================
+// Stop FlexCAN modul
+//===========================================================================
+static void flexcan_stop_chip(can_channel *chan)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint16 tmp16;
+
+ info->state = CYGNUM_CAN_STATE_STOPPED;
+ HAL_READ_UINT16(&flexcan->CANMCR, tmp16);
+ HAL_WRITE_UINT16(&flexcan->CANMCR, tmp16 | FLEXCAN_MCR_HALT);
+}
+
+
+//===========================================================================
+// Set FlexCAN modul into standby mode
+// If the flag selfwake is active then the FlexCAN modul will be set into
+// standby mode with selwake. This means the FlexCAN modul will leave
+// standby as soon as a message box will receive a message
+//===========================================================================
+static void flexcan_enter_standby(can_channel *chan, bool selfwake)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint16 tmp16;
+ cyg_uint8 tmp8;
+ cyg_uint8 i;
+
+ //
+ // The CPU should disable all interrupts in the FlexCAN before entering low-power
+ // stop mode. Otherwise it may be interrupted while in STOP mode upon a non
+ // wake-up condition; If desired, the WAKEMASK bit should be set to enable the
+ // WAKEINT.
+ //
+ HAL_READ_UINT8(&flexcan->CANCTRL0, tmp8);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL0, tmp8 & ~(FLEXCAN_CTRL0_BOFFMSK | FLEXCAN_CTRL0_ERRMASK));
+
+ //
+ // We disable all message box interrupts. The WAKE DSR will reenable it later
+ // after processing the WAKE event. This ensures that the wake event will be the
+ // first event if a message arrives
+ //
+ HAL_WRITE_UINT16(&flexcan->IMASK, 0);
+
+ HAL_READ_UINT16(&flexcan->CANMCR, tmp16);
+
+ tmp16 |= FLEXCAN_MCR_STOP;
+
+ //
+ // if we should go to standby then we activate the SELWAKE bit so that a received
+ // frame will bring us back to live
+ //
+ if (selfwake)
+ {
+ tmp16 |= FLEXCAN_MCR_SELFWAKE;
+ }
+
+ HAL_WRITE_UINT16(&flexcan->CANMCR, tmp16);
+
+ //
+ // we have to poll the STOPACK bit in order to determine if chip
+ // has entered stop mode. We poll 10 times - se we spent a maximum
+ // of 2 ms here
+ //
+ for (i = 0; i < 10; ++i)
+ {
+ HAL_READ_UINT16(&flexcan->CANMCR, tmp16);
+
+ if (tmp16 & FLEXCAN_MCR_STOPACK)
+ {
+ info->state = CYGNUM_CAN_STATE_STANDBY;
+ break;
+ }
+ HAL_DELAY_US(200);
+ }
+
+ //
+ // if we are not in low power stop mode then we have to reenable interrupts
+ //
+ if (10 == i)
+ {
+ HAL_READ_UINT8(&flexcan->CANCTRL0, tmp8);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL0, tmp8 | (FLEXCAN_CTRL0_BOFFMSK | FLEXCAN_CTRL0_ERRMASK));
+ }
+ else
+ {
+ //
+ // if we go into standby then we activate the wake interrupt so we will receive
+ // a wake interrupt if we leave standby and can reenable interrups
+ //
+ if (selfwake)
+ {
+ HAL_READ_UINT16(&flexcan->CANMCR, tmp16);
+ HAL_WRITE_UINT16(&flexcan->CANMCR, tmp16 | FLEXCAN_MCR_WAKEMSK);
+ }
+ }
+}
+
+
+//===========================================================================
+// Leave standby mode
+//===========================================================================
+static void flexcan_leave_standby(can_channel *chan)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint16 tmp16;
+ cyg_uint8 i;
+
+ HAL_READ_UINT16(&flexcan->CANMCR, tmp16);
+ HAL_WRITE_UINT16(&flexcan->CANMCR, tmp16 & ~(FLEXCAN_MCR_STOP | FLEXCAN_MCR_SELFWAKE));
+
+ //
+ // we have to poll the STOPACK bit in order to determine if chip
+ // has leaved stop mode. We poll 10 times - se we spent a maximum
+ // of 2 ms here
+ //
+ for (i = 0; i < 10; ++i)
+ {
+ HAL_READ_UINT16(&flexcan->CANMCR, tmp16);
+
+ if (!(tmp16 & FLEXCAN_MCR_STOPACK))
+ {
+ HAL_WRITE_UINT16(&flexcan->IMASK, info->imask_shadow);
+ info->state = CYGNUM_CAN_STATE_ACTIVE;
+ break;
+ }
+ HAL_DELAY_US(200);
+ } // for (i = 0; i < 10; ++i)
+}
+
+
+//===========================================================================
+// Set acceptance mask for message buffer
+//===========================================================================
+static void flexcan_set_acceptance_mask(cyg_uint16 *rxmask_reg, cyg_uint32 mask, cyg_can_id_type ext)
+{
+ cyg_uint16 id;
+ //
+ // 32 bit access to RXMASK filters is broken so we use 16 Bit
+ // access here
+ //
+ if (CYGNUM_CAN_ID_EXT == ext)
+ {
+ id = ((mask >> 13) & 0xFFE0); // set mask bits 18 - 28
+ id |= ((mask >> 15) & 0x7); // set mask bits 15 -17
+ HAL_WRITE_UINT16(&rxmask_reg[0], id);
+
+ id = (mask << 1) & 0xFFFE;
+ HAL_WRITE_UINT16(&rxmask_reg[1], id);
+ }
+ else // (CYGNUM_CAN_ID_STD == ext)
+ {
+ id = ((mask << 5) & 0xFFE0);
+ HAL_WRITE_UINT16(&rxmask_reg[0], id);
+ HAL_WRITE_UINT16(&rxmask_reg[1], 0xFFFF);
+ }
+
+}
+
+
+
+//===========================================================================
+// Configure message box for transmission
+//===========================================================================
+static bool flexcan_cfg_mbox_tx(flexcan_mbox *pmbox,
+ cyg_can_message *pmsg,
+ bool rtr)
+{
+ cyg_uint16 id;
+
+ HAL_WRITE_UINT8(&pmbox->ctrlstat, MBOX_TXCODE_NOT_READY);
+
+ if (CYGNUM_CAN_ID_EXT == pmsg->ext)
+ {
+ id = ((pmsg->id >> 13) & 0xFFE0); // setup id bits 18 - 28
+ id |= (MBOX_CFG_IDE | MBOX_CFG_SSR); // set SSR and IDE bit to 1
+ id |= ((pmsg->id >> 15) & 0x7); // set id bits 15 - 17
+ HAL_WRITE_UINT16(&pmbox->id_hi, id);
+
+ id = ((pmsg->id << 1) & 0xFFFE);
+
+ if (pmsg->rtr)
+ {
+ id |= MBOX_CFG_RTR_EXT;
+ }
+
+ HAL_WRITE_UINT16(&pmbox->id_lo, id);
+ }
+ else
+ {
+ id = ((pmsg->id << 5) & 0xFFE0);
+ if (pmsg->rtr)
+ {
+ id |= MBOX_CFG_RTR_STD; // set rtr bit for standard ID
+ }
+ HAL_WRITE_UINT16(&pmbox->id_hi, id);
+ HAL_WRITE_UINT16(&pmbox->id_lo, 0);
+ }
+
+ pmsg->dlc %= 9; // limit data length to 8 bytes
+
+ //
+ // Now copy data bytes into buffer and start transmission
+ //
+ HAL_WRITE_UINT8_VECTOR(&pmbox->data, pmsg->data.bytes, pmsg->dlc, 1);
+
+
+ if (rtr)
+ {
+ HAL_WRITE_UINT8(&pmbox->ctrlstat, MBOX_TXCODE_RESPONSE | pmsg->dlc);
+ }
+ else
+ {
+ HAL_WRITE_UINT8(&pmbox->ctrlstat, MBOX_TXCODE_TRANSMIT | pmsg->dlc);
+ }
+
+ return true;
+}
+
+
+
+//===========================================================================
+// Configure message box for reception of a certain CAN identifier
+//===========================================================================
+static void flexcan_cfg_mbox_rx(flexcan_mbox *pmbox,
+ cyg_can_message *pmsg,
+ bool enable)
+{
+ cyg_uint16 id;
+
+ HAL_WRITE_UINT8(&pmbox->ctrlstat, MBOX_RXCODE_NOT_ACTIVE);
+
+ if (CYGNUM_CAN_ID_EXT == pmsg->ext)
+ {
+ id = ((pmsg->id >> 13) & 0xFFE0); // setup id bits 18 - 28
+ id |= (MBOX_CFG_IDE | MBOX_CFG_SSR); // set SSR and IDE bit to 1
+ id |= ((pmsg->id >> 15) & 0x7); // set id bits 15 - 17
+ HAL_WRITE_UINT16(&pmbox->id_hi, id); // write ID high
+
+ id = ((pmsg->id << 1) & 0xFFFE);
+
+ HAL_WRITE_UINT16(&pmbox->id_lo, id);// write ID low
+ }
+ else
+ {
+ id = ((pmsg->id << 5) & 0xFFE0);
+
+ HAL_WRITE_UINT16(&pmbox->id_hi, id);
+ HAL_WRITE_UINT16(&pmbox->id_lo, 0);
+ }
+
+ if (enable)
+ {
+ HAL_WRITE_UINT8(&pmbox->ctrlstat, MBOX_RXCODE_EMPTY);
+ }
+}
+
+
+//===========================================================================
+// Read date from a message box
+//==========================================================================
+static void flexcan_read_from_mbox(can_channel *chan,
+ cyg_uint8 mbox,
+ cyg_can_event *pevent,
+ cyg_uint8 *ctrlstat)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ flexcan_mbox *pmbox = &flexcan->mbox[mbox];
+ cyg_can_message *pmsg = &pevent->msg;
+ cyg_uint16 id;
+ bool enable_mbox = false;
+
+ //
+ // If controlstat was not read, then read it now
+ //
+ if (FLEXCAN_CTRLSTAT_NOT_READ == *ctrlstat)
+ {
+ HAL_READ_UINT8(&pmbox->ctrlstat, *ctrlstat); // this read will lock the mbox
+ enable_mbox = true;
+ }
+
+ //
+ // If message buffer is busy then it is now beeing filled with a new message
+ // This condition will be cleared within 20 cycles - we simply do a 20 µs
+ // delay here, that should be enougth
+ //
+ if (*ctrlstat & MBOX_RXCODE_BUSY)
+ {
+ HAL_DELAY_US(20);
+ }
+
+ pmsg->dlc = (*ctrlstat & MBOX_CFG_DLC_MASK); // store received data len
+
+ HAL_READ_UINT16(&pmbox->id_hi, id); // read ID high
+
+ if (id & MBOX_CFG_IDE)
+ {
+ pmsg->ext = CYGNUM_CAN_ID_EXT;
+ pmsg->id = (id & 0xFFE0) << 13;
+ pmsg->id |= (id & 0x07) << 15;
+
+ HAL_READ_UINT16(&pmbox->id_lo, id);
+ pmsg->id |= (id & 0xFFFE) >> 1;
+
+ if (id & MBOX_CFG_RTR_EXT)
+ {
+ pmsg->rtr = CYGNUM_CAN_FRAME_RTR;
+ }
+ else
+ {
+ pmsg->rtr = CYGNUM_CAN_FRAME_DATA;
+ }
+ }
+ else
+ {
+ pmsg->ext = CYGNUM_CAN_ID_STD;
+ pmsg->id = (id & 0xFFE0) >> 5;
+
+ if (id & MBOX_CFG_RTR_STD)
+ {
+ pmsg->rtr = CYGNUM_CAN_FRAME_RTR;
+ }
+ else
+ {
+ pmsg->rtr = CYGNUM_CAN_FRAME_DATA;
+ }
+ }
+
+ //
+ // now finally copy data
+ //
+ HAL_READ_UINT8_VECTOR(&pmbox->data, pmsg->data.bytes, pmsg->dlc, 1);
+
+ //
+ // now mark this mbox as empty and read the free running timer
+ // to unlock this mbox
+ //
+ if (enable_mbox)
+ {
+ HAL_WRITE_UINT8(&pmbox->ctrlstat, MBOX_RXCODE_EMPTY);
+ HAL_READ_UINT16(&flexcan->TIMER, id);
+ }
+#ifdef CYGOPT_IO_CAN_SUPPORT_TIMESTAMP
+ pevent->timestamp = id;
+#endif
+}
+
+
+//===========================================================================
+// INIT CAN BAUD RATE
+//===========================================================================
+static bool flexcan_set_baud(can_channel *chan, cyg_uint16 baud)
+{
+ flexcan_info *info = (flexcan_info *)chan->dev_priv;
+ flexcan_regs *flexcan = (flexcan_regs *)info->base;
+ cyg_uint16 mcr_bck;
+ cyg_uint8 tmp8;
+ cyg_uint8 presdiv;
+ cyg_uint8 propseg;
+ cyg_uint8 pseg1_2;
+ cyg_uint16 baudrate = flexcan_baud_rates[baud];
+
+ //
+ // Get bit timings from HAL because bit timings depend on sysclock
+ //
+ HAL_MCF52xx_FLEXCAN_GET_BIT_TIMINGS(&baudrate, &presdiv, &propseg, &pseg1_2);
+
+ //
+ // return false if baudrate is not supported
+ //
+ if (0 == baudrate)
+ {
+ return false;
+ }
+
+ //
+ // For setting the bit timings we have to stop the flexcan modul
+ //
+ HAL_READ_UINT16(&flexcan->CANMCR, mcr_bck);
+ HAL_WRITE_UINT16(&flexcan->CANMCR, mcr_bck | FLEXCAN_MCR_HALT);
+
+ //
+ // now we setup bit timings
+ //
+ HAL_WRITE_UINT8(&flexcan->PRESDIV, presdiv);
+ HAL_READ_UINT8(&flexcan->CANCTRL1, tmp8);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL1, (tmp8 & 0xF8) | propseg);
+ HAL_READ_UINT8(&flexcan->CANCTRL2, tmp8);
+ HAL_WRITE_UINT8(&flexcan->CANCTRL2, (tmp8 & 0xC0) | pseg1_2);
+
+ //
+ // Now restore the previous state - if the modul was started then
+ // it will no be started again, if it was stopped, then it remains stopped
+ //
+ HAL_WRITE_UINT16(&flexcan->CANMCR, mcr_bck);
+
+ return true;
+}
+
+//---------------------------------------------------------------------------
+// end of can_mcf_flexcan.c
+
diff --git a/ecos/packages/devs/can/m68k/mcf52xx/current/tests/can_test_aux.inl b/ecos/packages/devs/can/m68k/mcf52xx/current/tests/can_test_aux.inl
new file mode 100644
index 0000000..2bb2e07
--- /dev/null
+++ b/ecos/packages/devs/can/m68k/mcf52xx/current/tests/can_test_aux.inl
@@ -0,0 +1,147 @@
+//==========================================================================
+//
+// can_test_aux.inl
+//
+// CAN test auxiliary functions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-08-07
+// Description: Auxiliary functions for CAN driver tests
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// PRINT CAN EVENT
+//===========================================================================
+void print_can_msg(cyg_can_message *pmsg, char *pMsg)
+{
+ char *pmsg_str;
+ static char* msg_tbl[] =
+ {
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X]\n",
+ "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X %02X]\n"
+ };
+
+ if (pmsg->rtr)
+ {
+ diag_printf("%s [ID:%03X] [RTR:%d] [EXT:%d] [DLC:%d]\n",
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->dlc);
+
+ return;
+ }
+
+ if (pmsg->dlc > 8)
+ {
+ pmsg_str = msg_tbl[8];
+ }
+ else
+ {
+ pmsg_str = msg_tbl[pmsg->dlc];
+ }
+
+ diag_printf(pmsg_str,
+ pMsg,
+ pmsg->id,
+ pmsg->rtr,
+ pmsg->ext,
+ pmsg->data.bytes[0],
+ pmsg->data.bytes[1],
+ pmsg->data.bytes[2],
+ pmsg->data.bytes[3],
+ pmsg->data.bytes[4],
+ pmsg->data.bytes[5],
+ pmsg->data.bytes[6],
+ pmsg->data.bytes[7]);
+}
+
+
+//===========================================================================
+// PRINT CAN EVENT FLAGS
+//===========================================================================
+void print_can_flags(cyg_uint16 flags, char *pMsg)
+{
+ char *pmsg_str;
+ cyg_uint8 i ;
+ static char* msg_tbl[] =
+ {
+ "RX ",
+ "TX ",
+ "WRX ",
+ "WTX ",
+ "ERRP ",
+ "BOFF ",
+ "OVRX ",
+ "OVTX ",
+ "CERR ",
+ "LSTY ",
+ "ESTY ",
+ "ALOS ",
+ "DEVC ",
+ "PHYF ",
+ "PHYH ",
+ "PHYL "
+ };
+ i = 0;
+ while (flags && (i < 16))
+ {
+ if (flags & 0x0001)
+ {
+ pmsg_str = msg_tbl[i];
+ diag_printf(pmsg_str);
+ }
+ flags >>=1;
+ i++;
+ }
+
+ diag_printf("\n");
+}
+
+//---------------------------------------------------------------------------
+// end of can_test_aux.inl
diff --git a/ecos/packages/devs/can/m68k/mcf52xx/current/tests/flexcan_wake.c b/ecos/packages/devs/can/m68k/mcf52xx/current/tests/flexcan_wake.c
new file mode 100644
index 0000000..28ef9a2
--- /dev/null
+++ b/ecos/packages/devs/can/m68k/mcf52xx/current/tests/flexcan_wake.c
@@ -0,0 +1,246 @@
+//==========================================================================
+//
+// flexcan_wake.c
+//
+// FlexCAN wake test
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: Uwe Kindler
+// Date: 2005-09-10
+// Description: FlexCAN test of standby and wake
+//####DESCRIPTIONEND####
+
+
+//===========================================================================
+// INCLUDES
+//===========================================================================
+#include <pkgconf/system.h>
+
+#include <cyg/infra/testcase.h> // test macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/diag.h>
+
+// Package requirements
+#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
+
+#include <pkgconf/kernel.h>
+#include <cyg/io/io.h>
+#include <cyg/io/canio.h>
+
+// Package option requirements
+#if defined(CYGFUN_KERNEL_API_C)
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+
+//===========================================================================
+// DATA TYPES
+//===========================================================================
+typedef struct st_thread_data
+{
+ cyg_thread obj;
+ long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_handle_t hdl;
+} thread_data_t;
+
+
+//===========================================================================
+// LOCAL DATA
+//===========================================================================
+cyg_thread_entry_t can0_thread;
+thread_data_t can0_thread_data;
+
+
+cyg_io_handle_t hDrvFlexCAN;
+
+
+//===========================================================================
+// LOCAL FUNCTIONS
+//===========================================================================
+#include "can_test_aux.inl" // include CAN test auxiliary functions
+
+
+//===========================================================================
+// READER THREAD
+//===========================================================================
+void can0_thread(cyg_addrword_t data)
+{
+ cyg_uint32 len;
+ cyg_can_event rx_event1;
+ cyg_can_event rx_event2;
+ cyg_can_msgbuf_info msgbox_info;
+ cyg_can_mode mode;
+ cyg_can_state state;
+
+
+ diag_printf("Test of FlexCAN standby mode with selfwakeup\n"
+ "As soon as a message arrives the FlexCAN modul\n"
+ "will leave standby and generates a leave standby event.\n"
+ "Each time you send a message you should see LSTY first\n"
+ "for \"leaving standby\" and then \"RX\" for the\n"
+ "RX event that caused the leave standby event. You can send\n"
+ "a CAN data frame with any ID\n");
+
+ diag_printf("!!! This test can be stopped by sending a data frame with ID 0x100 !!!\n\n");
+
+ len = sizeof(msgbox_info);
+ if (ENOERR != cyg_io_get_config(hDrvFlexCAN, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+ else
+ {
+ diag_printf("Message boxes available: %d free: %d\n",
+ msgbox_info.count, msgbox_info.free);
+ }
+
+ while (1)
+ {
+ //
+ // now we set FlexCAN into standby mode
+ //
+ mode = CYGNUM_CAN_MODE_STANDBY;
+ len = sizeof(mode);
+ if (ENOERR != cyg_io_set_config(hDrvFlexCAN, CYG_IO_SET_CONFIG_CAN_MODE ,&mode, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+ }
+
+ //
+ // now check if FlexCAN modul is really in standby mode
+ //
+ len = sizeof(state);
+ if (ENOERR != cyg_io_get_config(hDrvFlexCAN, CYG_IO_GET_CONFIG_CAN_STATE ,&state, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
+ }
+
+
+ if (state != CYGNUM_CAN_STATE_STANDBY)
+ {
+ CYG_TEST_FAIL_FINISH("Error stopping FlexCAN /dev/can0");
+ }
+
+ //
+ // as soon as a message arrives the FlexCAN modul leaves standby mode
+ // and we should receive a CYGNUM_CAN_EVENT_LEAVING_STANDBY event but
+ // we will also receive a RX event because a message arrived
+ //
+ len = sizeof(rx_event1);
+ if (ENOERR != cyg_io_read(hDrvFlexCAN, &rx_event1, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+
+ len = sizeof(rx_event2);
+ if (ENOERR != cyg_io_read(hDrvFlexCAN, &rx_event2, &len))
+ {
+ CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
+ }
+
+ print_can_flags(rx_event1.flags, "");
+ print_can_flags(rx_event2.flags, "");
+
+ //
+ // The first event we receive should be a leaving standby event because
+ // first flexcan leaves standby and then a message will be received
+ //
+ if (!(rx_event1.flags & CYGNUM_CAN_EVENT_LEAVING_STANDBY))
+ {
+ CYG_TEST_FAIL_FINISH("CYGNUM_CAN_EVENT_LEAVING_STANDBY event expexted /dev/can0");
+ }
+
+ if (rx_event2.msg.id == 0x100)
+ {
+ CYG_TEST_PASS_FINISH("flexcan_wake test OK");
+ }
+ }
+}
+
+
+void
+cyg_start(void)
+{
+ CYG_TEST_INIT();
+
+ //
+ // open flexcan device driver
+ //
+ if (ENOERR != cyg_io_lookup("/dev/can0", &hDrvFlexCAN))
+ {
+ CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
+ }
+
+
+ //
+ // create the two threads which access the CAN device driver
+ // a reader thread with a higher priority and a writer thread
+ // with a lower priority
+ //
+ cyg_thread_create(4, can0_thread,
+ (cyg_addrword_t) 0,
+ "can0_thread",
+ (void *) can0_thread_data.stack,
+ 1024 * sizeof(long),
+ &can0_thread_data.hdl,
+ &can0_thread_data.obj);
+
+ cyg_thread_resume(can0_thread_data.hdl);
+
+ cyg_scheduler_start();
+}
+
+#else // CYGFUN_KERNEL_API_C
+#define N_A_MSG "Needs kernel C API"
+#endif
+
+#else // CYGPKG_IO_CAN && CYGPKG_KERNEL
+#define N_A_MSG "Needs IO/CAN and Kernel"
+#endif
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG);
+}
+#endif // N_A_MSG
+
+// EOF flexcan_wake.c
diff --git a/ecos/packages/devs/disk/generic/mmc/current/ChangeLog b/ecos/packages/devs/disk/generic/mmc/current/ChangeLog
new file mode 100644
index 0000000..186f28b
--- /dev/null
+++ b/ecos/packages/devs/disk/generic/mmc/current/ChangeLog
@@ -0,0 +1,122 @@
+2013-02-18 Ilija Stanislevik <ilijas@siva.mk>
+
+ * src/mmc_spi.c: Add support for high capacity SD cards.
+ * include/mmc_protocol.h: Add definitions of V2 specific commands,
+ responses and card structure. [ Bugzilla 1001764 ]
+
+2013-02-21 Mike Jones <mike@proclivis.com>
+
+ * src/mmc_spi.c (mmc_spi_check_for_disk): Modify DEBUG1 to to show
+ CHS in partition table.
+
+2012-05-04 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/mmc_spi.c (mmc_spi_send_init): Silence unused var warning.
+ Spotted by Ilija Kocho.
+
+2008-08-19 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/devs_disk_mmc.cdl: Renamed the device to /dev/mmcdiskX so
+ that it is unique with respect to other disk drivers.
+
+2007-05-30 Hajime Ishitani <pigmon@mail.snd.co.jp>
+
+ * src/mmc_spi.c: Revise debug information with addition.
+ Add idle to operational retry wait.
+ * cdl/devs_disk_mmc.cdl: Add idle to operational retry wait parameter.
+
+2006-09-27 Sergei Gavrikov <sg@sgs.gomel.by>
+
+ * src/mmc_spi.c: (mmc_spi_disk_lookup): just fixed a missed
+ semicolon.
+
+2006-09-21 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * Contribution of MMC/SPI package from eCosCentric. eCosCentric
+ changes prior to contribution are included below for reference:
+
+ 2006-09-20 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/mmc_spi.c: DISK_FUNS, DISK_CHANNEL and DISK_CONTROLLER are now
+ implicitly static.
+ Update DISK_CHANNEL for new io/disk macro definition.
+
+ 2006-04-05 John Dallaway <jld@ecoscentric.com>
+
+ * cdl/devs_disk_mmc.cdl: Add reference to package documentation.
+
+ 2006-03-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/mmc_spi.c (struct cyg_mmc_spi_disk_info_t): Store underlying
+ medium's read/write block length.
+ (mmc_spi_check_for_disk): Store underlying medium's
+ read/write block length.
+ (mmc_spi_disk_lookup): Report medium block size to disk layer.
+ (mmc_spi_disk_read): API now requires sector reads to be with length
+ of sectors not bytes.
+ (mmc_spi_disk_write): Ditto.
+
+ 2005-10-28 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * include/mmc_protocol.h: Move from src/ to here.
+ * src/mmc_spi.c: Reflect above move.
+
+ 2004-08-30 Bart Veer <bartv@ecoscentric.com>
+
+ * src/mmc_spi.c (mmc_spi_write_disk_block): disable background
+ writes. Some MMC cards don't seem to implement this correctly so
+ if you are trying to talking to another SPI device the MMC card
+ still replies.
+
+ 2004-07-03 Bart Veer <bartv@ecoscentric.com>
+
+ * src/mmc_spi.c (MMC_SPI_READ_DATA_TOKEN_RETRIES): increase the
+ number of iterations. With some cards a read can occasionally take
+ 50* longer than normal.
+
+ 2004-07-01 Bart Veer <bartv@ecoscentric.com>
+
+ * src/mmc_spi.c: reorganize write code, to work around problems
+ with some cards.
+
+ 2004-06-29 Bart Veer <bartv@ecoscentric.com>
+
+ * src/mmc_spi.c: some cards require an extra delay during a mount
+ sequence, when doing the first read of a data block. Also added
+ some recovery code to the mount code in case a previous session
+ left the card still sending data.
+
+ 2004-06-15 Bart Veer <bartv@ecoscentric.com>
+
+ * src/mmc_spi.c (mmc_spi_check_for_disk): allow platform HALs to
+ customize the mount sequence.
+
+ * doc/disk_mmc.sgml: document the above change.
+
+ 2004-04-25 Bart Veer <bartv@ecoscentric.com>
+
+ * MMC package created
+
+ //===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/disk/generic/mmc/current/cdl/devs_disk_mmc.cdl b/ecos/packages/devs/disk/generic/mmc/current/cdl/devs_disk_mmc.cdl
new file mode 100644
index 0000000..4bd1a90
--- /dev/null
+++ b/ecos/packages/devs/disk/generic/mmc/current/cdl/devs_disk_mmc.cdl
@@ -0,0 +1,113 @@
+# ====================================================================
+#
+# devs_disk_mmc.cdl
+#
+# Support for MMC cards
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv,jlarmour
+# Date: 2004-04-25
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_DISK_MMC {
+ display "Disk driver for MMC cards"
+ doc ecos-ref/devs-disk-mmc-part.html
+
+ include_dir cyg/io
+
+ parent CYGPKG_IO_DISK_DEVICES
+ active_if CYGPKG_IO_DISK
+
+ cdl_interface CYGINT_DEVS_DISK_MMC_SPI_CONNECTORS {
+ active_if CYGPKG_IO_SPI
+ display "Number of MMC connectors accessed via SPI"
+ }
+
+ cdl_component CYGPKG_DEVS_DISK_MMC_SPI {
+ display "Access an MMC card via an SPI bus"
+ default_value { CYGINT_DEVS_DISK_MMC_SPI_CONNECTORS > 0 }
+ compile -library=libextras.a mmc_spi.c
+ requires CYGPKG_ERROR CYGPKG_LIBC_STRING
+ description "
+ This option enables support for accessing an MMC card via an
+ SPI bus."
+
+ define_proc {
+ puts $::cdl_system_header "/***** MMC/SPI disk driver output start *****/"
+ puts $::cdl_system_header "#ifndef CYGDAT_DEVS_DISK_CFG"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_DISK_CFG <pkgconf/devs_disk_mmc.h>"
+ puts $::cdl_system_header "#endif"
+ puts $::cdl_system_header "/***** MMC/SPI disk driver output end *****/"
+ }
+
+ cdl_option CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME {
+ display "Device name for the MMC/SPI disk 0 device"
+ flavor data
+ default_value { "\"/dev/mmcdisk0/\"" }
+ description "
+ This is the device name used to access the raw disk device
+ in eCos, for example for mount operations. Note that the
+ trailing slash must be present."
+ }
+ }
+
+ cdl_option CYGIMP_DEVS_DISK_MMC_SPI_POLLED {
+ display "Run the driver in polled mode rather than interrupt-driven"
+ default_value !CYGPKG_KERNEL
+ description "
+ By default the MMC disk driver will operate in
+ interrupt-driven mode if the kernel is present,
+ i.e. if the application is likely to be
+ multi-threaded. Otherwise it will operate in polled
+ mode."
+
+ }
+ cdl_option CYGPKG_DEVS_DISK_MMC_SPI_IDLE_RETRIES_WAIT {
+ display "Idle to operational retry wait"
+ flavor booldata
+ default_value 10000
+ description "
+
+ This option sets how long to wait between retries of
+ attempts to change the card state from idle to
+ operational. It is measured in microseconds."
+ }
+}
+
+# EOF devs_disk_mmc.cdl
diff --git a/ecos/packages/devs/disk/generic/mmc/current/doc/disk_mmc.sgml b/ecos/packages/devs/disk/generic/mmc/current/doc/disk_mmc.sgml
new file mode 100644
index 0000000..bbb291b
--- /dev/null
+++ b/ecos/packages/devs/disk/generic/mmc/current/doc/disk_mmc.sgml
@@ -0,0 +1,212 @@
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- disk_mmc.sgml -->
+<!-- -->
+<!-- Documentation for the MMC disk device driver -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2004/04/25 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-disk-mmc-part"><title>MMC MultiMedia Card Disk Driver</title>
+
+<refentry id="devs-disk-mmc">
+ <refmeta>
+ <refentrytitle>Device Driver for MMC MultiMedia Cards</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname><varname>CYGPKG_DEVS_DISK_MMC</varname></refname>
+ <refpurpose>eCos Support for MMC MultiMedia Cards</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="devs-disk-mmc-description"><title>Description</title>
+ <para>
+This package provides a disk device driver for MultiMediaCards (MMC).
+A MultiMediaCard provides non-volatile storage in a small footprint
+(24mm &ast; 32mm &ast; 1.4mm), and weighing less than 2 grams. Typical
+card sizes are 16MB to 128MB, with an upper limit of 4GB. It
+should be noted that these sizes are measured in millions of bytes,
+not 2^20. The <ulink url="http://www.mmca.org">MultiMediaCard
+Association</ulink> defines the standard for these cards.
+ </para>
+ <para>
+At the hardware level there are two ways of accessing an MMC card,
+either using a custom interface or via an SPI bus. A card will detect
+the interface in use at run-time. The custom interface allows for
+better performance but requires additional hardware. Currently only
+SPI mode is supported by this package.
+ </para>
+ <para>
+Theoretically an MMC card can be used with any file system. In
+practice all cards are formatted for PC compatibility, with a
+partition table in the first block and a single FAT file system on the
+rest of the card. Currently this package checks the format of the MMC
+card and will only allow access to a card if it is formatted this way.
+ </para>
+ <para>
+An MMC socket allows cards to be removed and inserted at any time. The
+device driver will detect removal events when the next I/O operation
+happens and will report them to higher-level code via an error code
+<literal>ENODEV</literal>. However there are no guarantees that the
+higher-level code will be able to recover from this error. The
+expected usage is that application code will explicitly
+<function>mount</function> the card before attempting any file I/O,
+and will <function>umount</function> the card before it is removed.
+Between these operations the system is likely to keep some disk blocks
+cached, for performance reasons. If the card is removed before the
+<function>umount</function> then it may end up with a corrupted file
+system, and the disk subsystem may be left in an inconsistent state.
+Regular uses of <function>sync</function> will reduce the risk
+of file system corruption.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-disk-mmc-config"><title>Configuration Options</title>
+ <para>
+<varname>CYGPKG_DEVS_DISK_MMC</varname> is a hardware package which
+should get loaded automatically when you configure for a suitable eCos
+target platform. In this case suitable means that the hardware has an
+MMC socket connected to an SPI bus, that an SPI bus driver package
+exists and is also automatically loaded, and that the platform HAL
+provides <link linkend="devs-disk-mmc-porting">information</link>
+on how the card is connected to the SPI bus.
+ </para>
+ <para>
+The package depends on support from the generic disk package
+<varname>CYGPKG_IO_DISK</varname>. That will not be loaded
+automatically: the presence of an MMC socket on the board does not
+mean that the application has any need for a file system. Hence by
+default <varname>CYGPKG_DEVS_DISK_MMC</varname> will be inactive and
+will not contribute any code or data to the application's memory
+footprint. To activate the driver it will be necessary to add one or
+more packages to the configuration using
+<command>ecosconfig&nbsp;add</command> or the graphical configuration
+tool: the generic disk support <varname>CYGPKG_IO_DISK</varname>;
+usually a file system, <varname>CYGPKG_FS_FAT</varname>; support for
+the file I/O API <varname>CYGPKG_IO_FILEIO</varname>; and possibly
+additional support packages that may be needed by the file system, for
+example <varname>CYGPKG_LINUX_COMPAT</varname>. Depending on the
+template used to create the initial configuration some of these may be
+loaded already.
+ </para>
+ <para>
+The package provides two main configuration options.
+<varname>CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME</varname> specifies the
+name of the raw disk device, for example <literal>/dev/hd0</literal>.
+Allowing for partition tables that makes <literal>/dev/hd0/1</literal>
+the first argument that shoul be passed to a
+<function>mount</function> call. If the hardware has multiple disk
+devices then each one will need a unique name.
+<varname>CYGIMP_DEVS_DISK_MMC_SPI_POLLED</varname> controls whether
+the SPI bus will be accessed in interrupt-driven or polled mode. It
+will default to interrupt-driven if the application is multi-threaded,
+which is assumed to be the case if the kernel is present. If the
+kernel is absent, for example in a RedBoot configuration, then the
+driver will default to polled mode. With some hardware polled mode may
+significantly increase disk throughput even in a multi-threaded
+application, but will consume cpu cycles that could be used by other
+threads.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-disk-mmc-extra"><title>Additional Functionality</title>
+ <para>
+The disk driver package exports a variable
+<varname>cyg_mmc_spi_polled</varname>. This defaults to true or false
+depending on the configuration option
+<varname>CYGIMP_DEVS_DISK_MMC_SPI_POLLED</varname>. If the default
+mode is interrupt-driven then file I/O, including mount operations,
+are only allowed when the scheduler has started and interrupts have
+been enabled. Any attempts at file I/O earlier during system
+initialization, for example inside a C++ static constructor, will lock
+up. If it is necessary to perform file I/O at this time then the
+driver can be temporarily switched to polling mode before the I/O
+operation by setting <varname>cyg_mmc_spi_polled</varname>, and
+clearing it again after the I/O. Alternatively the default mode can be
+changed to polling by editing the configuration, and then the
+<function>main()</function> thread can change the mode to
+interrupt-driven once the scheduler has started.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-disk-mmc-porting"><title>Porting to New Hardware</title>
+ <para>
+Assuming that the MMC connector is hooked up to a standard SPI bus and
+that there is already an eCos SPI bus driver, porting the MMC disk
+driver package should be straightforward. Some other package, usually
+the platform HAL, should provide a <type>cyg_spi_device</type>
+structure <varname>cyg_spi_mmc_dev0</varname>. That structure contains
+the information needed by this package to interact with the MMC card
+via the usual SPI interface, for example how to activate the
+appropriate chip select. The platform HAL should also implement the
+CDL interface <varname>CYGINT_DEVS_DISK_MMC_SPI_CONNECTORS</varname>.
+ </para>
+ <para>
+When defining <varname>cyg_spi_mmc_dev0</varname> special care must be
+taken with the chip select. The MMC protocol is transaction-oriented.
+For example a read operation involves an initial command sent to the
+card, then a reply, then the actual data, and finally a checksum. The
+card's chip select must be kept asserted for the entire operation, and
+there can be no interactions with other devices on the same SPI bus
+during this time.
+ </para>
+ <para>
+Optionally the platform HAL may define a macro
+<function>HAL_MMC_SPI_INIT</function> which will be invoked during a
+mount operation. This can take any hardware-specific actions that may
+be necessary, for example manipulating GPIO pins. Usually no such
+macro is needed because the hardware is set up during platform
+initialization.
+ </para>
+ <para>
+Currently the package does not provide any support for accessing MMC
+cards using an interface other than SPI. On some targets there may be
+additional hardware to detect events such as card insertion or
+removal, but there is no support for exploiting such hardware at
+present.
+ </para>
+ <para>
+Only a single MMC socket is supported. Extending the package to
+support multiple sockets would be straightforward but it seems
+unlikely that any hardware would come with multiple MMC sockets. Given
+the nature of SPI buses there is a problem if the MMC socket is hooked
+up via an expansion connector rather than being attached to the main
+board. The platform HAL would not know about the socket so would not
+implement the CDL interface
+<varname>CYGINT_DEVS_DISK_MMC_SPI_CONNECTORS</varname>, and the
+<database>ecos.db</database> target entry would not include
+<varname>CYGPKG_DEVS_DISK_MMC</varname>. Because this is a hardware
+package it cannot easily be added by hand. Instead this scenario would
+require some editing of the existing platform HAL and target entry.
+ </para>
+ </refsect1>
+
+</refentry>
+</part>
diff --git a/ecos/packages/devs/disk/generic/mmc/current/include/mmc_protocol.h b/ecos/packages/devs/disk/generic/mmc/current/include/mmc_protocol.h
new file mode 100644
index 0000000..291499a
--- /dev/null
+++ b/ecos/packages/devs/disk/generic/mmc/current/include/mmc_protocol.h
@@ -0,0 +1,197 @@
+#ifndef CYGONCE_DEVS_DISK_MMC_PROTOCOL_H
+#define CYGONCE_DEVS_DISK_MMC_PROTOCOL_H
+//==========================================================================
+//
+// mmc_protocol.h
+//
+// Define the protocol used for interacting with MMC cards
+//
+//===========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author: bartv
+// Contributors: jlarmour
+// Date: 2004-04-25
+// Usage: Only this package and implementing device drivers should
+// include this header file.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h> /* Common types */
+
+// The MMC command set. A request is a six-byte sequence. First a
+// single command byte, one of the following with bit 6 (0x40) or'd in
+// and bit 7 clear as a start bit. Then a four-byte argument, usually
+// a 32-bit integer most significant byte first. Finally a 7-bit CRC
+// and a stop bit. In SPI mode the CRC is usually optional, except for
+// the GO_IDLE_STATE command.
+//
+// Commands ALL_SEND_CID, SEND_RELATIVE_ADDR, SET_DSR,
+// SELECT_DESELECT, READ_DATA_UNTIL_STOP, STOP_TRANSMISSION,
+// GO_INACTIVE, READ_MULTIPLE_BLOCK, WRITE_DATA_UNTIL_STOP,
+// WRITE_MULTIPLE_BLOCK, and PROGRAM_CID are MMC only, and not
+// available in SPI mode.
+//
+// Device drivers may use values with bit 7 set to indicate
+// driver-specific commands.
+
+#define MMC_REQUEST_GO_IDLE_STATE 0x00
+#define MMC_REQUEST_SEND_OP_COND 0x01
+#define MMC_REQUEST_ALL_SEND_CID 0x02
+#define MMC_REQUEST_SEND_RELATIVE_ADDR 0x03
+#define MMC_REQUEST_SET_DSR 0x04
+#define MMC_REQUEST_SELECT_DESELECT 0x07
+#define MMC_REQUEST_SEND_CSD 0x09
+#define MMC_REQUEST_SEND_CID 0x0A
+#define MMC_REQUEST_READ_DATA_UNTIL_STOP 0x0B
+#define MMC_REQUEST_STOP_TRANSMISSION 0x0C
+#define MMC_REQUEST_SEND_STATUS 0x0D
+#define MMC_REQUEST_GO_INACTIVE 0x0F
+#define MMC_REQUEST_SET_BLOCKLEN 0x10
+#define MMC_REQUEST_READ_SINGLE_BLOCK 0x11
+#define MMC_REQUEST_READ_MULTIPLE_BLOCK 0x12
+#define MMC_REQUEST_WRITE_DATA_UNTIL_STOP 0x14
+#define MMC_REQUEST_WRITE_BLOCK 0x18
+#define MMC_REQUEST_WRITE_MULTIPLE_BLOCK 0x19
+#define MMC_REQUEST_PROGRAM_CID 0x1A
+#define MMC_REQUEST_PROGRAM_CSD 0x1B
+#define MMC_REQUEST_SET_WRITE_PROT 0x1C
+#define MMC_REQUEST_CLR_WRITE_PROT 0x1D
+#define MMC_REQUEST_SEND_WRITE_PROT 0x1E
+#define MMC_REQUEST_TAG_SECTOR_START 0x20
+#define MMC_REQUEST_TAG_SECTOR_END 0x21
+#define MMC_REQUEST_UNTAG_SECTOR 0x22
+#define MMC_REQUEST_TAG_ERASE_GROUP_START 0x23
+#define MMC_REQUEST_TAG_ERASE_GROUP_END 0x24
+#define MMC_REQUEST_UNTAG_ERASE_GROUP 0x25
+#define MMC_REQUEST_ERASE 0x26
+#define MMC_REQUEST_LOCK_UNLOCK 0x2A
+#define MMC_REQUEST_READ_OCR 0x3A
+#define MMC_REQUEST_CRC_ON_OFF 0x3B
+
+// SD V2.x specific commands
+#define SD_REQUEST_SEND_IF_COND 8
+#define SD_REQUEST_SD_SEND_OP_COND 41
+#define SD_REQUEST_APP_CMD 55
+
+// Response formats are different for MMC vs. SPI mode, so are defined
+// in the appropriate source files.
+
+// SD V2.x specific responses
+#define SD_ARGUMENT_HCS ( 1 << 30 )
+
+// The CID register is generally treated as an opaque data structure
+// used only for unique identification of cards.
+typedef struct mmc_cid_register {
+ cyg_uint8 cid_data[16];
+} mmc_cid_register;
+
+#define MMC_CID_REGISTER_MID(_data_) ((_data_)->cid_data[0])
+#define MMC_CID_REGISTER_OID(_data_) (((_data_)->cid_data[1] << 8) | \
+ ((_data_)->cid_data[2]))
+#define MMC_CID_REGISTER_PNM(_data_) ((const char*)&((_data_)->cid_data[3]))
+#define MMC_CID_REGISTER_PRV(_data_) ((_data_)->cid_data[9])
+#define MMC_CID_REGISTER_PSN(_data_) (((_data_)->cid_data[10] << 24) | \
+ ((_data_)->cid_data[11] << 16) | \
+ ((_data_)->cid_data[12] << 8) | \
+ ((_data_)->cid_data[13]))
+#define MMC_CID_REGISTER_MDT(_data_) ((_data_)->cid_data[14])
+#define MMC_CID_REGISTER_CRC(_data_) ((_data_)->cid_data[15] >> 1)
+
+
+// The CSD register is just lots of small bitfields. For now keep it
+// as an array of 16 bytes and provide macros to read the fields.
+typedef struct mmc_csd_register {
+ cyg_uint8 csd_data[16];
+} mmc_csd_register;
+
+#define MMC_CSD_REGISTER_CSD_STRUCTURE(_data_) (((_data_)->csd_data[0] & 0x00C0) >> 6)
+#define MMC_CSD_REGISTER_SPEC_VERS(_data_) (((_data_)->csd_data[0] & 0x003C) >> 2)
+#define MMC_CSD_REGISTER_TAAC_MANTISSA(_data_) (((_data_)->csd_data[1] & 0x0078) >> 3)
+#define MMC_CSD_REGISTER_TAAC_EXPONENT(_data_) ((_data_)->csd_data[1] & 0x0007)
+#define MMC_CSD_REGISTER_NSAC(_data_) ((_data_)->csd_data[2])
+#define MMC_CSD_REGISTER_TRAN_SPEED_MANTISSA(_data_) (((_data_)->csd_data[3] & 0x0078) >> 3)
+#define MMC_CSD_REGISTER_TRAN_SPEED_EXPONENT(_data_) ((_data_)->csd_data[3] & 0x0007)
+#define MMC_CSD_REGISTER_CCC(_data_) (((_data_)->csd_data[4] << 4) | (((_data_)->csd_data[5] & 0x00F0) >> 4))
+#define MMC_CSD_REGISTER_READ_BL_LEN(_data_) ((_data_)->csd_data[5] & 0x000F)
+#define MMC_CSD_REGISTER_READ_BL_PARTIAL(_data_) (((_data_)->csd_data[6] & 0x0080) >> 7)
+#define MMC_CSD_REGISTER_WRITE_BLK_MISALIGN(_data_) (((_data_)->csd_data[6] & 0x0040) >> 6)
+#define MMC_CSD_REGISTER_READ_BLK_MISALIGN(_data_) (((_data_)->csd_data[6] & 0x0020) >> 5)
+#define MMC_CSD_REGISTER_DSR_IMP(_data_) (((_data_)->csd_data[6] & 0x0010) >> 4)
+#define MMC_CSD_REGISTER_C_SIZE(_data_) ((((_data_)->csd_data[6] & 0x0003) << 10) | \
+ ((_data_)->csd_data[7] << 2) | \
+ (((_data_)->csd_data[8] & 0x00C0) >> 6))
+#define MMC_CSD_REGISTER_VDD_R_CURR_MIN(_data_) (((_data_)->csd_data[8] & 0x0038) >> 3)
+#define MMC_CSD_REGISTER_VDD_R_CURR_MAX(_data_) ((_data_)->csd_data[8] & 0x0007)
+#define MMC_CSD_REGISTER_VDD_W_CURR_MIN(_data_) (((_data_)->csd_data[9] & 0x00E0) >> 5)
+#define MMC_CSD_REGISTER_VDD_W_CURR_MAX(_data_) (((_data_)->csd_data[9] & 0x001C) >> 2)
+#define MMC_CSD_REGISTER_C_SIZE_MULT(_data_) ((((_data_)->csd_data[9] & 0x0003) << 1) | \
+ (((_data_)->csd_data[10] & 0x0080) >> 7))
+#define MMC_CSD_REGISTER_SECTOR_SIZE(_data_) (((_data_)->csd_data[10] & 0x007C) >> 2)
+#define MMC_CSD_REGISTER_ERASE_GRP_SIZE(_data_) ((((_data_)->csd_data[10] & 0x0003) << 3) | \
+ (((_data_)->csd_data[11] & 0x00E0) >> 5))
+#define MMC_CSD_REGISTER_WR_GRP_SIZE(_data_) ((_data_)->csd_data[11] & 0x001F)
+#define MMC_CSD_REGISTER_WR_GRP_ENABLE(_data_) (((_data_)->csd_data[12] & 0x0080) >> 7)
+#define MMC_CSD_REGISTER_DEFAULT_ECC(_data_) (((_data_)->csd_data[12] & 0x0060) >> 5)
+#define MMC_CSD_REGISTER_R2W_FACTOR(_data_) (((_data_)->csd_data[12] & 0x001C) >> 2)
+#define MMC_CSD_REGISTER_WRITE_BL_LEN(_data_) ((((_data_)->csd_data[12] & 0x0003) << 2) | \
+ (((_data_)->csd_data[13] & 0x00C0) >> 6))
+#define MMC_CSD_REGISTER_WR_BL_PARTIAL(_data_) (((_data_)->csd_data[13] & 0x0020) >> 5)
+#define MMC_CSD_REGISTER_FILE_FORMAT_GROUP(_data_) (((_data_)->csd_data[14] & 0x0080) >> 7)
+#define MMC_CSD_REGISTER_COPY(_data_) (((_data_)->csd_data[14] & 0x0040) >> 6)
+#define MMC_CSD_REGISTER_PERM_WRITE_PROTECT(_data_) (((_data_)->csd_data[14] & 0x0020) >> 5)
+#define MMC_CSD_REGISTER_TMP_WRITE_PROTECT(_data_) (((_data_)->csd_data[14] & 0x0010) >> 4)
+#define MMC_CSD_REGISTER_FILE_FORMAT(_data_) (((_data_)->csd_data[14] & 0x000C) >> 2)
+#define MMC_CSD_REGISTER_ECC(_data_) ((_data_)->csd_data[14] & 0x0003)
+#define MMC_CSD_REGISTER_CRC(_data_) (((_data_)->csd_data[15] & 0xFE) >> 1)
+
+// CSD V2.x structure
+#define SD_CSD_V2_REGISTER_C_SIZE(_data_) ((((_data_)->csd_data[7] & 0x007f) << 16) | \
+ ((_data_)->csd_data[8] << 8) | \
+ ((_data_)->csd_data[9] ))
+
+// OCR
+typedef struct sd_ocr_register {
+ cyg_uint8 ocr_data[4];
+} sd_ocr_register_t;
+
+#define SD_OCR_REGISTER_POWER_UP(_data_) (((_data_)->ocr_data[0] & 0x80) >> 7)
+// CCS bit denotes Standard (0) or High/Extended (1) capacity
+#define SD_OCR_REGISTER_CCS(_data_) (((_data_)->ocr_data[0] & 0x40) >> 6)
+
+#endif // ifdef CYGONCE_DEVS_DISK_MMC_PROTOCOL_H
+
+/* EOF mmc_protocol.h */
diff --git a/ecos/packages/devs/disk/generic/mmc/current/src/mmc_spi.c b/ecos/packages/devs/disk/generic/mmc/current/src/mmc_spi.c
new file mode 100644
index 0000000..294888d
--- /dev/null
+++ b/ecos/packages/devs/disk/generic/mmc/current/src/mmc_spi.c
@@ -0,0 +1,1372 @@
+//==========================================================================
+//
+// mmc_spi.c
+//
+// Provide a disk device driver for MMC cards over SPI
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author: bartv
+// Date: 2004-04-25
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_disk_mmc.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_if.h> // delays
+#include <cyg/hal/hal_intr.h>
+#include <string.h>
+#include <errno.h>
+#include <cyg/io/io.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/disk.h>
+#include <cyg/io/mmc_protocol.h>
+
+// Communication parameters. First some debug support
+#define DEBUG 0
+#if DEBUG > 0
+# define DEBUG1(format, ...) diag_printf(format, ## __VA_ARGS__)
+#else
+# define DEBUG1(format, ...)
+#endif
+#if DEBUG > 1
+# define DEBUG2(format, ...) diag_printf(format, ## __VA_ARGS__)
+#else
+# define DEBUG2(format, ...)
+#endif
+
+// Should the SPI operations run in polled or interrupt-driven mode?
+// The default value is determined by CDL, but can be overridden at
+// run-time if necessary. For example if configured for
+// interrupt-driven I/O then it will be impossible to perform disk
+// operations during system initialization, e.g. from a static
+// constructor, unless this flag is changed for the duration.
+#ifdef CYGIMP_DEVS_DISK_MMC_SPI_POLLED
+cyg_bool cyg_mmc_spi_polled = true;
+#else
+cyg_bool cyg_mmc_spi_polled = false;
+#endif
+
+// Should write operations be allowed to complete in the background,
+// or must the operation complete in the foreground. The latter
+// requires polling for potentially a long time, up to some 100's of
+// milliseconds, but the former appears unreliable if there are other
+// devices on the SPI bus. In theory the MMC card should detect that
+// the chip select line is dropped and tristate the output line, but
+// in practice this does not always happen.
+#undef MMC_SPI_BACKGROUND_WRITES
+
+// The size of each disk block
+#define MMC_SPI_BLOCK_SIZE 512
+// The number of retries during a mount operation when switching to
+// IDLE mode.
+#define MMC_SPI_GO_IDLE_RETRIES 16
+// The number of retries during a mount operation when switching from
+// idle to operational
+#define MMC_SPI_OP_COND_RETRIES 128
+// The number of retries when waiting for a response to any command
+#define MMC_SPI_COMMAND_RETRIES 32
+// Retries when waiting for a data response token during a read
+#define MMC_SPI_READ_DATA_TOKEN_RETRIES 32768
+// Retries during a write while waiting for completion
+#define MMC_SPI_WRITE_BUSY_RETRIES 32768
+
+// ----------------------------------------------------------------------------
+// SPI-specific parts of the MMC protocol.
+//
+// Host supply voltage information
+#define MMC_SPI_VHS 0x01 // 2.7 - 3.6V
+// Check pattern
+#define MMC_CMD8_CHECK_PATTERN 0xaa
+//
+// The main response byte. 0 indicates success, other bits
+// indicate various error conditions.
+#define MMC_REPLY_SUCCESS 0x00
+#define MMC_REPLY_PARAMETER_ERROR (0x01 << 6)
+#define MMC_REPLY_ADDRESS_ERROR (0x01 << 5)
+#define MMC_REPLY_ERASE_SEQUENCE_ERROR (0x01 << 4)
+#define MMC_REPLY_COM_CRC_ERROR (0x01 << 3)
+#define MMC_REPLY_ILLEGAL_COMMAND (0x01 << 2)
+#define MMC_REPLY_ERASE_RESET (0x01 << 1)
+#define MMC_REPLY_IN_IDLE_STATE (0x01 << 0)
+
+// A send-status command generates a second response byte
+#define MMC_REPLY2_OUT_OF_RANGE (0x01 << 7)
+#define MMC_REPLY2_ERASE_PARAM (0x01 << 6)
+#define MMC_REPLY2_WP_VIOLATION (0x01 << 5)
+#define MMC_REPLY2_CARD_ECC_FAILED (0x01 << 4)
+#define MMC_REPLY2_CC_ERROR (0x01 << 3)
+#define MMC_REPLY2_ERROR (0x01 << 2)
+#define MMC_REPLY2_WP_ERASE_SKIP (0x01 << 1)
+// Alias for the above
+#define MMC_REPLY2_LOCK_UNLOCK_FAILED (0x01 << 1)
+#define MMC_REPLY2_CARD_LOCKED (0x01 << 0)
+
+// The data error token byte which may get sent if a read
+// operation fails. The top 3 bits will be 0. A successful
+// response will have these bits 1.
+#define MMC_DATA_TOKEN_SUCCESS (0x00FE)
+#define MMC_DATA_ERROR_TOKEN_CARD_LOCKED (0x01 << 4)
+#define MMC_DATA_ERROR_TOKEN_OUT_OF_RANGE (0x01 << 3)
+#define MMC_DATA_ERROR_TOKEN_CARD_ECC_FAILED (0x01 << 2)
+#define MMC_DATA_ERROR_TOKEN_CC_ERROR (0x01 << 1)
+#define MMC_DATA_ERROR_TOKEN_ERROR (0x01 << 0)
+
+// ----------------------------------------------------------------------------
+// Structures and statics.
+//
+// There should be an SPI device cyg_spi_mmc_dev0, probably provided by
+// the HAL, possibly by the application. Because of the latter we cannot
+// assume the variable will be defined in a header.
+extern cyg_spi_device cyg_spi_mmc_dev0;
+
+// When retrieving data it is necessary to send an 0xff byte stream,
+// which the card will not confuse with further commands. The largest
+// transfer is 512 bytes, too large a buffer to place on the stack.
+static cyg_uint8 mmc_spi_ff_data[512];
+#define MMC_SPI_INIT_FF_DATA() \
+ CYG_MACRO_START \
+ memset(mmc_spi_ff_data, 0x00FF, 512); \
+ CYG_MACRO_END
+
+typedef enum sd_capacity_e {
+ STANDARD_CAPACITY,
+ HIGH_CAPACITY,
+ EXTENDED_CAPACITY
+} sd_capacity_t;
+
+// Details of a specific MMC card
+typedef struct cyg_mmc_spi_disk_info_t {
+ cyg_spi_device* mmc_spi_dev;
+ cyg_uint32 mmc_saved_baudrate;
+ cyg_uint32 mmc_block_count;
+#ifdef MMC_SPI_BACKGROUND_WRITES
+ cyg_bool mmc_writing;
+#endif
+ cyg_bool mmc_read_only;
+ cyg_bool mmc_connected;
+ cyg_uint32 mmc_heads_per_cylinder;
+ cyg_uint32 mmc_sectors_per_head;
+ cyg_uint32 mmc_read_block_length;
+ cyg_uint32 mmc_write_block_length;
+ mmc_cid_register mmc_id;
+ sd_ocr_register_t sd_ocr;
+ cyg_uint32 sd_version;
+ sd_capacity_t sd_capacity;
+ cyg_uint32 sd_csd_version;
+} cyg_mmc_spi_disk_info_t;
+
+// There is no need for a hardware-specific disk controller structure.
+// The closest equivalent is probably an SPI bus, i.e. if there were
+// MMC connectors attached to different SPI buses then these would
+// have separate controllers with independent locking. However that
+// can be handled without a cyg_mmc_spi_controller_info_t structure.
+
+// ----------------------------------------------------------------------------
+// The low-level MMC operations
+
+// After power-on an MMC card is in idle state and needs at least 74
+// clock cycles before any communication. These might be supplied
+// courtesy of another SPI device, but no guarantees, so generate some
+// ticks.
+static void
+mmc_spi_send_init(cyg_mmc_spi_disk_info_t* disk)
+{
+#if DEBUG > 1
+ cyg_spi_device *dev = disk->mmc_spi_dev;
+ cyg_spi_bus *bus = dev->spi_bus;
+#endif
+
+ DEBUG2("%s(): dev pointer 0x%p, %d\n", __FUNCTION__, disk->mmc_spi_dev, cyg_mmc_spi_polled );
+ DEBUG2(" : begin pointer %p\n", bus->spi_transaction_begin );
+ cyg_spi_tick(disk->mmc_spi_dev, cyg_mmc_spi_polled, 10);
+}
+
+// Send the first part of a command sequence. This consists of the
+// command itself, an argument, a CRC, and then waiting for a
+// reply byte from the card.
+static cyg_uint32
+mmc_spi_send_command_start(cyg_mmc_spi_disk_info_t* disk, cyg_uint32 command, cyg_uint32 arg)
+{
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+ cyg_uint8 request[7];
+ cyg_uint8 response[7];
+ cyg_uint8 reply;
+ int i;
+
+#ifdef MMC_SPI_BACKGROUND_WRITES
+ // If the last operation was a block write, those can take a while
+ // to complete. Rather than wait at the end of the write(), do so
+ // at the beginning of the next operation i.e. here. This also
+ // allows the chip select to be dropped while the write comples,
+ // so communication is possible with other devices. The polling is
+ // done as a sequence of transactions rather than in a single
+ // transaction, again to let other threads in to communicate with
+ // other devices.
+ //
+ // The card will send a stream of 0x00 bytes while the write
+ // completes. Some cards have been observed to send a byte 0x03 at
+ // the end, Either way, when the card sends a byte 0xff it should
+ // be ready for the next command.
+ if (disk->mmc_writing) {
+ DEBUG2("%s(): polling for completion of previous write\n", __FUNCTION__);
+ disk->mmc_writing = 0;
+ response[0] = 0x00;
+ for (i = 0; (i < MMC_SPI_WRITE_BUSY_RETRIES) && (0x00FF != response[0]); i++) {
+ cyg_spi_transfer(dev, cyg_mmc_spi_polled, 1, mmc_spi_ff_data, response);
+ }
+ }
+#endif
+
+ request[0] = command | 0x0040;
+ request[1] = (arg >> 24) & 0x00FF;
+ request[2] = (arg >> 16) & 0x00FF;
+ request[3] = (arg >> 8) & 0x00FF;
+ request[4] = arg & 0x00FF;
+ // A CRC is needed for the go-idle-state command, because that
+ // command switches the device from MMC to SPI mode. Also, a CRC
+ // is needed in case of CMD8. Here we take for granted that the
+ // host has 2.7-3.6V range and that the check pattern is 0xaa.
+ // These CRCs are well-known. Once in SPI mode the card will not
+ // use CRCs by default.
+ request[5] = (command == 0x00) ? 0x0095 :
+ (command == SD_REQUEST_SEND_IF_COND) ? 0x87 : 0xff;
+
+ // There will need to be at least one extra byte transfer to get
+ // the card's response, so send that straightaway. Extra
+ // outgoing data like this should be 0xff so that the card
+ // does not confuse it with a new incoming command.
+ request[6] = 0x00ff;
+
+ // Lock the SPI bus. It remains locked until a subsequent call to
+ // mmc_spi_end_command().
+ cyg_spi_transaction_begin(dev);
+
+ // Transfer the whole command, and try to read the response back
+ // immediately.
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 7, request, response, 0);
+ DEBUG2("Sent command %02x %d: reply bytes %02x %02x %02x %02x %02x %02x %02x\n", command, arg, \
+ response[0], response[1], response[2], response[3], response[4], response[5], response[6]);
+
+ // The response will be a single byte with the top bit clear.
+ // The remaining bits are error/status flags. If the command
+ // involves an additional response then that will be handled
+ // by the calling code.
+ reply = response[6];
+ for (i = 0; (i < MMC_SPI_COMMAND_RETRIES) && (0 != (reply & 0x0080)); i++) {
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, mmc_spi_ff_data, response, 0);
+ reply = response[0];
+ DEBUG2(" loop %d, additional reply %02x\n", i, reply);
+ }
+
+ // Leave the interpretation of the reply code to the caller
+ return (cyg_uint32) reply;
+}
+
+// At the end of each command the card needs eight clocks to finish
+// its processing. A tick() call takes care of that, and will have
+// the side effect of dropping the chip select. Ending the transaction
+// unlocks the bus for other SPI I/O operations
+static void
+mmc_spi_end_command(cyg_mmc_spi_disk_info_t* disk)
+{
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+ cyg_spi_transaction_tick(dev, cyg_mmc_spi_polled, 1);
+ cyg_spi_transaction_end(dev);
+}
+
+// A utility combination of the above two for simple commands which do
+// not involve any other data.
+static cyg_uint32
+mmc_spi_send_command(cyg_mmc_spi_disk_info_t* disk, cyg_uint32 command, cyg_uint32 arg)
+{
+ cyg_uint32 reply;
+ reply = mmc_spi_send_command_start(disk, command, arg);
+ mmc_spi_end_command(disk);
+ return reply;
+}
+
+// The card will return a data block when reading a disk block, or
+// for certain other commands like reading card registers. Each
+// data block consists of:
+// 1) some number of padding bytes 0xff while the card is still
+// processing the command and preparing the data
+// 2) a data token byte, usually 0xFE for success
+// 3) n bytes of data
+// 4) two bytes of crc, which can be ignored.
+//
+// The data token byte is the only indication of success or failure,
+// so that gets returned.
+//
+// When mounting certain types of card an extra delay may be needed
+// before reading the first data block. This is handled by the
+// extra_delay argument.
+static cyg_uint32
+mmc_spi_read_data(cyg_mmc_spi_disk_info_t* disk, cyg_uint8* buf, cyg_uint32 count, cyg_bool extra_delay)
+{
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+ int i;
+ cyg_uint8 response[2];
+ cyg_uint32 retries;
+
+ if (extra_delay) {
+ retries = MMC_SPI_READ_DATA_TOKEN_RETRIES * 100;
+ } else {
+ retries = MMC_SPI_READ_DATA_TOKEN_RETRIES;
+ }
+
+ response[0] = 0x00FF;
+ for (i = 0; (i < retries) && (0x00FF == response[0]); i++) {
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, mmc_spi_ff_data, response, 0);
+ }
+
+ if (MMC_DATA_TOKEN_SUCCESS != response[0]) {
+ DEBUG1("%s(): got error response %02x after %d iterations\n", __FUNCTION__, response[0], i);
+ return response[0];
+ }
+
+ // Now for the actual data. There is no way of detecting a failure from
+ // this point on.
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, count, mmc_spi_ff_data, buf, 0);
+ // And the CRC, which can be ignored
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 2, mmc_spi_ff_data, response, 0);
+ DEBUG2("%s(): got data and CRC %02x %02x\n", __FUNCTION__, response[0], response[1]);
+
+ return MMC_DATA_TOKEN_SUCCESS;
+}
+
+// Determine if card complies with SD Physical Spec. Version 1.x or 2.x
+// If it is V1, also set information on capacity. MMC cards are recognized as SD V1.
+static Cyg_ErrNo
+mmc_spi_check_version(cyg_mmc_spi_disk_info_t* disk)
+{
+#define R7_RESPONSE_LENGTH 5
+ cyg_uint32 reply;
+ cyg_uint8 response[R7_RESPONSE_LENGTH];
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+
+ disk->sd_version = 0;
+ reply = mmc_spi_send_command_start(disk, SD_REQUEST_SEND_IF_COND,
+ ( MMC_SPI_VHS << 8 ) + MMC_CMD8_CHECK_PATTERN);
+ DEBUG2("SEND_IF_COND (CMD8) reply: %02x\n", reply);
+
+ if (MMC_REPLY_ILLEGAL_COMMAND & reply) { // V1 cards do not understand CMD8
+ disk->sd_version = 1;
+ disk->sd_capacity = STANDARD_CAPACITY;
+ mmc_spi_end_command(disk);
+ return ENOERR;
+ }
+ disk->sd_version = 2;
+ if (~MMC_REPLY_IN_IDLE_STATE & reply) { // Anything other than idle state?
+ DEBUG1("SEND_IF_COND (CMD8) replies error %02x\n", reply);
+ mmc_spi_end_command(disk);
+ return -EIO;
+ }
+
+ // Card gives no error, so the response is R7. Take the rest of it.
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled,
+ R7_RESPONSE_LENGTH, mmc_spi_ff_data, response, 0);
+ DEBUG2("%s(): R7: %02x %02x %02x %02x %02x.\n", __FUNCTION__,
+ response[0], response[1], response[2], response[3], response[4]);
+ if (0 == (MMC_SPI_VHS & response[2])) {
+ DEBUG1("%s(): card doesn't accept voltage %02x\n", __FUNCTION__, MMC_SPI_VHS);
+ mmc_spi_end_command(disk);
+ return -ENOTSUP;
+ }
+
+ mmc_spi_end_command(disk);
+ return ENOERR;
+}
+
+static Cyg_ErrNo
+mmc_spi_sd_check_v2_capacity_class(cyg_mmc_spi_disk_info_t* disk)
+{
+#define R3_RESPONSE_LENGTH 4
+ cyg_uint32 reply;
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+
+ reply = mmc_spi_send_command_start(disk, MMC_REQUEST_READ_OCR, 0);
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("READ_OCR (CMD58) replies error %02x\n", reply);
+ mmc_spi_end_command(disk);
+ return -EIO;
+ }
+
+ // Card gives no error. Take the rest of response.
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled,
+ R3_RESPONSE_LENGTH, mmc_spi_ff_data, disk->sd_ocr.ocr_data, 0);
+ DEBUG2("%s(): R3: %02x %02x %02x %02x.\n", __FUNCTION__,
+ disk->sd_ocr.ocr_data[0], disk->sd_ocr.ocr_data[1], disk->sd_ocr.ocr_data[2],
+ disk->sd_ocr.ocr_data[3]);
+ mmc_spi_end_command(disk);
+
+ disk->sd_capacity = (SD_OCR_REGISTER_CCS(&(disk->sd_ocr))) ?
+ HIGH_CAPACITY : STANDARD_CAPACITY ;
+
+ return ENOERR;
+}
+
+// Read one of the card registers, e.g. CSD or CID
+static Cyg_ErrNo
+mmc_spi_read_register(cyg_mmc_spi_disk_info_t* disk, cyg_uint32 command, cyg_uint8* buf, cyg_uint32 count)
+{
+ cyg_uint32 reply;
+
+ reply = mmc_spi_send_command_start(disk, command, 0);
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("%s(): unexpected response to command %02x, reply code %02x\n",
+ __FUNCTION__, command, reply);
+ mmc_spi_end_command(disk);
+ return (0x00FF == reply) ? -ENODEV : -EIO;
+ }
+ reply = mmc_spi_read_data(disk, buf, count, false);
+ mmc_spi_end_command(disk);
+ if (MMC_DATA_TOKEN_SUCCESS != reply) {
+ DEBUG1("%s(): unexpected response to command %02x, expected 0x00FE data token, got %02x\n",
+ __FUNCTION__, command, reply);
+ return -EIO;
+ }
+ return ENOERR;
+}
+
+// Reading a disk block is just a combination of the above utilities.
+// This code is also responsible for translating error codes, since
+// higher-level code does not get to see the initial response vs. the
+// data token byte.
+static Cyg_ErrNo
+mmc_spi_read_disk_block(cyg_mmc_spi_disk_info_t* disk, cyg_uint8* buf, cyg_uint32 block, cyg_bool extra_delay)
+{
+ cyg_uint32 reply;
+
+ // First the command itself.
+ DEBUG2("%s(%d): sending command\n", __FUNCTION__, block);
+ if (STANDARD_CAPACITY == disk->sd_capacity) {
+ reply = mmc_spi_send_command_start(disk, MMC_REQUEST_READ_SINGLE_BLOCK, block * MMC_SPI_BLOCK_SIZE);
+ }
+ else {
+ reply = mmc_spi_send_command_start(disk, MMC_REQUEST_READ_SINGLE_BLOCK, block);
+ }
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("%s(%d): unexpected response to READ_SINGLE_BLOCK command, code %02x\n",
+ __FUNCTION__, block, reply);
+ mmc_spi_end_command(disk);
+ // A byte 0xFF indicates the card has been removed.
+ if (0x00FF == reply) {
+ return -ENODEV;
+ }
+ // Parameter or address error should not occur, higher-level
+ // code should have checked the block to ensure that it is
+ // in range.
+ if (0 != (reply & (MMC_REPLY_PARAMETER_ERROR | MMC_REPLY_ADDRESS_ERROR))) {
+ return -EINVAL;
+ }
+ // The disk should not be in idle state or in an erase sequence. The
+ // command is definitely legal and CRCs should be disabled. So everything
+ // else is an I/O error.
+ return -EIO;
+ }
+
+ // Now read back the data block. That code can be shared with other read
+ // operations, e.g. for retrieving registers.
+ DEBUG2("%s(%d): reading data token/data/crc\n", __FUNCTION__, block);
+ reply = mmc_spi_read_data(disk, buf, MMC_SPI_BLOCK_SIZE, extra_delay);
+ mmc_spi_end_command(disk);
+ if (MMC_DATA_TOKEN_SUCCESS != reply) {
+ DEBUG1("%s(%d): failed to retrieve data, error token %02x\n",
+ __FUNCTION__, block, reply);
+
+ // Possibilities are password-locked, range error, ECC failure
+ // if the raw data is corrupt, CC error for an internal card
+ // error, or some other error. A byte 0xFF indicates the card
+ // has been removed.
+ if (0x00FF == reply) {
+ return -ENODEV;
+ } else if (0 != (MMC_DATA_ERROR_TOKEN_CARD_LOCKED & reply)) {
+ // This should have been caught by a mount operation.
+ return -EPERM;
+ } else if (0 != (MMC_DATA_ERROR_TOKEN_OUT_OF_RANGE & reply)) {
+ return -EINVAL;
+ } else {
+ return -EIO;
+ }
+ }
+ return ENOERR;
+}
+
+// Writing a block involves a bit more work. Some of this could be
+// moved into a utility routine if necessary, shared with code for
+// e.g. updating the CSD register, but for now that other functionality
+// is not needed.
+static Cyg_ErrNo
+mmc_spi_write_disk_block(cyg_mmc_spi_disk_info_t* disk, const cyg_uint8* buf, cyg_uint32 block)
+{
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+ cyg_uint32 reply;
+ cyg_uint8 extra[4];
+ int i;
+
+ // First, send the command itself and get the initial response
+ DEBUG2("%s(): sending command\n", __FUNCTION__);
+ if (STANDARD_CAPACITY == disk->sd_capacity) {
+ reply = mmc_spi_send_command_start(disk, MMC_REQUEST_WRITE_BLOCK, block * MMC_SPI_BLOCK_SIZE);
+ }
+ else {
+ reply = mmc_spi_send_command_start(disk, MMC_REQUEST_WRITE_BLOCK, block );
+ }
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("%s(): unexpected response to WRITE_BLOCK command, code %02x\n",
+ __FUNCTION__, reply);
+ mmc_spi_end_command(disk);
+ if (0x00FF == reply) {
+ return -ENODEV;
+ }
+ // Parameter or address error should not occur, higher-level
+ // code should have checked the block to ensure that it is
+ // in range.
+ if (0 != (reply & (MMC_REPLY_PARAMETER_ERROR | MMC_REPLY_ADDRESS_ERROR))) {
+ return -EINVAL;
+ }
+ // The disk should not be in idle state or in an erase sequence. The
+ // command is definitely legal and CRCs should be disabled. So everything
+ // else is an I/O error.
+ return -EIO;
+ }
+
+ // The card is now expecting a data block. This consists of a single byte
+ // 0x00FE, then the data itself, and a dummy CRC. The reply from the card
+ // does not contain any useful information.
+ DEBUG2("%s(): sending data token/data/crc\n", __FUNCTION__);
+ extra[0] = 0x00FE;
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, extra, (cyg_uint8*)0, 0);
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, MMC_SPI_BLOCK_SIZE, buf, (cyg_uint8*)0, 0);
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 2, mmc_spi_ff_data, (cyg_uint8*)0, 0);
+
+ // The card should respond immediately with a data response token.
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, mmc_spi_ff_data, extra, 0);
+ DEBUG2("%s(): got data response token %02x\n", __FUNCTION__, extra[0]);
+
+ // The bottom five bits contain the response. 00101 indicates success,
+ // anything else is a CRC error. Everything else will have been checked
+ // before the data got transferred.
+ if (0x05 != (extra[0] & 0x1F)) {
+ DEBUG1("%s(): invalid data response token %02x\n", __FUNCTION__, extra[0]);
+ mmc_spi_end_command(disk);
+ if (0x00FF == extra[0]) {
+ return -ENODEV;
+ }
+ return -EIO;
+ }
+
+#ifdef MMC_SPI_BACKGROUND_WRITES
+ // Mark the card as writing. The next operation will poll for completion.
+ disk->mmc_writing = true;
+#else
+ // The card is now busy doing the write and will output a stream of 0's
+ // while busy. The timeout should really be calculated using the CSD
+ // register settings.
+ //
+ // It should be legal to drop the chip select here, i.e. to end
+ // the current transaction and start a new one for each poll
+ // operation. That would allow other SPI devices to be accessed.
+ // However it appears that this does not work with all MMC cards.
+ extra[0] = 0x00;
+ for (i = 0; (i < MMC_SPI_WRITE_BUSY_RETRIES) && (0x00 == extra[0]); i++) {
+ cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, mmc_spi_ff_data, extra, 0);
+ DEBUG2("%s(): polling for ! busy, got response %02x\n", __FUNCTION__, extra[0]);
+ }
+#endif
+
+ // Assume that the loop did in fact terminate.
+ mmc_spi_end_command(disk);
+ return ENOERR;
+}
+
+// MMC sockets will default to a slow clockrate. During a successful mount
+// the SPI device settings will be changed to the fastest supported by the
+// card, as per the CSD register. This will need to be undone during an
+// unmount, or if the final stages of a mount are unsuccessful.
+static void
+mmc_spi_restore_baud(cyg_mmc_spi_disk_info_t* disk)
+{
+ cyg_uint32 len = sizeof(cyg_uint32);
+ (void) cyg_spi_set_config(disk->mmc_spi_dev, CYG_IO_SET_CONFIG_SPI_CLOCKRATE, (void*) &(disk->mmc_saved_baudrate), &len);
+}
+
+// check_for_disk() tries to communicate with an MMC card that is not
+// currently mounted. It performs the appropriate initialization so
+// that read and write operations are possible, checks the disk format,
+// distinguishes between read-only and read-write cards, calculates the
+// card size, stores the unique id, etc.
+//
+// The main error conditions are ENODEV (no card), EIO (card not
+// responding sensibly to requests), ENOTDIR (wrong format), or EPERM
+// (card is password-locked).
+static Cyg_ErrNo
+mmc_spi_check_for_disk(cyg_mmc_spi_disk_info_t* disk)
+{
+ cyg_spi_device* dev = disk->mmc_spi_dev;
+ int i;
+ cyg_uint32 reply;
+ Cyg_ErrNo code;
+ mmc_csd_register csd;
+
+#ifdef MMC_SPI_BACKGROUND_WRITES
+ // If we have unmounted a disk and are remounting it, assume that
+ // any writes have completed.
+ disk->mmc_writing = false;
+#endif
+ reply = 0x00ff;
+
+ for (i = 0; (i < MMC_SPI_GO_IDLE_RETRIES) && (0x01 != reply); i++) {
+ // Allow platform HALs to provide additional initialization,
+ // if the hardware needs it.
+#ifdef HAL_MMC_SPI_INIT
+ HAL_MMC_SPI_INIT(dev, reply);
+ if (! reply) {
+ return -ENODEV;
+ }
+#endif
+ // MMC cards generic initialization. The card may have just
+ // been plugged in so there is no guarantee that any previous
+ // init() calls or other traffic will have affected this card.
+ mmc_spi_send_init(disk);
+
+ // Now set the card to idle state. This involves the GO_IDLE_STATE
+ // command which will be accepted irrespective of whether the card is
+ // currently in MMC or SPI mode, and will leave the card in SPI mode.
+ reply = mmc_spi_send_command(disk, MMC_REQUEST_GO_IDLE_STATE, 0);
+
+ // The card should reply with 0x01. FF suggests that there is
+ // no card. Any other response indicates some synchronization
+ // problem. For example the card might still be responding to
+ // some request from a previous session which aborted at an
+ // inconvenient moment. Some dummy traffic is generated in the
+ // hope that this gets things back in sync.
+ if (0x01 != reply) {
+ DEBUG1("%s(): loop %d, card did not enter idle state, code %02x\n",
+ __FUNCTION__, i, reply);
+ if (0x0ff != reply) {
+ cyg_spi_transfer(dev, cyg_mmc_spi_polled, 128, mmc_spi_ff_data, (cyg_uint8*) 0);
+ }
+ }
+ }
+ if (0x0ff == reply) {
+ DEBUG1("%s(): unable to get a response from the MMC card: code %02x\n",
+ __FUNCTION__, reply);
+ // A working card should be returning some data
+ return -ENODEV;
+ }
+ if (0x01 != reply) {
+ DEBUG1("%s(): card did not enter idle state, code %02x\n", __FUNCTION__, reply);
+ return -EIO;
+ }
+
+ // Determine if card complies with SD Physical Spec Version 1 or 2 or later.
+ reply = mmc_spi_check_version(disk);
+ if (ENOERR != reply) {
+ DEBUG1("%s(): can't determine card's version, code %02x\n", __FUNCTION__, reply);
+ return reply;
+ }
+ DEBUG2("%s(): card version %u\n", __FUNCTION__, disk->sd_version);
+
+ // Next, wait for the card to initialize. This involves repeatedly
+ // trying the SEND_OP_COND command until we get a reply that is
+ // not idle.
+ reply = 0x00ff;
+ for (i = 0; (i < MMC_SPI_OP_COND_RETRIES) && ((0x00ff == reply) || (0 != (MMC_REPLY_IN_IDLE_STATE & reply))); i++) {
+#ifdef CYGPKG_DEVS_DISK_MMC_SPI_IDLE_RETRIES_WAIT
+ CYGACC_CALL_IF_DELAY_US(CYGPKG_DEVS_DISK_MMC_SPI_IDLE_RETRIES_WAIT);
+#endif
+ if (1 == disk->sd_version) {
+ reply = mmc_spi_send_command(disk, MMC_REQUEST_SEND_OP_COND, 0);
+ }
+ else {
+ reply = mmc_spi_send_command(disk, SD_REQUEST_APP_CMD, 0);
+ reply &= ~MMC_REPLY_IN_IDLE_STATE;
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("%s(): card doesn't accept APP_CMD: reply code %02x\n",
+ __FUNCTION__, reply);
+ return -EIO;
+ }
+ reply = mmc_spi_send_command(disk, SD_REQUEST_SD_SEND_OP_COND, SD_ARGUMENT_HCS);
+ }
+ }
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("%s(): card has not entered operational state: reply code %02x\n",
+ __FUNCTION__, reply);
+ return (0x00FF == reply) ? -ENODEV : -EIO;
+ }
+
+ // The card has now generated sufficient responses that we don't need to
+ // worry about a missing card anymore.
+ // In case of V2 card, determine its capacity class
+ if (2 == disk->sd_version) {
+ reply = mmc_spi_sd_check_v2_capacity_class(disk);
+ if (MMC_REPLY_SUCCESS != reply) {
+ DEBUG1("%s(): can't establish card's capacity class: reply code %02x\n",
+ __FUNCTION__, reply);
+ return -EIO;
+ }
+ }
+ DEBUG2("%s capacity card.\n", (STANDARD_CAPACITY == disk->sd_capacity) ?
+ "Standard" : (HIGH_CAPACITY == disk->sd_capacity) ? "High" : "Extended" );
+
+ // Get hold of the card's unique ID and store it, to allow disk changes
+ // to be detected.
+ code = mmc_spi_read_register(disk, MMC_REQUEST_SEND_CID, (cyg_uint8*) &(disk->mmc_id), 16);
+ if (code) {
+ mmc_spi_end_command(disk);
+ return code;
+ }
+ DEBUG2("CID data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", \
+ disk->mmc_id.cid_data[ 0], disk->mmc_id.cid_data[ 1], disk->mmc_id.cid_data[ 2], disk->mmc_id.cid_data[ 3], \
+ disk->mmc_id.cid_data[ 4], disk->mmc_id.cid_data[ 5], disk->mmc_id.cid_data[ 6], disk->mmc_id.cid_data[ 7], \
+ disk->mmc_id.cid_data[ 8], disk->mmc_id.cid_data[ 9], disk->mmc_id.cid_data[10], disk->mmc_id.cid_data[11], \
+ disk->mmc_id.cid_data[12], disk->mmc_id.cid_data[13], disk->mmc_id.cid_data[14], disk->mmc_id.cid_data[15]);
+#if DEBUG > 0
+ DEBUG1("CID data: register\n");
+ DEBUG1(" : Manufacturer ID : MID = 0x%02x\n", MMC_CID_REGISTER_MID(&(disk->mmc_id)) & 0xff);
+ DEBUG1(" : OEM/Application ID : OID = 0x%04x\n", MMC_CID_REGISTER_OID(&(disk->mmc_id)) & 0xffff);
+ DEBUG1(" : Product name : PNM = 0x%02x%02x%02x%02x%02x%02x\n",
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[0] & 0xff,
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[1] & 0xff,
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[2] & 0xff,
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[3] & 0xff,
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[4] & 0xff,
+ MMC_CID_REGISTER_PNM(&(disk->mmc_id))[5] & 0xff);
+ DEBUG1(" : Product revision : PRV = 0x%02x\n", MMC_CID_REGISTER_PRV(&(disk->mmc_id)) & 0xff);
+ DEBUG1(" : Product serial number : PSN = 0x%08x\n", MMC_CID_REGISTER_PSN(&(disk->mmc_id)) & 0xffffffff);
+ DEBUG1(" : Manufacturing date : MDT = 0x%02x\n", MMC_CID_REGISTER_MDT(&(disk->mmc_id)) & 0xff);
+ DEBUG1(" : 7-bit CRC checksum : CRC = 0x%02x\n", MMC_CID_REGISTER_CRC(&(disk->mmc_id)) & 0xff);
+#endif
+
+ // And retrieve the card's configuration data.
+ code = mmc_spi_read_register(disk, MMC_REQUEST_SEND_CSD, (cyg_uint8*) &csd, 16);
+ if (code) {
+ mmc_spi_end_command(disk);
+ return code;
+ }
+ DEBUG2("CSD data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", \
+ csd.csd_data[ 0], csd.csd_data[ 1], csd.csd_data[ 2], csd.csd_data[3], \
+ csd.csd_data[ 4], csd.csd_data[ 5], csd.csd_data[ 6], csd.csd_data[7], \
+ csd.csd_data[ 8], csd.csd_data[ 9], csd.csd_data[10], csd.csd_data[11], \
+ csd.csd_data[12], csd.csd_data[13], csd.csd_data[14], csd.csd_data[15]);
+
+ disk->sd_csd_version = MMC_CSD_REGISTER_CSD_STRUCTURE(&csd) + 1 ;
+
+ // Optionally dump the whole CSD register. This takes a lot of
+ // code but gives a lot of info about the card. If the info looks
+ // correct then we really are interacting properly with an MMC card.
+#if DEBUG > 0
+ DEBUG1("CSD data: structure 0x%02x, version 0x%02x\n", MMC_CSD_REGISTER_CSD_STRUCTURE(&csd), MMC_CSD_REGISTER_SPEC_VERS(&csd));
+ if (0 != MMC_CSD_REGISTER_FILE_FORMAT_GROUP(&csd)) {
+ DEBUG1(" : Reserved (unknown), FILE_FORMAT_GROUP %d, FILE_FORMAT %d\n", \
+ MMC_CSD_REGISTER_FILE_FORMAT_GROUP(&csd), MMC_CSD_REGISTER_FILE_FORMAT(&csd));
+ } else if (0 == MMC_CSD_REGISTER_FILE_FORMAT(&csd)) {
+ DEBUG1(" : Partioned disk, FILE_FORMAT_GROUP 0, FILE_FORMAT 0\n");
+ } else if (1 == MMC_CSD_REGISTER_FILE_FORMAT(&csd)) {
+ DEBUG1(" : FAT disk, FILE_FORMAT_GROUP 0, FILE_FORMAT 1\n");
+ } else if (2 == MMC_CSD_REGISTER_FILE_FORMAT(&csd)) {
+ DEBUG1(" : Universal File format, FILE_FORMAT_GROUP 0, FILE_FORMAT 2\n");
+ } else {
+ DEBUG1(" : Others/Unknown disk, FILE_FORMAT_GROUP 0, FILE_FORMAT 3\n");
+ }
+
+ {
+ static const cyg_uint32 mantissa_speeds_x10[16] = { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
+ static const cyg_uint32 exponent_speeds_div10[8] = { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
+ cyg_uint32 speed = mantissa_speeds_x10[MMC_CSD_REGISTER_TRAN_SPEED_MANTISSA(&csd)] *
+ exponent_speeds_div10[MMC_CSD_REGISTER_TRAN_SPEED_EXPONENT(&csd)];
+ speed /= 1000;
+ DEBUG1(" : TRAN_SPEED %d %d -> %d kbit/s\n", \
+ MMC_CSD_REGISTER_TRAN_SPEED_MANTISSA(&csd), MMC_CSD_REGISTER_TRAN_SPEED_EXPONENT(&csd), speed);
+ }
+
+ DEBUG1(" : READ_BL_LEN block length 2^%d (%d)\n", MMC_CSD_REGISTER_READ_BL_LEN(&csd), \
+ 0x01 << MMC_CSD_REGISTER_READ_BL_LEN(&csd));
+
+ if (1 == disk->sd_csd_version) {
+ DEBUG1(" : C_SIZE %d, C_SIZE_MULT %d\n", \
+ MMC_CSD_REGISTER_C_SIZE(&csd), MMC_CSD_REGISTER_C_SIZE_MULT(&csd));
+ {
+ cyg_uint32 block_len = 0x01 << MMC_CSD_REGISTER_READ_BL_LEN(&csd);
+ cyg_uint32 mult = 0x01 << (MMC_CSD_REGISTER_C_SIZE_MULT(&csd) + 2);
+ cyg_uint32 size = block_len * mult * (MMC_CSD_REGISTER_C_SIZE(&csd) + 1);
+ cyg_uint32 sizeK = (cyg_uint32) (size / 1024);
+ cyg_uint32 sizeM = sizeK / 1024;
+ sizeK -= (sizeM * 1024);
+ DEBUG1(" : total card size %dM%dK\n", sizeM, sizeK);
+ }
+ }
+ else {
+ DEBUG1(" : C_SIZE %d\n", SD_CSD_V2_REGISTER_C_SIZE(&csd));
+ {
+ cyg_uint32 sizeK = 512 * (SD_CSD_V2_REGISTER_C_SIZE(&csd) + 1 ) ;
+ cyg_uint32 sizeM = sizeK / 1024;
+ sizeK -= (sizeM * 1024);
+ DEBUG1(" : total card size %uM%uK\n", sizeM, sizeK);
+ }
+ }
+
+ DEBUG1(" : WR_BL_LEN block length 2^%d (%d)\n", \
+ MMC_CSD_REGISTER_WRITE_BL_LEN(&csd), 0x01 << MMC_CSD_REGISTER_WRITE_BL_LEN(&csd));
+
+ if ( 1 == disk->sd_csd_version) {
+ static cyg_uint32 taac_mantissa_speeds_x10[16] = { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
+ static cyg_uint32 taac_exponent_speeds_div10[8] = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
+ cyg_uint32 taac_speed = taac_mantissa_speeds_x10[MMC_CSD_REGISTER_TAAC_MANTISSA(&csd)] *
+ taac_exponent_speeds_div10[MMC_CSD_REGISTER_TAAC_EXPONENT(&csd)];
+ taac_speed /= 100;
+ DEBUG1(" : asynchronous read access time TAAC %d %d -> %d ns\n", \
+ MMC_CSD_REGISTER_TAAC_MANTISSA(&csd), MMC_CSD_REGISTER_TAAC_EXPONENT(&csd), taac_speed);
+ }
+ if ( 1 == disk->sd_csd_version) {
+ DEBUG1(" : synchronous read access time NSAC %d * 100 cycles\n", \
+ MMC_CSD_REGISTER_NSAC(&csd));
+ }
+ DEBUG1(" : typical write program time %d * read time\n", MMC_CSD_REGISTER_R2W_FACTOR(&csd));
+ DEBUG1(" : CCC command classes 0x%04x\n", MMC_CSD_REGISTER_CCC(&csd));
+ DEBUG1(" : READ_BL_PARTIAL %d, WRITE_BLK_MISALIGN %d, READ_BLK_MISALIGN %d, DSR_IMP %d\n", \
+ MMC_CSD_REGISTER_READ_BL_PARTIAL(&csd), MMC_CSD_REGISTER_WRITE_BLK_MISALIGN(&csd), \
+ MMC_CSD_REGISTER_READ_BLK_MISALIGN(&csd), MMC_CSD_REGISTER_DSR_IMP(&csd));
+ DEBUG1(" : WR_BL_PARTIAL %d\n", MMC_CSD_REGISTER_WR_BL_PARTIAL(&csd));
+
+ if ( 1 == disk->sd_csd_version) {
+ static cyg_uint8 min_currents[8] = { 1, 1, 5, 10, 25, 35, 60, 100 };
+ static cyg_uint8 max_currents[8] = { 1, 5, 10, 25, 35, 45, 80, 200 };
+ DEBUG1(" : read current min %dmA, max %dmA\n", \
+ min_currents[MMC_CSD_REGISTER_VDD_R_CURR_MIN(&csd)], \
+ max_currents[MMC_CSD_REGISTER_VDD_R_CURR_MAX(&csd)]);
+ DEBUG1(" : write current min %dmA, max %dmA\n", \
+ min_currents[MMC_CSD_REGISTER_VDD_W_CURR_MIN(&csd)], \
+ max_currents[MMC_CSD_REGISTER_VDD_W_CURR_MAX(&csd)]);
+ }
+ if ( 1 == disk->sd_csd_version) {
+ DEBUG1(" : erase sector size %d, erase group size %d\n", \
+ MMC_CSD_REGISTER_SECTOR_SIZE(&csd) + 1, MMC_CSD_REGISTER_ERASE_GRP_SIZE(&csd) + 1);
+ DEBUG1(" : write group enable %d, write group size %d\n", \
+ MMC_CSD_REGISTER_WR_GRP_ENABLE(&csd), MMC_CSD_REGISTER_WR_GRP_SIZE(&csd) + 1);
+ }
+ DEBUG1(" : copy bit %d\n", MMC_CSD_REGISTER_COPY(&csd));
+ DEBUG1(" : permanent write protect %d, temporary write protect %d\n", \
+ MMC_CSD_REGISTER_PERM_WRITE_PROTECT(&csd), MMC_CSD_REGISTER_TMP_WRITE_PROTECT(&csd));
+ if ( 1 == disk->sd_csd_version) {
+ DEBUG1(" : ecc %d, default ecc %d\n", MMC_CSD_REGISTER_ECC(&csd), MMC_CSD_REGISTER_DEFAULT_ECC(&csd));
+ }
+ DEBUG1(" : crc 0x%08x\n", MMC_CSD_REGISTER_CRC(&csd));
+#endif
+
+ if ( 1 == disk->sd_csd_version) {
+ // There is information available about the file format, e.g.
+ // partitioned vs. simple FAT. With the current version of the
+ // generic disk code this needs to be known statically, via
+ // the mbr field of the disk channel structure. If the card
+ // is inappropriately formatted, reject the mount request.
+ if ((0 != MMC_CSD_REGISTER_FILE_FORMAT_GROUP(&csd)) ||
+ (0 != MMC_CSD_REGISTER_FILE_FORMAT(&csd))) {
+ return -ENOTDIR;
+ }
+ } // According to Spec V3.01, host should not use these two fields in CSD V2 cards
+
+ // Look for a write-protect bit (permanent or temporary), and set
+ // the disk as read-only or read-write as appropriate. The
+ // temporary write-protect could be cleared by rewriting the CSD
+ // register (including recalculating the CRC) but the effort
+ // involves does not seem worth-while.
+ if ((0 != MMC_CSD_REGISTER_PERM_WRITE_PROTECT(&csd)) || (0 != MMC_CSD_REGISTER_TMP_WRITE_PROTECT(&csd))) {
+ disk->mmc_read_only = true;
+ } else {
+ disk->mmc_read_only = false;
+ }
+ DEBUG1("Disk read-only flag %d\n", disk->mmc_read_only);
+
+ // Calculate the disk size, primarily for assertion purposes.
+ if ( 1 == disk->sd_csd_version) {
+ // By design MMC cards are limited to 4GB, which still doesn't
+ // quite fit into 32 bits.
+ disk->mmc_block_count = (((cyg_uint64)(0x01 << MMC_CSD_REGISTER_READ_BL_LEN(&csd))) *
+ ((cyg_uint64)(0x01 << (MMC_CSD_REGISTER_C_SIZE_MULT(&csd) + 2))) *
+ ((cyg_uint64)(MMC_CSD_REGISTER_C_SIZE(&csd) + 1))) / (cyg_uint64)MMC_SPI_BLOCK_SIZE;
+ }
+ else {
+ disk->mmc_block_count = 1024 * ( SD_CSD_V2_REGISTER_C_SIZE(&csd) + 1 ) ;
+ }
+ DEBUG1("Disk blockcount %u (0x%08x)\n", disk->mmc_block_count, disk->mmc_block_count);
+
+ // Assume for now that the block length is 512 bytes. This is
+ // probably a safe assumption since we have just got the card
+ // initialized out of idle state. If it ever proves to be a problem
+ // the SET_BLOCK_LEN command can be used.
+ // Nevertheless store the underlying block sizes
+ disk->mmc_read_block_length = 0x01 << MMC_CSD_REGISTER_READ_BL_LEN(&csd);
+ disk->mmc_write_block_length = 0x01 << MMC_CSD_REGISTER_WRITE_BL_LEN(&csd);
+
+ // The CSD contains the maximum supported transfer speed. Adjust
+ // the SPI device to match, saving the old value for an unmount
+ // operation. It is assumed that the SPI bus driver will munge
+ // the supplied speed to something appropriate.
+ {
+ static const cyg_uint32 mantissa_speeds_x10[16] = { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
+ static const cyg_uint32 exponent_speeds_div10[8] = { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
+ cyg_uint32 speed, len;
+
+ len = sizeof(cyg_uint32);
+ if (cyg_spi_get_config(dev, CYG_IO_GET_CONFIG_SPI_CLOCKRATE, (void*) &disk->mmc_saved_baudrate, &len)) {
+ DEBUG1("Failed to retrieve current SPI device clockrate\n");
+ return -EIO;
+ }
+ speed = mantissa_speeds_x10[MMC_CSD_REGISTER_TRAN_SPEED_MANTISSA(&csd)] * exponent_speeds_div10[MMC_CSD_REGISTER_TRAN_SPEED_EXPONENT(&csd)];
+ if (speed > disk->mmc_saved_baudrate) {
+ DEBUG1("Old SPI speed %d, switching to %d\n", disk->mmc_saved_baudrate, speed);
+ cyg_spi_set_config(dev, CYG_IO_SET_CONFIG_SPI_CLOCKRATE, (void*) &speed, &len);
+ } else {
+ DEBUG1("Old SPI speed %d already greater than max speed %d, leaving it alone\n",
+ disk->mmc_saved_baudrate, speed);
+ }
+ }
+
+ // Read the partition table off the card. This is a way of
+ // checking that the card is not password-locked. It also
+ // provides information about the "disk geometry" which is
+ // needed by higher-level code.
+ // FIXME: the higher-level code should be made to use LBA
+ // addressing instead.
+ {
+ cyg_uint8 data[MMC_SPI_BLOCK_SIZE];
+ cyg_uint8* partition;
+ cyg_uint32 lba_first, lba_size, lba_end, head, cylinder, sector;
+
+ code = mmc_spi_read_disk_block(disk, data, 0, true);
+ if (code) {
+ mmc_spi_restore_baud(disk);
+ return code;
+ }
+#if DEBUG > 1
+ {
+ cyg_uint8 *ptr_data;
+
+ DEBUG2("MBR dump\n");
+ for (i = 0; i < MMC_SPI_BLOCK_SIZE; i += 16) {
+ ptr_data = &data[i];
+ DEBUG2(" %04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ i,
+ ptr_data[ 0], ptr_data[ 1], ptr_data[ 2], ptr_data[ 3],
+ ptr_data[ 4], ptr_data[ 5], ptr_data[ 6], ptr_data[ 7],
+ ptr_data[ 8], ptr_data[ 9], ptr_data[10], ptr_data[11],
+ ptr_data[12], ptr_data[13], ptr_data[14], ptr_data[15]);
+ }
+ }
+#endif
+#if DEBUG > 0
+ DEBUG1("Read block 0 (partition table)\n");
+ DEBUG1("Signature 0x%02x 0x%02x, should be 0x55 0xaa\n", data[0x1fe], data[0x1ff]);
+ // There should be four 16-byte partition table entries at offsets
+ // 0x1be, 0x1ce, 0x1de and 0x1ee. The numbers are stored little-endian
+ for (i = 0; i < 4; i++) {
+ partition = &(data[0x1be + (0x10 * i)]);
+ DEBUG1("Partition %d: boot %02x, first CHS %02x, last CHS %02x, first sector %02x %02x %02x, file system %02x, last sector %02x %02x %02x\n", i, \
+ partition[0], \
+ ((partition[2] & 0xC0) << 2) | partition[3], ((partition[6] & 0xC0) << 2) | partition[7], \
+ partition[1], partition[2], partition[3], partition[4], \
+ partition[5], partition[6], partition[7]);
+ DEBUG1(" : first sector (linear) %02x %02x %02x %02x, sector count %02x %02x %02x %02x\n", \
+ partition[11], partition[10], partition[9], partition[8], \
+ partition[15], partition[14], partition[13], partition[12]);
+ }
+#endif
+ if ((0x0055 != data[0x1fe]) || (0x00aa != data[0x1ff])) {
+ mmc_spi_restore_baud(disk);
+ return -ENOTDIR;
+ }
+ partition = &(data[0x1be]);
+ lba_first = (partition[11] << 24) | (partition[10] << 16) | (partition[9] << 8) | partition[8];
+ lba_size = (partition[15] << 24) | (partition[14] << 16) | (partition[13] << 8) | partition[12];
+ lba_end = lba_first + lba_size - 1;
+
+ // First sector in c/h/s format
+ cylinder = ((partition[2] & 0xC0) << 2) | partition[3];
+ head = partition[1];
+ sector = partition[2] & 0x3F;
+
+ // lba_start == (((cylinder * Nh) + head) * Ns) + sector - 1, where (Nh == heads/cylinder) and (Ns == sectors/head)
+ // Strictly speaking we should be solving some simultaneous
+ // equations here for lba_start/lba_end, but that gets messy.
+ // The first partition is at the start of the card so cylinder will be 0,
+ // and we can ignore Nh.
+ CYG_ASSERT(0 == cylinder, "Driver assumption - partition 0 is at start of card\n");
+ CYG_ASSERT(0 != head, "Driver assumption - partition table is sensible\n");
+ disk->mmc_sectors_per_head = ((lba_first + 1) - sector) / head;
+
+ // Now for lba_end.
+ cylinder = ((partition[6] & 0xC0) << 2) | partition[7];
+ head = partition[5];
+ sector = partition[6] & 0x3F;
+ disk->mmc_heads_per_cylinder = ((((lba_end + 1) - sector) / disk->mmc_sectors_per_head) - head) / cylinder;
+ }
+
+ return ENOERR;
+}
+
+// Check that the current card is the one that was previously
+// accessed. This may fail if the card has been removed and the
+// slot is empty, or if the card has been removed and a different
+// one inserted. It may pass incorrectly if a card is removed,
+// modified elsewhere, and reinserted without eCos noticing.
+// There is no way around that without some way of detecting
+// disk removal in hardware.
+//
+// Re-reading the cid may actually be overkill. If a new card
+// has been plugged in then it will not have been initialized so
+// it will respond with 0xff anyway. It is very unlikely that
+// an init sequence will have happened by accident.
+static cyg_bool
+mmc_spi_disk_changed(cyg_mmc_spi_disk_info_t* disk)
+{
+ mmc_cid_register cid;
+ Cyg_ErrNo code;
+
+ code = mmc_spi_read_register(disk, MMC_REQUEST_SEND_CID, (cyg_uint8*) &cid, 16);
+ if (-ENODEV == code) {
+ return true;
+ }
+
+ if (0 != memcmp(&cid, &(disk->mmc_id), sizeof(mmc_cid_register))) {
+ return true;
+ }
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+
+// No hardware initialization is performed here. Even if a card is
+// currently plugged in it may get removed before it gets mounted, so
+// there is no point looking at the card here. It is still necessary
+// to invoke the callback init function so that higher-level code gets
+// a chance to do its bit.
+static cyg_bool
+mmc_spi_disk_init(struct cyg_devtab_entry* tab)
+{
+ disk_channel* chan = (disk_channel*) tab->priv;
+ MMC_SPI_INIT_FF_DATA();
+ return (*chan->callbacks->disk_init)(tab);
+}
+
+// lookup() is called during a mount() operation, so this is the right
+// place to check whether or not there is a card.
+
+static char*
+mmc_spi_disk_lookup_itoa(cyg_uint32 num, char* where)
+{
+ if (0 == num) {
+ *where++ = '0';
+ } else {
+ char local[10]; // 2^32 just fits into 10 places
+ int index = 9;
+ while (num > 0) {
+ local[index--] = (num % 10) + '0';
+ num /= 10;
+ }
+ for (index += 1; index < 10; index++) {
+ *where++ = local[index];
+ }
+ }
+ return where;
+}
+
+static Cyg_ErrNo
+mmc_spi_disk_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry *sub_tab, const char* name)
+{
+ disk_channel* chan = (disk_channel*) (*tab)->priv;
+ cyg_mmc_spi_disk_info_t* disk = (cyg_mmc_spi_disk_info_t*) chan->dev_priv;
+ Cyg_ErrNo result;
+
+ DEBUG2("%s(): target name=%s\n", __FUNCTION__, name );
+ DEBUG2(" : device name=%s dep_name=%s\n", tab[0]->name, tab[0]->dep_name );
+// DEBUG2(" : sub name=%s dep_name=%s\n", sub_tab->name, sub_tab->dep_name );
+
+ if (disk->mmc_connected) {
+ // There was a card plugged in last time we looked. Is it still there?
+ if (mmc_spi_disk_changed(disk)) {
+ // The old card is gone. Either there is no card plugged in, or
+ // it has been replaced with a different one. If the latter the
+ // existing mounts must be removed before anything sensible
+ // can be done.
+ disk->mmc_connected = false;
+ (*chan->callbacks->disk_disconnected)(chan);
+ if (0 != chan->info->mounts) {
+ return -ENODEV;
+ }
+ }
+ }
+
+ if ((0 != chan->info->mounts) && !disk->mmc_connected) {
+ // There are still mount points to an old card. We cannot accept
+ // new mount requests until those have been cleaned out.
+ return -ENODEV;
+ }
+
+ if (!disk->mmc_connected) {
+ cyg_disk_identify_t ident;
+ cyg_uint32 id_data;
+ char* where;
+ int i;
+
+ // The world is consistent and the higher-level code does not
+ // know anything about the current card, if any. Is there a
+ // card?
+ result = mmc_spi_check_for_disk(disk);
+ if (ENOERR != result) {
+ return result;
+ }
+ // A card has been found. Tell the higher-level code about it.
+ // This requires an identify structure, although it is not
+ // entirely clear what purpose that serves.
+ disk->mmc_connected = true;
+ // Serial number, up to 20 characters; The CID register contains
+ // various fields which can be used for this.
+ where = &(ident.serial[0]);
+ id_data = disk->mmc_id.cid_data[0]; // 1-byte manufacturer id -> 3 chars, 17 left
+ where = mmc_spi_disk_lookup_itoa(id_data, where);
+ id_data = (disk->mmc_id.cid_data[1] << 8) + disk->mmc_id.cid_data[2]; // 2-byte OEM ID, 5 chars, 12 left
+ where = mmc_spi_disk_lookup_itoa(id_data, where);
+ id_data = (disk->mmc_id.cid_data[10] << 24) + (disk->mmc_id.cid_data[11] << 16) +
+ (disk->mmc_id.cid_data[12] << 8) + disk->mmc_id.cid_data[13];
+ where = mmc_spi_disk_lookup_itoa(id_data, where); // 4-byte OEM ID, 10 chars, 2 left
+ // And terminate the string with a couple of places to spare.
+ *where = '\0';
+
+ // Firmware revision number. There is a one-byte product
+ // revision number in the CID, BCD-encoded
+ id_data = disk->mmc_id.cid_data[9] >> 4;
+ if (id_data <= 9) {
+ ident.firmware_rev[0] = id_data + '0';
+ } else {
+ ident.firmware_rev[0] = id_data - 10 + 'A';
+ }
+ id_data = disk->mmc_id.cid_data[9] & 0x0F;
+ if (id_data <= 9) {
+ ident.firmware_rev[1] = id_data + '0';
+ } else {
+ ident.firmware_rev[1] = id_data - 10 + 'A';
+ }
+ ident.firmware_rev[2] = '\0';
+
+ // Model number. There is a six-byte product name in the CID.
+ for (i = 0; i < 6; i++) {
+ if ((disk->mmc_id.cid_data[i + 3] >= 0x20) && (disk->mmc_id.cid_data[i+3] <= 0x7E)) {
+ ident.model_num[i] = disk->mmc_id.cid_data[i + 3];
+ } else {
+ break;
+ }
+ }
+ ident.model_num[i] = '\0';
+
+ // We don't have no cylinders, heads, or sectors, but
+ // higher-level code may interpret partition data using C/H/S
+ // addressing rather than LBA. Hence values for some of these
+ // settings were calculated above.
+ ident.cylinders_num = 1;
+ ident.heads_num = disk->mmc_heads_per_cylinder;
+ ident.sectors_num = disk->mmc_sectors_per_head;
+ ident.lba_sectors_num = disk->mmc_block_count;
+ ident.phys_block_size = disk->mmc_write_block_length/512;
+ ident.max_transfer = disk->mmc_write_block_length;
+
+ DEBUG1("Calling disk_connected(): serial %s, firmware %s, model %s, heads %d, sectors %d, lba_sectors_num %d, phys_block_size %d\n", \
+ ident.serial, ident.firmware_rev, ident.model_num, ident.heads_num, ident.sectors_num,
+ ident.lba_sectors_num, ident.phys_block_size);
+ (*chan->callbacks->disk_connected)(*tab, &ident);
+
+ // We now have a valid card and higher-level code knows about it. Fall through.
+ }
+
+ // And leave it to higher-level code to finish the lookup, taking
+ // into accounts partitions etc.
+ return (*chan->callbacks->disk_lookup)(tab, sub_tab, name);
+}
+
+static Cyg_ErrNo
+mmc_spi_disk_read(disk_channel* chan, void* buf_arg, cyg_uint32 blocks, cyg_uint32 first_block)
+{
+ cyg_mmc_spi_disk_info_t* disk = (cyg_mmc_spi_disk_info_t*) chan->dev_priv;
+ cyg_uint32 i;
+ cyg_uint8* buf = (cyg_uint8*) buf_arg;
+ Cyg_ErrNo code = ENOERR;
+
+ DEBUG1("%s(): first block %d, buf %p, len %lu blocks (%lu bytes)\n",
+ __FUNCTION__, first_block, buf, (unsigned long)blocks,
+ (unsigned long)blocks*512);
+
+ if (! disk->mmc_connected) {
+ return -ENODEV;
+ }
+ if ((first_block + blocks) >= disk->mmc_block_count) {
+ return -EINVAL;
+ }
+
+ for (i = 0; (i < blocks) && (ENOERR == code); i++) {
+ code = mmc_spi_read_disk_block(disk, buf, first_block + i, false);
+ buf += MMC_SPI_BLOCK_SIZE;
+ }
+ return code;
+}
+
+static Cyg_ErrNo
+mmc_spi_disk_write(disk_channel* chan, const void* buf_arg, cyg_uint32 blocks, cyg_uint32 first_block)
+{
+ cyg_mmc_spi_disk_info_t* disk = (cyg_mmc_spi_disk_info_t*) chan->dev_priv;
+ cyg_uint32 i;
+ const cyg_uint8* buf = (cyg_uint8*) buf_arg;
+ Cyg_ErrNo code = ENOERR;
+
+ DEBUG1("%s(): first block %d, buf %p, len %lu blocks (%lu bytes)\n",
+ __FUNCTION__, first_block, buf, (unsigned long)blocks,
+ (unsigned long)blocks*512);
+
+ if (! disk->mmc_connected) {
+ return -ENODEV;
+ }
+ if (disk->mmc_read_only) {
+ return -EROFS;
+ }
+ if ((first_block + blocks) >= disk->mmc_block_count) {
+ return -EINVAL;
+ }
+
+ for (i = 0; (i < blocks) && (ENOERR == code); i++) {
+ code = mmc_spi_write_disk_block(disk, buf, first_block + i);
+ buf += MMC_SPI_BLOCK_SIZE;
+ }
+ return code;
+}
+
+// get_config() and set_config(). There are no supported get_config() operations
+// at this time.
+static Cyg_ErrNo
+mmc_spi_disk_get_config(disk_channel* chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ CYG_UNUSED_PARAM(disk_channel*, chan);
+ CYG_UNUSED_PARAM(cyg_uint32, key);
+ CYG_UNUSED_PARAM(const void*, buf);
+ CYG_UNUSED_PARAM(cyg_uint32*, len);
+
+ return -EINVAL;
+}
+
+static Cyg_ErrNo
+mmc_spi_disk_set_config(disk_channel* chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo result = ENOERR;
+ cyg_mmc_spi_disk_info_t* disk = (cyg_mmc_spi_disk_info_t*) chan->dev_priv;
+
+ switch(key) {
+ case CYG_IO_SET_CONFIG_DISK_MOUNT:
+ // There will have been a successful lookup(), so there's
+ // little point in checking the disk again.
+ break;
+
+ case CYG_IO_SET_CONFIG_DISK_UMOUNT:
+ if (0 == chan->info->mounts) {
+ // If this is the last unmount of the card, mark it as
+ // disconnected. If the user then removes the card and
+ // plugs in a new one everything works cleanly. Also
+ // reset the SPI device's clockrate.
+ disk->mmc_connected = false;
+ mmc_spi_restore_baud(disk);
+ result = (chan->callbacks->disk_disconnected)(chan);
+ }
+ break;
+ }
+
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// And finally the data structures that define this disk. Some of this
+// should be moved into an exported header file so that applications can
+// define additional disks.
+//
+// It is not obvious why there are quite so many structures. Apart
+// from the devtab entries there are no tables involved, so there is
+// no need to keep everything the same size. The cyg_disk_info_t could
+// be the common part of a h/w info_t. The channel structure is
+// redundant and its fields could be merged into the cyg_disk_info_t
+// structure. That would leave a devtab entry, a disk info structure
+// (h/w specific but with a common base), and a disk controller
+// structure (ditto).
+
+DISK_FUNS(cyg_mmc_spi_disk_funs,
+ mmc_spi_disk_read,
+ mmc_spi_disk_write,
+ mmc_spi_disk_get_config,
+ mmc_spi_disk_set_config
+ );
+
+static cyg_mmc_spi_disk_info_t cyg_mmc_spi_disk0_hwinfo = {
+ .mmc_spi_dev = &cyg_spi_mmc_dev0,
+#ifdef MMC_SPI_BACKGROUND_WRITES
+ .mmc_writing = 0,
+#endif
+ .mmc_connected = 0
+};
+
+// No h/w controller structure is needed, but the address of the
+// second argument is taken anyway.
+DISK_CONTROLLER(cyg_mmc_spi_disk_controller_0, cyg_mmc_spi_disk0_hwinfo);
+
+DISK_CHANNEL(cyg_mmc_spi_disk0_channel,
+ cyg_mmc_spi_disk_funs,
+ cyg_mmc_spi_disk0_hwinfo,
+ cyg_mmc_spi_disk_controller_0,
+ true, /* MBR support */
+ 1 /* Number of partitions supported */
+ );
+
+BLOCK_DEVTAB_ENTRY(cyg_mmc_spi_disk0_devtab_entry,
+ CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME,
+ 0,
+ &cyg_io_disk_devio,
+ &mmc_spi_disk_init,
+ &mmc_spi_disk_lookup,
+ &cyg_mmc_spi_disk0_channel);
+
+// EOF mmc_spi.c
diff --git a/ecos/packages/devs/disk/ide/current/ChangeLog b/ecos/packages/devs/disk/ide/current/ChangeLog
new file mode 100644
index 0000000..25fd543
--- /dev/null
+++ b/ecos/packages/devs/disk/ide/current/ChangeLog
@@ -0,0 +1,75 @@
+2008-08-19 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/ide_disk.cdl: Rename of the devices to be /dev/idediskX/Y
+ so that all disk drivers have unique device names.
+
+2008-08-18 Frank Pagliughi <fpagliughi@mindspring.com>
+
+ * cdl/ide_disk.cdl:
+ * src/ide_diskc: Add a configurable startup delay to allow slow
+ disks to initialize. Add support for 8-bit data path. Remove the
+ identity check which are retired in the ATA standard. Optimize the
+ read/write functions.
+
+2006-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/ide_disk.c (ide_read_sector, ide_write_sector): Length
+ is counted in sectors now, not bytes (due to change in io/disk
+ API).
+
+2006-09-21 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/ide_disk.h: DISK_FUNS is now implicitly static.
+ (IDE_DISK_INSTANCE): Reflect updated io/disk API by using
+ ide_disk_controller.
+ * src/ide_disk.c: Define ide_disk_controller (even though unused
+ in practice).
+ (ide_disk_init): Provide phys_block_size and max_transfer disk ident
+ members.
+
+2005-02-02 Knud Woehler <knud.woehler@microplex.de>
+
+ * src/ide_disk.c: Check the device is not busy before sending a
+ command to the device.
+
+2004-10-17 Iztok Zupet <iz@elsis.si>
+
+ * include/ide_disk.h : moved to ->
+ * src/ide_disk.h: because this is a private include file
+
+ * cdl/ide_disk.cdl: define CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE there.
+ * src/ide_disk.c: use the CDL defined sector size
+
+
+2004-10-16 Iztok Zupet <iz@elsis.si>
+
+ * cdl/ide_disk.cdl:
+ * src/ide_disk.c:
+ * include/ide_disk.h:
+ A generic IDE disk device driver
+
+
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/disk/ide/current/cdl/ide_disk.cdl b/ecos/packages/devs/disk/ide/current/cdl/ide_disk.cdl
new file mode 100644
index 0000000..6c751f1
--- /dev/null
+++ b/ecos/packages/devs/disk/ide/current/cdl/ide_disk.cdl
@@ -0,0 +1,154 @@
+# ====================================================================
+#
+# ide_disk.cdl
+#
+# A generic IDE disk driver package.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): iz
+# Contributors:
+# Date: 2004-10-16
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_DISK_IDE {
+ display "Disk driver for generic IDE"
+
+ parent CYGPKG_IO_DISK_DEVICES
+ active_if CYGPKG_IO_DISK
+
+ compile -library=libextras.a ide_disk.c
+
+ cdl_component CYGVAR_DEVS_DISK_IDE_DISK0 {
+ display "Provide disk 0 device"
+ flavor bool
+ default_value 1
+ description "IDE chanel 0:0 disk driver"
+
+ cdl_option CYGDAT_IO_DISK_IDE_DISK0_NAME {
+ display "Device name for disk 0 device"
+ flavor data
+ default_value {"\"/dev/idedisk0/\""}
+ }
+ }
+
+ cdl_component CYGVAR_DEVS_DISK_IDE_DISK1 {
+ display "Provide disk 1 device"
+ flavor bool
+ default_value 0
+ description "IDE chanel 0:1 disk driver"
+
+ cdl_option CYGDAT_IO_DISK_IDE_DISK1_NAME {
+ display "Device name for disk 1 device"
+ flavor data
+ default_value {"\"/dev/idedisk1/\""}
+ }
+ }
+
+ cdl_component CYGVAR_DEVS_DISK_IDE_DISK2 {
+ display "Provide disk 2 device"
+ flavor bool
+ default_value 0
+ description "IDE chanel 1:0 disk driver"
+
+ cdl_option CYGDAT_IO_DISK_IDE_DISK2_NAME {
+ display "Device name for disk 2 device"
+ flavor data
+ default_value {"\"/dev/idedisk2/\""}
+ }
+ }
+
+ cdl_component CYGVAR_DEVS_DISK_IDE_DISK3 {
+ display "Provide disk 3 device"
+ flavor bool
+ default_value 0
+ description "IDE chanel 1:1 disk driver"
+
+ cdl_option CYGDAT_IO_DISK_IDE_DISK3_NAME {
+ display "Device name for disk 3 device"
+ flavor data
+ default_value {"\"/dev/idedisk3/\""}
+ }
+ }
+
+ cdl_option CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE {
+ display "Disk sector size"
+ flavor data
+ default_value 512
+ description "
+ This option controls the disk sector size (default=512)"
+ }
+
+ cdl_option CYGDAT_DEVS_DISK_IDE_STARTUP_DELAY {
+ display "Startup delay (in ms)"
+ flavor data
+ default_value 0
+ description "
+ The amount of time (in ms) to wait for the IDE drives to
+ initialize on startup. For hard drives, this can usually
+ be set to zero, but for Compact Flash and other solid
+ state media this could be up to 500ms. If drives are not
+ detected at power-up, try increasing this value.
+ "
+ }
+
+ cdl_option CYGDAT_DEVS_DISK_IDE_8_BIT_DATA_PATH {
+ display "8-bit data path"
+ flavor bool
+ default_value false
+ description "
+ This allows the host to communicate with the IDE drives using an
+ 8-bit data, rather than 16-bits. It does so by requesting a \"Set
+ Feature\" on the drive for the 8-bit path. Note that this may
+ be ignored by most modern disk drives, but is supported by Compact
+ Flash drives. This is only used by proprietary boards, and should
+ be disabled for standard IDE controllers.
+ "
+ }
+
+
+ cdl_option CYGSEM_DEVS_DISK_IDE_VMWARE {
+ display "Work with VMware virtual disks"
+ flavor bool
+ default_value 0
+ description "
+ This option controls the disk driver behaviour at ide-init"
+ }
+}
+
+# EOF ide_disk.cdl
diff --git a/ecos/packages/devs/disk/ide/current/src/ide_disk.c b/ecos/packages/devs/disk/ide/current/src/ide_disk.c
new file mode 100644
index 0000000..35f40a3
--- /dev/null
+++ b/ecos/packages/devs/disk/ide/current/src/ide_disk.c
@@ -0,0 +1,530 @@
+//==========================================================================
+//
+// ide_disk.c
+//
+// IDE polled mode disk driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): iz
+// Contributors:
+// Date: 2004-10-16
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_disk_ide.h>
+#include <pkgconf/io_disk.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h> // delays
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/disk.h>
+
+#include "ide_disk.h"
+
+// ----------------------------------------------------------------------------
+
+#ifdef CYGDBG_IO_DISK_DEBUG
+# define DEBUG 1
+#endif
+
+#ifdef DEBUG
+# define D(fmt,args...) diag_printf(fmt, ## args)
+#else
+# define D(fmt,args...)
+#endif
+
+// ----------------------------------------------------------------------------
+
+// No h/w controller structure is needed in this driver, but the address of the
+// second argument is taken anyway.
+DISK_CONTROLLER(ide_disk_controller, ide_disk_controller);
+
+#ifdef CYGVAR_DEVS_DISK_IDE_DISK0
+IDE_DISK_INSTANCE(0, 0, 0, true, CYGDAT_IO_DISK_IDE_DISK0_NAME);
+#endif
+
+#ifdef CYGVAR_DEVS_DISK_IDE_DISK1
+IDE_DISK_INSTANCE(1, 0, 1, true, CYGDAT_IO_DISK_IDE_DISK1_NAME);
+#endif
+
+#ifdef CYGVAR_DEVS_DISK_IDE_DISK2
+IDE_DISK_INSTANCE(2, 1, 0, true, CYGDAT_IO_DISK_IDE_DISK2_NAME);
+#endif
+
+#ifdef CYGVAR_DEVS_DISK_IDE_DISK3
+IDE_DISK_INSTANCE(3, 1, 1, true, CYGDAT_IO_DISK_IDE_DISK3_NAME);
+#endif
+
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+
+// ----------------------------------------------------------------------------
+
+static void
+id_strcpy(char *dest, cyg_uint16 *src, cyg_uint16 size)
+{
+ int i;
+
+ for (i=0; i<size; i+=2) {
+ *dest++ = (char)(*src >> 8);
+ *dest++ = (char)(*src & 0x00FF);
+ src++;
+ }
+ *dest = '\0';
+}
+
+// ----------------------------------------------------------------------------
+
+static inline void
+__wait_for_ready(int ctlr)
+{
+ cyg_uint8 status;
+ do {
+ HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+ } while (status & (IDE_STAT_BSY | IDE_STAT_DRQ));
+}
+
+// ----------------------------------------------------------------------------
+// Wait while the device is busy with the last command
+
+static inline int
+__wait_busy(int ctlr)
+{
+ cyg_uint8 status;
+ cyg_ucount32 tries;
+
+ for (tries=0; tries < 1000000; tries++) {
+ CYGACC_CALL_IF_DELAY_US(10);
+ HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+ if ((status & IDE_STAT_BSY) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+static inline int
+__wait_for_drq(int ctlr)
+{
+ cyg_uint8 status;
+ cyg_ucount32 tries;
+
+ for (tries=0; tries<1000000; tries++) {
+ CYGACC_CALL_IF_DELAY_US(10);
+ HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+ if (!(status & IDE_STAT_BSY)) {
+ if (status & IDE_STAT_DRQ)
+ return 1;
+ else
+ return 0;
+ }
+ }
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+// Return true if any devices attached to controller
+
+static int
+ide_presence_detect(int ctlr)
+{
+ cyg_uint8 sel, val;
+ int i;
+
+ for (i = 0; i < HAL_IDE_NUM_CONTROLLERS; i++) {
+ sel = (i << 4) | 0xA0;
+ CYGACC_CALL_IF_DELAY_US(50000U);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, sel);
+ CYGACC_CALL_IF_DELAY_US(50000U);
+ HAL_IDE_READ_UINT8(ctlr, IDE_REG_DEVICE, val);
+ if (val == sel) {
+#ifndef CYGSEM_DEVS_DISK_IDE_VMWARE
+ if (i)
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, 0);
+#endif
+ return 1;
+ }
+ }
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+static int
+ide_reset(int ctlr)
+{
+ cyg_uint8 status;
+ int delay;
+//
+// VMware note:
+// VMware virtual IDE device handler obviously expects that
+// the reset and setup functions were already done
+// by it's bios and complains if one uses reset here...
+//
+#ifndef CYGSEM_DEVS_DISK_IDE_VMWARE
+ HAL_IDE_WRITE_CONTROL(ctlr, 6); // polled mode, reset asserted
+ CYGACC_CALL_IF_DELAY_US(5000U);
+ HAL_IDE_WRITE_CONTROL(ctlr, 2); // polled mode, reset cleared
+ CYGACC_CALL_IF_DELAY_US(50000U);
+#endif
+
+ // wait 30 seconds max for not busy and drive ready
+ for (delay=0; delay<300; ++delay) {
+ CYGACC_CALL_IF_DELAY_US(100000U);
+ HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+ if (!(status & IDE_STAT_BSY)) {
+ if (status & IDE_STAT_DRDY) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+static int
+ide_ident(int ctlr, int dev, cyg_uint16 *buf)
+{
+ int i;
+
+ if (!__wait_busy(ctlr))
+ return 0;
+
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xEC);
+ CYGACC_CALL_IF_DELAY_US(50000U);
+
+ if (!__wait_for_drq(ctlr))
+ return 0;
+
+ for (i=0; i<(CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE/sizeof(cyg_uint16));
+ i++, buf++) {
+ HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *buf);
+ }
+ return 1;
+}
+
+// ----------------------------------------------------------------------------
+// Requests the disk to use an 8-bit data path. This is probably ignored by
+// most modern drives, but is supported by compact flash devices.
+
+#ifdef CYGDAT_DEVS_DISK_IDE_8_BIT_DATA_PATH
+static int
+ide_8bit_mode(int ctlr, int dev, cyg_bool on)
+{
+ cyg_uint8 stat;
+
+ if (!__wait_busy(ctlr))
+ return 0;
+
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_FEATURES, 0x01);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xEF);
+
+ if (!__wait_busy(ctlr))
+ return 0;
+
+ HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, stat);
+ return (stat & 1) ? 0 : 1;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// Reads a group of contiguous sectors from the drive.
+// It can read up to 256 sectors.
+
+static int
+ide_read_sector(int ctlr, int dev, cyg_uint32 start,
+ cyg_uint8 *buf, cyg_uint32 len)
+{
+ int i, nword;
+ cyg_uint8 lenb;
+ cyg_uint16 w;
+
+ if (len==0 || !__wait_busy(ctlr))
+ return 0;
+
+ len = MIN(len, 256);
+ lenb = (len == 256) ? 0 : ((cyg_uint8) len);
+
+ nword = len * CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16);
+
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, lenb);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE,
+ ((start >> 24) & 0xf) | (dev << 4) | 0x40);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x20);
+
+ if (!__wait_for_drq(ctlr))
+ return 0;
+
+ if ((int) buf & 1) {
+ // Unaligned buffer, so split each word manually
+ for (i=0; i<nword; i++) {
+ HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, w);
+ *buf++ = w & 0xff;
+ *buf++ = (w>>8) & 0xff;
+ }
+ }
+ else {
+ cyg_uint16* wbuf = (cyg_uint16*) buf;
+ for (i=0; i<nword; i++, wbuf++)
+ HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *wbuf);
+ }
+ return (int) len;
+}
+
+// ----------------------------------------------------------------------------
+// Writes a group of contiguous sectors to the drive.
+// It can write up to 256 sectors.
+
+static int
+ide_write_sector(int ctlr, int dev, cyg_uint32 start,
+ cyg_uint8 *buf, cyg_uint32 len)
+{
+ int i, nword;
+ cyg_uint8 lenb;
+ cyg_uint16 w;
+
+ if (len==0 || !__wait_busy(ctlr))
+ return 0;
+
+ len = MIN(len, 256);
+ lenb = (len == 256) ? 0 : ((cyg_uint8) len);
+
+ nword = len * CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16);
+
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, lenb);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE,
+ ((start >> 24) & 0xf) | (dev << 4) | 0x40);
+ HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x30);
+
+ if (!__wait_for_drq(ctlr))
+ return 0;
+
+ if ((int) buf & 1) {
+ // Unaligned buffer, so assemble each word manually
+ for (i=0; i<nword; ++i) {
+ w = *buf++;
+ w |= (cyg_uint16) (*buf++) << 8;
+ HAL_IDE_WRITE_UINT16(ctlr, IDE_REG_DATA, w);
+ }
+ }
+ else {
+ cyg_uint16* wbuf = (cyg_uint16*) buf;
+ for (i=0; i<nword; ++i)
+ HAL_IDE_WRITE_UINT16(ctlr, IDE_REG_DATA, *wbuf++);
+ }
+ return (int) len;
+}
+
+// ----------------------------------------------------------------------------
+
+static cyg_bool
+ide_disk_init(struct cyg_devtab_entry *tab)
+{
+ disk_channel *chan = (disk_channel *) tab->priv;
+ ide_disk_info_t *info = (ide_disk_info_t *) chan->dev_priv;
+ cyg_uint32 id_buf[CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE/sizeof(cyg_uint32)];
+ static int num_controllers;
+ static int ide_present[4], ide_reset_done[4];
+ cyg_disk_identify_t ident;
+ ide_identify_data_t *ide_idData=(ide_identify_data_t*)id_buf;
+
+ if (chan->init)
+ return true;
+
+ D("IDE(%d:%d) hw init\n", info->port, info->chan);
+
+ if (!num_controllers) num_controllers=HAL_IDE_INIT();
+ if (info->chan>=num_controllers) {
+ D("No IDE controller for channel %d:%d\n", info->port, info->chan);
+ return false;
+ }
+
+#if CYGDAT_DEVS_DISK_IDE_STARTUP_DELAY
+ CYGACC_CALL_IF_DELAY_US(CYGDAT_DEVS_DISK_IDE_STARTUP_DELAY*1000U);
+#endif
+
+ if (!ide_present[info->port]) {
+ ide_present[info->port]=ide_presence_detect(info->port);
+ if (!ide_present[info->port]) {
+ diag_printf("No devices on IDE controller #%d\n",info->port);
+ return false;
+ }
+ }
+ if (!ide_reset_done[info->port]) {
+ ide_reset_done[info->port]=ide_reset(info->port);
+ if (!ide_reset_done[info->port]) {
+ D("Controller #%d reset failure\n",info->port);
+ return false;
+ }
+ }
+
+#ifdef CYGDAT_DEVS_DISK_IDE_8_BIT_DATA_PATH
+ if (!ide_8bit_mode(info->port, info->chan, true)) {
+ D("IDE disk %d:%d failed to enter 8-bit mode\n",
+ info->port, info->chan);
+ }
+#endif
+
+ D("IDE %d:%d identify drive\n", info->port, info->chan);
+
+ if (!ide_ident(info->port, info->chan, (cyg_uint16 *)id_buf)) {
+ diag_printf("IDE %d:%d ident DRQ error\n", info->port, info->chan);
+ return false;
+ }
+
+ id_strcpy(ident.serial, ide_idData->serial, 20);
+ id_strcpy(ident.firmware_rev, ide_idData->firmware_rev, 8);
+ id_strcpy(ident.model_num, ide_idData->model_num, 40);
+
+ ident.cylinders_num = ide_idData->num_cylinders;
+ ident.heads_num = ide_idData->num_heads;
+ ident.sectors_num = ide_idData->num_sectors;
+ ident.lba_sectors_num = ide_idData->lba_total_sectors[1] << 16 |
+ ide_idData->lba_total_sectors[0];
+ ident.phys_block_size = 1;
+
+ // TODO: Should this be CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE?
+ ident.max_transfer = 512;
+
+ D("\tSerial : %s\n", ident.serial);
+ D("\tFirmware rev. : %s\n", ident.firmware_rev);
+ D("\tModel : %s\n", ident.model_num);
+ D("\tC/H/S : %d/%d/%d\n", ident.cylinders_num,
+ ident.heads_num, ident.sectors_num);
+
+ if (!(chan->callbacks->disk_init)(tab))
+ return false;
+
+ if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident))
+ return false;
+
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+
+static Cyg_ErrNo
+ide_disk_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ disk_channel *chan = (disk_channel *) (*tab)->priv;
+ return (chan->callbacks->disk_lookup)(tab, sub_tab, name);
+}
+
+// ----------------------------------------------------------------------------
+
+static Cyg_ErrNo
+ide_disk_read(disk_channel *chan,
+ void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num)
+{
+ ide_disk_info_t *info = (ide_disk_info_t *)chan->dev_priv;
+
+ D("IDE %d:%d read block %d\n", info->port, info->chan, block_num);
+
+ if (!ide_read_sector(info->port, info->chan, block_num,
+ (cyg_uint8 *)buf, len)) {
+ diag_printf("IDE %d:%d read DRQ error\n", info->port, info->chan);
+ return -EIO;
+ }
+
+ return ENOERR;
+}
+
+// ----------------------------------------------------------------------------
+
+static Cyg_ErrNo
+ide_disk_write(disk_channel *chan,
+ const void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num)
+{
+ ide_disk_info_t *info = (ide_disk_info_t *)chan->dev_priv;
+
+ D("IDE %d:%d write block %d\n", info->port, info->chan, block_num);
+
+ if (!ide_write_sector(info->port, info->chan, block_num,
+ (cyg_uint8 *)buf, len)) {
+ diag_printf("IDE %d:%d read DRQ error\n", info->port, info->chan);
+ return -EIO;
+ }
+
+ return ENOERR;
+}
+
+// ----------------------------------------------------------------------------
+
+static Cyg_ErrNo
+ide_disk_get_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len)
+{
+ return -EINVAL;
+}
+
+// ----------------------------------------------------------------------------
+
+static Cyg_ErrNo
+ide_disk_set_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len)
+{
+ return -EINVAL;
+}
+
+//EOF ide_disk.c
diff --git a/ecos/packages/devs/disk/ide/current/src/ide_disk.h b/ecos/packages/devs/disk/ide/current/src/ide_disk.h
new file mode 100644
index 0000000..7922003
--- /dev/null
+++ b/ecos/packages/devs/disk/ide/current/src/ide_disk.h
@@ -0,0 +1,187 @@
+#ifndef CYGONCE_IDE_DISK_H
+#define CYGONCE_IDE_DISK_H
+//==========================================================================
+//
+// ide_disk.h
+//
+// IDE polled mode disk driver defines
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): iz
+// Contributors:
+// Date: 2004-10-16
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// IDE Register Indices
+#define IDE_REG_DATA 0
+#define IDE_REG_ERROR 1
+#define IDE_REG_FEATURES 1
+#define IDE_REG_COUNT 2
+#define IDE_REG_REASON 2 // ATAPI
+#define IDE_REG_LBALOW 3
+#define IDE_REG_LBAMID 4
+#define IDE_REG_LBAHI 5
+#define IDE_REG_DEVICE 6
+#define IDE_REG_STATUS 7
+#define IDE_REG_COMMAND 7
+
+#define IDE_STAT_BSY 0x80
+#define IDE_STAT_DRDY 0x40
+#define IDE_STAT_SERVICE 0x10
+#define IDE_STAT_DRQ 0x08
+#define IDE_STAT_CORR 0x04
+#define IDE_STAT_ERR 0x01
+
+#define IDE_REASON_REL 0x04
+#define IDE_REASON_IO 0x02
+#define IDE_REASON_COD 0x01
+
+/* flag values */
+#define IDE_DEV_PRESENT 1 // Device is present
+#define IDE_DEV_PACKET 2 // Supports packet interface
+#define IDE_DEV_ADDR48 3 // Supports 48bit addressing
+
+typedef struct ide_identify_data_t_ {
+ cyg_uint16 general_conf; // 00 : general configuration
+ cyg_uint16 num_cylinders; // 01 : number of cylinders (default CHS trans)
+ cyg_uint16 reserved0; // 02 : reserved
+ cyg_uint16 num_heads; // 03 : number of heads (default CHS trans)
+ cyg_uint16 num_ub_per_track; // 04 : number of unformatted bytes per track
+ cyg_uint16 num_ub_per_sector; // 05 : number of unformatted bytes per sector
+ cyg_uint16 num_sectors; // 06 : number of sectors per track (default CHS trans)
+ cyg_uint16 num_card_sectors[2]; // 07-08 : number of sectors per card
+ cyg_uint16 reserved1; // 09 : reserved
+ cyg_uint16 serial[10]; // 10-19 : serial number (string)
+ cyg_uint16 buffer_type; // 20 : buffer type (dual ported)
+ cyg_uint16 buffer_size; // 21 : buffer size in 512 increments
+ cyg_uint16 num_ECC_bytes; // 22 : number of ECC bytes passed on R/W Long cmds
+ cyg_uint16 firmware_rev[4]; // 23-26 : firmware revision (string)
+ cyg_uint16 model_num[20]; // 27-46 : model number (string)
+ cyg_uint16 rw_mult_support; // 47 : max number of sectors on R/W multiple cmds
+ cyg_uint16 reserved2; // 48 : reserved
+ cyg_uint16 capabilities; // 49 : LBA, DMA, IORDY support indicator
+ cyg_uint16 reserved3; // 50 : reserved
+ cyg_uint16 pio_xferc_timing; // 51 : PIO data transfer cycle timing mode
+ cyg_uint16 dma_xferc_timing; // 52 : single word DMA data transfer cycle timing mode
+ cyg_uint16 cur_field_validity; // 53 : words 54-58 validity (0 == not valid)
+ cyg_uint16 cur_cylinders; // 54 : number of current cylinders
+ cyg_uint16 cur_heads; // 55 : number of current heads
+ cyg_uint16 cur_spt; // 56 : number of current sectors per track
+ cyg_uint16 cur_capacity[2]; // 57-58 : current capacity in sectors
+ cyg_uint16 mult_sectors; // 59 : multiple sector setting
+ cyg_uint16 lba_total_sectors[2]; // 60-61 : total sectors in LBA mode
+ cyg_uint16 sw_dma; // 62 : single word DMA support
+ cyg_uint16 mw_dma; // 63 : multi word DMA support
+ cyg_uint16 apio_modes; // 64 : advanced PIO transfer mode supported
+ cyg_uint16 min_dma_timing; // 65 : minimum multiword DMA transfer cycle
+ cyg_uint16 rec_dma_timing; // 66 : recommended multiword DMA cycle
+ cyg_uint16 min_pio_timing; // 67 : min PIO transfer time without flow control
+ cyg_uint16 min_pio_iordy_timing; // 68 : min PIO transfer time with IORDY flow control
+// cyg_uint16 reserved4[187]; // 69-255: reserved
+} ide_identify_data_t;
+
+
+typedef struct ide_disk_info_t_ {
+ cyg_uint8 port;
+ cyg_uint8 chan;
+} ide_disk_info_t;
+
+// ----------------------------------------------------------------------------
+
+static cyg_bool ide_disk_init(struct cyg_devtab_entry *tab);
+
+static Cyg_ErrNo ide_disk_read(disk_channel *chan,
+ void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num);
+
+
+static Cyg_ErrNo ide_disk_write(disk_channel *chan,
+ const void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num);
+
+static Cyg_ErrNo ide_disk_get_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len);
+
+static Cyg_ErrNo ide_disk_set_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len);
+
+static Cyg_ErrNo ide_disk_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+
+DISK_FUNS(ide_disk_funs,
+ ide_disk_read,
+ ide_disk_write,
+ ide_disk_get_config,
+ ide_disk_set_config
+);
+
+// ----------------------------------------------------------------------------
+
+#define IDE_DISK_INSTANCE(_number_,_port_,_chan_,_mbr_supp_,_name_) \
+static ide_disk_info_t ide_disk_info##_number_ = { \
+ port: (cyg_uint8) _port_, \
+ chan: (cyg_uint8) _chan_ \
+}; \
+DISK_CHANNEL(ide_disk_channel##_number_, \
+ ide_disk_funs, \
+ ide_disk_info##_number_, \
+ ide_disk_controller, \
+ _mbr_supp_, \
+ 4 \
+); \
+BLOCK_DEVTAB_ENTRY(ide_disk_io##_number_, \
+ _name_, \
+ 0, \
+ &cyg_io_disk_devio, \
+ ide_disk_init, \
+ ide_disk_lookup, \
+ &ide_disk_channel##_number_ \
+);
+
+// ----------------------------------------------------------------------------
+
+#endif // CYGONCE_IDE_DISK_H
diff --git a/ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/ChangeLog b/ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/ChangeLog
new file mode 100644
index 0000000..19dbbeb
--- /dev/null
+++ b/ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/ChangeLog
@@ -0,0 +1,29 @@
+2012-01-06 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/disk_mmc_freescale_dspi.cdl:
+ * src/freescale_dspi_mmc.c:
+ New package -- Disk driver fot Freescale DSPI
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/cdl/disk_mmc_freescale_dspi.cdl b/ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/cdl/disk_mmc_freescale_dspi.cdl
new file mode 100644
index 0000000..1ebff2f
--- /dev/null
+++ b/ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/cdl/disk_mmc_freescale_dspi.cdl
@@ -0,0 +1,92 @@
+##==========================================================================
+##
+## disk_mmc_freescale_dspi.cdl
+##
+## MMC/SD disk instatntiation for Freescale DSPI
+##
+##==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+##==========================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): Ilija Kocho <ilijak@siva.com.mk>
+## Date: 2011-12-27
+##
+######DESCRIPTIONEND####
+##
+##==========================================================================
+
+
+cdl_package CYGPKG_DEVS_DISK_MMC_FREESCALE_DSPI {
+ display "MMC/SD disk device for Freescale DSPI"
+
+ active_if CYGPKG_DEVS_DISK_MMC_SPI
+ requires CYGPKG_DEVS_SPI_FREESCALE_DSPI
+ requires is_active(CYGHWR_DEVS_DISK_MMC_FREESCALE_DSPI_BUS)
+ requires is_active(CYGHWR_DEVS_DISK_MMC_FREESCALE_DSPI_CS)
+
+
+ parent CYGPKG_DEVS_DISK_MMC_SPI
+ compile -library=libextras.a freescale_dspi_mmc.c
+
+ cdl_component CYGHWR_DEVS_MMC_SPI_INITIAL_SPEED {
+ display "Initial nominal SPI clock speed Hz"
+ flavor data
+ default_value 400000
+
+ cdl_option CYGHWR_DEVS_MMC_SPI_USE_DBR {
+ display "Use double baud rate"
+ flavor bool
+ default_value 1
+ description "
+ Double baud rate is a feature of Freescale DSPI
+ that may provide higher baud rates but duty the cycle may be
+ different than 50/50 depdent on scaler/prescaler setting
+ for achieved baud rate."
+ }
+ }
+
+ cdl_option CYGHWR_DEVS_DISK_MMC_CS_DELAY {
+ display "Nominal chip select delays (units)"
+ flavor data
+ legal_values { 1 1000 }
+ default_value 1
+ }
+
+ cdl_option CYGHWR_DEVS_DISK_MMC_CS_DELAY_UNIT {
+ display "Chip select delay unit (ns)"
+ flavor data
+ default_value 100
+ legal_values { 100 1000 }
+ }
+}
diff --git a/ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/src/freescale_dspi_mmc.c b/ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/src/freescale_dspi_mmc.c
new file mode 100644
index 0000000..5ecf94d
--- /dev/null
+++ b/ecos/packages/devs/disk/spi/freescale/dspi/mmc/current/src/freescale_dspi_mmc.c
@@ -0,0 +1,99 @@
+//==========================================================================
+//
+// freescale_dspi_mmc.c
+//
+// Cortex-M4 Freescale DSPI disk device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ilijak
+// Contributor(s):
+// Date: 2011-12-27
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_cortexm.h>
+#include <pkgconf/hal_cortexm_kinetis.h>
+#include <pkgconf/devs_disk_mmc_freescale_dspi.h>
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#endif
+
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <cyg/hal/hal_arch.h> // HAL header
+#include <cyg/hal/hal_intr.h> // HAL header
+#include <cyg/io/spi_freescale_dspi.h>
+
+#define MMC_SPI_FRAME_SIZE 8
+#define MMC_SPI_CLOCK_POL 0
+#define MMC_SPI_CLOCK_PHASE 0
+#define MMC_SPI_INITIAL_SPEED CYGHWR_DEVS_MMC_SPI_INITIAL_SPEED
+#define MMC_SPI_CSUP_DL CYGHWR_DEVS_DISK_MMC_CS_DELAY
+#define MMC_SPI_CSDW_DL CYGHWR_DEVS_DISK_MMC_CS_DELAY
+#define MMC_SPI_TRBD_DL CYGHWR_DEVS_DISK_MMC_CS_DELAY
+#define MMC_SPI_DELAY_UNIT CYGHWR_DEVS_DISK_MMC_CS_DELAY_UNIT
+#ifdef CYGHWR_DEVS_MMC_SPI_USE_DBR
+# define MMC_SPI_DBR 1
+#else
+# define MMC_SPI_DBR 0
+#endif
+
+
+CYG_DEVS_SPI_FREESCALE_DSPI_DEVICE(
+ cyg_spi_mmc_dev0, // Device name
+ CYGHWR_DEVS_DISK_MMC_FREESCALE_DSPI_BUS, // SPI bus
+ CYGHWR_DEVS_DISK_MMC_FREESCALE_DSPI_CS, // Dev num
+ MMC_SPI_FRAME_SIZE, // Frame size
+ MMC_SPI_CLOCK_POL, // Clock pol
+ MMC_SPI_CLOCK_PHASE, // Clock phase
+ MMC_SPI_INITIAL_SPEED, // Clock speed (Hz)
+ MMC_SPI_CSUP_DL, // CS assert delay
+ MMC_SPI_CSDW_DL, // CS negate delay
+ MMC_SPI_TRBD_DL, // Delay between transfers
+ MMC_SPI_DELAY_UNIT, // Delay unit (100 or 1000 ns)
+ MMC_SPI_DBR // Use double baud rate
+);
+
+//==========================================================================
+// EOF freescale_spi_disk.c
diff --git a/ecos/packages/devs/disk/synth/current/ChangeLog b/ecos/packages/devs/disk/synth/current/ChangeLog
new file mode 100644
index 0000000..5920f8d
--- /dev/null
+++ b/ecos/packages/devs/disk/synth/current/ChangeLog
@@ -0,0 +1,78 @@
+2008-08-19 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/synthdisk.cdl: Renamed the disk device to /dev/synthdiskX to
+ be unique with respect to other disk drivers. Remove the test
+ configury which is not used anywhere.
+
+
+2006-02-03 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/synthdisk.c: Updated to match changes in io/disk package.
+
+2004-07-01 Savin Zlobec <savin@elatec.si>
+
+ * src/synthdisk.c:
+ Updated to work with the new DISK_CHANNEL macro definition.
+
+2004-04-15 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/synthdisk.c: Mildly reorganized to support changeable
+ media. Added synth_disk_change() function to allow us to fake a
+ disk change for testing purposes.
+
+2004-02-05 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/synthdisk.cdl: Added testing config options, plus
+ define_proc to export CYGDAT_DEVS_DISK_CFG include file name.
+
+2004-01-30 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/synthdisk.c: Updated to latest disk device specification.
+
+2004-01-15 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/synthdisk.cdl:
+ * src/synthdisk.c:
+ Added _FILENAME option for disk instances to map device to an
+ arbitrary configured file.
+
+ * src/synthdisk.c: Removed block_pos arguments from read
+ and write calls: it is not necessary.
+
+2003-09-01 Savin Zlobec <savin@elatec.si>
+
+ * cdl/synthdisk.cdl:
+ * src/synthdisk.c:
+ Updated to work with the current disk interface.
+
+2003-08-19 Savin Zlobec <savin@elatec.si>
+
+ * cdl/synthdisk.cdl:
+ * src/synthdisk.c:
+ A synthetic block device driver.
+
+
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/disk/synth/current/cdl/synthdisk.cdl b/ecos/packages/devs/disk/synth/current/cdl/synthdisk.cdl
new file mode 100644
index 0000000..80101b0
--- /dev/null
+++ b/ecos/packages/devs/disk/synth/current/cdl/synthdisk.cdl
@@ -0,0 +1,173 @@
+# ====================================================================
+#
+# synthdisk.cdl
+#
+# Synthetic target disk package.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): savin
+# Contributors:
+# Date: 2003-06-18
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_DISK_ECOSYNTH {
+ display "Synthetic target disk driver"
+
+ parent CYGPKG_IO_DISK_DEVICES
+ active_if CYGPKG_IO_DISK
+ active_if CYGPKG_HAL_SYNTH
+
+ define_proc {
+ puts $::cdl_system_header "/***** Synthdisk driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_DISK_CFG <pkgconf/devs_disk_ecosynth.h>"
+ puts $::cdl_system_header "/***** Synthdisk driver proc output end *****/"
+ }
+
+ cdl_component CYGVAR_DEVS_DISK_ECOSYNTH_DISK0 {
+ display "Provide disk 0 device"
+ flavor bool
+ default_value 0
+ description "Synthetic disk 0 driver."
+
+ cdl_option CYGDAT_IO_DISK_ECOSYNTH_DISK0_NAME {
+ display "Device name for ecosynth disk 0 device"
+ flavor data
+ default_value {"\"/dev/synthdisk0/\""}
+ description "This is the device name used to access this
+ device in eCos. Note that the trailing slash
+ character must be present."
+ }
+
+ cdl_option CYGDAT_IO_DISK_ECOSYNTH_DISK0_FILENAME {
+ display "Linux file name for ecosynth disk 0 device"
+ flavor data
+ default_value {"\"disk0.img\""}
+ description "This is the name of the file in the Linux filesystem that
+ the driver will use to simulate a real disk. It should have
+ been formatted with a DOS filesystem image before being used.
+ The driver may also be pointed at real devices. For example
+ setting this option to \"/dev/fd\" will cause the driver to access
+ any real floppy disk inserted in the host's floppy drive."
+ }
+
+ cdl_option CYGNUM_IO_DISK_ECOSYNTH_DISK0_SIZE {
+ display "Size in bytes for ecosynth disk 0"
+ flavor data
+ default_value 10240000
+ legal_values 512 to 99999999
+ requires { (CYGNUM_IO_DISK_ECOSYNTH_DISK0_SIZE % 512) == 0 }
+ description "
+ This option specifies the size in bytes used
+ for the ecosynth disk 0 device."
+ }
+
+ cdl_option CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR {
+ display "Expect MBR in synth disk 0 image"
+ flavor bool
+ default_value 0
+ description "
+ This option controls the scanning of MBR in synthetic
+ disk 0 image."
+ }
+
+ cdl_option CYGIMP_IO_DISK_ECOSYNTH_DISK0_CYLINDERS {
+ display "Number of cylinders on synth disk 0"
+ flavor data
+ default_value 0
+ active_if CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR
+ description "
+ This option controls the number of cylinders on
+ synthetic disk 0. It is only needed if
+ CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR is set."
+ }
+
+ cdl_option CYGIMP_IO_DISK_ECOSYNTH_DISK0_HEADS {
+ display "Number of heads on synth disk 0"
+ flavor data
+ default_value 0
+ active_if CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR
+ description "
+ This option controls the number of heads on
+ synthetic disk 0. It is only needed if
+ CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR is set."
+ }
+
+ cdl_option CYGIMP_IO_DISK_ECOSYNTH_DISK0_SECTORS {
+ display "Number of sectors per track on synth disk 0"
+ flavor data
+ default_value 0
+ active_if CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR
+ description "
+ This option controls the number of sectors per track on
+ synthetic disk 0.It is only needed if
+ CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR is set."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_DISK_ECOSYNTH_OPTIONS {
+ display "Build options"
+ active_if { CYGVAR_DEVS_DISK_ECOSYNTH_DISK0 }
+ flavor none
+ compile -library=libextras.a synthdisk.c
+ description "
+ Package-specific build options including control over compiler
+ flags used only in building this package."
+
+ cdl_option CYGPKG_DEVS_DISK_ECOSYNTH_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building this package. These flags are used in addition
+ to the set of global flags."
+ }
+ cdl_option CYGPKG_DEVS_DISK_ECOSYNTH_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building this package. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
diff --git a/ecos/packages/devs/disk/synth/current/src/synthdisk.c b/ecos/packages/devs/disk/synth/current/src/synthdisk.c
new file mode 100644
index 0000000..89e1688
--- /dev/null
+++ b/ecos/packages/devs/disk/synth/current/src/synthdisk.c
@@ -0,0 +1,406 @@
+//==========================================================================
+//
+// synthdisk.c
+//
+// Disk device driver for the synthetic target
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): savin
+// Contributors:
+// Date: 2003-06-18
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_disk_ecosynth.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/disk.h>
+
+#include <stdio.h> // sprintf
+
+// ----------------------------------------------------------------------------
+
+//#define DEBUG 1
+
+// ----------------------------------------------------------------------------
+
+typedef struct {
+ int num;
+ cyg_uint32 cylinders_num;
+ cyg_uint32 heads_num;
+ cyg_uint32 sectors_num;
+ cyg_uint32 size;
+ int filefd;
+ char *filename;
+} synth_disk_info_t;
+
+typedef struct { int dummy; } synth_controller_t;
+
+// ----------------------------------------------------------------------------
+
+static cyg_bool synth_disk_init(struct cyg_devtab_entry *tab);
+
+static Cyg_ErrNo synth_disk_read(disk_channel *chan,
+ void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num);
+
+static Cyg_ErrNo synth_disk_write(disk_channel *chan,
+ const void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num);
+
+static Cyg_ErrNo synth_disk_get_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len);
+
+static Cyg_ErrNo synth_disk_set_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len);
+
+static Cyg_ErrNo synth_disk_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+
+DISK_FUNS(synth_disk_funs,
+ synth_disk_read,
+ synth_disk_write,
+ synth_disk_get_config,
+ synth_disk_set_config
+);
+
+// ----------------------------------------------------------------------------
+
+
+#define SYNTH_DISK_INSTANCE(_number_,_mbr_supp_, _cyl_,_hpt_,_spt_) \
+static synth_disk_info_t synth_disk_info##_number_ = { \
+ num: _number_, \
+ cylinders_num: _cyl_, \
+ heads_num: _hpt_, \
+ sectors_num: _spt_, \
+ size: CYGNUM_IO_DISK_ECOSYNTH_DISK##_number_##_SIZE, \
+ filefd: -1, \
+ filename: CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_FILENAME \
+}; \
+static synth_controller_t synth_controller_##_number_; \
+DISK_CONTROLLER( synth_disk_controller_##_number_, synth_controller_##_number_ ); \
+DISK_CHANNEL(synth_disk_channel##_number_, \
+ synth_disk_funs, \
+ synth_disk_info##_number_, \
+ synth_disk_controller_##_number_, \
+ _mbr_supp_, \
+ 4 \
+); \
+BLOCK_DEVTAB_ENTRY(synth_disk_io##_number_, \
+ CYGDAT_IO_DISK_ECOSYNTH_DISK##_number_##_NAME, \
+ 0, \
+ &cyg_io_disk_devio, \
+ synth_disk_init, \
+ synth_disk_lookup, \
+ &synth_disk_channel##_number_ \
+);
+
+// ----------------------------------------------------------------------------
+
+#ifdef CYGVAR_DEVS_DISK_ECOSYNTH_DISK0
+# ifndef CYGIMP_IO_DISK_ECOSYNTH_DISK0_MBR
+SYNTH_DISK_INSTANCE(0, false, 0, 0, 0);
+# else
+SYNTH_DISK_INSTANCE(0, true, CYGIMP_IO_DISK_ECOSYNTH_DISK0_CYLINDERS,
+ CYGIMP_IO_DISK_ECOSYNTH_DISK0_HEADS,
+ CYGIMP_IO_DISK_ECOSYNTH_DISK0_SECTORS);
+# endif
+#endif
+
+// ----------------------------------------------------------------------------
+
+static cyg_bool
+synth_disk_init(struct cyg_devtab_entry *tab)
+{
+ disk_channel *chan = (disk_channel *) tab->priv;
+ synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv;
+ bool result = true;
+
+ if (chan->init)
+ return true;
+
+#ifdef DEBUG
+ diag_printf("synth disk %d init size=%d\n",
+ synth_info->num, synth_info->size);
+#endif
+
+ synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
+ CYG_HAL_SYS_O_RDWR,
+ CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
+
+ if (-ENOENT == synth_info->filefd)
+ {
+ synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
+ CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, 0644);
+
+ if (synth_info->filefd >= 0)
+ {
+ unsigned char b = 0x00;
+ int i;
+
+ for (i = 0; i < synth_info->size; i++)
+ cyg_hal_sys_write(synth_info->filefd, &b, 1);
+ }
+ }
+
+ if (synth_info->filefd < 0)
+ {
+ CYG_ASSERT(false, "Can't open/create disk image file");
+ return false;
+ }
+
+ if (result)
+ {
+
+ if (!(chan->callbacks->disk_init)(tab))
+ return false;
+ }
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+
+static Cyg_ErrNo
+synth_disk_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ Cyg_ErrNo res;
+ disk_channel *chan = (disk_channel *) (*tab)->priv;
+ synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv;
+ cyg_disk_identify_t ident;
+
+ ident.serial[0] = '\0';
+ ident.firmware_rev[0] = '\0';
+ ident.model_num[0] = '\0';
+ ident.lba_sectors_num = synth_info->size / 512;
+ ident.cylinders_num = synth_info->cylinders_num;
+ ident.heads_num = synth_info->heads_num;
+ ident.sectors_num = synth_info->sectors_num;
+ ident.phys_block_size = 1;
+ ident.max_transfer = 2048;
+
+ res = (chan->callbacks->disk_connected)(*tab, &ident);
+
+ if( res == ENOERR )
+ res = (chan->callbacks->disk_lookup(tab, sub_tab, name));
+
+ return res;
+}
+
+// ----------------------------------------------------------------------------
+
+static Cyg_ErrNo
+synth_disk_read(disk_channel *chan,
+ void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num)
+{
+ synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv;
+
+#ifdef DEBUG
+ diag_printf("synth disk read block %d\n", block_num);
+#endif
+
+ if (synth_info->filefd >= 0)
+ {
+ cyg_hal_sys_lseek(synth_info->filefd,
+ block_num * chan->info->block_size,
+ CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_read(synth_info->filefd, buf, len*512);
+ return ENOERR;
+ }
+ return -EIO;
+}
+
+// ----------------------------------------------------------------------------
+
+static Cyg_ErrNo
+synth_disk_write(disk_channel *chan,
+ const void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num)
+{
+ synth_disk_info_t *synth_info = (synth_disk_info_t *)chan->dev_priv;
+
+#ifdef DEBUG
+ diag_printf("synth disk write block %d\n", block_num);
+#endif
+
+ if (synth_info->filefd >= 0)
+ {
+ cyg_hal_sys_lseek(synth_info->filefd,
+ block_num * chan->info->block_size,
+ CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_write(synth_info->filefd, buf, len*512);
+// cyg_hal_sys_fdatasync(synth_info->filefd);
+ return ENOERR;
+ }
+ return -EIO;
+}
+
+// ----------------------------------------------------------------------------
+
+static Cyg_ErrNo
+synth_disk_get_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len)
+{
+
+#ifdef DEBUG
+ diag_printf("synth disk get config\n");
+#endif
+
+ return -EINVAL;
+}
+
+// ----------------------------------------------------------------------------
+
+static Cyg_ErrNo
+synth_disk_set_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len)
+{
+ Cyg_ErrNo res = ENOERR;
+#ifdef DEBUG
+ diag_printf("synth disk set config\n");
+#endif
+
+ switch ( key )
+ {
+ case CYG_IO_SET_CONFIG_DISK_MOUNT:
+ // We have nothing to do here for this option.
+ break;
+
+ case CYG_IO_SET_CONFIG_DISK_UMOUNT:
+ if( chan->info->mounts == 0 )
+ {
+ // If this is the last unmount of this disk, then disconnect it from
+ // the driver system so the user can swap it out if he wants.
+ res = (chan->callbacks->disk_disconnected)(chan);
+ }
+ break;
+
+ default:
+ res = -EINVAL;
+ break;
+ }
+
+ return res;
+}
+
+// ----------------------------------------------------------------------------
+
+externC cyg_bool synth_disk_change( int unit, char *filename, int size,
+ int cyls, int heads, int sectors)
+{
+ struct cyg_devtab_entry *tab = &synth_disk_io0;
+ disk_channel *chan = (disk_channel *) tab->priv;
+ synth_disk_info_t *synth_info = (synth_disk_info_t *) chan->dev_priv;
+ int err = 0;
+
+ if (!chan->init)
+ return false;
+
+ synth_info->filename = filename;
+ synth_info->size = size;
+ synth_info->cylinders_num = cyls;
+ synth_info->heads_num = heads;
+ synth_info->sectors_num = sectors;
+
+#ifdef DEBUG
+ diag_printf("synth disk %d change size=%d\n",
+ synth_info->num, synth_info->size);
+#endif
+
+ err = cyg_hal_sys_close( synth_info->filefd );
+
+#ifdef DEBUG
+ if( err != 0 )
+ {
+ diag_printf("synth disk change, failed to close old image: %d\n",err);
+ }
+#endif
+
+ synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
+ CYG_HAL_SYS_O_RDWR,
+ CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
+
+ if (-ENOENT == synth_info->filefd)
+ {
+ synth_info->filefd = cyg_hal_sys_open(synth_info->filename,
+ CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, 0644);
+
+ if (synth_info->filefd >= 0)
+ {
+ unsigned char b = 0x00;
+ int i;
+
+ for (i = 0; i < synth_info->size; i++)
+ cyg_hal_sys_write(synth_info->filefd, &b, 1);
+ }
+ }
+
+ if (synth_info->filefd < 0)
+ {
+ CYG_ASSERT(false, "Can't open/create disk image file");
+ return false;
+ }
+
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+// EOF synthdisk.c
diff --git a/ecos/packages/devs/disk/v85x/edb_v850/current/ChangeLog b/ecos/packages/devs/disk/v85x/edb_v850/current/ChangeLog
new file mode 100644
index 0000000..8e90a80
--- /dev/null
+++ b/ecos/packages/devs/disk/v85x/edb_v850/current/ChangeLog
@@ -0,0 +1,59 @@
+2008-08-19 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/v85x_edb_v850_disk.cdl: Rename the disk device to
+ /dev/v85xdiskX to be unique with respect to other disk drivers.
+
+2006-09-21 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/v85x_edb_v850_disk.c (cf_disk_init): Provide phys_block_size
+ and max_transfer disk ident members.
+
+2006-09-20 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/v85x_edb_v850_disk.c:
+ DISK_CHANNEL and DISK_FUNS are now implicitly static.
+ Update DISK_CHANNEL for new io/disk macro.
+
+2004-07-02 Savin Zlobec <savin@elatec.si>
+
+ * src/v85x_edb_v850_disk.c:
+ Updated to work with the new DISK_CHANNEL macro definition
+ and fixed read and write calls to honor the len parameter.
+
+2004-01-15 Nick Garnett <nickg@calivar.com>
+
+ * src/v85x_edb_v850_disk.c: Removed block_pos arguments from read
+ and write calls: it is not necessary.
+
+2003-09-01 Savin Zlobec <savin@elatec.si>
+
+ * cdl/v85x_edb_v850_disk.cdl:
+ * src/v85x_edb_v850_disk.c:
+ * src/cf_ata.h:
+ A Elatec development board CF disk device driver
+
+
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/disk/v85x/edb_v850/current/cdl/v85x_edb_v850_disk.cdl b/ecos/packages/devs/disk/v85x/edb_v850/current/cdl/v85x_edb_v850_disk.cdl
new file mode 100644
index 0000000..4c47833
--- /dev/null
+++ b/ecos/packages/devs/disk/v85x/edb_v850/current/cdl/v85x_edb_v850_disk.cdl
@@ -0,0 +1,72 @@
+# ====================================================================
+#
+# v85x_edb_v850_disk.cdl
+#
+# Elatec v850 development board disk package.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): savin
+# Contributors:
+# Date: 2003-08-21
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_DISK_V85X_EDB_V850 {
+ display "Disk driver for Elatec v850 development board"
+
+ parent CYGPKG_IO_DISK_DEVICES
+ active_if CYGPKG_IO_DISK
+ active_if CYGPKG_HAL_V85X_EDB_V850
+
+ compile -library=libextras.a v85x_edb_v850_disk.c
+
+ cdl_component CYGVAR_DEVS_DISK_V85X_EDB_V850_DISK0 {
+ display "Provide disk 0 device"
+ flavor bool
+ default_value 0
+ description "Elatec v850 development board disk 0 driver."
+
+ cdl_option CYGDAT_IO_DISK_V85X_EDB_V850_DISK0_NAME {
+ display "Device name for disk 0 device"
+ flavor data
+ default_value {"\"/dev/v85xdisk0/\""}
+ }
+ }
+}
+
+# EOF v85x_edb_v850_disk.cdl
diff --git a/ecos/packages/devs/disk/v85x/edb_v850/current/src/cf_ata.h b/ecos/packages/devs/disk/v85x/edb_v850/current/src/cf_ata.h
new file mode 100644
index 0000000..54accd9
--- /dev/null
+++ b/ecos/packages/devs/disk/v85x/edb_v850/current/src/cf_ata.h
@@ -0,0 +1,184 @@
+#ifndef CYGONCE_CF_ATA_H
+#define CYGONCE_CF_ATA_H
+//==========================================================================
+//
+// cf_ata.h
+//
+// CompactFlash ATA interface definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): savin
+// Contributors:
+// Date: 2003-08-21
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// -------------------------------------------------------------------------
+// CF Error Register bits
+//
+#define CF_EREG_BBK (1<<7) // bad block detected
+#define CF_EREG_UNC (1<<6) // uncorrectable error
+#define CF_EREG_IDNF (1<<4) // req sector ID is in error or cannot be found
+#define CF_EREG_ABORT (1<<2) // command aborted
+#define CF_EREG_AMNF (1<<0) // general error
+
+// -------------------------------------------------------------------------
+// CF Status Register bits
+//
+#define CF_SREG_BUSY (1<<7) // busy (no other bits in this register are valid)
+#define CF_SREG_RDY (1<<6) // ready to accept a command
+#define CF_SREG_DWF (1<<5) // write fault has occurred
+#define CF_SREG_DSC (1<<4) // card is ready
+#define CF_SREG_DRQ (1<<3) // information req transfer to/from the host
+ // through the Data register
+#define CF_SREG_CORR (1<<2) // correctable data error (data corrected)
+#define CF_SREG_IDX (1<<1) // always 0
+#define CF_SREG_ERR (1<<0) // command has ended in error (see error reg)
+
+// -------------------------------------------------------------------------
+// CF Device Control Register bits
+//
+#define CF_DREG_SWRST (1<<2) // soft reset
+#define CF_DREG_IEN (1<<1) // interrupt enable (0 - enabled, 1 - disabled)
+
+// -------------------------------------------------------------------------
+// CF ATA Command Set
+//
+// FR - Features register
+// SC - Sector count register
+// SN - Sector number register
+// CY - Cylinder registers
+// DH - Card/Drive/Head register
+// LBA - Logical Block Address Mode Supported
+//
+// Y - The register contains a valid parameter for this command
+// For the Drive/Head Register Y means both the CF Card and head
+// parameters are used
+// D - Only the CompactFlash Card parameter is valid and not the head parameter
+//
+// Note FR SC SN CY DH LBA
+#define CF_ATA_CHECK_POWER_MODE_CMD 0xE5 // - - - - - D -
+#define CF_ATA_EXE_DRIVE_DIAG_CMD 0x90 // - - - - - D -
+#define CF_ATA_ERASE_SECTORS_CMD 0xC0 // 2 - Y Y Y Y Y
+#define CF_ATA_FORMAT_TRACK_CMD 0x50 // - - Y - Y Y Y
+#define CF_ATA_IDENTIFY_DRIVE_CMD 0xEC // - - - - - D -
+#define CF_ATA_IDLE_CMD 0xE3 // - - Y - - D -
+#define CF_ATA_IDLE_IMMEDIATE_CMD 0xE1 // - - - - - D -
+#define CF_ATA_INIT_DRIVE_PARAMS_CMD 0x91 // - - Y - - Y -
+#define CF_ATA_READ_BUFFER_CMD 0xE4 // - - - - - D -
+#define CF_ATA_READ_MULTIPLE_CMD 0xC4 // - - Y Y Y Y Y
+#define CF_ATA_READ_LONG_SECTOR_CMD 0x22 // - - - Y Y Y Y
+#define CF_ATA_READ_SECTORS_CMD 0x20 // - - Y Y Y Y Y
+#define CF_ATA_READ_VERIFY_SECTORS_CMD 0x40 // - - Y Y Y Y Y
+#define CF_ATA_RECALIBRATE_CMD 0x10 // - - - - - D -
+#define CF_ATA_REQUEST_SENSE_CMD 0x03 // 1 - - - - D -
+#define CF_ATA_SEEK_CMD 0x70 // - - - Y Y Y Y
+#define CF_ATA_SET_FEATURES_CMD 0xEF // - Y - - - D -
+#define CF_ATA_SET_MULTIPLE_MODE_CMD 0xC6 // - - Y - - D -
+#define CF_ATA_SET_SLEEP_MODE_CMD 0xE6 // - - - - - D -
+#define CF_ATA_STAND_BY_CMD 0xE2 // - - - - - D -
+#define CF_ATA_STAND_BY_IMMEDIATE_CMD 0xE0 // - - - - - D -
+#define CF_ATA_TRANSLATE_SECTOR_CMD 0x87 // 1 - Y Y Y Y Y
+#define CF_ATA_WEAR_LEVEL_CMD 0xF5 // 1 - - - - Y -
+#define CF_ATA_WRITE_BUFFER_CMD 0xE8 // - - - - - D -
+#define CF_ATA_WRITE_LONG_SECTOR_CMD 0x32 // - - - Y Y Y Y
+#define CF_ATA_WRITE_MULTIPLE_CMD 0xC5 // - - Y Y Y Y Y
+#define CF_ATA_WRITE_MULTIPLE_WO_ERASE_CMD 0xCD // 2 - Y Y Y Y Y
+#define CF_ATA_WRITE_SECTORS_CMD 0x30 // - - Y Y Y Y Y
+#define CF_ATA_WRITE_SECTORS_WO_ERASE_CMD 0x38 // 2 - Y Y Y Y Y
+#define CF_ATA_WRITE_VERIFY_SECTORS_CMD 0x3C // - - Y Y Y Y Y
+//
+// Note 1 : These commands are not standard PC Card ATA commands but
+// provide additional functionality
+// Note 2 : These commands are not standard PC Card ATA commands and
+// these features are no longer supported with the
+// introduction of 256 Mbit flash technology. If one
+// of these commands is issued, the sectors will be
+// erased but there will be no net gain in write
+// performance when using the Write Without Erase command.
+
+// -------------------------------------------------------------------------
+// CF ATA Identify drive command response
+//
+typedef struct cf_ata_identify_data_t
+{
+ cyg_uint16 general_conf; // 00 : general configuration
+ cyg_uint16 num_cylinders; // 01 : number of cylinders (default CHS trans)
+ cyg_uint16 reserved0; // 02 : reserved
+ cyg_uint16 num_heads; // 03 : number of heads (default CHS trans)
+ cyg_uint16 num_ub_per_track; // 04 : number of unformatted bytes per track
+ cyg_uint16 num_ub_per_sector; // 05 : number of unformatted bytes per sector
+ cyg_uint16 num_sectors; // 06 : number of sectors per track (default CHS trans)
+ cyg_uint16 num_card_sectors[2]; // 07-08 : number of sectors per card
+ cyg_uint16 reserved1; // 09 : reserved
+ cyg_uint16 serial[10]; // 10-19 : serial number (string)
+ cyg_uint16 buffer_type; // 20 : buffer type (dual ported)
+ cyg_uint16 buffer_size; // 21 : buffer size in 512 increments
+ cyg_uint16 num_ECC_bytes; // 22 : number of ECC bytes passed on R/W Long cmds
+ cyg_uint16 firmware_rev[4]; // 23-26 : firmware revision (string)
+ cyg_uint16 model_num[20]; // 27-46 : model number (string)
+ cyg_uint16 rw_mult_support; // 47 : max number of sectors on R/W multiple cmds
+ cyg_uint16 reserved2; // 48 : reserved
+ cyg_uint16 capabilities; // 49 : LBA, DMA, IORDY support indicator
+ cyg_uint16 reserved3; // 50 : reserved
+ cyg_uint16 pio_xferc_timing; // 51 : PIO data transfer cycle timing mode
+ cyg_uint16 dma_xferc_timing; // 52 : single word DMA data transfer cycle timing mode
+ cyg_uint16 cur_field_validity; // 53 : words 54-58 validity (0 == not valid)
+ cyg_uint16 cur_cylinders; // 54 : number of current cylinders
+ cyg_uint16 cur_heads; // 55 : number of current heads
+ cyg_uint16 cur_spt; // 56 : number of current sectors per track
+ cyg_uint16 cur_capacity[2]; // 57-58 : current capacity in sectors
+ cyg_uint16 mult_sectors; // 59 : multiple sector setting
+ cyg_uint16 lba_total_sectors[2]; // 60-61 : total sectors in LBA mode
+ cyg_uint16 sw_dma; // 62 : single word DMA support
+ cyg_uint16 mw_dma; // 63 : multi word DMA support
+ cyg_uint16 apio_modes; // 64 : advanced PIO transfer mode supported
+ cyg_uint16 min_dma_timing; // 65 : minimum multiword DMA transfer cycle
+ cyg_uint16 rec_dma_timing; // 66 : recommended multiword DMA cycle
+ cyg_uint16 min_pio_timing; // 67 : min PIO transfer time without flow control
+ cyg_uint16 min_pio_iordy_timing; // 68 : min PIO transfer time with IORDY flow control
+// cyg_uint16 reserved4[187]; // 69-255: reserved
+} cf_ata_identify_data_t;
+
+#endif // CYGONCE_CF_ATA_H
+
+// -------------------------------------------------------------------------
+// EOF cf_ata.h
diff --git a/ecos/packages/devs/disk/v85x/edb_v850/current/src/v85x_edb_v850_disk.c b/ecos/packages/devs/disk/v85x/edb_v850/current/src/v85x_edb_v850_disk.c
new file mode 100644
index 0000000..e9dd8d3
--- /dev/null
+++ b/ecos/packages/devs/disk/v85x/edb_v850/current/src/v85x_edb_v850_disk.c
@@ -0,0 +1,415 @@
+//==========================================================================
+//
+// v85x_edb_v850_disk.c
+//
+// Elatec v850 development board disk driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): savin
+// Contributors:
+// Date: 2003-08-21
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_disk_v85x_edb_v850.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/disk.h>
+
+#include <cf_ata.h>
+
+// ----------------------------------------------------------------------------
+
+//#define DEBUG 1
+
+#ifdef DEBUG
+# define D(_args_) diag_printf _args_
+#else
+# define D(_args_)
+#endif
+
+// ----------------------------------------------------------------------------
+
+#include <cyg/hal/v850_common.h>
+
+static volatile unsigned char* P10 = (volatile unsigned char*)V850_REG_P10;
+static volatile unsigned char* PM10 = (volatile unsigned char*)V850_REG_PM10;
+static volatile unsigned char* PU10 = (volatile unsigned char*)V850_REG_PU10;
+
+#define CF_BASE 0x00380000
+
+#define CF_HW_INIT() \
+ do { \
+ *PU10 |= (1<<4); \
+ *PM10 |= (1<<4); \
+ *PM10 &= ~2; \
+ } while (0)
+
+#define CF_HW_RESET() \
+ do { \
+ int i; \
+ *P10 |= 2; \
+ for (i = 0; i < 500000; i++); \
+ *P10 &= ~2; \
+ for (i = 0; i < 500000; i++); \
+ } while (0)
+
+#define CF_HW_BUSY_WAIT() \
+ do { \
+ while (0 == (*P10 & (1<<4))); \
+ } while (0)
+
+// ----------------------------------------------------------------------------
+
+typedef struct {
+ volatile cyg_uint16 *base;
+} cf_disk_info_t;
+
+// ----------------------------------------------------------------------------
+
+static cyg_bool cf_disk_init(struct cyg_devtab_entry *tab);
+
+static Cyg_ErrNo cf_disk_read(disk_channel *chan,
+ void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num);
+
+
+static Cyg_ErrNo cf_disk_write(disk_channel *chan,
+ const void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num);
+
+static Cyg_ErrNo cf_disk_get_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len);
+
+static Cyg_ErrNo cf_disk_set_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len);
+
+static Cyg_ErrNo cf_disk_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+
+DISK_FUNS(cf_disk_funs,
+ cf_disk_read,
+ cf_disk_write,
+ cf_disk_get_config,
+ cf_disk_set_config
+);
+
+// ----------------------------------------------------------------------------
+
+// No h/w controller structure is needed, but the address of the
+// second argument is taken anyway.
+DISK_CONTROLLER(cf_disk_controller, cf_disk_controller);
+
+#define CF_DISK_INSTANCE(_number_,_base_,_mbr_supp_,_name_) \
+static cf_disk_info_t cf_disk_info##_number_ = { \
+ base: (volatile cyg_uint16 *)_base_, \
+}; \
+DISK_CHANNEL(cf_disk_channel##_number_, \
+ cf_disk_funs, \
+ cf_disk_info##_number_, \
+ cf_disk_controller, \
+ _mbr_supp_, \
+ 4 \
+); \
+BLOCK_DEVTAB_ENTRY(cf_disk_io##_number_, \
+ _name_, \
+ 0, \
+ &cyg_io_disk_devio, \
+ cf_disk_init, \
+ cf_disk_lookup, \
+ &cf_disk_channel##_number_ \
+);
+
+// ----------------------------------------------------------------------------
+
+#ifdef CYGVAR_DEVS_DISK_V85X_EDB_V850_DISK0
+CF_DISK_INSTANCE(0, CF_BASE, true, CYGDAT_IO_DISK_V85X_EDB_V850_DISK0_NAME);
+#endif
+
+// ----------------------------------------------------------------------------
+
+static __inline__ cyg_uint8
+get_status(volatile cyg_uint16 *base)
+{
+ cyg_uint16 val;
+ HAL_READ_UINT16(base + 7, val);
+ return (val & 0x00FF);
+}
+
+static __inline__ cyg_uint8
+get_error(volatile cyg_uint16 *base)
+{
+ cyg_uint16 val;
+ HAL_READ_UINT16(base + 6, val);
+ return ((val >> 8) & 0x00FF);
+}
+
+static __inline__ void
+set_dctrl(volatile cyg_uint16 *base, cyg_uint8 dbits)
+{
+ cyg_uint16 val = dbits;
+ HAL_WRITE_UINT16(base + 7, val);
+}
+
+static cyg_bool
+exe_cmd(volatile cyg_uint16 *base,
+ cyg_uint8 cmd,
+ cyg_uint8 drive,
+ cyg_uint32 lba_addr,
+ cyg_uint8 sec_cnt)
+{
+ cyg_uint8 lba0_7;
+ cyg_uint16 lba8_23;
+ cyg_uint8 lba24_27;
+ cyg_uint8 drv;
+
+ lba0_7 = lba_addr & 0xFF;
+ lba8_23 = (lba_addr >> 8) & 0xFFFF;
+ lba24_27 = (lba_addr >> 24) & 0x0F;
+
+ // drive and LBA addressing mode flag
+ if (0 == drive) drv = 0x40;
+ else drv = 0x50;
+
+ CF_HW_BUSY_WAIT();
+
+ HAL_WRITE_UINT16(base + 1, sec_cnt | (lba0_7 << 8));
+ HAL_WRITE_UINT16(base + 2, lba8_23);
+ HAL_WRITE_UINT16(base + 3, lba24_27 | drv | (cmd << 8));
+
+ CF_HW_BUSY_WAIT();
+
+ return (0 == (get_status(base) & CF_SREG_ERR));
+}
+
+static void
+read_data(volatile cyg_uint16 *base,
+ void *buf,
+ cyg_uint16 len)
+{
+ cyg_uint16 *bufp = (cyg_uint16 *)buf;
+ int i;
+
+ CF_HW_BUSY_WAIT();
+
+ for (i = 0; i < 512; i += 2)
+ {
+ cyg_uint16 data;
+ HAL_READ_UINT16(base + 4, data);
+ if (i < len) *bufp++ = data;
+ }
+
+ CF_HW_BUSY_WAIT();
+}
+
+static void
+write_data(volatile cyg_uint16 *base,
+ const void *buf,
+ cyg_uint16 len)
+{
+ cyg_uint16 *bufp = (cyg_uint16 * const)buf;
+ int i;
+
+ CF_HW_BUSY_WAIT();
+
+ for (i = 0; i < 512; i += 2)
+ {
+ cyg_uint16 data;
+
+ if (i < len) data = *bufp++;
+ else data = 0x0000;
+
+ HAL_WRITE_UINT16(base + 4, data);
+ }
+
+ CF_HW_BUSY_WAIT();
+}
+
+static void
+id_strcpy(char *dest, cyg_uint16 *src, cyg_uint16 size)
+{
+ int i;
+
+ for (i = 0; i < size; i+=2)
+ {
+ *dest++ = (char)(*src >> 8);
+ *dest++ = (char)(*src & 0x00FF);
+ src++;
+ }
+ *dest = '\0';
+}
+
+// ----------------------------------------------------------------------------
+
+static cyg_bool
+cf_disk_init(struct cyg_devtab_entry *tab)
+{
+ disk_channel *chan = (disk_channel *) tab->priv;
+ cf_disk_info_t *info = (cf_disk_info_t *) chan->dev_priv;
+ cf_ata_identify_data_t *ata_id;
+ cyg_uint8 id_buf[sizeof(cf_ata_identify_data_t)];
+ cyg_disk_identify_t ident;
+
+ if (chan->init)
+ return true;
+
+ D(("CF(%p) hw init\n", info->base));
+
+ CF_HW_INIT();
+ CF_HW_RESET();
+
+ D(("CF(%p) identify drive\n", info->base));
+
+ if (!exe_cmd(info->base, CF_ATA_IDENTIFY_DRIVE_CMD, 0, 0, 0))
+ {
+ D(("CF(%p) error (%x)\n", info->base, get_error(info->base)));
+ return false;
+ }
+ read_data(info->base, id_buf, sizeof(cf_ata_identify_data_t));
+
+ ata_id = (cf_ata_identify_data_t *)id_buf;
+
+ D(("CF(%p) general conf = %x\n", info->base, ata_id->general_conf));
+
+ if (0x848A != ata_id->general_conf)
+ return false;
+
+ id_strcpy(ident.serial, ata_id->serial, 20);
+ id_strcpy(ident.firmware_rev, ata_id->firmware_rev, 8);
+ id_strcpy(ident.model_num, ata_id->model_num, 40);
+
+ ident.cylinders_num = ata_id->num_cylinders;
+ ident.heads_num = ata_id->num_heads;
+ ident.sectors_num = ata_id->num_sectors;
+ ident.lba_sectors_num = ata_id->lba_total_sectors[1] << 16 |
+ ata_id->lba_total_sectors[0];
+ ident.phys_block_size = 1;
+ ident.max_transfer = 512;
+ if (!(chan->callbacks->disk_init)(tab))
+ return false;
+
+ if (ENOERR != (chan->callbacks->disk_connected)(tab, &ident))
+ return false;
+
+ return true;
+}
+
+static Cyg_ErrNo
+cf_disk_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ disk_channel *chan = (disk_channel *) (*tab)->priv;
+ return (chan->callbacks->disk_lookup)(tab, sub_tab, name);
+}
+
+static Cyg_ErrNo
+cf_disk_read(disk_channel *chan,
+ void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num)
+{
+ cf_disk_info_t *info = (cf_disk_info_t *)chan->dev_priv;
+
+ D(("CF(%p) read block %d\n", info->base, block_num));
+
+ if (!exe_cmd(info->base, CF_ATA_READ_SECTORS_CMD, 0, block_num, 1))
+ {
+ D(("CF(%p) error (%x)\n", info->base, get_error(info->base)));
+ return -EIO;
+ }
+ read_data(info->base, buf, len);
+
+ return ENOERR;
+}
+
+static Cyg_ErrNo
+cf_disk_write(disk_channel *chan,
+ const void *buf,
+ cyg_uint32 len,
+ cyg_uint32 block_num)
+{
+ cf_disk_info_t *info = (cf_disk_info_t *)chan->dev_priv;
+
+ D(("CF(%p) write block %d\n", info->base, block_num));
+
+ if (!exe_cmd(info->base, CF_ATA_WRITE_SECTORS_CMD, 0, block_num, 1))
+ {
+ D(("CF(%p) error (%x)\n", info->base, get_error(info->base)));
+ return -EIO;
+ }
+ write_data(info->base, buf, len);
+
+ return ENOERR;
+}
+
+static Cyg_ErrNo
+cf_disk_get_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len)
+{
+ return -EINVAL;
+}
+
+static Cyg_ErrNo
+cf_disk_set_config(disk_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len)
+{
+ return -EINVAL;
+}
+
+// ----------------------------------------------------------------------------
+// EOF v85x_edb_v850_disk.c
diff --git a/ecos/packages/devs/eth/amd/lancepci/current/ChangeLog b/ecos/packages/devs/eth/amd/lancepci/current/ChangeLog
new file mode 100644
index 0000000..6462d57
--- /dev/null
+++ b/ecos/packages/devs/eth/amd/lancepci/current/ChangeLog
@@ -0,0 +1,63 @@
+2009-05-25 John Dallaway <john@dallaway.org.uk>
+
+ * src/if_lancepci.c: Fix casting in the use of HAL_PCI_CPU_TO_BUS().
+
+2004-08-12 Jani Monoses <jani@iv.ro>
+
+ * src/if_lancepci.c: Fix builing with lwip.
+
+2004-03-02 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/if_lancepci.c: Added casts to fix various compiler warnings.
+
+2004-02-27 Iztok Zupet <iz@elsis.si>
+
+ * if_lancepci.c: fetch ESA from chips registers instead
+ EEPROM. There seems to be no usable data in the VMware EEPROM
+ emulation. But the data which comes in CSR_PAR registers seems
+ OK.
+
+2003-01-26 Iztok Zupet <iz@vsr.si>
+
+ * if_lancepci.c: added aditional delay (printf) to init
+ function, to fix it under Vmware 4.
+
+2003-01-26 Iztok Zupet <iz@vsr.si>
+
+ * if_lancepci.c: fixed buffer reset after start,
+ added additional delays (50ms)after start and control
+ function, to let Vmware get a tick so that it can
+ service the virtual chip. Added an interrupt controled
+ transmit busy flag (cpd->txbusyh), so that the stop/start
+ function can wait for it, thus not stopping the chip
+ aburptly.
+
+ * amd_lance.h: additional items in cpd data structure.
+
+2002-07-17 Iztok Zupet <iz@vsr.si>
+
+ * all: Cloned from PCnet original
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/amd/lancepci/current/cdl/amd_lancepci_eth_drivers.cdl b/ecos/packages/devs/eth/amd/lancepci/current/cdl/amd_lancepci_eth_drivers.cdl
new file mode 100644
index 0000000..ca947ce
--- /dev/null
+++ b/ecos/packages/devs/eth/amd/lancepci/current/cdl/amd_lancepci_eth_drivers.cdl
@@ -0,0 +1,95 @@
+# ====================================================================
+#
+# amd_lancepci_eth_drivers.cdl
+#
+# Ethernet drivers - support for AMD LANCE PCI (vmWare) ethernet
+# controllers
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov, iz
+# Date: 2002-07-17
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_AMD_LANCEPCI {
+ display "AMD LANCE compatible ethernet driver"
+ description "Ethernet driver for AMD PCI LANCE compatible controllers."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ active_if CYGINT_DEVS_ETH_AMD_LANCEPCI_REQUIRED
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ compile -library=libextras.a if_lancepci.c
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_AMD_LANCEPCI_CFG";
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_AMD_LANCEPCI_DEV_COUNT {
+ display "Number of supported interfaces."
+ calculated { CYGINT_DEVS_ETH_AMD_LANCEPCI_REQUIRED }
+ flavor data
+ description "
+ This option selects the number of PCI ethernet interfaces to
+ be supported by the driver."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_AMD_LANCEPCI_OPTIONS {
+ display "LANCEPCI ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_AMD_LANCEPCI_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the LANCEPCI ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/amd/lancepci/current/src/amd_lance.h b/ecos/packages/devs/eth/amd/lancepci/current/src/amd_lance.h
new file mode 100644
index 0000000..8a155b4
--- /dev/null
+++ b/ecos/packages/devs/eth/amd/lancepci/current/src/amd_lance.h
@@ -0,0 +1,521 @@
+#ifndef CYGONCE_DEVS_ETH_AMD_LANCE_H
+#define CYGONCE_DEVS_ETH_AMD_LANCE_H
+//==========================================================================
+//
+// amd_lance.h
+//
+// AMD Lance Ethernet chip
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, iz
+// Contributors: jskov, hmt, iz
+// Date: 2002-07-17
+// Purpose: Hardware description of AMD Lance series.
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+
+//------------------------------------------------------------------------
+// Get macros from platform header
+#define __WANT_CONFIG
+#include CYGDAT_DEVS_ETH_AMD_LANCEPCI_INL
+#undef __WANT_CONFIG
+
+//------------------------------------------------------------------------
+// Set to perms of:
+// 0 disables all debug output
+// 1 for process debug output
+// 2 for added data IO output: get_reg, put_reg
+// 4 for packet allocation/free output
+// 8 for only startup status, so we can tell we're installed OK
+#define DEBUG 0x0
+
+#if DEBUG & 1
+#define DEBUG_FUNCTION() do { os_printf("%s\n", __FUNCTION__); } while (0)
+#else
+#define DEBUG_FUNCTION() do {} while(0)
+#endif
+
+// ------------------------------------------------------------------------
+// Macros for keeping track of statistics
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+# define KEEP_STATISTICS
+#endif
+
+#ifdef KEEP_STATISTICS
+# define INCR_STAT( _x_ ) (cpd->stats. _x_ ++)
+#else
+# define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
+#endif
+
+//------------------------------------------------------------------------
+// Cache translation
+#ifndef CYGARC_UNCACHED_ADDRESS
+# define CYGARC_UNCACHED_ADDRESS(x) (x)
+#endif
+
+//------------------------------------------------------------------------
+// Address translation
+#ifndef HAL_PCI_CPU_TO_BUS
+# error "HAL PCI support must define translation macros"
+#endif
+
+// ------------------------------------------------------------------------
+// Macros for accessing structure elements
+
+#define _SU8( _base_, _offset_) \
+ *((cyg_uint8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU16( _base_, _offset_) \
+ *((cyg_uint16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU32( _base_, _offset_) \
+ *((cyg_uint32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+#define _SI8( _base_, _offset_) \
+ *((cyg_int8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI16( _base_, _offset_) \
+ *((cyg_int16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI32( _base_, _offset_) \
+ *((cyg_int32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+// ------------------------------------------------------------------------
+// Macros for accessing controller registers
+#ifndef HAL_PCI_IO_READ_UINT8
+# define HAL_PCI_IO_READ_UINT8(addr, datum) HAL_READ_UINT8(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT8(addr, datum) HAL_WRITE_UINT8(addr, datum)
+# define HAL_PCI_IO_READ_UINT16(addr, datum) HAL_READ_UINT16(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT16(addr, datum) HAL_WRITE_UINT16(addr, datum)
+# define HAL_PCI_IO_READ_UINT32(addr, datum) HAL_READ_UINT32(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT32(addr, datum) HAL_WRITE_UINT32(addr, datum)
+#endif
+
+// ------------------------------------------------------------------------
+// IO map registers
+#define LANCE_IO_EEPROM 0x00
+#define LANCE_IO_ID 0x0e
+#define LANCE_IO_RDP 0x10
+#define LANCE_IO_RAP 0x12
+#define LANCE_IO_RESET 0x14
+#define LANCE_IO_BDP 0x16
+
+// The ID of the 79C790 is 0x5757 - that may be different in other
+// (older) cards.
+#define LANCE_IO_ID_KEY 0x5757
+
+// ------------------------------------------------------------------------
+// Controller registers come in three sets: CSR, BCR and ANR. Use
+// high-bits do differentiate, make the put/get functions do the right
+// thing depending the state of these bits.
+#define LANCE_RAP_MASK 0x007f
+//#define LANCE_CSR_FLAG 0x0000 // implied
+#define LANCE_BCR_FLAG 0x0080
+#define LANCE_ANR_FLAG 0x0100
+
+
+// CSR registers
+#define LANCE_CSR_CSCR 0
+#define LANCE_CSR_IBA0 1
+#define LANCE_CSR_IBA1 2
+#define LANCE_CSR_IM 3
+#define LANCE_CSR_TFC 4
+#define LANCE_CSR_ECI 5
+#define LANCE_CSR_LAR0 8
+#define LANCE_CSR_LAR1 9
+#define LANCE_CSR_LAR2 10
+#define LANCE_CSR_LAR3 11
+#define LANCE_CSR_PAR0 12
+#define LANCE_CSR_PAR1 13
+#define LANCE_CSR_PAR2 14
+#define LANCE_CSR_MODE 15
+#define LANCE_CSR_BARRL 24
+#define LANCE_CSR_BARRU 25
+#define LANCE_CSR_BATRL 30
+#define LANCE_CSR_BATRU 31
+#define LANCE_CSR_RRC 72
+#define LANCE_CSR_TRC 74
+#define LANCE_CSR_RRLEN 76
+#define LANCE_CSR_TRLEN 78
+#define LANCE_CSR_ID_LO 88
+#define LANCE_CSR_ID_HI 89
+
+
+#define LANCE_CSR_CSCR_ERR 0x8000
+#define LANCE_CSR_CSCR_RES 0x4000
+#define LANCE_CSR_CSCR_CERR 0x2000
+#define LANCE_CSR_CSCR_MISS 0x1000
+#define LANCE_CSR_CSCR_MERR 0x0800
+#define LANCE_CSR_CSCR_RINT 0x0400
+#define LANCE_CSR_CSCR_TINT 0x0200
+#define LANCE_CSR_CSCR_IDON 0x0100
+#define LANCE_CSR_CSCR_INTR 0x0080
+#define LANCE_CSR_CSCR_IENA 0x0040
+#define LANCE_CSR_CSCR_RXON 0x0020
+#define LANCE_CSR_CSCR_TXON 0x0010
+#define LANCE_CSR_CSCR_TDMD 0x0008
+#define LANCE_CSR_CSCR_STOP 0x0004
+#define LANCE_CSR_CSCR_STRT 0x0002
+#define LANCE_CSR_CSCR_INIT 0x0001
+
+#define LANCE_CSR_CSCR_EV_MASK 0x007f
+
+#define LANCE_CSR_IM_MISSM 0x1000
+#define LANCE_CSR_IM_MERRM 0x0800
+#define LANCE_CSR_IM_RINTM 0x0400
+#define LANCE_CSR_IM_TINTM 0x0200
+#define LANCE_CSR_IM_IDONM 0x0100
+#define LANCE_CSR_IM_DXSUFLO 0x0040
+#define LANCE_CSR_IM_LAPPEN 0x0020
+#define LANCE_CSR_IM_DXMT2PD 0x0010
+#define LANCE_CSR_IM_EMBA 0x0008
+#define LANCE_CSR_IM_BSWP 0x0004
+
+#define LANCE_CSR_TFC_TXDPOLL 0x1000
+#define LANCE_CSR_TFC_APAD_XMT 0x0800
+#define LANCE_CSR_TFC_ASTRP_RCV 0x0400
+#define LANCE_CSR_TFC_MFCO 0x0200
+#define LANCE_CSR_TFC_MFCOM 0x0100
+#define LANCE_CSR_TFC_UINTCMD 0x0080
+#define LANCE_CSR_TFC_UINT 0x0040
+#define LANCE_CSR_TFC_RCVCCO 0x0020
+#define LANCE_CSR_TFC_RCVCCOM 0x0010
+#define LANCE_CSR_TFC_TXSTRT 0x0008
+#define LANCE_CSR_TFC_TXSTRTM 0x0004
+
+#define LANCE_CSR_ECI_TOKINTD 0x8000
+#define LANCE_CSR_ECI_LTINTEN 0x4000
+#define LANCE_CSR_ECI_SINT 0x0800
+#define LANCE_CSR_ECI_SINTE 0x0400
+#define LANCE_CSR_ECI_EXDINT 0x0080
+#define LANCE_CSR_ECI_EXDINTE 0x0040
+#define LANCE_CSR_ECI_MPPLBA 0x0020
+#define LANCE_CSR_ECI_MPINT 0x0010
+#define LANCE_CSR_ECI_MPINTE 0x0008
+#define LANCE_CSR_ECI_MPEN 0x0004
+#define LANCE_CSR_ECI_MPMODE 0x0002
+#define LANCE_CSR_ECI_SPND 0x0001
+
+#define LANCE_CSR_MODE_PROM 0x8000
+#define LANCE_CSR_MODE_DRCVBC 0x4000
+#define LANCE_CSR_MODE_DRCVPA 0x2000
+#define LANCE_CSR_MODE_PORTSEL 0x0180
+#define LANCE_CSR_MODE_INTL 0x0040
+#define LANCE_CSR_MODE_DRTY 0x0020
+#define LANCE_CSR_MODE_FCOLL 0x0010
+#define LANCE_CSR_MODE_DXMTFCS 0x0008
+#define LANCE_CSR_MODE_LOOP 0x0004
+#define LANCE_CSR_MODE_DTX 0x0002
+#define LANCE_CSR_MODE_DRX 0x0001
+
+// BCR registers
+#define LANCE_BCR_SWSTYLE (20 |LANCE_BCR_FLAG)
+#define LANCE_BCR_MIIADDR (33 |LANCE_BCR_FLAG)
+#define LANCE_BCR_MIIDATA (34 |LANCE_BCR_FLAG)
+
+#define LANCE_BCR_MIIADDR_PHYAD 0x03e0
+
+
+//----------------------------------------------------------------------------
+// Receive buffer Descriptor
+#if 1
+#define LANCE_RD_PTR 0x00 // 32 bit
+#define LANCE_RD_BLEN 0x04 // 16 bit (2's complement, negative)
+#define LANCE_RD_MLEN 0x06 // 16 bit
+#define LANCE_RD_SIZE 0x08
+
+#define LANCE_RD_PTR_OWN 0x80000000
+#define LANCE_RD_PTR_ERR 0x40000000
+#define LANCE_RD_PTR_FRAM 0x20000000
+#define LANCE_RD_PTR_OFLO 0x10000000
+#define LANCE_RD_PTR_CRC 0x08000000
+#define LANCE_RD_PTR_BUFF 0x04000000
+#define LANCE_RD_PTR_STP 0x02000000
+#define LANCE_RD_PTR_ENP 0x01000000
+#define LANCE_RD_PTR_MASK 0x00ffffff
+#else
+
+#define LANCE_RD_PTR 0x00
+#define LANCE_RD_BLEN 0x04
+#define LANCE_RD_MLEN 0x08
+#define LANCE_RD_USER 0x0c
+#define LANCE_RD_SIZE 0x10
+
+#define LANCE_RD_BLEN_OWN 0x80000000
+#define LANCE_RD_BLEN_ERR 0x40000000
+#define LANCE_RD_BLEN_FRAM 0x20000000
+#define LANCE_RD_BLEN_OFLO 0x10000000
+#define LANCE_RD_BLEN_CRC 0x08000000
+#define LANCE_RD_BLEN_BUFF 0x04000000
+#define LANCE_RD_BLEN_STP 0x02000000
+#define LANCE_RD_BLEN_ENP 0x01000000
+#define LANCE_RD_BLEN_BPE 0x00800000
+#define LANCE_RD_BLEN_PAM 0x00400000
+#define LANCE_RD_BLEN_LAFM 0x00200000
+#define LANCE_RD_BLEN_BAM 0x00100000
+#define LANCE_RD_BLEN_MASK 0x0000ffff
+#endif
+
+// Transmit buffer Descriptor
+#if 1
+#define LANCE_TD_PTR 0x00 // 32 bit
+#define LANCE_TD_LEN 0x04 // 16 bit (2's complement, negative)
+#define LANCE_TD_MISC 0x06 // 16 bit
+#define LANCE_TD_SIZE 0x08
+
+#define LANCE_TD_PTR_OWN 0x80000000
+#define LANCE_TD_PTR_ERR 0x40000000
+#define LANCE_TD_PTR_ADD_FCS 0x20000000
+#define LANCE_TD_PTR_MORE 0x10000000
+#define LANCE_TD_PTR_ONE 0x08000000
+#define LANCE_TD_PTR_DEF 0x04000000
+#define LANCE_TD_PTR_STP 0x02000000
+#define LANCE_TD_PTR_ENP 0x01000000
+#define LANCE_TD_PTR_MASK 0x00ffffff
+#else
+#define LANCE_TD_PTR 0x00
+#define LANCE_TD_LEN 0x04
+#define LANCE_TD_MISC 0x08
+#define LANCE_TD_USER 0x0c
+#define LANCE_TD_SIZE 0x10
+
+#define LANCE_TD_LEN_OWN 0x80000000
+#define LANCE_TD_LEN_ERR 0x40000000
+#define LANCE_TD_LEN_ADD_FCS 0x20000000
+#define LANCE_TD_LEN_MORE 0x10000000
+#define LANCE_TD_LEN_ONE 0x08000000
+#define LANCE_TD_LEN_DEF 0x04000000
+#define LANCE_TD_LEN_STP 0x02000000
+#define LANCE_TD_LEN_ENP 0x01000000
+#define LANCE_TD_LEN_BPE 0x00800000
+#define LANCE_TD_LEN_MASK 0x0000ffff
+
+#define LANCE_TD_FLAGS_BUFF 0x80000000
+#define LANCE_TD_FLAGS_UFLO 0x40000000
+#define LANCE_TD_FLAGS_EX_DEF 0x20000000
+#define LANCE_TD_FLAGS_LCOL 0x10000000
+#define LANCE_TD_FLAGS_LCAR 0x08000000
+#define LANCE_TD_FLAGS_RTRY 0x04000000
+#define LANCE_TD_FLAGS_TRC_MASK 0x0000000f
+#endif
+
+
+#define LANCE_TD_MISC_BUFF 0x8000
+#define LANCE_TD_MISC_UFLO 0x4000
+#define LANCE_TD_MISC_EXDEF 0x2000
+#define LANCE_TD_MISC_LCOL 0x1000
+#define LANCE_TD_MISC_LCAR 0x0800
+#define LANCE_TD_MISC_RTRY 0x0400
+#define LANCE_TD_MISC_TDR 0x03ff
+
+// Initialization Buffer
+#define LANCE_IB_MODE 0
+#define LANCE_IB_PADR0 2
+#define LANCE_IB_PADR1 4
+#define LANCE_IB_PADR2 6
+#define LANCE_IB_LADRF0 8
+#define LANCE_IB_LADRF1 10
+#define LANCE_IB_LADRF2 12
+#define LANCE_IB_LADRF3 14
+#define LANCE_IB_RDRA 16
+#define LANCE_IB_TDRA 20
+#define LANCE_IB_SIZE 24
+
+#define LANCE_IB_TDRA_CNT_shift 29
+#define LANCE_IB_TDRA_PTR_mask 0x00ffffff
+#define LANCE_IB_RDRA_CNT_shift 29
+#define LANCE_IB_RDRA_PTR_mask 0x00ffffff
+
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+struct amd_lancepci_stats {
+ unsigned int tx_good ;
+ unsigned int tx_max_collisions ;
+ unsigned int tx_late_collisions ;
+ unsigned int tx_underrun ;
+ unsigned int tx_carrier_loss ;
+ unsigned int tx_deferred ;
+ unsigned int tx_sqetesterrors ;
+ unsigned int tx_single_collisions;
+ unsigned int tx_mult_collisions ;
+ unsigned int tx_total_collisions ;
+ unsigned int rx_good ;
+ unsigned int rx_crc_errors ;
+ unsigned int rx_align_errors ;
+ unsigned int rx_resource_errors ;
+ unsigned int rx_overrun_errors ;
+ unsigned int rx_collisions ;
+ unsigned int rx_short_frames ;
+ unsigned int rx_too_long_frames ;
+ unsigned int rx_symbol_errors ;
+ unsigned int interrupts ;
+ unsigned int rx_count ;
+ unsigned int rx_deliver ;
+ unsigned int rx_resource ;
+ unsigned int rx_restart ;
+ unsigned int tx_count ;
+ unsigned int tx_complete ;
+ unsigned int tx_dropped ;
+};
+#endif
+
+typedef struct lancepci_priv_data {
+ int index;
+ cyg_uint8 // (split up for atomic byte access)
+ found:1, // was hardware discovered?
+ mac_addr_ok:1, // can we bring up?
+ active:1, // has this if been brung up?
+ hardwired_esa:1, // set if ESA is hardwired via CDL
+ txbusy:1, // A packet has been sent
+ txbusyh:1, // A packet has been sent for HW
+ spare1:2;
+
+ cyg_uint16 event;
+
+ unsigned long txkey; // Used to ack when packet sent
+ unsigned char* base; // Base address of controller EPROM region
+ int interrupt; // Interrupt vector used by controller
+ unsigned char esa[6]; // Controller ESA
+ // Function to configure the ESA - may fetch ESA from EPROM or
+ // RedBoot config option.
+ void (*config_esa)(struct lancepci_priv_data* cpd);
+ void *ndp; // Network Device Pointer
+
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+ int devid;
+
+ cyg_uint8* rx_buffers; // ptr to base of buffer mem
+ cyg_uint8* rx_ring; // ptr to base of rx ring memory
+ int rx_ring_cnt; // number of entries in ring
+ int rx_ring_log_cnt; // log of above
+ int rx_ring_next; // index of next full ring entry
+
+ cyg_uint8* tx_buffers;
+ cyg_uint8* tx_ring;
+ int tx_ring_cnt;
+ int tx_ring_log_cnt;
+ int tx_ring_free; // index of next free ring entry
+ int tx_ring_alloc; // index of first controller owned ring
+ int tx_ring_owned; // number of controller owned ring entries
+
+ int rxpacket;
+#ifdef KEEP_STATISTICS
+ struct amd_lancepci_stats stats;
+#endif
+#if DEBUG & 1
+ cyg_uint32 txd;
+#endif
+ cyg_uint8* init_table; // lance init table pointer
+
+} lancepci_priv_data;
+
+// ------------------------------------------------------------------------
+
+static __inline__ cyg_uint16
+get_reg(struct eth_drv_sc *sc, int regno)
+{
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+ cyg_uint16 val, addr;
+
+ if (regno & LANCE_ANR_FLAG) {
+ // We could do this with recursive calls to get/put reg
+ // functions, but might as well just do it directly.
+ // First set ANR address
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, LANCE_BCR_MIIADDR & LANCE_RAP_MASK);
+ HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_BDP, addr);
+ addr &= LANCE_BCR_MIIADDR_PHYAD;
+ addr |= (regno & LANCE_RAP_MASK);
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_BDP, addr);
+ // Then read ANR register data
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, LANCE_BCR_MIIDATA & LANCE_RAP_MASK);
+ HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_BDP, val);
+ } else {
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, regno & LANCE_RAP_MASK);
+ if (regno & LANCE_BCR_FLAG)
+ HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_BDP, val);
+ else
+ HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_RDP, val);
+ }
+#if DEBUG & 2
+ os_printf("read %s reg %d val 0x%04x\n",
+ (regno & LANCE_ANR_FLAG) ? "anr" : (regno & LANCE_BCR_FLAG) ? "bcr" : "csr",
+ regno & LANCE_RAP_MASK, val);
+#endif
+ return val;
+}
+
+static __inline__ void
+put_reg(struct eth_drv_sc *sc, int regno, cyg_uint16 val)
+{
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+ cyg_uint16 addr;
+
+ if (regno & LANCE_ANR_FLAG) {
+ // We could do this with recursive calls to get/put reg
+ // functions, but might as well just do it directly.
+ // First set ANR address
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, LANCE_BCR_MIIADDR & LANCE_RAP_MASK);
+ HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_BDP, addr);
+ addr &= LANCE_BCR_MIIADDR_PHYAD;
+ addr |= (regno & LANCE_RAP_MASK);
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_BDP, addr);
+ // Then write ANR register data
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, LANCE_BCR_MIIDATA & LANCE_RAP_MASK);
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_BDP, val);
+ } else {
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RAP, regno & LANCE_RAP_MASK);
+ if (regno & LANCE_BCR_FLAG)
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_BDP, val);
+ else
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+LANCE_IO_RDP, val);
+ }
+
+#if DEBUG & 2
+ os_printf("write %s reg %d val 0x%04x\n",
+ (regno & LANCE_ANR_FLAG) ? "anr" : (regno & LANCE_BCR_FLAG) ? "bcr" : "csr",
+ regno & LANCE_RAP_MASK, val);
+#endif
+}
+
+// ------------------------------------------------------------------------
+#endif // CYGONCE_DEVS_ETH_AMD_LANCE_H
+// EOF amd_lance.h
diff --git a/ecos/packages/devs/eth/amd/lancepci/current/src/if_lancepci.c b/ecos/packages/devs/eth/amd/lancepci/current/src/if_lancepci.c
new file mode 100644
index 0000000..08ef8b1
--- /dev/null
+++ b/ecos/packages/devs/eth/amd/lancepci/current/src/if_lancepci.c
@@ -0,0 +1,1312 @@
+//==========================================================================
+//
+// dev/if_lancepci.c
+//
+// Ethernet device driver for AMD PCI Lance (for instance vmWare VLANCE)
+// compatible controllers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, based on lan91cxx driver by hmt & jskov, iz
+// Contributors: gthomas, jskov, hmt, iz
+// Date: 2002-07-17, 2003-01-26
+// Purpose:
+// Description: hardware driver for AMD Lance PCI (and possibly PCnet)
+// and wmWare VLANCE ethernet
+// Notes: The controller is used in its 16bit mode. That means that
+// all addresses are 24bit only - and that all controller
+// accessed memory must be within the same 16MB region
+// (starting at 0 on older controllers).
+//
+// The KEEP_STATISTICS code is not implemented yet. Look
+// for FIXME macro.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+//#####VMWAREDESCRIPTIONBEGIN####
+//
+// Notes: The vmWare VLACNCE virtual controller does not seem to do
+// anything about SUSPEND and seems it must be reinitialized after
+// every STOP. In addition it lacks some registers.
+//
+// Sometimes, the driver must wait to let Vmware get a tick, to
+// process the chip initialization and control functions!!!
+//
+// That's the reason for not patching the PCnet driver
+// but cloning a special one from it.
+//
+//
+//####VMWAREDESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_amd_lancepci.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h> // delays
+#include <string.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <cyg/kernel/kapi.h>
+#include <net/if.h> // Needed for struct ifnet
+#include <pkgconf/io_eth_drivers.h>
+#endif
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#ifdef CYGPKG_IO_PCI
+#include <cyg/io/pci.h>
+#else
+#error "Need PCI package here"
+#endif
+
+#define FIXME 0
+
+#define _BUF_SIZE 1544
+
+#ifdef CYGPKG_INFRA_DEBUG
+// Then we log, OOI, the number of times we get a bad packet number
+// from the tx done fifo.
+int lancepci_txfifo_good = 0;
+int lancepci_txfifo_bad = 0;
+#endif
+
+#include "amd_lance.h"
+#define __WANT_DEVS
+#include CYGDAT_DEVS_ETH_AMD_LANCEPCI_INL
+#undef __WANT_DEVS
+
+//#define DEBUG 0xff
+
+#if defined(CYGPKG_REDBOOT)
+
+static void db_printf( char *fmt, ... )
+{
+ extern int start_console(void);
+ extern void end_console(int);
+ va_list a;
+ int old_console;
+ va_start( a, fmt );
+ old_console = start_console();
+ diag_vprintf( fmt, a );
+ end_console(old_console);
+ va_end( a );
+}
+
+#else
+
+#define db_printf diag_printf
+
+#endif
+
+
+static struct eth_drv_sc *oursc; //a dummy sc pointer
+
+static void lancepci_poll(struct eth_drv_sc *sc);
+
+
+// This ISR is called when the ethernet interrupt occurs
+static cyg_uint32
+lancepci_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct lancepci_priv_data *cpd = (struct lancepci_priv_data *)data;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( interrupts );
+ cpd->event = get_reg(oursc, LANCE_CSR_CSCR);
+ if (cpd->event & LANCE_CSR_CSCR_TINT)
+ cpd->txbusyh=0; // take care of HW txbusy flag
+ cyg_drv_interrupt_mask(cpd->interrupt);
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+static void
+lancepci_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ // This conditioning out is necessary because of explicit calls to this
+ // DSR - which would not ever be called in the case of a polled mode
+ // usage ie. in RedBoot.
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ struct lancepci_priv_data* cpd = (struct lancepci_priv_data *)data;
+ struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->ndp);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ // but here, it must be a *sc:
+ eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+#else
+# ifndef CYGPKG_REDBOOT
+# error Empty lancepci ethernet DSR is compiled. Is this what you want?
+# endif
+#endif
+}
+
+
+// The deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+lancepci_deliver(struct eth_drv_sc *sc)
+{
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ // Service the interrupt:
+ lancepci_poll(sc);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+}
+
+static int
+lancepci_int_vector(struct eth_drv_sc *sc)
+{
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+
+ return (cpd->interrupt);
+}
+
+// ------------------------------------------------------------------------
+// Memory management
+//
+// Simply carve off from the front of the PCI mapped window into real memory
+static cyg_uint32 lancepci_heap_size;
+static cyg_uint8 *lancepci_heap_base;
+static cyg_uint8 *lancepci_heap_free;
+
+static void*
+pciwindow_mem_alloc(int size)
+{
+ void *p_memory;
+ int _size = size;
+
+ CYG_ASSERT(
+ (CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE <= (int)lancepci_heap_free)
+ &&
+ ((CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE +
+ CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE) > (int)lancepci_heap_free)
+ &&
+ (0 < lancepci_heap_size)
+ &&
+ (CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE >= lancepci_heap_size)
+ &&
+ (CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE == (int)lancepci_heap_base),
+ "Heap variables corrupted" );
+
+ p_memory = (void *)0;
+ size = (size + 3) & ~3;
+ if ( (lancepci_heap_free+size) < (lancepci_heap_base+lancepci_heap_size) ) {
+ cyg_uint32 *p;
+ p_memory = (void *)lancepci_heap_free;
+ lancepci_heap_free += size;
+ for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 )
+ *p++ = 0;
+ }
+
+#if DEBUG & 9
+ db_printf("Allocated %d bytes at 0x%08x\n", size, p_memory);
+#endif
+
+ return p_memory;
+}
+
+static cyg_pci_match_func find_lancepci_match_func;
+
+static cyg_bool
+find_lancepci_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+{
+#if DEBUG & 9
+ db_printf("PCI match vendor 0x%04x device 0x%04x\n", v, d);
+#endif
+ return (0x1022 == v) && (0x2000 == d);
+}
+
+static int
+pci_init_find_lancepci( void )
+{
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+ cyg_uint16 cmd;
+ int device_index;
+ int found_devices = 0;
+
+ DEBUG_FUNCTION();
+
+#ifdef CYGARC_UNCACHED_ADDRESS
+ CYG_ASSERT( CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) ==
+ CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE,
+ "PCI window configured does not match PCI memory section base" );
+#else
+ CYG_ASSERT( (CYG_ADDRWORD)CYGMEM_SECTION_pci_window ==
+ CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE,
+ "PCI window configured does not match PCI memory section base" );
+#endif
+ CYG_ASSERT( CYGMEM_SECTION_pci_window_SIZE ==
+ CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE,
+ "PCI window configured does not match PCI memory section size" );
+
+ if (
+#ifdef CYGARC_UNCACHED_ADDRESS
+ CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) !=
+#else
+ (CYG_ADDRWORD)CYGMEM_SECTION_pci_window !=
+#endif
+ (CYG_ADDRWORD)CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE
+ ||
+ CYGMEM_SECTION_pci_window_SIZE !=
+ CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE ) {
+#if DEBUG & 8
+ db_printf("pci_init_find_lancepci(): PCI window misconfigured\n");
+#endif
+ return 0;
+ }
+
+ // First initialize the heap in PCI window'd memory
+ lancepci_heap_size = CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE;
+ lancepci_heap_base = (cyg_uint8 *)CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE;
+ lancepci_heap_free = lancepci_heap_base;
+#if DEBUG & 9
+ db_printf("pcimem : 0x%08x size: 0x%08x\n", lancepci_heap_base, lancepci_heap_size);
+#endif
+
+ cyg_pci_init();
+#if DEBUG & 8
+ db_printf("Finished cyg_pci_init();\n");
+#endif
+
+ devid = CYG_PCI_NULL_DEVID;
+
+ for (device_index = 0;
+ device_index < CYGNUM_DEVS_ETH_AMD_LANCEPCI_DEV_COUNT;
+ device_index++) {
+ struct lancepci_priv_data* cpd = lancepci_priv_array[device_index];
+
+ cpd->index = device_index;
+
+ // See above for find_lancepci_match_func - it selects any of several
+ // variants. This is necessary in case we have multiple mixed-type
+ // devices on one board in arbitrary orders.
+ if (cyg_pci_find_matching( &find_lancepci_match_func, NULL, &devid )) {
+#if DEBUG & 8
+ db_printf("eth%d = lancepci\n", device_index);
+#endif
+ cyg_pci_get_device_info(devid, &dev_info);
+
+ cpd->interrupt_handle = 0; // Flag not attached.
+ if (cyg_pci_translate_interrupt(&dev_info, &cpd->interrupt)) {
+#if DEBUG & 8
+ db_printf(" Wired to HAL vector %d\n", cpd->interrupt);
+#endif
+ cyg_drv_interrupt_create(
+ cpd->interrupt,
+ 1, // Priority - unused
+ (cyg_addrword_t)cpd,// Data item passed to ISR & DSR
+ lancepci_isr, // ISR
+ lancepci_dsr, // DSR
+ &cpd->interrupt_handle, // handle to intr obj
+ &cpd->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(cpd->interrupt_handle);
+
+ // Don't unmask the interrupt yet, that could get us into a
+ // race.
+ }
+ else {
+ cpd->interrupt = 0;
+#if DEBUG & 8
+ db_printf(" Does not generate interrupts.\n");
+#endif
+ }
+
+ if (cyg_pci_configure_device(&dev_info)) {
+#if DEBUG & 8
+ int i;
+ db_printf("Found device on bus %d, devfn 0x%02x:\n",
+ CYG_PCI_DEV_GET_BUS(devid),
+ CYG_PCI_DEV_GET_DEVFN(devid));
+
+ if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
+ db_printf(" Note that board is active. Probed"
+ " sizes and CPU addresses invalid!\n");
+ }
+ db_printf(" Vendor 0x%04x", dev_info.vendor);
+ db_printf("\n Device 0x%04x", dev_info.device);
+ db_printf("\n Command 0x%04x, Status 0x%04x\n",
+ dev_info.command, dev_info.status);
+
+ db_printf(" Class/Rev 0x%08x", dev_info.class_rev);
+ db_printf("\n Header 0x%02x\n", dev_info.header_type);
+
+ db_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+ dev_info.header.normal.sub_vendor,
+ dev_info.header.normal.sub_id);
+
+ for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
+ db_printf(" BAR[%d] 0x%08x /", i, dev_info.base_address[i]);
+ db_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
+ dev_info.base_size[i], dev_info.base_map[i]);
+ }
+ db_printf(" eth%d configured\n", device_index);
+#endif
+ found_devices++;
+ cpd->found = 1;
+ cpd->active = 0;
+ cpd->devid = devid;
+ cpd->base = (unsigned char*) dev_info.base_map[0];
+#if DEBUG & 8
+ db_printf(" I/O address = 0x%08x\n", cpd->base);
+#endif
+
+ // Don't use cyg_pci_set_device_info since it clears
+ // some of the fields we want to print out below.
+ cyg_pci_read_config_uint16(dev_info.devid,
+ CYG_PCI_CFG_COMMAND, &cmd);
+ cmd |= (CYG_PCI_CFG_COMMAND_IO // enable I/O space
+ | CYG_PCI_CFG_COMMAND_MEMORY // enable memory space
+ | CYG_PCI_CFG_COMMAND_MASTER); // enable bus master
+ cyg_pci_write_config_uint16(dev_info.devid,
+ CYG_PCI_CFG_COMMAND, cmd);
+
+ // This is the indicator for "uses an interrupt"
+ if (cpd->interrupt_handle != 0) {
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+#if DEBUG & 8
+ db_printf(" Enabled interrupt %d\n", cpd->interrupt);
+#endif
+ }
+#if DEBUG & 8
+ db_printf(" **** Device enabled for I/O and Memory "
+ "and Bus Master\n");
+#endif
+ }
+ else {
+ cpd->found = 0;
+ cpd->active = 0;
+#if DEBUG & 8
+ db_printf("Failed to configure device %d\n", device_index);
+#endif
+ }
+ }
+ else {
+ cpd->found = 0;
+ cpd->active = 0;
+#if DEBUG & 8
+ db_printf("eth%d not found\n", device_index);
+#endif
+ }
+ }
+
+ if (0 == found_devices)
+ return 0;
+
+ return 1;
+}
+
+
+static bool
+amd_lancepci_init(struct cyg_netdevtab_entry *tab)
+{
+ static int initialized = 0; // only probe PCI et al *once*
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+ cyg_uint16 val;
+ cyg_uint32 b;
+ cyg_uint8* p;
+ cyg_uint8* d;
+ int i;
+
+ DEBUG_FUNCTION();
+
+ if ( 0 == initialized++ ) {
+ // then this is the first time ever:
+ if ( ! pci_init_find_lancepci() ) {
+#if DEBUG & 8
+ db_printf( "pci_init_find_lancepci failed" );
+#endif
+ return false;
+ }
+ }
+
+ // If this device is not present, exit
+ if (0 == cpd->found)
+ return 0;
+
+#if DEBUG & 8
+ db_printf("lancepci at base 0x%08x, EEPROM key 0x%04x\n",
+ cpd->base, _SU16(cpd->base, LANCE_IO_ID));
+#endif
+
+#if 0
+ // FIXME: Doesn't work with non-conforming EEPROMS
+ if (LANCE_IO_ID_KEY != _SU16(cpd->base, LANCE_IO_ID) ) {
+ db_printf("Lance EPROM key not found\n");
+ return false;
+ }
+#endif
+
+#if DEBUG & 9
+ db_printf("pcimem : %08x size: %08x\n", lancepci_heap_base, lancepci_heap_size);
+#endif
+
+ // Prepare ESA
+ if (!cpd->hardwired_esa) {
+ // Don't use the address from the EEPROM for VMware
+ // Use the address that VMware prepares in CSR_PAR registers
+ // if You want to be able to use NAT networking. (iz@elsis.si Feb 27 04)
+ //
+ // p = cpd->base + LANCE_IO_EEPROM;
+ // for (i = 0; i < 6; i++)
+ // cpd->esa[i] = *p++;
+ put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);
+ for (i = 0; i < sizeof(cpd->esa); i += 2) {
+ cyg_uint16 z = get_reg(sc, LANCE_CSR_PAR0+i/2 );
+ cpd->esa[i] = (cyg_uint8)(0xff & z);
+ cpd->esa[i+1] = (cyg_uint8)(0xff & (z >> 8));
+ }
+
+ }
+#if DEBUG & 9
+ db_printf("Lance - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ (cpd->hardwired_esa) ? "static" : "eeprom",
+ cpd->esa[0], cpd->esa[1], cpd->esa[2],
+ cpd->esa[3], cpd->esa[4], cpd->esa[5] );
+#endif
+
+
+ // Prepare RX and TX rings
+ p = cpd->rx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->rx_ring_log_cnt)*LANCE_RD_SIZE));
+ memset(cpd->rx_ring,0,(1<<cpd->rx_ring_log_cnt)*LANCE_RD_SIZE);
+
+ d = cpd->rx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->rx_ring_cnt));
+ memset(cpd->rx_buffers,0,_BUF_SIZE*cpd->rx_ring_cnt);
+
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)d, b);
+ _SU32(p, LANCE_RD_PTR) = (b & LANCE_RD_PTR_MASK) | LANCE_RD_PTR_OWN;
+ _SU16(p, LANCE_RD_BLEN) = (-_BUF_SIZE);
+ p += LANCE_RD_SIZE;
+ d += _BUF_SIZE;
+ }
+ cpd->rx_ring_next = 0;
+
+ p = cpd->tx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->tx_ring_log_cnt)*LANCE_TD_SIZE));
+ memset(cpd->tx_ring,0,(1<<cpd->tx_ring_log_cnt)*LANCE_TD_SIZE);
+
+ d = cpd->tx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->tx_ring_cnt));
+ for (i = 0; i < cpd->tx_ring_cnt; i++) {
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)d, b);
+ _SU32(p, LANCE_RD_PTR) = b & LANCE_TD_PTR_MASK;
+ p += LANCE_TD_SIZE;
+ d += _BUF_SIZE;
+ }
+ cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;
+
+ // Initialization table
+ cpd->init_table = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(LANCE_IB_SIZE));
+ _SU16(cpd->init_table, LANCE_IB_MODE) = 0x0000;
+ for (i = 0; i < 6; i++)
+ _SU8(cpd->init_table, LANCE_IB_PADR0+i) = cpd->esa[i];
+ for (i = 0; i < 8; i++)
+ _SU8(cpd->init_table, LANCE_IB_LADRF0+i) = 0;
+
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->rx_ring, b);
+ _SU32(cpd->init_table, LANCE_IB_RDRA) = ((b & LANCE_IB_RDRA_PTR_mask)
+ | (cpd->rx_ring_log_cnt << LANCE_IB_RDRA_CNT_shift));
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->tx_ring, b);
+ _SU32(cpd->init_table, LANCE_IB_TDRA) = ((b & LANCE_IB_TDRA_PTR_mask)
+ | (cpd->tx_ring_log_cnt << LANCE_IB_TDRA_CNT_shift));
+
+#if DEBUG & 9
+ db_printf("Loading up lance controller from table at 0x%08x\n", cpd->init_table);
+ db_printf(" Mode 0x%04x\n", _SU16(cpd->init_table, LANCE_IB_MODE));
+ db_printf(" PADR %02x:%02x:%02x:%02x:%02x:%02x ",
+ _SU8(cpd->init_table, LANCE_IB_PADR0+0), _SU8(cpd->init_table, LANCE_IB_PADR0+1),
+ _SU8(cpd->init_table, LANCE_IB_PADR0+2), _SU8(cpd->init_table, LANCE_IB_PADR0+3),
+ _SU8(cpd->init_table, LANCE_IB_PADR0+4), _SU8(cpd->init_table, LANCE_IB_PADR0+5));
+ db_printf("LADR %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ _SU8(cpd->init_table, LANCE_IB_LADRF0+0), _SU8(cpd->init_table, LANCE_IB_LADRF0+1),
+ _SU8(cpd->init_table, LANCE_IB_LADRF0+2), _SU8(cpd->init_table, LANCE_IB_LADRF0+3),
+ _SU8(cpd->init_table, LANCE_IB_LADRF0+4), _SU8(cpd->init_table, LANCE_IB_LADRF0+5),
+ _SU8(cpd->init_table, LANCE_IB_LADRF0+5), _SU8(cpd->init_table, LANCE_IB_LADRF0+7));
+ db_printf(" RX 0x%08x (len %d) TX 0x%08x (len %d)\n",
+ _SU32(cpd->init_table, LANCE_IB_RDRA) & 0x1fffffff,
+ (_SU32(cpd->init_table, LANCE_IB_RDRA) >> LANCE_IB_RDRA_CNT_shift) & 7,
+ _SU32(cpd->init_table, LANCE_IB_TDRA) & 0x1fffffff,
+ (_SU32(cpd->init_table, LANCE_IB_TDRA) >> LANCE_IB_TDRA_CNT_shift) & 7);
+#endif
+
+ // Reset chip
+ HAL_PCI_IO_READ_UINT16(cpd->base+LANCE_IO_RESET, val);
+
+ // Load up chip with buffers.
+ // Note: There is a 16M limit on the addresses used by the driver
+ // since the top 8 bits of the init_table address is appended to
+ // all other addresses used by the controller.
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->init_table, b);
+ put_reg(sc, LANCE_CSR_IBA0, (b >> 0) & 0xffff);
+ put_reg(sc, LANCE_CSR_IBA1, (b >> 16) & 0xffff);
+ // Disable automatic TX polling (_send will force a poll), pad
+ // XT frames to legal length, mask status interrupts.
+ put_reg(sc, LANCE_CSR_TFC, (LANCE_CSR_TFC_TXDPOLL | LANCE_CSR_TFC_APAD_XMT
+ | LANCE_CSR_TFC_MFCOM | LANCE_CSR_TFC_RCVCCOM
+ | LANCE_CSR_TFC_TXSTRTM));
+ // Recover after TX FIFO underflow
+ put_reg(sc, LANCE_CSR_IM, LANCE_CSR_IM_DXSUFLO);
+ // Initialize controller - load up init_table
+ put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_INIT);
+ while (0 == (get_reg(sc, LANCE_CSR_CSCR) & LANCE_CSR_CSCR_IDON));
+
+ // Stop controller
+ put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);
+
+#if DEBUG & 9
+ db_printf("lancepci controller state is now:\n");
+ db_printf(" Mode 0x%04x TFC 0x%04x\n", _SU16(cpd->init_table, LANCE_IB_MODE), get_reg(sc, LANCE_CSR_TFC));
+ db_printf(" PADR %04x:%04x:%04x ",
+ get_reg(sc, LANCE_CSR_PAR0),
+ get_reg(sc, LANCE_CSR_PAR1),
+ get_reg(sc, LANCE_CSR_PAR2));
+ db_printf("LADR %04x:%04x:%04x:%04x\n",
+ get_reg(sc, LANCE_CSR_LAR0),
+ get_reg(sc, LANCE_CSR_LAR1),
+ get_reg(sc, LANCE_CSR_LAR2),
+ get_reg(sc, LANCE_CSR_LAR3));
+ db_printf(" RX 0x%04x%04x (len 0x%04x) TX 0x%04x%04x (len 0x%04x)\n",
+ get_reg(sc, LANCE_CSR_BARRU), get_reg(sc, LANCE_CSR_BARRL),
+ get_reg(sc, LANCE_CSR_RRLEN),
+ get_reg(sc, LANCE_CSR_BATRU), get_reg(sc, LANCE_CSR_BATRL),
+ get_reg(sc, LANCE_CSR_TRLEN));
+
+ val = get_reg(sc, LANCE_CSR_ID_LO);
+ db_printf("lancepci ID 0x%04x (%s) ",
+ val,
+ (0x5003 == val) ? "Am79C973" : (0x7003 == val) ? "Am79C975" :
+ (0x1003 == val) ? "Am79C900 or wmWare VLANCE" : "Unknown");
+ val = get_reg(sc, LANCE_CSR_ID_HI);
+ db_printf("Part IDU 0x%03x Silicon rev %d\n",
+ val & 0x0fff, (val >> 12) & 0xf);
+#endif
+ // and record the net dev pointer
+ cpd->ndp = (void *)tab;
+ cpd->active = 0;
+ oursc=sc;
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, cpd->esa);
+ cpd->txbusyh=cpd->txbusy=0;
+ cpd->event=0;
+ db_printf("Lancepci driver loaded and Init Done\n");
+ return true;
+}
+
+static void
+lancepci_stop(struct eth_drv_sc *sc)
+{
+ cyg_uint32 b;
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+ if (!cpd->active)
+ return;
+ if (cpd->txbusyh) {
+#if DEBUG & 9
+ db_printf("Lancepci-stop:waiting for tx empty\n");
+#endif
+ b=100;
+ while (cpd->txbusyh && b) {
+ CYGACC_CALL_IF_DELAY_US(200);
+ b--;
+ }
+ }
+ put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);
+ cpd->active = 0;
+#if DEBUG & 9
+ db_printf("Lancepci-stop:done\n");
+#endif
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+lancepci_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ cyg_uint16 reg;
+ cyg_uint32 b;
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+#ifdef CYGPKG_NET
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+ DEBUG_FUNCTION();
+
+ // If device is already active, stop it
+#if DEBUG & 9
+ db_printf("Lancepci-start:entered\n");
+#endif
+ if (cpd->active)
+ {
+ if (cpd->txbusyh) {
+#if DEBUG & 9
+ db_printf("Lancepci-start:waiting for tx empty\n");
+#endif
+ b=100;
+ while (cpd->txbusyh && b) {
+ CYGACC_CALL_IF_DELAY_US(200);
+ b--;
+ }
+ }
+ put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_STOP);
+ cpd->active = 0;
+#if DEBUG & 9
+ db_printf("Lancepci-start:stopped\n");
+#endif
+ }
+ CYGACC_CALL_IF_DELAY_US(200);
+
+#ifdef CYGPKG_NET
+ if (( 0
+#ifdef ETH_DRV_FLAGS_PROMISC_MODE
+ != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
+#endif
+ ) || (ifp->if_flags & IFF_PROMISC)
+ ) {
+ // Then we select promiscuous mode.
+ _SU16(cpd->init_table, LANCE_IB_MODE) = 0x0000|LANCE_CSR_MODE_PROM;
+#if DEBUG & 9
+ db_printf("Promisc MODE!");
+#endif
+ }
+ else _SU16(cpd->init_table, LANCE_IB_MODE) = 0x0000;
+#endif
+ cpd->rx_ring_next = 0;
+ cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;
+ // Init the chip again
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->init_table, b);
+ put_reg(sc, LANCE_CSR_IBA0, (b >> 0) & 0xffff);
+ put_reg(sc, LANCE_CSR_IBA1, (b >> 16) & 0xffff);
+ // Disable automatic TX polling (_send will force a poll), pad
+ // XT frames to legal length, mask status interrupts.
+ put_reg(sc, LANCE_CSR_TFC, (LANCE_CSR_TFC_TXDPOLL | LANCE_CSR_TFC_APAD_XMT
+ | LANCE_CSR_TFC_MFCOM | LANCE_CSR_TFC_RCVCCOM
+ | LANCE_CSR_TFC_TXSTRTM));
+ // Recover after TX FIFO underflow
+ put_reg(sc, LANCE_CSR_IM, LANCE_CSR_IM_DXSUFLO);
+ // Initialize controller - load up init_table
+ put_reg(sc, LANCE_CSR_CSCR, LANCE_CSR_CSCR_INIT);
+ while (0 == (get_reg(sc, LANCE_CSR_CSCR) & LANCE_CSR_CSCR_IDON));
+ reg=get_reg(sc,LANCE_CSR_CSCR);
+ put_reg(sc, LANCE_CSR_CSCR, (reg|(LANCE_CSR_CSCR_IENA | LANCE_CSR_CSCR_STRT))&~LANCE_CSR_CSCR_INIT);
+#if DEBUG & 9
+ reg=get_reg(sc,LANCE_CSR_CSCR);
+ db_printf("CSR after start = %4x\n",reg);
+#endif
+ cpd->active = 1; cpd->txbusy=0; cpd->txbusyh=0;
+ // delay is necessary for Vmware to get a tick !!!
+ CYGACC_CALL_IF_DELAY_US(50000);
+}
+
+//
+// This routine is called to perform special "control" opertions
+//
+static int
+lancepci_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ cyg_uint8 *esa = (cyg_uint8 *)data;
+ int i, res;
+ cyg_uint16 reg;
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+#if DEBUG & 9
+ db_printf("Lancepci-control:entered\n");
+#endif
+ res = 0; // expect success
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+#if 9 & DEBUG
+ db_printf("PCNET - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ esa[0], esa[1], esa[2], esa[3], esa[4], esa[5] );
+#endif // DEBUG
+ for ( i = 0; i < sizeof(cpd->esa); i++ )
+ cpd->esa[i] = esa[i];
+ for (i = 0; i < sizeof(cpd->esa); i += 2) {
+ reg = cpd->esa[i] | (cpd->esa[i+1] << 8);
+ put_reg(sc, LANCE_CSR_PAR0+i/2, reg );
+ }
+ for (i = 0; i < 6; i++) // in case of later restart
+ _SU8(cpd->init_table, LANCE_IB_PADR0+i) = cpd->esa[i];
+ break;
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ // Extract the MAC address that is in the chip, and tell the
+ // system about it.
+ for (i = 0; i < sizeof(cpd->esa); i += 2) {
+ cyg_uint16 z = get_reg(sc, LANCE_CSR_PAR0+i/2 );
+ esa[i] = (cyg_uint8)(0xff & z);
+ esa[i+1] = (cyg_uint8)(0xff & (z >> 8));
+ }
+ break;
+#endif
+#ifdef ETH_DRV_GET_IF_STATS_UD
+ case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+#endif
+ // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+ case ETH_DRV_GET_IF_STATS:
+#endif
+
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+ {
+ struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+ // Chipset entry is no longer supported; RFC1573.
+ for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+ p->snmp_chipset[i] = 0;
+
+ // This perhaps should be a config opt, so you can make up your own
+ // description, or supply it from the instantiation.
+ strcpy( p->description, "AMD LancePCI" );
+ // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+ p->operational = 3; // LINK UP
+ p->duplex = 2; // 2 = SIMPLEX
+ p->speed = 10 * 1000000;
+
+#if FIXME
+#ifdef KEEP_STATISTICS
+ {
+ struct amd_lancepci_stats *ps = &(cpd->stats);
+
+ // Admit to it...
+ p->supports_dot3 = true;
+
+ p->tx_good = ps->tx_good ;
+ p->tx_max_collisions = ps->tx_max_collisions ;
+ p->tx_late_collisions = ps->tx_late_collisions ;
+ p->tx_underrun = ps->tx_underrun ;
+ p->tx_carrier_loss = ps->tx_carrier_loss ;
+ p->tx_deferred = ps->tx_deferred ;
+ p->tx_sqetesterrors = ps->tx_sqetesterrors ;
+ p->tx_single_collisions = ps->tx_single_collisions;
+ p->tx_mult_collisions = ps->tx_mult_collisions ;
+ p->tx_total_collisions = ps->tx_total_collisions ;
+ p->rx_good = ps->rx_good ;
+ p->rx_crc_errors = ps->rx_crc_errors ;
+ p->rx_align_errors = ps->rx_align_errors ;
+ p->rx_resource_errors = ps->rx_resource_errors ;
+ p->rx_overrun_errors = ps->rx_overrun_errors ;
+ p->rx_collisions = ps->rx_collisions ;
+ p->rx_short_frames = ps->rx_short_frames ;
+ p->rx_too_long_frames = ps->rx_too_long_frames ;
+ p->rx_symbol_errors = ps->rx_symbol_errors ;
+
+ p->interrupts = ps->interrupts ;
+ p->rx_count = ps->rx_count ;
+ p->rx_deliver = ps->rx_deliver ;
+ p->rx_resource = ps->rx_resource ;
+ p->rx_restart = ps->rx_restart ;
+ p->tx_count = ps->tx_count ;
+ p->tx_complete = ps->tx_complete ;
+ p->tx_dropped = ps->tx_dropped ;
+ }
+#endif // KEEP_STATISTICS
+#endif // FIXME
+
+ p->tx_queue_len = 1;
+ break;
+ }
+#endif
+ default:
+ res = 1;
+ break;
+ }
+#if DEBUG & 9
+ db_printf("Lancepci-control:done\n");
+#endif
+ CYGACC_CALL_IF_DELAY_US(50000); // let VMware get a tick
+ return res;
+}
+
+//
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+//
+static int
+lancepci_can_send(struct eth_drv_sc *sc)
+{
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ return (0 == cpd->txbusy);
+}
+
+//
+// This routine is called to send data to the hardware.
+static void
+lancepci_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+ int i, len, plen, ring_entry;
+
+ cyg_uint8* sdata = NULL;
+ cyg_uint8 *d, *buf, *txd;
+ cyg_uint16 ints;
+ cyg_uint32 b;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( tx_count );
+
+ cpd->txbusy = 1; cpd->txbusyh=1;
+ cpd->txkey = key;
+
+ // Find packet length
+ plen = 0;
+ for (i = 0; i < sg_len; i++)
+ plen += sg_list[i].len;
+
+ CYG_ASSERT( plen == total_len, "sg data length mismatch" );
+
+ // Get next TX descriptor
+ ring_entry = cpd->tx_ring_free;
+ do {
+ if (cpd->tx_ring_owned == cpd->tx_ring_cnt) {
+ // Is this a dead end? Probably is.
+#if DEBUG & 1
+ db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
+#endif
+ continue;
+ }
+
+ cpd->tx_ring_free++;
+ cpd->tx_ring_owned++;
+ if (cpd->tx_ring_free == cpd->tx_ring_cnt)
+ cpd->tx_ring_free = 0;
+ } while (0);
+
+ txd = cpd->tx_ring + ring_entry*LANCE_TD_SIZE;
+ buf = cpd->tx_buffers + ring_entry*_BUF_SIZE;
+ CYG_ASSERT(0 == (_SU32(txd, LANCE_TD_PTR) & LANCE_TD_PTR_OWN),
+ "TX descriptor not free");
+
+#if DEBUG & 4
+ db_printf("#####Tx descriptor 0x%08x buffer 0x%08x\n",
+ txd, buf);
+#endif
+
+ // Put data into buffer
+ d = buf;
+ for (i = 0; i < sg_len; i++) {
+ sdata = (cyg_uint8 *)sg_list[i].buf;
+ len = sg_list[i].len;
+
+ CYG_ASSERT( sdata, "No sg data pointer here" );
+ while(len--)
+ *d++ = *sdata++;
+ }
+ CYG_ASSERT( sdata, "No sg data pointer outside" );
+
+#if DEBUG & 1
+ db_printf("CSCR %04x\n", get_reg(sc, LANCE_CSR_CSCR));
+#endif
+ _SU16(txd, LANCE_TD_LEN) = (-plen);
+ _SU16(txd, LANCE_TD_MISC) = 0;
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)buf, b);
+ _SU32(txd, LANCE_TD_PTR) = ((b & LANCE_TD_PTR_MASK)
+ | LANCE_TD_PTR_OWN | LANCE_TD_PTR_STP | LANCE_TD_PTR_ENP);
+
+#if DEBUG & 1
+ db_printf("Last TX: LEN %04x MISC %04x PTR %08x\n",
+ _SU16(txd, LANCE_TD_LEN),
+ _SU16(txd, LANCE_TD_MISC),
+ _SU32(txd, LANCE_TD_PTR));
+#endif
+
+ // This delay seems to be necessary on some platforms
+ // (Malta 5kc for example).
+ // Why it is needed is not clear, but removing it or
+ // reducing it cause transmission failures in RedBoot (at least).
+ CYGACC_CALL_IF_DELAY_US(100);
+
+
+ // Set transmit demand
+ ints = get_reg(sc, LANCE_CSR_CSCR);
+ ints &= LANCE_CSR_CSCR_EV_MASK;
+ ints |= LANCE_CSR_CSCR_TDMD;
+ put_reg(sc, LANCE_CSR_CSCR, ints);
+
+#if DEBUG & 1
+ ints = get_reg(sc, LANCE_CSR_CSCR);
+ db_printf("%s:END: ints at TX: 0x%04x\n", __FUNCTION__, ints);
+#endif
+
+ // This is another mystery delay like the one above. This one is
+ // even stranger, since waiting here at the _end_ of the function
+ // should have no effect.
+ CYGACC_CALL_IF_DELAY_US(200);
+}
+
+static void
+lancepci_TxEvent(struct eth_drv_sc *sc, int stat)
+{
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+ int success = 1;
+ cyg_uint8 *txd;
+ cyg_uint16 ints;
+ cyg_uint32 pkt_stat;
+
+ DEBUG_FUNCTION();
+
+ if (0 == cpd->tx_ring_owned) {
+#if DEBUG & 1
+ db_printf("%s: got TX completion when no outstanding packets\n", __FUNCTION__);
+#endif
+ return;
+ }
+
+ INCR_STAT( tx_complete );
+
+ txd = cpd->tx_ring + cpd->tx_ring_alloc*LANCE_TD_SIZE;
+ pkt_stat = _SU32(txd, LANCE_TD_PTR);
+ if (pkt_stat & LANCE_TD_PTR_OWN) {
+#if DEBUG & 1
+ db_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__);
+#endif
+ // first dirty ring entry not freed - wtf?
+ }
+
+ if (pkt_stat & LANCE_TD_PTR_ERR) {
+ // We had an error. Tell the stack.
+ success = 0;
+#if DEBUG & 1
+ db_printf("%s: TX failure, retrying...\n", __FUNCTION__);
+#endif
+ }
+
+ cpd->tx_ring_alloc++;
+ if (cpd->tx_ring_alloc == cpd->tx_ring_cnt)
+ cpd->tx_ring_alloc = 0;
+ cpd->tx_ring_owned--;
+
+#if FIXME
+#ifdef KEEP_STATISTICS
+ {
+ cyg_uint16 reg;
+
+ reg = get_reg( sc, LANCE_CSR_CSCR );
+
+ // Covering each bit in turn...
+ if ( reg & LANCE_STATUS_TX_UNRN ) INCR_STAT( tx_underrun );
+ //if ( reg & LANCE_STATUS_LINK_OK ) INCR_STAT( );
+ //if ( reg & LANCE_STATUS_CTR_ROL ) INCR_STAT( );
+ //if ( reg & LANCE_STATUS_EXC_DEF ) INCR_STAT( );
+ if ( reg & LANCE_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss );
+ if ( reg & LANCE_STATUS_LATCOL ) INCR_STAT( tx_late_collisions );
+ //if ( reg & LANCE_STATUS_WAKEUP ) INCR_STAT( );
+ if ( reg & LANCE_STATUS_TX_DEFR ) INCR_STAT( tx_deferred );
+ //if ( reg & LANCE_STATUS_LTX_BRD ) INCR_STAT( );
+ if ( reg & LANCE_STATUS_SQET ) INCR_STAT( tx_sqetesterrors );
+ if ( reg & LANCE_STATUS_16COL ) INCR_STAT( tx_max_collisions );
+ //if ( reg & LANCE_STATUS_LTX_MULT) INCR_STAT( );
+ if ( reg & LANCE_STATUS_MUL_COL ) INCR_STAT( tx_mult_collisions );
+ if ( reg & LANCE_STATUS_SNGL_COL ) INCR_STAT( tx_single_collisions );
+ if ( reg & LANCE_STATUS_TX_SUC ) INCR_STAT( tx_good );
+
+ cpd->stats.tx_total_collisions =
+ cpd->stats.tx_late_collisions +
+ cpd->stats.tx_max_collisions +
+ cpd->stats.tx_mult_collisions +
+ cpd->stats.tx_single_collisions;
+
+ // We do not need to look in the Counter Register (LANCE_COUNTER)
+ // because it just mimics the info we already have above.
+ }
+#endif // KEEP_STATISTICS
+#endif // FIXME
+
+ // Ack the TX int which clears the packet from the TX completion
+ // queue.
+ ints = get_reg(sc, LANCE_CSR_CSCR);
+ ints |= LANCE_CSR_CSCR_TINT;
+ put_reg(sc, LANCE_CSR_CSCR, ints);
+
+#if DEBUG & 4
+ db_printf("#####Tx packet freed 0x%08x\n", txd );
+#endif
+
+ if ( cpd->txbusy ) {
+ cpd->txbusy = 0;
+ (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
+ }
+}
+
+
+//
+// This function is called when a packet has been received. Its job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'lancepci_recv' will be called to actually fetch it from the hardware.
+//
+static void
+lancepci_RxEvent(struct eth_drv_sc *sc)
+{
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+ cyg_uint8 *rxd;
+ cyg_uint32 rstat;
+ cyg_uint16 ints, len;
+
+ DEBUG_FUNCTION();
+
+ ints = get_reg(sc, LANCE_CSR_CSCR);
+#if DEBUG & 1
+ db_printf("RxEvent - CSR: 0x%04x\n", ints);
+#endif
+
+ while (1) {
+ // Get state of next (supposedly) full ring entry
+ cpd->rxpacket = cpd->rx_ring_next;
+ rxd = cpd->rx_ring + cpd->rxpacket*LANCE_RD_SIZE;
+ rstat = _SU32(rxd, LANCE_RD_PTR);
+
+ // Keep going until we hit an entry that is owned by the
+ // controller.
+ if (rstat & LANCE_RD_PTR_OWN) {
+#if DEBUG & 1
+ int i;
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*LANCE_RD_SIZE;
+ rstat = _SU32(rxd, LANCE_RD_PTR);
+
+ if (!(rstat & LANCE_RD_PTR_OWN)) {
+ int i;
+ cyg_uint32 rstat;
+ cyg_uint16 mlen, blen;
+ cyg_uint8* rxd;
+
+ db_printf("%s: Inconsistent RX state\n", __FUNCTION__);
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*LANCE_RD_SIZE;
+
+ rstat = _SU32(rxd, LANCE_RD_PTR);
+ blen = _SU16(rxd, LANCE_RD_BLEN);
+ mlen = _SU16(rxd, LANCE_RD_MLEN);
+ db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
+ }
+ }
+ }
+#endif
+ break;
+ }
+
+#if DEBUG & 4
+ db_printf("#####Rx packet at index %d\n", cpd->rxpacket);
+#endif
+
+ // Increment counts
+ INCR_STAT( rx_count );
+ cpd->rx_ring_next++;
+ if (cpd->rx_ring_next == cpd->rx_ring_cnt) cpd->rx_ring_next = 0;
+
+ len = _SU16(rxd, LANCE_RD_MLEN);
+
+#ifdef KEEP_STATISTICS
+ //if ( rstat & LANCE_RD_PTR_FRAM ) INCR_STAT( rx_frame_errors );
+ //if ( rstat & LANCE_RD_PTR_OFLO ) INCR_STAT( );
+ if ( rstat & LANCE_RD_PTR_CRC ) INCR_STAT( rx_crc_errors );
+ //if ( rstat & LANCE_RD_PTR_BUFF ) INCR_STAT( );
+#endif // KEEP_STATISTICS
+
+ if (0 == (rstat & LANCE_RD_PTR_ERR)) {
+ // It's OK
+ INCR_STAT( rx_good );
+
+#if DEBUG & 1
+ db_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len);
+#endif
+ // Check for bogusly short packets; can happen in promisc
+ // mode: Asserted against and checked by upper layer
+ // driver.
+#ifdef CYGPKG_NET
+ if ( len > sizeof( struct ether_header ) )
+ // then it is acceptable; offer the data to the network stack
+#endif
+ (sc->funs->eth_drv->recv)(sc, len);
+ } else {
+ // Not OK for one reason or another...
+#if DEBUG & 1
+ db_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n",
+ rstat, len);
+#endif
+ }
+
+ // Free packet (clear all status flags, and set OWN)
+ _SU32(rxd, LANCE_RD_PTR) &= LANCE_RD_PTR_MASK;
+ _SU32(rxd, LANCE_RD_PTR) |= LANCE_RD_PTR_OWN;
+ }
+
+ // Ack RX interrupt set
+ ints = get_reg(sc, LANCE_CSR_CSCR);
+ ints &= LANCE_CSR_CSCR_EV_MASK;
+ ints |= LANCE_CSR_CSCR_RINT;
+ put_reg(sc, LANCE_CSR_CSCR, ints);
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// Its job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+lancepci_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+ int i, mlen=0, plen;
+ cyg_uint8 *data, *rxd, *buf;
+
+ DEBUG_FUNCTION();
+
+ rxd = cpd->rx_ring + cpd->rxpacket*LANCE_RD_SIZE;
+ buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
+
+ INCR_STAT( rx_deliver );
+
+ plen = _SU16(rxd, LANCE_RD_MLEN);
+
+ for (i = 0; i < sg_len; i++) {
+ data = (cyg_uint8*)sg_list[i].buf;
+ mlen = sg_list[i].len;
+
+#if DEBUG & 1
+ db_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
+#endif
+ if (data) {
+ while (mlen > 0) {
+ *data++ = *buf++;
+ mlen--;
+ plen--;
+ }
+ }
+ }
+}
+
+static void
+lancepci_poll(struct eth_drv_sc *sc)
+{
+ cyg_uint16 event;
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+
+// DEBUG_FUNCTION();
+
+ while (1) {
+ // Get the (unmasked) requests
+ if (cpd->event) {
+ event=cpd->event;
+ cpd->event=0;
+ }
+ else
+ event = get_reg(sc, LANCE_CSR_CSCR);
+ if (!((LANCE_CSR_CSCR_ERR|LANCE_CSR_CSCR_INTR) & event))
+ break;
+
+ if (event & LANCE_CSR_CSCR_RINT) {
+ lancepci_RxEvent(sc);
+ }
+ else if (event & LANCE_CSR_CSCR_TINT) {
+ cpd->txbusyh=0; // again , for polled mode
+ lancepci_TxEvent(sc, event);
+ }
+ else if (event & LANCE_CSR_CSCR_MISS) {
+#if DEBUG & 1
+ int i;
+ cyg_uint32 rstat;
+ cyg_uint16 mlen, blen;
+ cyg_uint8* rxd;
+ struct lancepci_priv_data *cpd =
+ (struct lancepci_priv_data *)sc->driver_private;
+
+ db_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event);
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*LANCE_TD_SIZE;
+
+ rstat = _SU32(rxd, LANCE_RD_PTR);
+ blen = _SU16(rxd, LANCE_RD_BLEN);
+ mlen = _SU16(rxd, LANCE_RD_MLEN);
+ db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
+ }
+#endif
+ event &= LANCE_CSR_CSCR_EV_MASK;
+ event |= LANCE_CSR_CSCR_MISS;
+ put_reg(sc, LANCE_CSR_CSCR, event);
+ }
+ else {
+#if DEBUG & 1
+ db_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event);
+#endif
+ put_reg(sc, LANCE_CSR_CSCR, event);
+ }
+ }
+}
+
+// EOF if_lancepci.c
diff --git a/ecos/packages/devs/eth/amd/pcnet/current/ChangeLog b/ecos/packages/devs/eth/amd/pcnet/current/ChangeLog
new file mode 100644
index 0000000..409189b
--- /dev/null
+++ b/ecos/packages/devs/eth/amd/pcnet/current/ChangeLog
@@ -0,0 +1,175 @@
+2004-08-12 Jani Monoses <jani@iv.ro>
+
+ * src/if_pcnet.c: Fix builing with lwip.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_pcnet.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-02-19 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c: Fix a typo. Skip TX handling when there's no
+ outstanding TX packets.
+
+2001-12-17 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c (amd_pcnet_init): Fix warning.
+ (pcnet_send): Fix bad debug code.
+
+2001-12-04 Nick Garnett <nickg@redhat.com>
+
+ * src/if_pcnet.c:
+ Added a couple of 100us delays in transmit code. These appear to
+ be necessary to meet timing constraints on some platforms. These
+ are not a very satisfying fix, but they will have to do for now.
+ Also changed all references to diag_printf to db_printf, and added
+ a static implementation of db_printf() that will gnerate
+ diagnostic output properly on RedBoot.
+
+ * src/amd_pcnet.h: diag_printf -> db_printf
+
+2001-10-16 David Howells <dhowells@redhat.com>
+
+ * src/if_pcnet.c: don't invert the logic of the auto-negotiation
+ completion flag.
+
+2001-10-16 David Howells <dhowells@redhat.com>
+
+ * src/if_pcnet.c: check the correct flag to determine end of
+ auto-negotiation.
+ * src/amd_pcnet.h: ditto
+
+2001-10-15 David Howells <dhowells@redhat.com>
+
+ * cdl/amd_pcnet_eth_drivers.cdl: added option to force 10Mbps only
+ speed negotiation.
+ * src/amd_pcnet.h: ditto
+ * src/if_pcnet.c: ditto
+
+2001-09-12 Jesper Skov <jskov@redhat.com>
+
+ * src/amd_pcnet.h: fix warning.
+
+2001-07-26 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c (amd_pcnet_init): Wait for init table loadup
+ completion. Removed ESA hack.
+
+2001-07-25 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c: Be more careful with the use of STOP since it
+ clears interrupt request flags. Moved some code from _start to
+ _init. Don't double check RX int flag in RxEvent function.
+ (amd_pcnet_init): Move ID output below initialization.
+ Get rid of the last use of STOP, replace with SUSPEND. Minor
+ cleanups.
+ (amd_pcnet_init): Fix silly compile error.
+ (amd_pcnet_init): Check that the controller actually
+ starts. Appears that it needs to be kicked a couple of times under
+ certain conditions.
+
+ * src/amd_pcnet.h: Added TFC bits.
+
+2001-07-24 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c: Mask off RDRA/TDRA pointers. Additional debug
+ info. Hack for broken ESA init. Don't clear TX interrupt flag in
+ send function (leave it to the event handler).
+ (pcnet_stop): Don't reset the controller, just stop it.
+ (pcnet_TxEvent): Only ack interrupt once.
+
+ * src/amd_pcnet.h: Added more registers.
+
+2001-07-18 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c: Make controller recover after FIFO
+ underflow. Removed unnecessary stall checking. Signal stack on TX
+ errors.
+
+2001-07-16 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c: Minor cleanups, avoid use of diag_printf unless
+ when debugging.
+
+2001-07-12 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c: Use PCI_IO accessor macros instead of HAL IO
+ macros. Added a few more CPU->PCI address conversions. Print
+ controller data.
+
+ * src/amd_pcnet.h: Added default PCI_IO accessor macros. Use
+ PCI_IO accessor macros instead of HAL IO macros.
+
+ * src/if_pcnet.c: Removed macros. Added new interrupt handling
+ code. Added code to find resources via PCI library. Change from
+ enaddr to esa. Use HAL_PCI_CPU_TO_BUS macros instead of phys
+ address macro. Fix esa setup code. Debug output tidied up.
+
+ * src/amd_pcnet.h: Moved macros here. Added definitions for 32 bit
+ RD/TD (unused). Changes for PCI configury.
+
+ * cdl/amd_pcnet_eth_drivers.cdl: Removed static esa option (now
+ per-device option). Added dev count option.
+
+ * src/if_pcnet.c: Get rid of within_send.
+ * src/amd_pcnet.h: Same.
+
+ * src/if_pcnet.c: Fix compile error.
+
+2001-04-09 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c: More updates.
+
+ * src/amd_pcnet.h: A few more defs.
+
+ * cdl/amd_pcnet_eth_drivers.cdl: Removed write EEPROM option.
+
+ * src/if_pcnet.c: Fix link status check code. Change some C types
+ to cyg types.
+ * src/amd_pcnet.h (get_reg, put_reg): Also access ANR registers.
+
+ * src/amd_pcnet.h: Macros for accessing structure elements.
+ * src/if_pcnet.c: Use those macros.
+
+2001-04-04 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c: Keep local counter of where to expect RX
+ packets. Appears that the receive ring counter always points at
+ the first buffer.
+ (pcnet_poll): Handle RX events before TX events.
+ Make sure to not accidently clear IENA flag.
+
+ * src/if_pcnet.c: Added RX code.
+ * src/amd_pcnet.h: A few more defs.
+
+2001-04-03 Jesper Skov <jskov@redhat.com>
+
+ * src/if_pcnet.c (amd_pcnet_init): Feed controller physical address.
+
+ * Cloned from LAN91Cxx driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/amd/pcnet/current/cdl/amd_pcnet_eth_drivers.cdl b/ecos/packages/devs/eth/amd/pcnet/current/cdl/amd_pcnet_eth_drivers.cdl
new file mode 100644
index 0000000..041a30d
--- /dev/null
+++ b/ecos/packages/devs/eth/amd/pcnet/current/cdl/amd_pcnet_eth_drivers.cdl
@@ -0,0 +1,104 @@
+# ====================================================================
+#
+# amd_pcnet_eth_drivers.cdl
+#
+# Ethernet drivers - support for AMD PCNET ethernet controllers
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov
+# Date: 2001-04-02
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_AMD_PCNET {
+ display "AMD PCNET compatible ethernet driver"
+ description "Ethernet driver for AMD PCNET compatible controllers."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ active_if CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ compile -library=libextras.a if_pcnet.c
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_AMD_PCNET_CFG";
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_AMD_PCNET_DEV_COUNT {
+ display "Number of supported interfaces."
+ calculated { CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED }
+ flavor data
+ description "
+ This option selects the number of PCI ethernet interfaces to
+ be supported by the driver."
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_AMD_PCNET_FORCE_10MBPS {
+ display "Force negotiation of a 10Mbps link"
+ flavor bool
+ default_value 0
+ description "
+ If this option is enabled then the driver will force the chipset
+ to negotiate only for a 10Mbps link (rather than a 100Mbps
+ link)."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_AMD_PCNET_OPTIONS {
+ display "PCNET ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_AMD_PCNET_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the PCNET ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/amd/pcnet/current/src/amd_pcnet.h b/ecos/packages/devs/eth/amd/pcnet/current/src/amd_pcnet.h
new file mode 100644
index 0000000..a78a224
--- /dev/null
+++ b/ecos/packages/devs/eth/amd/pcnet/current/src/amd_pcnet.h
@@ -0,0 +1,535 @@
+#ifndef CYGONCE_DEVS_ETH_AMD_PCNET_H
+#define CYGONCE_DEVS_ETH_AMD_PCNET_H
+//==========================================================================
+//
+// amd_pcnet.h
+//
+// AMD PCNet Ethernet chip
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov, hmt
+// Date: 2001-04-02
+// Purpose: Hardware description of AMD PCnet series.
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+
+//------------------------------------------------------------------------
+// Get macros from platform header
+#define __WANT_CONFIG
+#include CYGDAT_DEVS_ETH_AMD_PCNET_INL
+#undef __WANT_CONFIG
+
+//------------------------------------------------------------------------
+// Set to perms of:
+// 0 disables all debug output
+// 1 for process debug output
+// 2 for added data IO output: get_reg, put_reg
+// 4 for packet allocation/free output
+// 8 for only startup status, so we can tell we're installed OK
+#define DEBUG 0x0
+
+#if DEBUG & 1
+#define DEBUG_FUNCTION() do { os_printf("%s\n", __FUNCTION__); } while (0)
+#else
+#define DEBUG_FUNCTION() do {} while(0)
+#endif
+
+// ------------------------------------------------------------------------
+// Macros for keeping track of statistics
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+# define KEEP_STATISTICS
+#endif
+
+#ifdef KEEP_STATISTICS
+# define INCR_STAT( _x_ ) (cpd->stats. _x_ ++)
+#else
+# define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
+#endif
+
+//------------------------------------------------------------------------
+// Cache translation
+#ifndef CYGARC_UNCACHED_ADDRESS
+# define CYGARC_UNCACHED_ADDRESS(x) (x)
+#endif
+
+//------------------------------------------------------------------------
+// Address translation
+#ifndef HAL_PCI_CPU_TO_BUS
+# error "HAL PCI support must define translation macros"
+#endif
+
+// ------------------------------------------------------------------------
+// Macros for accessing structure elements
+
+#define _SU8( _base_, _offset_) \
+ *((cyg_uint8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU16( _base_, _offset_) \
+ *((cyg_uint16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU32( _base_, _offset_) \
+ *((cyg_uint32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+#define _SI8( _base_, _offset_) \
+ *((cyg_int8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI16( _base_, _offset_) \
+ *((cyg_int16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI32( _base_, _offset_) \
+ *((cyg_int32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+// ------------------------------------------------------------------------
+// Macros for accessing controller registers
+#ifndef HAL_PCI_IO_READ_UINT8
+# define HAL_PCI_IO_READ_UINT8(addr, datum) HAL_READ_UINT8(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT8(addr, datum) HAL_WRITE_UINT8(addr, datum)
+# define HAL_PCI_IO_READ_UINT16(addr, datum) HAL_READ_UINT16(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT16(addr, datum) HAL_WRITE_UINT16(addr, datum)
+# define HAL_PCI_IO_READ_UINT32(addr, datum) HAL_READ_UINT32(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT32(addr, datum) HAL_WRITE_UINT32(addr, datum)
+#endif
+
+// ------------------------------------------------------------------------
+// IO map registers
+#define PCNET_IO_EEPROM 0x00
+#define PCNET_IO_ID 0x0e
+#define PCNET_IO_RDP 0x10
+#define PCNET_IO_RAP 0x12
+#define PCNET_IO_RESET 0x14
+#define PCNET_IO_BDP 0x16
+
+// The ID of the 79C790 is 0x5757 - that may be different in other
+// (older) cards.
+#define PCNET_IO_ID_KEY 0x5757
+
+// ------------------------------------------------------------------------
+// Controller registers come in three sets: CSR, BCR and ANR. Use
+// high-bits do differentiate, make the put/get functions do the right
+// thing depending the state of these bits.
+#define PCNET_RAP_MASK 0x007f
+//#define PCNET_CSR_FLAG 0x0000 // implied
+#define PCNET_BCR_FLAG 0x0080
+#define PCNET_ANR_FLAG 0x0100
+
+
+// CSR registers
+#define PCNET_CSR_CSCR 0
+#define PCNET_CSR_IBA0 1
+#define PCNET_CSR_IBA1 2
+#define PCNET_CSR_IM 3
+#define PCNET_CSR_TFC 4
+#define PCNET_CSR_ECI 5
+#define PCNET_CSR_LAR0 8
+#define PCNET_CSR_LAR1 9
+#define PCNET_CSR_LAR2 10
+#define PCNET_CSR_LAR3 11
+#define PCNET_CSR_PAR0 12
+#define PCNET_CSR_PAR1 13
+#define PCNET_CSR_PAR2 14
+#define PCNET_CSR_MODE 15
+#define PCNET_CSR_BARRL 24
+#define PCNET_CSR_BARRU 25
+#define PCNET_CSR_BATRL 30
+#define PCNET_CSR_BATRU 31
+#define PCNET_CSR_RRC 72
+#define PCNET_CSR_TRC 74
+#define PCNET_CSR_RRLEN 76
+#define PCNET_CSR_TRLEN 78
+#define PCNET_CSR_ID_LO 88
+#define PCNET_CSR_ID_HI 89
+
+
+#define PCNET_CSR_CSCR_ERR 0x8000
+#define PCNET_CSR_CSCR_RES 0x4000
+#define PCNET_CSR_CSCR_CERR 0x2000
+#define PCNET_CSR_CSCR_MISS 0x1000
+#define PCNET_CSR_CSCR_MERR 0x0800
+#define PCNET_CSR_CSCR_RINT 0x0400
+#define PCNET_CSR_CSCR_TINT 0x0200
+#define PCNET_CSR_CSCR_IDON 0x0100
+#define PCNET_CSR_CSCR_INTR 0x0080
+#define PCNET_CSR_CSCR_IENA 0x0040
+#define PCNET_CSR_CSCR_RXON 0x0020
+#define PCNET_CSR_CSCR_TXON 0x0010
+#define PCNET_CSR_CSCR_TDMD 0x0008
+#define PCNET_CSR_CSCR_STOP 0x0004
+#define PCNET_CSR_CSCR_STRT 0x0002
+#define PCNET_CSR_CSCR_INIT 0x0001
+
+#define PCNET_CSR_CSCR_EV_MASK 0x007f
+
+#define PCNET_CSR_IM_MISSM 0x1000
+#define PCNET_CSR_IM_MERRM 0x0800
+#define PCNET_CSR_IM_RINTM 0x0400
+#define PCNET_CSR_IM_TINTM 0x0200
+#define PCNET_CSR_IM_IDONM 0x0100
+#define PCNET_CSR_IM_DXSUFLO 0x0040
+#define PCNET_CSR_IM_LAPPEN 0x0020
+#define PCNET_CSR_IM_DXMT2PD 0x0010
+#define PCNET_CSR_IM_EMBA 0x0008
+#define PCNET_CSR_IM_BSWP 0x0004
+
+#define PCNET_CSR_TFC_TXDPOLL 0x1000
+#define PCNET_CSR_TFC_APAD_XMT 0x0800
+#define PCNET_CSR_TFC_ASTRP_RCV 0x0400
+#define PCNET_CSR_TFC_MFCO 0x0200
+#define PCNET_CSR_TFC_MFCOM 0x0100
+#define PCNET_CSR_TFC_UINTCMD 0x0080
+#define PCNET_CSR_TFC_UINT 0x0040
+#define PCNET_CSR_TFC_RCVCCO 0x0020
+#define PCNET_CSR_TFC_RCVCCOM 0x0010
+#define PCNET_CSR_TFC_TXSTRT 0x0008
+#define PCNET_CSR_TFC_TXSTRTM 0x0004
+
+#define PCNET_CSR_ECI_TOKINTD 0x8000
+#define PCNET_CSR_ECI_LTINTEN 0x4000
+#define PCNET_CSR_ECI_SINT 0x0800
+#define PCNET_CSR_ECI_SINTE 0x0400
+#define PCNET_CSR_ECI_EXDINT 0x0080
+#define PCNET_CSR_ECI_EXDINTE 0x0040
+#define PCNET_CSR_ECI_MPPLBA 0x0020
+#define PCNET_CSR_ECI_MPINT 0x0010
+#define PCNET_CSR_ECI_MPINTE 0x0008
+#define PCNET_CSR_ECI_MPEN 0x0004
+#define PCNET_CSR_ECI_MPMODE 0x0002
+#define PCNET_CSR_ECI_SPND 0x0001
+
+#define PCNET_CSR_MODE_PROM 0x8000
+#define PCNET_CSR_MODE_DRCVBC 0x4000
+#define PCNET_CSR_MODE_DRCVPA 0x2000
+#define PCNET_CSR_MODE_PORTSEL 0x0180
+#define PCNET_CSR_MODE_INTL 0x0040
+#define PCNET_CSR_MODE_DRTY 0x0020
+#define PCNET_CSR_MODE_FCOLL 0x0010
+#define PCNET_CSR_MODE_DXMTFCS 0x0008
+#define PCNET_CSR_MODE_LOOP 0x0004
+#define PCNET_CSR_MODE_DTX 0x0002
+#define PCNET_CSR_MODE_DRX 0x0001
+
+// BCR registers
+#define PCNET_BCR_SWSTYLE (20 |PCNET_BCR_FLAG)
+#define PCNET_BCR_MIIADDR (33 |PCNET_BCR_FLAG)
+#define PCNET_BCR_MIIDATA (34 |PCNET_BCR_FLAG)
+
+#define PCNET_BCR_MIIADDR_PHYAD 0x03e0
+
+
+// ANR registers
+#define PCNET_ANR_PHYCTRL ( 0 |PCNET_ANR_FLAG)
+#define PCNET_ANR_PHYSTAT ( 1 |PCNET_ANR_FLAG)
+#define PCNET_ANR_AAR ( 4 |PCNET_ANR_FLAG)
+
+#define PCNET_ANR_PHYCTRL_100MBPS 0x2000
+#define PCNET_ANR_PHYCTRL_RENEGOTIATE 0x0200
+#define PCNET_ANR_PHYCTRL_DUPLEX 0x0100
+
+#define PCNET_ANR_PHYSTAT_AUTONEG_COMP 0x0020
+#define PCNET_ANR_PHYSTAT_LINK 0x0004
+
+#define PCNET_ANR_AAR_100_FD 0x0100
+#define PCNET_ANR_AAR_100_HD 0x0080
+#define PCNET_ANR_AAR_100 0x0180
+#define PCNET_ANR_AAR_10_FD 0x0040
+#define PCNET_ANR_AAR_10_HD 0x0020
+#define PCNET_ANR_AAR_10 0x0060
+
+//----------------------------------------------------------------------------
+// Receive buffer Descriptor
+#if 1
+#define PCNET_RD_PTR 0x00 // 32 bit
+#define PCNET_RD_BLEN 0x04 // 16 bit (2's complement, negative)
+#define PCNET_RD_MLEN 0x06 // 16 bit
+#define PCNET_RD_SIZE 0x08
+
+#define PCNET_RD_PTR_OWN 0x80000000
+#define PCNET_RD_PTR_ERR 0x40000000
+#define PCNET_RD_PTR_FRAM 0x20000000
+#define PCNET_RD_PTR_OFLO 0x10000000
+#define PCNET_RD_PTR_CRC 0x08000000
+#define PCNET_RD_PTR_BUFF 0x04000000
+#define PCNET_RD_PTR_STP 0x02000000
+#define PCNET_RD_PTR_ENP 0x01000000
+#define PCNET_RD_PTR_MASK 0x00ffffff
+#else
+
+#define PCNET_RD_PTR 0x00
+#define PCNET_RD_BLEN 0x04
+#define PCNET_RD_MLEN 0x08
+#define PCNET_RD_USER 0x0c
+#define PCNET_RD_SIZE 0x10
+
+#define PCNET_RD_BLEN_OWN 0x80000000
+#define PCNET_RD_BLEN_ERR 0x40000000
+#define PCNET_RD_BLEN_FRAM 0x20000000
+#define PCNET_RD_BLEN_OFLO 0x10000000
+#define PCNET_RD_BLEN_CRC 0x08000000
+#define PCNET_RD_BLEN_BUFF 0x04000000
+#define PCNET_RD_BLEN_STP 0x02000000
+#define PCNET_RD_BLEN_ENP 0x01000000
+#define PCNET_RD_BLEN_BPE 0x00800000
+#define PCNET_RD_BLEN_PAM 0x00400000
+#define PCNET_RD_BLEN_LAFM 0x00200000
+#define PCNET_RD_BLEN_BAM 0x00100000
+#define PCNET_RD_BLEN_MASK 0x0000ffff
+#endif
+
+// Transmit buffer Descriptor
+#if 1
+#define PCNET_TD_PTR 0x00 // 32 bit
+#define PCNET_TD_LEN 0x04 // 16 bit (2's complement, negative)
+#define PCNET_TD_MISC 0x06 // 16 bit
+#define PCNET_TD_SIZE 0x08
+
+#define PCNET_TD_PTR_OWN 0x80000000
+#define PCNET_TD_PTR_ERR 0x40000000
+#define PCNET_TD_PTR_ADD_FCS 0x20000000
+#define PCNET_TD_PTR_MORE 0x10000000
+#define PCNET_TD_PTR_ONE 0x08000000
+#define PCNET_TD_PTR_DEF 0x04000000
+#define PCNET_TD_PTR_STP 0x02000000
+#define PCNET_TD_PTR_ENP 0x01000000
+#define PCNET_TD_PTR_MASK 0x00ffffff
+#else
+#define PCNET_TD_PTR 0x00
+#define PCNET_TD_LEN 0x04
+#define PCNET_TD_MISC 0x08
+#define PCNET_TD_USER 0x0c
+#define PCNET_TD_SIZE 0x10
+
+#define PCNET_TD_LEN_OWN 0x80000000
+#define PCNET_TD_LEN_ERR 0x40000000
+#define PCNET_TD_LEN_ADD_FCS 0x20000000
+#define PCNET_TD_LEN_MORE 0x10000000
+#define PCNET_TD_LEN_ONE 0x08000000
+#define PCNET_TD_LEN_DEF 0x04000000
+#define PCNET_TD_LEN_STP 0x02000000
+#define PCNET_TD_LEN_ENP 0x01000000
+#define PCNET_TD_LEN_BPE 0x00800000
+#define PCNET_TD_LEN_MASK 0x0000ffff
+
+#define PCNET_TD_FLAGS_BUFF 0x80000000
+#define PCNET_TD_FLAGS_UFLO 0x40000000
+#define PCNET_TD_FLAGS_EX_DEF 0x20000000
+#define PCNET_TD_FLAGS_LCOL 0x10000000
+#define PCNET_TD_FLAGS_LCAR 0x08000000
+#define PCNET_TD_FLAGS_RTRY 0x04000000
+#define PCNET_TD_FLAGS_TRC_MASK 0x0000000f
+#endif
+
+
+#define PCNET_TD_MISC_BUFF 0x8000
+#define PCNET_TD_MISC_UFLO 0x4000
+#define PCNET_TD_MISC_EXDEF 0x2000
+#define PCNET_TD_MISC_LCOL 0x1000
+#define PCNET_TD_MISC_LCAR 0x0800
+#define PCNET_TD_MISC_RTRY 0x0400
+#define PCNET_TD_MISC_TDR 0x03ff
+
+// Initialization Buffer
+#define PCNET_IB_MODE 0
+#define PCNET_IB_PADR0 2
+#define PCNET_IB_PADR1 4
+#define PCNET_IB_PADR2 6
+#define PCNET_IB_LADRF0 8
+#define PCNET_IB_LADRF1 10
+#define PCNET_IB_LADRF2 12
+#define PCNET_IB_LADRF3 14
+#define PCNET_IB_RDRA 16
+#define PCNET_IB_TDRA 20
+#define PCNET_IB_SIZE 24
+
+#define PCNET_IB_TDRA_CNT_shift 29
+#define PCNET_IB_TDRA_PTR_mask 0x00ffffff
+#define PCNET_IB_RDRA_CNT_shift 29
+#define PCNET_IB_RDRA_PTR_mask 0x00ffffff
+
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+struct amd_pcnet_stats {
+ unsigned int tx_good ;
+ unsigned int tx_max_collisions ;
+ unsigned int tx_late_collisions ;
+ unsigned int tx_underrun ;
+ unsigned int tx_carrier_loss ;
+ unsigned int tx_deferred ;
+ unsigned int tx_sqetesterrors ;
+ unsigned int tx_single_collisions;
+ unsigned int tx_mult_collisions ;
+ unsigned int tx_total_collisions ;
+ unsigned int rx_good ;
+ unsigned int rx_crc_errors ;
+ unsigned int rx_align_errors ;
+ unsigned int rx_resource_errors ;
+ unsigned int rx_overrun_errors ;
+ unsigned int rx_collisions ;
+ unsigned int rx_short_frames ;
+ unsigned int rx_too_long_frames ;
+ unsigned int rx_symbol_errors ;
+ unsigned int interrupts ;
+ unsigned int rx_count ;
+ unsigned int rx_deliver ;
+ unsigned int rx_resource ;
+ unsigned int rx_restart ;
+ unsigned int tx_count ;
+ unsigned int tx_complete ;
+ unsigned int tx_dropped ;
+};
+#endif
+
+typedef struct pcnet_priv_data {
+ int index;
+ cyg_uint8 // (split up for atomic byte access)
+ found:1, // was hardware discovered?
+ mac_addr_ok:1, // can we bring up?
+ active:1, // has this if been brung up?
+ hardwired_esa:1, // set if ESA is hardwired via CDL
+ txbusy:1, // A packet has been sent
+ spare1:3;
+
+ unsigned long txkey; // Used to ack when packet sent
+ unsigned char* base; // Base address of controller EPROM region
+ int interrupt; // Interrupt vector used by controller
+ unsigned char esa[6]; // Controller ESA
+ // Function to configure the ESA - may fetch ESA from EPROM or
+ // RedBoot config option.
+ void (*config_esa)(struct pcnet_priv_data* cpd);
+ void *ndp; // Network Device Pointer
+
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+ int devid;
+
+ cyg_uint8* rx_buffers; // ptr to base of buffer mem
+ cyg_uint8* rx_ring; // ptr to base of rx ring memory
+ int rx_ring_cnt; // number of entries in ring
+ int rx_ring_log_cnt; // log of above
+ int rx_ring_next; // index of next full ring entry
+
+ cyg_uint8* tx_buffers;
+ cyg_uint8* tx_ring;
+ int tx_ring_cnt;
+ int tx_ring_log_cnt;
+ int tx_ring_free; // index of next free ring entry
+ int tx_ring_alloc; // index of first controller owned ring
+ int tx_ring_owned; // number of controller owned ring entries
+
+ int rxpacket;
+#ifdef KEEP_STATISTICS
+ struct amd_pcnet_stats stats;
+#endif
+#if DEBUG & 1
+ cyg_uint32 txd;
+#endif
+} pcnet_priv_data;
+
+// ------------------------------------------------------------------------
+
+static __inline__ cyg_uint16
+get_reg(struct eth_drv_sc *sc, int regno)
+{
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+ cyg_uint16 val, addr;
+
+ if (regno & PCNET_ANR_FLAG) {
+ // We could do this with recursive calls to get/put reg
+ // functions, but might as well just do it directly.
+ // First set ANR address
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIADDR & PCNET_RAP_MASK);
+ HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, addr);
+ addr &= PCNET_BCR_MIIADDR_PHYAD;
+ addr |= (regno & PCNET_RAP_MASK);
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, addr);
+ // Then read ANR register data
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIDATA & PCNET_RAP_MASK);
+ HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, val);
+ } else {
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, regno & PCNET_RAP_MASK);
+ if (regno & PCNET_BCR_FLAG)
+ HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, val);
+ else
+ HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_RDP, val);
+ }
+#if DEBUG & 2
+ os_printf("read %s reg %d val 0x%04x\n",
+ (regno & PCNET_ANR_FLAG) ? "anr" : (regno & PCNET_BCR_FLAG) ? "bcr" : "csr",
+ regno & PCNET_RAP_MASK, val);
+#endif
+ return val;
+}
+
+static __inline__ void
+put_reg(struct eth_drv_sc *sc, int regno, cyg_uint16 val)
+{
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+ cyg_uint16 addr;
+
+ if (regno & PCNET_ANR_FLAG) {
+ // We could do this with recursive calls to get/put reg
+ // functions, but might as well just do it directly.
+ // First set ANR address
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIADDR & PCNET_RAP_MASK);
+ HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, addr);
+ addr &= PCNET_BCR_MIIADDR_PHYAD;
+ addr |= (regno & PCNET_RAP_MASK);
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, addr);
+ // Then write ANR register data
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIDATA & PCNET_RAP_MASK);
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, val);
+ } else {
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, regno & PCNET_RAP_MASK);
+ if (regno & PCNET_BCR_FLAG)
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, val);
+ else
+ HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RDP, val);
+ }
+
+#if DEBUG & 2
+ os_printf("write %s reg %d val 0x%04x\n",
+ (regno & PCNET_ANR_FLAG) ? "anr" : (regno & PCNET_BCR_FLAG) ? "bcr" : "csr",
+ regno & PCNET_RAP_MASK, val);
+#endif
+}
+
+// ------------------------------------------------------------------------
+#endif // CYGONCE_DEVS_ETH_AMD_PCNET_H
+// EOF amd_pcnet.h
diff --git a/ecos/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c b/ecos/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c
new file mode 100644
index 0000000..64bf40a
--- /dev/null
+++ b/ecos/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c
@@ -0,0 +1,1317 @@
+//==========================================================================
+//
+// dev/if_pcnet.c
+//
+// Ethernet device driver for AMD PCNET compatible controllers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, based on lan91cxx driver by hmt & jskov
+// Contributors: gthomas, jskov, hmt
+// Date: 2001-04-02
+// Purpose:
+// Description: hardware driver for AMD PCNet (and possibly Lance) ethernet
+// Notes: The controller is used in its 16bit mode. That means that
+// all addresses are 24bit only - and that all controller
+// accessed memory must be within the same 16MB region
+// (starting at 0 on older controllers).
+//
+// The KEEP_STATISTICS code is not implemented yet. Look
+// for FIXME macro.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_amd_pcnet.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h> // delays
+#include <string.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <cyg/kernel/kapi.h>
+#include <net/if.h> /* Needed for struct ifnet */
+#include <pkgconf/io_eth_drivers.h>
+#endif
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#ifdef CYGPKG_IO_PCI
+#include <cyg/io/pci.h>
+#else
+#error "Need PCI package here"
+#endif
+
+#define FIXME 0
+
+#define _BUF_SIZE 1544
+
+#ifdef CYGPKG_INFRA_DEBUG
+// Then we log, OOI, the number of times we get a bad packet number
+// from the tx done fifo.
+int pcnet_txfifo_good = 0;
+int pcnet_txfifo_bad = 0;
+#endif
+
+#include "amd_pcnet.h"
+#define __WANT_DEVS
+#include CYGDAT_DEVS_ETH_AMD_PCNET_INL
+#undef __WANT_DEVS
+
+#if defined(CYGPKG_REDBOOT) && DEBUG
+
+static void db_printf( char *fmt, ... )
+{
+ extern int start_console(void);
+ extern void end_console(int);
+ va_list a;
+ int old_console;
+ va_start( a, fmt );
+ old_console = start_console();
+ diag_vprintf( fmt, a );
+ end_console(old_console);
+ va_end( a );
+}
+
+#else
+
+#define db_printf diag_printf
+
+#endif
+
+static void pcnet_poll(struct eth_drv_sc *sc);
+
+// This ISR is called when the ethernet interrupt occurs
+static cyg_uint32
+pcnet_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct pcnet_priv_data *cpd = (struct pcnet_priv_data *)data;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( interrupts );
+
+ cyg_drv_interrupt_mask(cpd->interrupt);
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+static void
+pcnet_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ // This conditioning out is necessary because of explicit calls to this
+ // DSR - which would not ever be called in the case of a polled mode
+ // usage ie. in RedBoot.
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ struct pcnet_priv_data* cpd = (struct pcnet_priv_data *)data;
+ struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->ndp);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ // but here, it must be a *sc:
+ eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+#else
+# ifndef CYGPKG_REDBOOT
+# error Empty PCnet ethernet DSR is compiled. Is this what you want?
+# endif
+#endif
+}
+
+
+// The deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+pcnet_deliver(struct eth_drv_sc *sc)
+{
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ // Service the interrupt:
+ pcnet_poll(sc);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+}
+
+static int
+pcnet_int_vector(struct eth_drv_sc *sc)
+{
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+
+ return (cpd->interrupt);
+}
+
+// ------------------------------------------------------------------------
+// Memory management
+//
+// Simply carve off from the front of the PCI mapped window into real memory
+static cyg_uint32 pcnet_heap_size;
+static cyg_uint8 *pcnet_heap_base;
+static cyg_uint8 *pcnet_heap_free;
+
+static void*
+pciwindow_mem_alloc(int size)
+{
+ void *p_memory;
+ int _size = size;
+
+ CYG_ASSERT(
+ (CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE <= (int)pcnet_heap_free)
+ &&
+ ((CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE +
+ CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE) > (int)pcnet_heap_free)
+ &&
+ (0 < pcnet_heap_size)
+ &&
+ (CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE >= pcnet_heap_size)
+ &&
+ (CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE == (int)pcnet_heap_base),
+ "Heap variables corrupted" );
+
+ p_memory = (void *)0;
+ size = (size + 3) & ~3;
+ if ( (pcnet_heap_free+size) < (pcnet_heap_base+pcnet_heap_size) ) {
+ cyg_uint32 *p;
+ p_memory = (void *)pcnet_heap_free;
+ pcnet_heap_free += size;
+ for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 )
+ *p++ = 0;
+ }
+
+#if DEBUG & 9
+ db_printf("Allocated %d bytes at 0x%08x\n", size, p_memory);
+#endif
+
+ return p_memory;
+}
+
+static cyg_pci_match_func find_pcnet_match_func;
+
+static cyg_bool
+find_pcnet_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+{
+#if DEBUG & 9
+ db_printf("PCI match vendor 0x%04x device 0x%04x\n", v, d);
+#endif
+ return (0x1022 == v) && (0x2000 == d);
+}
+
+static int
+pci_init_find_pcnet( void )
+{
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+ cyg_uint16 cmd;
+ int device_index;
+ int found_devices = 0;
+
+ DEBUG_FUNCTION();
+
+#ifdef CYGARC_UNCACHED_ADDRESS
+ CYG_ASSERT( CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) ==
+ CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE,
+ "PCI window configured does not match PCI memory section base" );
+#else
+ CYG_ASSERT( (CYG_ADDRWORD)CYGMEM_SECTION_pci_window ==
+ CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE,
+ "PCI window configured does not match PCI memory section base" );
+#endif
+ CYG_ASSERT( CYGMEM_SECTION_pci_window_SIZE ==
+ CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE,
+ "PCI window configured does not match PCI memory section size" );
+
+ if (
+#ifdef CYGARC_UNCACHED_ADDRESS
+ CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) !=
+#else
+ (CYG_ADDRWORD)CYGMEM_SECTION_pci_window !=
+#endif
+ CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE
+ ||
+ CYGMEM_SECTION_pci_window_SIZE !=
+ CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE ) {
+#if DEBUG & 8
+ db_printf("pci_init_find_pcnets(): PCI window misconfigured\n");
+#endif
+ return 0;
+ }
+
+ // First initialize the heap in PCI window'd memory
+ pcnet_heap_size = CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE;
+ pcnet_heap_base = (cyg_uint8 *)CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE;
+ pcnet_heap_free = pcnet_heap_base;
+#if DEBUG & 9
+ db_printf("pcimem : 0x%08x size: 0x%08x\n", pcnet_heap_base, pcnet_heap_size);
+#endif
+
+ cyg_pci_init();
+#if DEBUG & 8
+ db_printf("Finished cyg_pci_init();\n");
+#endif
+
+ devid = CYG_PCI_NULL_DEVID;
+
+ for (device_index = 0;
+ device_index < CYGNUM_DEVS_ETH_AMD_PCNET_DEV_COUNT;
+ device_index++) {
+ struct pcnet_priv_data* cpd = pcnet_priv_array[device_index];
+
+ cpd->index = device_index;
+
+ // See above for find_pcnet_match_func - it selects any of several
+ // variants. This is necessary in case we have multiple mixed-type
+ // devices on one board in arbitrary orders.
+ if (cyg_pci_find_matching( &find_pcnet_match_func, NULL, &devid )) {
+#if DEBUG & 8
+ db_printf("eth%d = pcnet\n", device_index);
+#endif
+ cyg_pci_get_device_info(devid, &dev_info);
+
+ cpd->interrupt_handle = 0; // Flag not attached.
+ if (cyg_pci_translate_interrupt(&dev_info, &cpd->interrupt)) {
+#if DEBUG & 8
+ db_printf(" Wired to HAL vector %d\n", cpd->interrupt);
+#endif
+ cyg_drv_interrupt_create(
+ cpd->interrupt,
+ 1, // Priority - unused
+ (cyg_addrword_t)cpd,// Data item passed to ISR & DSR
+ pcnet_isr, // ISR
+ pcnet_dsr, // DSR
+ &cpd->interrupt_handle, // handle to intr obj
+ &cpd->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(cpd->interrupt_handle);
+
+ // Don't unmask the interrupt yet, that could get us into a
+ // race.
+ }
+ else {
+ cpd->interrupt = 0;
+#if DEBUG & 8
+ db_printf(" Does not generate interrupts.\n");
+#endif
+ }
+
+ if (cyg_pci_configure_device(&dev_info)) {
+#if DEBUG & 8
+ int i;
+ db_printf("Found device on bus %d, devfn 0x%02x:\n",
+ CYG_PCI_DEV_GET_BUS(devid),
+ CYG_PCI_DEV_GET_DEVFN(devid));
+
+ if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
+ db_printf(" Note that board is active. Probed"
+ " sizes and CPU addresses invalid!\n");
+ }
+ db_printf(" Vendor 0x%04x", dev_info.vendor);
+ db_printf("\n Device 0x%04x", dev_info.device);
+ db_printf("\n Command 0x%04x, Status 0x%04x\n",
+ dev_info.command, dev_info.status);
+
+ db_printf(" Class/Rev 0x%08x", dev_info.class_rev);
+ db_printf("\n Header 0x%02x\n", dev_info.header_type);
+
+ db_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+ dev_info.header.normal.sub_vendor,
+ dev_info.header.normal.sub_id);
+
+ for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
+ db_printf(" BAR[%d] 0x%08x /", i, dev_info.base_address[i]);
+ db_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
+ dev_info.base_size[i], dev_info.base_map[i]);
+ }
+ db_printf(" eth%d configured\n", device_index);
+#endif
+ found_devices++;
+ cpd->found = 1;
+ cpd->active = 0;
+ cpd->devid = devid;
+ cpd->base = (unsigned char*) dev_info.base_map[0];
+#if DEBUG & 8
+ db_printf(" I/O address = 0x%08x\n", cpd->base);
+#endif
+
+ // Don't use cyg_pci_set_device_info since it clears
+ // some of the fields we want to print out below.
+ cyg_pci_read_config_uint16(dev_info.devid,
+ CYG_PCI_CFG_COMMAND, &cmd);
+ cmd |= (CYG_PCI_CFG_COMMAND_IO // enable I/O space
+ | CYG_PCI_CFG_COMMAND_MEMORY // enable memory space
+ | CYG_PCI_CFG_COMMAND_MASTER); // enable bus master
+ cyg_pci_write_config_uint16(dev_info.devid,
+ CYG_PCI_CFG_COMMAND, cmd);
+
+ // This is the indicator for "uses an interrupt"
+ if (cpd->interrupt_handle != 0) {
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+#if DEBUG & 8
+ db_printf(" Enabled interrupt %d\n", cpd->interrupt);
+#endif
+ }
+#if DEBUG & 8
+ db_printf(" **** Device enabled for I/O and Memory "
+ "and Bus Master\n");
+#endif
+ }
+ else {
+ cpd->found = 0;
+ cpd->active = 0;
+#if DEBUG & 8
+ db_printf("Failed to configure device %d\n", device_index);
+#endif
+ }
+ }
+ else {
+ cpd->found = 0;
+ cpd->active = 0;
+#if DEBUG & 8
+ db_printf("eth%d not found\n", device_index);
+#endif
+ }
+ }
+
+ if (0 == found_devices)
+ return 0;
+
+ return 1;
+}
+
+
+static bool
+amd_pcnet_init(struct cyg_netdevtab_entry *tab)
+{
+ static int initialized = 0; // only probe PCI et al *once*
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+ cyg_uint16 val;
+ cyg_uint32 b;
+ cyg_uint8* p;
+ cyg_uint8* d;
+ cyg_uint8* init_table;
+ int i;
+
+ DEBUG_FUNCTION();
+
+
+ if ( 0 == initialized++ ) {
+ // then this is the first time ever:
+ if ( ! pci_init_find_pcnet() ) {
+#if DEBUG & 8
+ db_printf( "pci_init_find_pcnet failed" );
+#endif
+ return false;
+ }
+ }
+
+ // If this device is not present, exit
+ if (0 == cpd->found)
+ return 0;
+
+ cpd->txbusy = 0;
+
+#if DEBUG & 8
+ db_printf("PCNet at base 0x%08x, EEPROM key 0x%04x\n",
+ cpd->base, _SU16(cpd->base, PCNET_IO_ID));
+#endif
+
+#if 0
+ // FIXME: Doesn't work with non-conforming EEPROMS
+ if (PCNET_IO_ID_KEY != _SU16(cpd->base, PCNET_IO_ID) ) {
+ db_printf("PCNet EPROM key not found\n");
+ return false;
+ }
+#endif
+
+#if DEBUG & 9
+ db_printf("pcimem : %08x size: %08x\n", pcnet_heap_base, pcnet_heap_size);
+#endif
+
+ // Prepare ESA
+ if (!cpd->hardwired_esa) {
+ // Use the address from the serial EEPROM
+ p = cpd->base + PCNET_IO_EEPROM;
+ for (i = 0; i < 6; i++)
+ cpd->esa[i] = *p++;
+ }
+#if DEBUG & 9
+ db_printf("PCNET - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ (cpd->hardwired_esa) ? "static" : "eeprom",
+ cpd->esa[0], cpd->esa[1], cpd->esa[2],
+ cpd->esa[3], cpd->esa[4], cpd->esa[5] );
+#endif
+
+#ifdef CYGSEM_DEVS_ETH_AMD_PCNET_FORCE_10MBPS
+ if (get_reg(sc,PCNET_ANR_AAR) & PCNET_ANR_AAR_100) {
+ cyg_uint16 anr;
+ int loop;
+
+#if DEBUG & 9
+ db_printf("%s: Forcing 10Mbps negotiation\n", __FUNCTION__);
+#endif
+ // adjust speed/duplex auto-negotiation mask to clear 100Mbps bits
+ anr = get_reg(sc,PCNET_ANR_AAR);
+ anr &= ~PCNET_ANR_AAR_100;
+ put_reg(sc,PCNET_ANR_AAR,anr);
+ // renegotiate
+ anr = get_reg(sc,PCNET_ANR_PHYCTRL);
+ anr |= PCNET_ANR_PHYCTRL_RENEGOTIATE;
+ put_reg(sc,PCNET_ANR_PHYCTRL,anr);
+ loop = 100000;
+ while (loop>0 && !(get_reg(sc,PCNET_ANR_PHYSTAT) & PCNET_ANR_PHYSTAT_AUTONEG_COMP))
+ loop--;
+#if DEBUG & 9
+ db_printf("ANR0: %04x\n",get_reg(sc,PCNET_ANR_PHYCTRL));
+ db_printf("ANR1: %04x\n",get_reg(sc,PCNET_ANR_PHYSTAT));
+ db_printf("ANR4: %04x\n",get_reg(sc,PCNET_ANR_AAR));
+#endif
+ }
+#endif
+
+ // Prepare RX and TX rings
+ p = cpd->rx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->rx_ring_log_cnt)*PCNET_RD_SIZE));
+ memset(cpd->rx_ring,0,(1<<cpd->rx_ring_log_cnt)*PCNET_RD_SIZE);
+
+ d = cpd->rx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->rx_ring_cnt));
+ memset(cpd->rx_buffers,0,_BUF_SIZE*cpd->rx_ring_cnt);
+
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ HAL_PCI_CPU_TO_BUS(d, b);
+ _SU32(p, PCNET_RD_PTR) = (b & PCNET_RD_PTR_MASK) | PCNET_RD_PTR_OWN;
+ _SU16(p, PCNET_RD_BLEN) = (-_BUF_SIZE);
+ p += PCNET_RD_SIZE;
+ d += _BUF_SIZE;
+ }
+ cpd->rx_ring_next = 0;
+
+ p = cpd->tx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->tx_ring_log_cnt)*PCNET_TD_SIZE));
+ memset(cpd->tx_ring,0,(1<<cpd->tx_ring_log_cnt)*PCNET_TD_SIZE);
+
+ d = cpd->tx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->tx_ring_cnt));
+ for (i = 0; i < cpd->tx_ring_cnt; i++) {
+ HAL_PCI_CPU_TO_BUS(d, b);
+ _SU32(p, PCNET_RD_PTR) = b & PCNET_TD_PTR_MASK;
+ p += PCNET_TD_SIZE;
+ d += _BUF_SIZE;
+ }
+ cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;
+
+ // Initialization table
+ init_table = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(PCNET_IB_SIZE));
+ _SU16(init_table, PCNET_IB_MODE) = 0x0000;
+ for (i = 0; i < 6; i++)
+ _SU8(init_table, PCNET_IB_PADR0+i) = cpd->esa[i];
+ for (i = 0; i < 8; i++)
+ _SU8(init_table, PCNET_IB_LADRF0+i) = 0;
+
+ HAL_PCI_CPU_TO_BUS(cpd->rx_ring, b);
+ _SU32(init_table, PCNET_IB_RDRA) = ((b & PCNET_IB_RDRA_PTR_mask)
+ | (cpd->rx_ring_log_cnt << PCNET_IB_RDRA_CNT_shift));
+ HAL_PCI_CPU_TO_BUS(cpd->tx_ring, b);
+ _SU32(init_table, PCNET_IB_TDRA) = ((b & PCNET_IB_TDRA_PTR_mask)
+ | (cpd->tx_ring_log_cnt << PCNET_IB_TDRA_CNT_shift));
+
+#if DEBUG & 9
+ db_printf("Loading up PCNet controller from table at 0x%08x\n", init_table);
+ db_printf(" Mode 0x%04x\n", _SU16(init_table, PCNET_IB_MODE));
+ db_printf(" PADR %02x:%02x:%02x:%02x:%02x:%02x ",
+ _SU8(init_table, PCNET_IB_PADR0+0), _SU8(init_table, PCNET_IB_PADR0+1),
+ _SU8(init_table, PCNET_IB_PADR0+2), _SU8(init_table, PCNET_IB_PADR0+3),
+ _SU8(init_table, PCNET_IB_PADR0+4), _SU8(init_table, PCNET_IB_PADR0+5));
+ db_printf("LADR %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ _SU8(init_table, PCNET_IB_LADRF0+0), _SU8(init_table, PCNET_IB_LADRF0+1),
+ _SU8(init_table, PCNET_IB_LADRF0+2), _SU8(init_table, PCNET_IB_LADRF0+3),
+ _SU8(init_table, PCNET_IB_LADRF0+4), _SU8(init_table, PCNET_IB_LADRF0+5),
+ _SU8(init_table, PCNET_IB_LADRF0+5), _SU8(init_table, PCNET_IB_LADRF0+7));
+ db_printf(" RX 0x%08x (len %d) TX 0x%08x (len %d)\n",
+ _SU32(init_table, PCNET_IB_RDRA) & 0x1fffffff,
+ (_SU32(init_table, PCNET_IB_RDRA) >> PCNET_IB_RDRA_CNT_shift) & 7,
+ _SU32(init_table, PCNET_IB_TDRA) & 0x1fffffff,
+ (_SU32(init_table, PCNET_IB_TDRA) >> PCNET_IB_TDRA_CNT_shift) & 7);
+#endif
+
+ // Reset chip
+ HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_RESET, val);
+
+ // Load up chip with buffers.
+ // Note: There is a 16M limit on the addresses used by the driver
+ // since the top 8 bits of the init_table address is appended to
+ // all other addresses used by the controller.
+ HAL_PCI_CPU_TO_BUS(init_table, b);
+ put_reg(sc, PCNET_CSR_IBA0, (b >> 0) & 0xffff);
+ put_reg(sc, PCNET_CSR_IBA1, (b >> 16) & 0xffff);
+ // Disable automatic TX polling (_send will force a poll), pad
+ // XT frames to legal length, mask status interrupts.
+ put_reg(sc, PCNET_CSR_TFC, (PCNET_CSR_TFC_TXDPOLL | PCNET_CSR_TFC_APAD_XMT
+ | PCNET_CSR_TFC_MFCOM | PCNET_CSR_TFC_RCVCCOM
+ | PCNET_CSR_TFC_TXSTRTM));
+ // Recover after TX FIFO underflow
+ put_reg(sc, PCNET_CSR_IM, PCNET_CSR_IM_DXSUFLO);
+ // Initialize controller - load up init_table
+ put_reg(sc, PCNET_CSR_CSCR, PCNET_CSR_CSCR_INIT);
+ while (0 == (get_reg(sc, PCNET_CSR_CSCR) & PCNET_CSR_CSCR_IDON));
+
+ // Stop controller
+ put_reg(sc, PCNET_CSR_CSCR, PCNET_CSR_CSCR_STOP);
+
+#if DEBUG & 9
+ db_printf("PCNet controller state is now:\n");
+ db_printf(" Mode 0x%04x TFC 0x%04x\n", _SU16(init_table, PCNET_IB_MODE), get_reg(sc, PCNET_CSR_TFC));
+ db_printf(" PADR %04x:%04x:%04x ",
+ get_reg(sc, PCNET_CSR_PAR0),
+ get_reg(sc, PCNET_CSR_PAR1),
+ get_reg(sc, PCNET_CSR_PAR2));
+ db_printf("LADR %04x:%04x:%04x:%04x\n",
+ get_reg(sc, PCNET_CSR_LAR0),
+ get_reg(sc, PCNET_CSR_LAR1),
+ get_reg(sc, PCNET_CSR_LAR2),
+ get_reg(sc, PCNET_CSR_LAR3));
+ db_printf(" RX 0x%04x%04x (len 0x%04x) TX 0x%04x%04x (len 0x%04x)\n",
+ get_reg(sc, PCNET_CSR_BARRU), get_reg(sc, PCNET_CSR_BARRL),
+ get_reg(sc, PCNET_CSR_RRLEN),
+ get_reg(sc, PCNET_CSR_BATRU), get_reg(sc, PCNET_CSR_BATRL),
+ get_reg(sc, PCNET_CSR_TRLEN));
+
+ val = get_reg(sc, PCNET_CSR_ID_LO);
+ db_printf("PCnet ID 0x%04x (%s) ",
+ val,
+ (0x5003 == val) ? "Am79C973" : (0x7003 == val) ? "Am79C975" : "Unknown");
+ val = get_reg(sc, PCNET_CSR_ID_HI);
+ db_printf("Part IDU 0x%03x Silicon rev %d\n",
+ val & 0x0fff, (val >> 12) & 0xf);
+#endif
+
+ // and record the net dev pointer
+ cpd->ndp = (void *)tab;
+
+ // Start controller, but put it in suspended mode
+ put_reg(sc, PCNET_CSR_CSCR, PCNET_CSR_CSCR_STOP);
+ put_reg(sc, PCNET_CSR_CSCR, (PCNET_CSR_CSCR_IENA | PCNET_CSR_CSCR_STRT));
+ i = 0;
+ while (0 == (PCNET_CSR_CSCR_STRT & get_reg(sc, PCNET_CSR_CSCR))) {
+ CYGACC_CALL_IF_DELAY_US(1000);
+ put_reg(sc, PCNET_CSR_CSCR, (PCNET_CSR_CSCR_IENA | PCNET_CSR_CSCR_STRT));
+ if (i++ == 1000) {
+#if DEBUG & 9
+ db_printf("Failed to start the controller\n");
+#endif
+ return false;
+ }
+ }
+
+ val = get_reg(sc, PCNET_CSR_ECI);
+ val |= PCNET_CSR_ECI_SPND;
+ put_reg(sc, PCNET_CSR_ECI, val);
+ // Wait for device to suspend
+ do {
+ val = get_reg(sc, PCNET_CSR_ECI);
+ } while (0 == (val & PCNET_CSR_ECI_SPND));
+ cpd->active = 0;
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, cpd->esa);
+
+#if DEBUG & 9
+ db_printf("Done\n");
+#endif
+ return true;
+}
+
+static void
+pcnet_stop(struct eth_drv_sc *sc)
+{
+ cyg_uint16 reg;
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ reg = get_reg(sc, PCNET_CSR_ECI);
+ reg |= PCNET_CSR_ECI_SPND;
+ put_reg(sc, PCNET_CSR_ECI, reg);
+ // Wait for device to suspend
+ do {
+ reg = get_reg(sc, PCNET_CSR_ECI);
+ } while (0 == (reg & PCNET_CSR_ECI_SPND));
+ cpd->active = 0;
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+pcnet_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ cyg_uint16 reg;
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+#ifdef CYGPKG_NET
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+ DEBUG_FUNCTION();
+
+ // If device is already active, suspend it
+ if (cpd->active) {
+ reg = get_reg(sc, PCNET_CSR_ECI);
+ reg |= PCNET_CSR_ECI_SPND;
+ put_reg(sc, PCNET_CSR_ECI, reg);
+ // Wait for device to suspend
+ do {
+ reg = get_reg(sc, PCNET_CSR_ECI);
+ } while (0 == (reg & PCNET_CSR_ECI_SPND));
+ cpd->active = 0;
+ }
+
+#ifdef CYGPKG_NET
+ if (( 0
+#ifdef ETH_DRV_FLAGS_PROMISC_MODE
+ != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
+#endif
+ ) || (ifp->if_flags & IFF_PROMISC)
+ ) {
+ // Then we select promiscuous mode.
+ cyg_uint16 rcr;
+ rcr = get_reg(sc, PCNET_CSR_MODE );
+ rcr |= PCNET_CSR_MODE_PROM;
+ put_reg(sc, PCNET_CSR_MODE, rcr );
+ }
+#endif
+
+ // Unsuspend the device
+ reg = get_reg(sc, PCNET_CSR_ECI);
+ reg &= ~PCNET_CSR_ECI_SPND;
+ put_reg(sc, PCNET_CSR_ECI, reg);
+ cpd->active = 1;
+}
+
+//
+// This routine is called to perform special "control" opertions
+//
+static int
+pcnet_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ cyg_uint8 *esa = (cyg_uint8 *)data;
+ int i, res;
+ cyg_uint16 reg;
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+ cyg_bool was_active = cpd->active;
+
+ DEBUG_FUNCTION();
+
+ // If device is already active, suspend it
+ if (cpd->active) {
+ reg = get_reg(sc, PCNET_CSR_ECI);
+ reg |= PCNET_CSR_ECI_SPND;
+ put_reg(sc, PCNET_CSR_ECI, reg);
+ // Wait for device to suspend
+ do {
+ reg = get_reg(sc, PCNET_CSR_ECI);
+ } while (0 == (reg & PCNET_CSR_ECI_SPND));
+ cpd->active = 0;
+ }
+
+ res = 0; // expect success
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+#if 9 & DEBUG
+ db_printf("PCNET - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ esa[0], esa[1], esa[2], esa[3], esa[4], esa[5] );
+#endif // DEBUG
+
+ for ( i = 0; i < sizeof(cpd->esa); i++ )
+ cpd->esa[i] = esa[i];
+ for (i = 0; i < sizeof(cpd->esa); i += 2) {
+ reg = cpd->esa[i] | (cpd->esa[i+1] << 8);
+ put_reg(sc, PCNET_CSR_PAR0+i/2, reg );
+ }
+ break;
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ // Extract the MAC address that is in the chip, and tell the
+ // system about it.
+ for (i = 0; i < sizeof(cpd->esa); i += 2) {
+ cyg_uint16 z = get_reg(sc, PCNET_CSR_PAR0+i/2 );
+ esa[i] = (cyg_uint8)(0xff & z);
+ esa[i+1] = (cyg_uint8)(0xff & (z >> 8));
+ }
+ break;
+#endif
+
+#ifdef ETH_DRV_GET_IF_STATS_UD
+ case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+#endif
+ // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+ case ETH_DRV_GET_IF_STATS:
+#endif
+
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+ {
+ cyg_uint16 anr;
+ struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+ // Chipset entry is no longer supported; RFC1573.
+ for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+ p->snmp_chipset[i] = 0;
+
+ // This perhaps should be a config opt, so you can make up your own
+ // description, or supply it from the instantiation.
+ strcpy( p->description, "AMD PCNet" );
+ // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+ anr = get_reg(sc, PCNET_ANR_PHYSTAT);
+ if ((anr & PCNET_ANR_PHYSTAT_LINK) == 0) {
+ p->operational = 2; // LINK DOWN
+ p->duplex = 1; // UNKNOWN
+ p->speed = 0;
+ }
+ else {
+ p->operational = 3; // LINK UP
+ anr = get_reg(sc, PCNET_ANR_PHYCTRL);
+
+ if (anr & PCNET_ANR_PHYCTRL_DUPLEX)
+ p->duplex = 3; // 3 = DUPLEX
+ else
+ p->duplex = 2; // 2 = SIMPLEX
+ p->speed = (anr & PCNET_ANR_PHYCTRL_100MBPS) ? 100 * 1000000 : 10 * 1000000;
+ }
+
+#if FIXME
+#ifdef KEEP_STATISTICS
+ {
+ struct amd_pcnet_stats *ps = &(cpd->stats);
+
+ // Admit to it...
+ p->supports_dot3 = true;
+
+ p->tx_good = ps->tx_good ;
+ p->tx_max_collisions = ps->tx_max_collisions ;
+ p->tx_late_collisions = ps->tx_late_collisions ;
+ p->tx_underrun = ps->tx_underrun ;
+ p->tx_carrier_loss = ps->tx_carrier_loss ;
+ p->tx_deferred = ps->tx_deferred ;
+ p->tx_sqetesterrors = ps->tx_sqetesterrors ;
+ p->tx_single_collisions = ps->tx_single_collisions;
+ p->tx_mult_collisions = ps->tx_mult_collisions ;
+ p->tx_total_collisions = ps->tx_total_collisions ;
+ p->rx_good = ps->rx_good ;
+ p->rx_crc_errors = ps->rx_crc_errors ;
+ p->rx_align_errors = ps->rx_align_errors ;
+ p->rx_resource_errors = ps->rx_resource_errors ;
+ p->rx_overrun_errors = ps->rx_overrun_errors ;
+ p->rx_collisions = ps->rx_collisions ;
+ p->rx_short_frames = ps->rx_short_frames ;
+ p->rx_too_long_frames = ps->rx_too_long_frames ;
+ p->rx_symbol_errors = ps->rx_symbol_errors ;
+
+ p->interrupts = ps->interrupts ;
+ p->rx_count = ps->rx_count ;
+ p->rx_deliver = ps->rx_deliver ;
+ p->rx_resource = ps->rx_resource ;
+ p->rx_restart = ps->rx_restart ;
+ p->tx_count = ps->tx_count ;
+ p->tx_complete = ps->tx_complete ;
+ p->tx_dropped = ps->tx_dropped ;
+ }
+#endif // KEEP_STATISTICS
+#endif // FIXME
+
+ p->tx_queue_len = 1;
+ break;
+ }
+#endif
+ default:
+ res = 1;
+ break;
+ }
+
+ // Restore controller state
+ if (was_active) {
+ // Unsuspend the device
+ reg = get_reg(sc, PCNET_CSR_ECI);
+ reg &= ~PCNET_CSR_ECI_SPND;
+ put_reg(sc, PCNET_CSR_ECI, reg);
+ }
+
+ return res;
+}
+
+//
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+//
+static int
+pcnet_can_send(struct eth_drv_sc *sc)
+{
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+ cyg_uint16 stat;
+
+ DEBUG_FUNCTION();
+
+ stat = get_reg(sc, PCNET_ANR_PHYSTAT);
+ if ((stat & PCNET_ANR_PHYSTAT_LINK) == 0) {
+ return 0; // Link not connected
+ }
+
+ return (0 == cpd->txbusy);
+}
+
+//
+// This routine is called to send data to the hardware.
+static void
+pcnet_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+ int i, len, plen, ring_entry;
+
+ cyg_uint8* sdata = NULL;
+ cyg_uint8 *d, *buf, *txd;
+ cyg_uint16 ints;
+ cyg_uint32 b;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( tx_count );
+
+ cpd->txbusy = 1;
+ cpd->txkey = key;
+
+ // Find packet length
+ plen = 0;
+ for (i = 0; i < sg_len; i++)
+ plen += sg_list[i].len;
+
+ CYG_ASSERT( plen == total_len, "sg data length mismatch" );
+
+ // Get next TX descriptor
+ ring_entry = cpd->tx_ring_free;
+ do {
+ if (cpd->tx_ring_owned == cpd->tx_ring_cnt) {
+ // Is this a dead end? Probably is.
+#if DEBUG & 1
+ db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
+#endif
+ continue;
+ }
+
+ cpd->tx_ring_free++;
+ cpd->tx_ring_owned++;
+ if (cpd->tx_ring_free == cpd->tx_ring_cnt)
+ cpd->tx_ring_free = 0;
+ } while (0);
+
+ txd = cpd->tx_ring + ring_entry*PCNET_TD_SIZE;
+ buf = cpd->tx_buffers + ring_entry*_BUF_SIZE;
+ CYG_ASSERT(0 == (_SU32(txd, PCNET_TD_PTR) & PCNET_TD_PTR_OWN),
+ "TX descriptor not free");
+
+#if DEBUG & 4
+ db_printf("#####Tx descriptor 0x%08x buffer 0x%08x\n",
+ txd, buf);
+#endif
+
+ // Put data into buffer
+ d = buf;
+ for (i = 0; i < sg_len; i++) {
+ sdata = (cyg_uint8 *)sg_list[i].buf;
+ len = sg_list[i].len;
+
+ CYG_ASSERT( sdata, "No sg data pointer here" );
+ while(len--)
+ *d++ = *sdata++;
+ }
+ CYG_ASSERT( sdata, "No sg data pointer outside" );
+
+#if DEBUG & 1
+ db_printf("CSCR %04x\n", get_reg(sc, PCNET_CSR_CSCR));
+#endif
+ _SU16(txd, PCNET_TD_LEN) = (-plen);
+ _SU16(txd, PCNET_TD_MISC) = 0;
+ HAL_PCI_CPU_TO_BUS(buf, b);
+ _SU32(txd, PCNET_TD_PTR) = ((b & PCNET_TD_PTR_MASK)
+ | PCNET_TD_PTR_OWN | PCNET_TD_PTR_STP | PCNET_TD_PTR_ENP);
+
+#if DEBUG & 1
+ db_printf("Last TX: LEN %04x MISC %04x PTR %08x\n",
+ _SU16(txd, PCNET_TD_LEN),
+ _SU16(txd, PCNET_TD_MISC),
+ _SU32(txd, PCNET_TD_PTR));
+#endif
+
+ // This delay seems to be necessary on some platforms
+ // (Malta 5kc for example).
+ // Why it is needed is not clear, but removing it or
+ // reducing it cause transmission failures in RedBoot (at least).
+ CYGACC_CALL_IF_DELAY_US(100);
+
+
+ // Set transmit demand
+ ints = get_reg(sc, PCNET_CSR_CSCR);
+ ints &= PCNET_CSR_CSCR_EV_MASK;
+ ints |= PCNET_CSR_CSCR_TDMD;
+ put_reg(sc, PCNET_CSR_CSCR, ints);
+
+#if DEBUG & 1
+ ints = get_reg(sc, PCNET_CSR_CSCR);
+ db_printf("%s:END: ints at TX: 0x%04x\n", __FUNCTION__, ints);
+#endif
+
+ // This is another mystery delay like the one above. This one is
+ // even stranger, since waiting here at the _end_ of the function
+ // should have no effect.
+ CYGACC_CALL_IF_DELAY_US(200);
+}
+
+static void
+pcnet_TxEvent(struct eth_drv_sc *sc, int stat)
+{
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+ int success = 1;
+ cyg_uint8 *txd;
+ cyg_uint16 ints;
+ cyg_uint32 pkt_stat;
+
+ DEBUG_FUNCTION();
+
+ if (0 == cpd->tx_ring_owned) {
+#if DEBUG & 1
+ db_printf("%s: got TX completion when no outstanding packets\n", __FUNCTION__);
+#endif
+ return;
+ }
+
+ INCR_STAT( tx_complete );
+
+ txd = cpd->tx_ring + cpd->tx_ring_alloc*PCNET_TD_SIZE;
+ pkt_stat = _SU32(txd, PCNET_TD_PTR);
+ if (pkt_stat & PCNET_TD_PTR_OWN) {
+#if DEBUG & 1
+ db_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__);
+#endif
+ // first dirty ring entry not freed - wtf?
+ }
+
+ if (pkt_stat & PCNET_TD_PTR_ERR) {
+ // We had an error. Tell the stack.
+ success = 0;
+#if DEBUG & 1
+ db_printf("%s: TX failure, retrying...\n", __FUNCTION__);
+#endif
+ }
+
+ cpd->tx_ring_alloc++;
+ if (cpd->tx_ring_alloc == cpd->tx_ring_cnt)
+ cpd->tx_ring_alloc = 0;
+ cpd->tx_ring_owned--;
+
+#if FIXME
+#ifdef KEEP_STATISTICS
+ {
+ cyg_uint16 reg;
+
+ reg = get_reg( sc, PCNET_CSR_CSCR );
+
+ // Covering each bit in turn...
+ if ( reg & PCNET_STATUS_TX_UNRN ) INCR_STAT( tx_underrun );
+ //if ( reg & PCNET_STATUS_LINK_OK ) INCR_STAT( );
+ //if ( reg & PCNET_STATUS_CTR_ROL ) INCR_STAT( );
+ //if ( reg & PCNET_STATUS_EXC_DEF ) INCR_STAT( );
+ if ( reg & PCNET_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss );
+ if ( reg & PCNET_STATUS_LATCOL ) INCR_STAT( tx_late_collisions );
+ //if ( reg & PCNET_STATUS_WAKEUP ) INCR_STAT( );
+ if ( reg & PCNET_STATUS_TX_DEFR ) INCR_STAT( tx_deferred );
+ //if ( reg & PCNET_STATUS_LTX_BRD ) INCR_STAT( );
+ if ( reg & PCNET_STATUS_SQET ) INCR_STAT( tx_sqetesterrors );
+ if ( reg & PCNET_STATUS_16COL ) INCR_STAT( tx_max_collisions );
+ //if ( reg & PCNET_STATUS_LTX_MULT) INCR_STAT( );
+ if ( reg & PCNET_STATUS_MUL_COL ) INCR_STAT( tx_mult_collisions );
+ if ( reg & PCNET_STATUS_SNGL_COL ) INCR_STAT( tx_single_collisions );
+ if ( reg & PCNET_STATUS_TX_SUC ) INCR_STAT( tx_good );
+
+ cpd->stats.tx_total_collisions =
+ cpd->stats.tx_late_collisions +
+ cpd->stats.tx_max_collisions +
+ cpd->stats.tx_mult_collisions +
+ cpd->stats.tx_single_collisions;
+
+ // We do not need to look in the Counter Register (PCNET_COUNTER)
+ // because it just mimics the info we already have above.
+ }
+#endif // KEEP_STATISTICS
+#endif // FIXME
+
+ // Ack the TX int which clears the packet from the TX completion
+ // queue.
+ ints = get_reg(sc, PCNET_CSR_CSCR);
+ ints |= PCNET_CSR_CSCR_TINT;
+ put_reg(sc, PCNET_CSR_CSCR, ints);
+
+#if DEBUG & 4
+ db_printf("#####Tx packet freed 0x%08x\n", txd );
+#endif
+
+ if ( cpd->txbusy ) {
+ cpd->txbusy = 0;
+ (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
+ }
+}
+
+
+//
+// This function is called when a packet has been received. Its job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'pcnet_recv' will be called to actually fetch it from the hardware.
+//
+static void
+pcnet_RxEvent(struct eth_drv_sc *sc)
+{
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+ cyg_uint8 *rxd;
+ cyg_uint32 rstat;
+ cyg_uint16 ints, len;
+
+ DEBUG_FUNCTION();
+
+ ints = get_reg(sc, PCNET_CSR_CSCR);
+#if DEBUG & 1
+ db_printf("RxEvent - CSR: 0x%04x\n", ints);
+#endif
+
+ while (1) {
+ // Get state of next (supposedly) full ring entry
+ cpd->rxpacket = cpd->rx_ring_next;
+ rxd = cpd->rx_ring + cpd->rxpacket*PCNET_RD_SIZE;
+ rstat = _SU32(rxd, PCNET_RD_PTR);
+
+ // Keep going until we hit an entry that is owned by the
+ // controller.
+ if (rstat & PCNET_RD_PTR_OWN) {
+#if DEBUG & 1
+ int i;
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*PCNET_RD_SIZE;
+ rstat = _SU32(rxd, PCNET_RD_PTR);
+
+ if (!(rstat & PCNET_RD_PTR_OWN)) {
+ int i;
+ cyg_uint32 rstat;
+ cyg_uint16 mlen, blen;
+ cyg_uint8* rxd;
+
+ db_printf("%s: Inconsistent RX state\n", __FUNCTION__);
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*PCNET_RD_SIZE;
+
+ rstat = _SU32(rxd, PCNET_RD_PTR);
+ blen = _SU16(rxd, PCNET_RD_BLEN);
+ mlen = _SU16(rxd, PCNET_RD_MLEN);
+ db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
+ }
+ }
+ }
+#endif
+ break;
+ }
+
+#if DEBUG & 4
+ db_printf("#####Rx packet at index %d\n", cpd->rxpacket);
+#endif
+
+ // Increment counts
+ INCR_STAT( rx_count );
+ cpd->rx_ring_next++;
+ if (cpd->rx_ring_next == cpd->rx_ring_cnt) cpd->rx_ring_next = 0;
+
+ len = _SU16(rxd, PCNET_RD_MLEN);
+
+#ifdef KEEP_STATISTICS
+ //if ( rstat & PCNET_RD_PTR_FRAM ) INCR_STAT( rx_frame_errors );
+ //if ( rstat & PCNET_RD_PTR_OFLO ) INCR_STAT( );
+ if ( rstat & PCNET_RD_PTR_CRC ) INCR_STAT( rx_crc_errors );
+ //if ( rstat & PCNET_RD_PTR_BUFF ) INCR_STAT( );
+#endif // KEEP_STATISTICS
+
+ if (0 == (rstat & PCNET_RD_PTR_ERR)) {
+ // It's OK
+ INCR_STAT( rx_good );
+
+#if DEBUG & 1
+ db_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len);
+#endif
+ // Check for bogusly short packets; can happen in promisc
+ // mode: Asserted against and checked by upper layer
+ // driver.
+#ifdef CYGPKG_NET
+ if ( len > sizeof( struct ether_header ) )
+ // then it is acceptable; offer the data to the network stack
+#endif
+ (sc->funs->eth_drv->recv)(sc, len);
+ } else {
+ // Not OK for one reason or another...
+#if DEBUG & 1
+ db_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n",
+ rstat, len);
+#endif
+ }
+
+ // Free packet (clear all status flags, and set OWN)
+ _SU32(rxd, PCNET_RD_PTR) &= PCNET_RD_PTR_MASK;
+ _SU32(rxd, PCNET_RD_PTR) |= PCNET_RD_PTR_OWN;
+ }
+
+ // Ack RX interrupt set
+ ints = get_reg(sc, PCNET_CSR_CSCR);
+ ints &= PCNET_CSR_CSCR_EV_MASK;
+ ints |= PCNET_CSR_CSCR_RINT;
+ put_reg(sc, PCNET_CSR_CSCR, ints);
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// Its job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+pcnet_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+ int i, mlen=0, plen;
+ cyg_uint8 *data, *rxd, *buf;
+
+ DEBUG_FUNCTION();
+
+ rxd = cpd->rx_ring + cpd->rxpacket*PCNET_RD_SIZE;
+ buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
+
+ INCR_STAT( rx_deliver );
+
+ plen = _SU16(rxd, PCNET_RD_MLEN);
+
+ for (i = 0; i < sg_len; i++) {
+ data = (cyg_uint8*)sg_list[i].buf;
+ mlen = sg_list[i].len;
+
+#if DEBUG & 1
+ db_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
+#endif
+ if (data) {
+ while (mlen > 0) {
+ *data++ = *buf++;
+ mlen--;
+ plen--;
+ }
+ }
+ }
+}
+
+static void
+pcnet_poll(struct eth_drv_sc *sc)
+{
+ cyg_uint16 event;
+
+// DEBUG_FUNCTION();
+
+ while (1) {
+ // Get the (unmasked) requests
+ event = get_reg(sc, PCNET_CSR_CSCR);
+ if (!((PCNET_CSR_CSCR_ERR|PCNET_CSR_CSCR_INTR) & event))
+ break;
+
+ if (event & PCNET_CSR_CSCR_RINT) {
+ pcnet_RxEvent(sc);
+ }
+ else if (event & PCNET_CSR_CSCR_TINT) {
+ pcnet_TxEvent(sc, event);
+ }
+ else if (event & PCNET_CSR_CSCR_MISS) {
+#if DEBUG & 1
+ int i;
+ cyg_uint32 rstat;
+ cyg_uint16 mlen, blen;
+ cyg_uint8* rxd;
+ struct pcnet_priv_data *cpd =
+ (struct pcnet_priv_data *)sc->driver_private;
+
+ db_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event);
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*PCNET_TD_SIZE;
+
+ rstat = _SU32(rxd, PCNET_RD_PTR);
+ blen = _SU16(rxd, PCNET_RD_BLEN);
+ mlen = _SU16(rxd, PCNET_RD_MLEN);
+ db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
+ }
+#endif
+ event &= PCNET_CSR_CSCR_EV_MASK;
+ event |= PCNET_CSR_CSCR_MISS;
+ put_reg(sc, PCNET_CSR_CSCR, event);
+ }
+ else {
+#if DEBUG & 1
+ db_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event);
+#endif
+ put_reg(sc, PCNET_CSR_CSCR, event);
+ }
+ }
+}
+
+// EOF if_pcnet.c
diff --git a/ecos/packages/devs/eth/arm/aaed2000/current/ChangeLog b/ecos/packages/devs/eth/arm/aaed2000/current/ChangeLog
new file mode 100644
index 0000000..ec8dd53
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/aaed2000/current/ChangeLog
@@ -0,0 +1,63 @@
+2002-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/aaed2000_eth_drivers.cdl: Don't define CYGHWR_NET_DRIVERS,
+ as it's defined by the generic driver.
+
+2001-11-29 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_arm_aaed2000.inl: Always include ESA run-time
+ lookup.
+
+2001-11-19 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_arm_aaed2000.inl (_aaed2000_provide_eth0_esa):
+ Use VV calls instead of RedBoot functions.
+
+2001-11-09 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_arm_aaed2000.inl: RedBoot ESA options updated
+ and added reader for those.
+
+2001-11-08 Jesper Skov <jskov@redhat.com>
+
+ * cdl/aaed2000_eth_drivers.cdl: Added NET implement statements.
+
+ * include/devs_eth_arm_aaed2000.inl: Moved the redboot eth0_esa
+ config here.
+
+2001-11-07 Jesper Skov <jskov@redhat.com>
+
+ * src/if_aaed2000.c: [deleted]
+ * src/cs8900.h: [deleted]
+ * include/devs_eth_arm_aaed2000.inl: [added] Definitions for
+ generic driver.
+
+ * cdl/aaed2000_eth_drivers.cdl: Changes for using generic driver.
+
+2001-10-30 Jesper Skov <jskov@redhat.com>
+
+ * Imported sources from Gary Thomas.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/aaed2000/current/cdl/aaed2000_eth_drivers.cdl b/ecos/packages/devs/eth/arm/aaed2000/current/cdl/aaed2000_eth_drivers.cdl
new file mode 100644
index 0000000..5bfaa2e
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/aaed2000/current/cdl/aaed2000_eth_drivers.cdl
@@ -0,0 +1,108 @@
+# ====================================================================
+#
+# aaed2000_eth_drivers.cdl
+#
+# Ethernet driver for Agilent AAED2000 development system
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2001-10-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_AAED2000 {
+ display "Ethernet driver for Agilent AAED2000 development board"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_ARM9_AAED2000
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the CL CS8900A package
+ cdl_interface CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED {
+ display "Cirrus Logic CS8900A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_INL <cyg/io/devs_eth_arm_aaed2000.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_CFG <pkgconf/devs_eth_arm_aaed2000.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_AAED2000_ETH0 {
+ display "AAED2000 ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ AAED2000 port."
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_AAED2000_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_AAED2000_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ calculated 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_AAED2000_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/arm/aaed2000/current/include/devs_eth_arm_aaed2000.inl b/ecos/packages/devs/eth/arm/aaed2000/current/include/devs_eth_arm_aaed2000.inl
new file mode 100644
index 0000000..4f90b88
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/aaed2000/current/include/devs_eth_arm_aaed2000.inl
@@ -0,0 +1,146 @@
+//==========================================================================
+//
+// devs_eth_arm_aaed2000.inl
+//
+// AAED2000 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-11-06
+// Purpose: AAED2000 ethernet defintions
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+#include <cyg/hal/hal_if.h>
+
+#ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+# endif
+#endif
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_ARM_AAED2000_ETH0
+
+#if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_ARM_AAED2000_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_ARM_AAED2000_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+#endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+// Note that this section *is* active in an application, outside RedBoot,
+// where the above section is not included.
+
+# include <cyg/hal/hal_if.h>
+
+# ifndef CONFIG_ESA
+# define CONFIG_ESA (6)
+# endif
+# ifndef CONFIG_BOOL
+# define CONFIG_BOOL (1)
+# endif
+
+cyg_bool
+_aaed2000_provide_eth0_esa(struct cs8900a_priv_data* cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa", &set_esa, CONFIG_BOOL);
+ if (ok && set_esa) {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data", cpd->esa, CONFIG_ESA);
+ }
+
+ return ok && set_esa;
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+static cs8900a_priv_data_t cs8900a_eth0_priv_data = {
+ base : (cyg_addrword_t) 0x10000300,
+ interrupt: CYGNUM_HAL_INTERRUPT_ETH,
+#ifdef CYGSEM_DEVS_ETH_ARM_AAED2000_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_ARM_AAED2000_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &_aaed2000_provide_eth0_esa,
+#else
+ provide_esa : NULL,
+#endif
+};
+
+ETH_DRV_SC(cs8900a_sc,
+ &cs8900a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_AAED2000_ETH0_NAME,
+ cs8900a_start,
+ cs8900a_stop,
+ cs8900a_control,
+ cs8900a_can_send,
+ cs8900a_send,
+ cs8900a_recv,
+ cs8900a_deliver, // "pseudoDSR" called from fast net thread
+ cs8900a_poll, // poll function, encapsulates ISR and DSR
+ cs8900a_int_vector);
+
+NETDEVTAB_ENTRY(cs8900a_netdev,
+ "cs8900a_" CYGDAT_DEVS_ETH_ARM_AAED2000_ETH0_NAME,
+ cs8900a_init,
+ &cs8900a_sc);
+
+#endif // CYGPKG_DEVS_ETH_ARM_AAED2000_ETH0
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_arm_aaed2000.inl
diff --git a/ecos/packages/devs/eth/arm/at91/current/ChangeLog b/ecos/packages/devs/eth/arm/at91/current/ChangeLog
new file mode 100755
index 0000000..967f8c6
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/at91/current/ChangeLog
@@ -0,0 +1,49 @@
+2010-08-02 John Dallaway <john@dallaway.org.uk>
+
+ * src/if_at91.c: Invert test for NSR IDLE bit. Issue reported by
+ Will Wagner.
+
+2007-04-08 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/at91_eth.cdl: Fixed typo. (Removed AT91RM9200 from
+ CYGPKG_DEVS_ETH_ARM_AT91_DEBUG_LEVEL)
+
+2007-03-23 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * src/if_at91.c: Added support for the ETH_DRV_SET_MAC_ADDRESS
+ control key. Added functionality to clear the transmit buffer
+ ownershiop bits when the TXCOMP status is detected.
+
+2007-01-17 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * src/if_at91.c, include/at91_eth.cdl: Working implementation
+ of a device driver for the AT91 EMAC device.
+
+2006-06-02 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/if_at91.c, include/at91_eth.cdl: Partially implementation
+ of a device driver for the AT91 EMAC device.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006, 2010 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/at91/current/cdl/at91_eth.cdl b/ecos/packages/devs/eth/arm/at91/current/cdl/at91_eth.cdl
new file mode 100755
index 0000000..12f8d7b
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/at91/current/cdl/at91_eth.cdl
@@ -0,0 +1,164 @@
+#==========================================================================
+#
+# at91_eth.cdl
+#
+# Ethernet drivers for Atmel AT91 Cores
+#
+#==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Andrew Lunn
+# Contributors:
+# Date: 2006-05-10
+# Purpose:
+# Description:
+#
+#####DESCRIPTIONEND####
+#
+#========================================================================*/
+
+cdl_package CYGPKG_DEVS_ETH_ARM_AT91 {
+ display "Atmel AT91 ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ include_dir net
+ description "
+ Ethernet driver for Atmel AT91 core. This has been tested with the
+ AT91SAM7X, but should be easy to get to work on other AT91 cores that
+ have the EMAC core."
+
+ compile -library=libextras.a if_at91.c
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_AT91_DEBUG_LEVEL {
+ display "Driver debug output level"
+ flavor data
+ legal_values {0 1 2}
+ default_value 1
+ description "
+ This option specifies the level of debug data output by
+ the AT91 ethernet device driver. A value of 0 signifies
+ no debug data output; 1 signifies normal debug data
+ output; and 2 signifies maximum debug data output (not
+ suitable when GDB and application are sharing an ethernet
+ port)."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS {
+ display "Number of RX buffers"
+ flavor data
+ default_value 32
+ description "
+ Number of receive buffers. Each buffer is 128 bytes in size"
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS {
+ display "Number of TX buffers"
+ flavor data
+ default_value 10
+ description "
+ Number of transmit buffer descriptors. We need one descriptor
+ for each element in the scatter/gather list."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_AT91_PHYADDR {
+ display "PHY MII address"
+ flavor data
+ legal_values 0 to 31
+ default_value 1
+ description "This option specifies the MII address of the PHY"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 0
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ active_if (CYGPKG_REDBOOT || CYGSEM_HAL_USE_ROM_MONITOR)
+
+ description "
+ Enabling this option will allow the ethernet station
+ address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually
+ by the 'Set the ethernet station address' option for each
+ interface."
+
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA_VARS {
+ display "Export RedBoot command to set ESA in FLASH config"
+ flavor none
+ no_define
+ description "
+ This component contains options which, when enabled, allow
+ RedBoot to support the setting of the ESA in the FLASH
+ configuration. This can then subsequently be accessed by
+ applications using virtual vector calls if those applications
+ are also built with
+ CYGPKG_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA enabled."
+
+ cdl_option CYGSEM_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 1
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+ }
+ }
+ }
+ cdl_option CYGPKG_DEVS_ETH_ARM_AT91_MACADDR {
+ display "Ethernet station (MAC) address for eth0"
+ flavor data
+ default_value {"0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC"}
+ description "The default ethernet station address. This is the
+ MAC address used when no value is found in the
+ RedBoot FLASH configuration field."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_AT91_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Atmel AT91 ethernet driver package.
+ These flags are used in addition to the set of global flags."
+ }
+}
+
+# EOF at91_eth.cdl
diff --git a/ecos/packages/devs/eth/arm/at91/current/src/if_at91.c b/ecos/packages/devs/eth/arm/at91/current/src/if_at91.c
new file mode 100755
index 0000000..2aabf94
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/at91/current/src/if_at91.c
@@ -0,0 +1,1030 @@
+//==========================================================================
+//
+// if_at91.c
+//
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2010 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Andrew Lunn, John Eigelaar
+// Contributors:
+// Date: 2006-05-10
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_eth_arm_at91.h>
+#include <pkgconf/io_eth_drivers.h>
+#if defined(CYGPKG_REDBOOT)
+ #include <pkgconf/redboot.h>
+#endif
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/eth_drv_stats.h>
+#include <cyg/io/eth_phy.h>
+#include <errno.h>
+#include <string.h>
+
+// Set up the level of debug output
+#if CYGPKG_DEVS_ETH_ARM_AT91_DEBUG_LEVEL > 0
+ #define debug1_printf(args...) diag_printf(args)
+#else
+ #define debug1_printf(args...)
+#endif
+#if CYGPKG_DEVS_ETH_ARM_AT91_DEBUG_LEVEL > 1
+ #define debug2_printf(args...) diag_printf(args)
+#else
+ #define debug2_printf(args...)
+#endif
+
+//Driver interface callbacks
+#define _eth_drv_init(sc,mac) \
+ (sc->funs->eth_drv->init)(sc,(unsigned char *)mac)
+#define _eth_drv_tx_done(sc,key,status) \
+ (sc->funs->eth_drv->tx_done)(sc,key,status)
+#define _eth_drv_recv(sc,len) \
+ (sc->funs->eth_drv->recv)(sc,len)
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32
+at91_eth_isr (cyg_vector_t vector, cyg_addrword_t data);
+#endif
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// Decide whether to have redboot config vars for it...
+#if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGPKG_REDBOOT_NETWORKING)
+ #include <redboot.h>
+ #include <flash_config.h>
+
+ #ifdef CYGSEM_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa_data,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0);
+ #endif
+
+#endif // CYGPKG_REDBOOT_NETWORKING && CYGSEM_REDBOOT_FLASH_CONFIG
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_ARM_AT91_REDBOOT_HOLDS_ESA
+
+ #include <cyg/hal/hal_if.h>
+
+ #ifndef CONFIG_ESA
+ #define CONFIG_ESA (6)
+ #endif
+
+ #define CYGHWR_DEVS_ETH_ARM_AT91_GET_ESA( mac_address, ok ) \
+ CYG_MACRO_START \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa_data", \
+ mac_address, \
+ CONFIG_ESA); \
+ CYG_MACRO_END
+
+#endif // CYGPKG_DEVS_ETH_AT91_ETH_REDBOOT_HOLDS_ESA
+
+//============================================================================
+
+// Private Data structures
+
+#ifndef AT91_EMAC_RX_BUFF_SIZE
+#define AT91_EMAC_RX_BUFF_SIZE 128
+#endif
+
+// Receive Buffer Descriptor
+typedef struct rbd_s
+{
+ cyg_uint32 addr;
+ cyg_uint32 sr;
+} rbd_t;
+
+// Receive Buffer
+typedef struct rb_s
+{
+ cyg_uint8 rb[AT91_EMAC_RX_BUFF_SIZE];
+} rb_t;
+
+// Transmit Buffer Descriptor
+typedef struct tbd_s
+{
+ cyg_uint32 addr;
+ cyg_uint32 sr;
+} tbd_t;
+
+// AT91 Ethernet private data
+typedef struct at91_eth_priv_s
+{
+ cyg_uint32 intr_vector;
+ char *esa_key; // RedBoot 'key' for device ESA
+ cyg_uint8 *enaddr;
+ cyg_uint32 base; // Base address of device
+ eth_phy_access_t *phy;
+ rbd_t rbd[CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS];
+ rb_t rb[CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS];
+ tbd_t tbd[CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS];
+ unsigned long curr_tx_key;
+ cyg_bool tx_busy;
+ cyg_uint32 last_tbd_idx;
+ cyg_uint32 curr_tbd_idx;
+ cyg_uint32 curr_rbd_idx;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_interrupt intr;
+ cyg_handle_t intr_handle;
+#endif
+} at91_eth_priv_t;
+
+//============================================================================
+// PHY access bits and pieces
+//
+
+static void
+at91_mdio_enable(void)
+{
+ cyg_uint32 val;
+ HAL_READ_UINT32(AT91_EMAC + AT91_EMAC_NCR, val);
+ val |= AT91_EMAC_NCR_MPE; /* enable management port */
+ HAL_WRITE_UINT32(AT91_EMAC + AT91_EMAC_NCR, val);
+}
+
+static void
+at91_mdio_disable(void)
+{
+ cyg_uint32 val;
+ HAL_READ_UINT32(AT91_EMAC + AT91_EMAC_NCR, val);
+ val &= ~AT91_EMAC_NCR_MPE; /* disable management port */
+ HAL_WRITE_UINT32(AT91_EMAC + AT91_EMAC_NCR, val);
+}
+
+// Write one of the PHY registers via the MII bus
+static void
+at91_write_phy(int reg_addr, int phy_addr, unsigned short data)
+{
+ cyg_uint32 val, cnt=0;
+
+ CYG_ASSERTC(reg_addr >= 0 && reg_addr <= AT91_EMAC_MAN_REGA_MASK);
+ CYG_ASSERTC(phy_addr >= 0 && phy_addr <= AT91_EMAC_MAN_PHY_MASK);
+
+ val = (AT91_EMAC_MAN_SOF |
+ AT91_EMAC_MAN_WR |
+ AT91_EMAC_MAN_CODE |
+ AT91_EMAC_MAN_PHYA(phy_addr) |
+ AT91_EMAC_MAN_REGA(reg_addr) |
+ AT91_EMAC_MAN_DATA(data));
+
+ HAL_WRITE_UINT32(AT91_EMAC + AT91_EMAC_MAN, val);
+
+ /* Wait until IDLE bit in Network Status register is set */
+ while (cnt < 1000000)
+ {
+ HAL_READ_UINT32((AT91_EMAC + AT91_EMAC_NSR), val);
+ if (!(val & AT91_EMAC_NSR_IDLE))
+ break;
+ }
+ CYG_ASSERTC(cnt < 1000000);
+}
+
+
+// Read one of the PHY registers via the MII bus
+static bool
+at91_read_phy(int reg_addr, int phy_addr, unsigned short *data)
+{
+ cyg_uint32 val;
+
+ CYG_ASSERTC(reg_addr >= 0 && reg_addr <= AT91_EMAC_MAN_REGA_MASK);
+ CYG_ASSERTC(phy_addr >= 0 && phy_addr <= AT91_EMAC_MAN_PHY_MASK);
+
+ val = (AT91_EMAC_MAN_SOF |
+ AT91_EMAC_MAN_RD |
+ AT91_EMAC_MAN_CODE |
+ AT91_EMAC_MAN_PHYA(phy_addr) |
+ AT91_EMAC_MAN_REGA(reg_addr));
+
+
+ HAL_WRITE_UINT32(AT91_EMAC + AT91_EMAC_MAN, val);
+ /* Wait until IDLE bit in Network Status register is set */
+ do
+ {
+ HAL_READ_UINT32((AT91_EMAC + AT91_EMAC_NSR), val);
+ }while(!(val & AT91_EMAC_NSR_IDLE));
+
+ HAL_DELAY_US(50);
+
+ HAL_READ_UINT32(AT91_EMAC + AT91_EMAC_MAN, val);
+ *data = val & AT91_EMAC_MAN_DATA_MASK;
+
+ return (true);
+}
+
+// Enable the MDIO bit in MAC control register so that we can talk to
+// the PHY. Also set the clock divider so that MDC is less than 2.5MHz.
+static void
+at91_init_phy(void)
+{
+ cyg_uint32 cfg;
+ cyg_uint32 div;
+
+ HAL_READ_UINT32(AT91_EMAC + AT91_EMAC_NCFG, cfg);
+ cfg &=~ AT91_EMAC_NCFG_CLK_MASK;
+
+ div = (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / 2500000);
+ if (div < 8)
+ {
+ cfg |= AT91_EMAC_NCFG_CLK_HCLK_8;
+ }
+ else if (div < 16)
+ {
+ cfg |= AT91_EMAC_NCFG_CLK_HCLK_16;
+ }
+ else if (div < 32)
+ {
+ cfg |= AT91_EMAC_NCFG_CLK_HCLK_32;
+ }
+ else if (div < 64)
+ {
+ cfg |= AT91_EMAC_NCFG_CLK_HCLK_64;
+ }
+ else
+ {
+ CYG_FAIL("Unable to program MII clock");
+ }
+
+ HAL_WRITE_UINT32(AT91_EMAC + AT91_EMAC_NCFG, cfg);
+}
+
+ETH_PHY_REG_LEVEL_ACCESS_FUNS(at91_phy,
+ at91_init_phy,
+ NULL,
+ at91_write_phy,
+ at91_read_phy);
+
+//======================================================================
+// Receiver buffer handling
+
+// Initialize the receiver buffers and descriptors
+static void
+at91_rb_init(at91_eth_priv_t *priv)
+{
+ int i;
+ for (i = 0 ; i < CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS; i++)
+ {
+ priv->rbd[i].addr = ((cyg_uint32)&priv->rb[i]) & AT91_EMAC_RBD_ADDR_MASK;
+ priv->rbd[i].sr = 0;
+ }
+ // Set the wrap bit on the last entry
+ priv->rbd[CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS-1].addr |=
+ AT91_EMAC_RBD_ADDR_WRAP;
+}
+
+//======================================================================
+// Transmit buffer handling
+
+// Initialize the transmit buffer descriptors
+static void
+at91_tb_init(at91_eth_priv_t *priv)
+{
+ int i;
+ for (i = 0 ; i < CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS; i++)
+ {
+ priv->tbd[i].addr = 0;
+ priv->tbd[i].sr = AT91_EMAC_TBD_SR_USED;
+ }
+ // Set the wrap bit on the last entry
+ priv->tbd[CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS-1].sr |= AT91_EMAC_TBD_SR_WRAP;
+}
+
+//======================================================================
+// Enable and Disable of the receiver and transmitter.
+
+static void
+at91_disable_rx(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl &= ~AT91_EMAC_NCR_RE;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+static void
+at91_disable_tx(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl &= ~AT91_EMAC_NCR_TX;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+static void
+at91_enable_rx(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl |= AT91_EMAC_NCR_RE;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+static void
+at91_enable_tx(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl |= AT91_EMAC_NCR_TX;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+static void
+at91_enable(at91_eth_priv_t *priv)
+{
+ at91_enable_tx(priv);
+ at91_enable_rx(priv);
+}
+
+static void
+at91_disable(at91_eth_priv_t *priv)
+{
+ at91_disable_tx(priv);
+ at91_disable_rx(priv);
+}
+
+static void
+at91_start_transmitter(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl |= AT91_EMAC_NCR_TSTART;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+
+//======================================================================
+// Initialization code
+
+// Configure the pins so that the EMAC has control of them. This
+// assumes the MII is used, not the RMII
+static void
+at91_cfg_pins(void)
+{
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_EREFCK);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ECRS);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ECOL);
+
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERXDV);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERX0);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERX1);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERX2);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERX3);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERXER);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ERXCK);
+
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETXEN);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETX0);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETX1);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETX2);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETX3);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_ETXER);
+
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_EMDC);
+ HAL_ARM_AT91_PIO_CFG(AT91_EMAC_EMDIO);
+}
+
+// Set a specific address match to a given address. Packets received which
+// match this address will be passed on.
+static void
+at91_set_mac(at91_eth_priv_t * priv, cyg_uint8 * enaddr, int sa)
+{
+ cyg_uint32 hi, lo;
+
+ CYG_ASSERTC(sa > 0 && sa < 5);
+ sa--;
+
+ lo = ((enaddr[3] << 24) |
+ (enaddr[2] << 16) |
+ (enaddr[1] << 8) |
+ (enaddr[0]));
+
+ hi = ((enaddr[5] << 8) |
+ (enaddr[4]));
+
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_SA1L + (8*sa), lo);
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_SA1H + (8*sa), hi);
+}
+
+static void
+at91_clear_stats(at91_eth_priv_t *priv)
+{
+ cyg_uint32 ctl;
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+ ctl |= AT91_EMAC_NCR_CSR;
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCR, ctl);
+}
+
+// Enable and Disable of the receiver and transmitter.
+// Initialize the interface. This configures the interface ready for use.
+// Interrupts are grabbed etc. This means the start function has
+// little to do except enable the receiver
+static bool
+at91_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ bool esa_ok = false;
+ unsigned char enaddr[6] = { CYGPKG_DEVS_ETH_ARM_AT91_MACADDR};
+ unsigned char enzero[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+ unsigned short phy_state = 0;
+ cyg_uint32 ncfg = 0;
+
+ debug1_printf("\nAT91_ETH: Initialising @ %x\n",priv->base);
+
+ priv->tx_busy = false;
+ priv->curr_tbd_idx = 0;
+ priv->curr_rbd_idx = 0;
+
+ // Enable the clock to the EMAC
+ HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_EMAC);
+ HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_PIOB);
+ HAL_WRITE_UINT32(AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_PIOA);
+
+ //at91_disable(priv);
+ at91_cfg_pins();
+
+ /* Enable IO Clock */
+ HAL_WRITE_UINT32(priv->base+AT91_EMAC_USRIO,AT91_EMAC_USRIO_CLKEN);
+
+ /* Disable all the interrupts for the moment */
+ /* The Start function actually enables all that we need */
+ //HAL_WRITE_UINT32(priv->base + AT91_EMAC_IDR, 0x3FFF);
+
+ // If we are building an interrupt enabled version, install the
+ // interrupt handler
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ debug1_printf("AT91_ETH: Installing Interrupts on IRQ %d\n",
+ priv->intr_vector);
+ cyg_drv_interrupt_create(priv->intr_vector,
+ 4,
+ (cyg_addrword_t)sc,
+ at91_eth_isr,
+ eth_drv_dsr,
+ &priv->intr_handle,
+ &priv->intr);
+
+ cyg_drv_interrupt_attach(priv->intr_handle);
+ cyg_drv_interrupt_unmask(priv->intr_vector);
+#endif
+
+#ifdef CYGHWR_DEVS_ETH_ARM_AT91_GET_ESA
+ // Get MAC address from RedBoot configuration variables
+ CYGHWR_DEVS_ETH_ARM_AT91_GET_ESA(&enaddr[0], esa_ok);
+ // If this call fails myMacAddr is unchanged and MAC address from
+ // CDL is used
+#endif
+
+ if (!esa_ok)
+ {
+ // Can't figure out ESA
+ debug1_printf("AT91_ETH - Warning! ESA unknown\n");
+ }
+ debug1_printf("AT91_ETH: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ enaddr[0],enaddr[1],enaddr[2],
+ enaddr[3],enaddr[4],enaddr[5]);
+
+ // Give the EMAC its address
+ at91_set_mac(priv, enaddr, 1);
+ at91_set_mac(priv, enzero, 2);
+ at91_set_mac(priv, enzero, 3);
+ at91_set_mac(priv, enzero, 4);
+
+ // Setup the receiver buffers and descriptors
+ at91_rb_init(priv);
+
+ // And tell the EMAC where the first receive buffer descriptor is
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_RBQP, (cyg_uint32)priv->rbd);
+
+ // Setup the transmit descriptors
+ at91_tb_init(priv);
+
+ // And tell the EMAC where the first transmit buffer descriptor is
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_TBQP, (cyg_uint32)priv->tbd);
+
+ // Setup the PHY
+ CYG_ASSERTC(priv->phy);
+
+ at91_mdio_enable();
+ if (!_eth_phy_init(priv->phy))
+ {
+ at91_mdio_disable();
+ return (false);
+ }
+
+ // Get the current mode and print it
+ phy_state = _eth_phy_state(priv->phy);
+ at91_mdio_disable();
+
+ HAL_READ_UINT32(priv->base + AT91_EMAC_NCFG,ncfg);
+
+
+ if ((phy_state & ETH_PHY_STAT_LINK) != 0)
+ {
+ if (((phy_state & ETH_PHY_STAT_100MB) != 0))
+ {
+ debug1_printf("AT91_ETH: 100Mbyte/s");
+ ncfg |= AT91_EMAC_NCFG_SPD_100Mbps;
+ }
+ else
+ {
+ debug1_printf("AT91_ETH: 10Mbyte/s");
+ ncfg &= ~(AT91_EMAC_NCFG_SPD_100Mbps);
+ }
+ if((phy_state & ETH_PHY_STAT_FDX))
+ {
+ debug1_printf(" Full Duplex\n");
+ ncfg |= AT91_EMAC_NCFG_FD;
+ }
+ else
+ {
+ debug1_printf(" Half Duplex\n");
+ ncfg &= ~(AT91_EMAC_NCFG_FD);
+ }
+ }
+ else
+ {
+ debug1_printf("AT91_ETH: No Link\n");
+ }
+
+
+ //Setup the network configuration
+ ncfg |= (AT91_EMAC_NCFG_RLCE);
+
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_NCFG,ncfg);
+
+ // Clear the Statistics counters;
+ at91_clear_stats(priv);
+
+
+ /* Clear the status registers */
+ HAL_READ_UINT32(priv->base + AT91_EMAC_ISR,ncfg);
+ HAL_READ_UINT32(priv->base + AT91_EMAC_RSR,ncfg);
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_RSR,ncfg);
+ HAL_READ_UINT32(priv->base + AT91_EMAC_TSR,ncfg);
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_TSR,ncfg);
+
+ // Initialize the upper layer driver
+ _eth_drv_init(sc,enaddr);
+
+ return (true);
+}
+
+// This function is called to stop the interface.
+static void
+at91_eth_stop(struct eth_drv_sc *sc)
+{
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+
+ at91_disable(priv);
+}
+
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running.
+static void
+at91_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ cyg_uint32 bits;
+
+ // Enable the interrupts we are interested in
+ // TODO: We probably need to add at least the RBNA interrupt here
+ // as well in order to do some error handling
+ bits = (AT91_EMAC_ISR_RCOM | AT91_EMAC_ISR_TCOM);
+
+ HAL_WRITE_UINT32(priv->base + AT91_EMAC_IER, bits);
+
+ // Enable the receiver and transmitter
+ at91_enable(priv);
+}
+
+// This function is called for low level "control" operations
+static int
+at91_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int length)
+{
+
+ switch (key)
+ {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ {
+ if(length >= ETHER_ADDR_LEN)
+ {
+ at91_eth_stop(sc);
+
+ cyg_uint8 * enaddr = (cyg_uint8 *)data;
+ debug1_printf("AT91_ETH: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ enaddr[0],enaddr[1],enaddr[2],
+ enaddr[3],enaddr[4],enaddr[5]);
+
+ at91_set_mac((at91_eth_priv_t *)sc->driver_private,enaddr,1);
+ at91_eth_start(sc,enaddr,0);
+ return 0;
+ }
+ return 1;
+ }
+ default:
+ {
+ diag_printf("%s.%d: key %lx\n", __FUNCTION__, __LINE__, key);
+ return (1);
+ }
+ }
+
+}
+
+// This function is called to see if another packet can be sent.
+// It should return the number of packets which can be handled.
+// Zero should be returned if the interface is busy and can not send
+// any more.
+//
+// We allocate one buffer descriptor per scatter/gather entry. We assume that
+// a typical packet will not have more than 3 such entries, and so we say we
+// can send a packet when we have 3 or more buffer descriptors free
+//
+// TODO: Implement what the comment actually says!
+static int
+at91_eth_can_send(struct eth_drv_sc *sc)
+{
+ int can_send;
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ if(priv->tx_busy)
+ {
+ can_send = 0;
+ }
+ else
+ {
+ can_send = 1;
+ }
+ return (can_send);
+}
+
+// This routine is called to send data to the hardware
+static void
+at91_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ int i;
+ cyg_uint32 sr;
+
+ priv->tx_busy = true;
+
+ priv->last_tbd_idx = priv->curr_tbd_idx;
+
+ for(i = 0;i<sg_len;i++)
+ {
+ priv->tbd[priv->curr_tbd_idx].addr = sg_list[i].buf;
+
+ sr = (sg_list[i].len & AT91_EMAC_TBD_SR_LEN_MASK);
+ // Set the End Of Frame bit in the last descriptor
+ if(i == (sg_len-1))
+ {
+ sr |= AT91_EMAC_TBD_SR_EOF;
+ }
+
+ if(priv->curr_tbd_idx < (CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS-1))
+ {
+ priv->tbd[priv->curr_tbd_idx].sr = sr;
+ priv->curr_tbd_idx++;
+ }
+ else
+ {
+ priv->tbd[priv->curr_tbd_idx].sr = (sr | AT91_EMAC_TBD_SR_WRAP);
+ priv->curr_tbd_idx = 0;
+ }
+ }
+
+ // Store away the key for when the transmit has completed
+ // and we need to tell the stack which transmit has completed.
+ priv->curr_tx_key = key;
+
+ at91_start_transmitter(priv);
+}
+
+static void at91_reset_tbd(at91_eth_priv_t *priv)
+{
+ while(priv->curr_tbd_idx != priv->last_tbd_idx)
+ {
+ if(priv->last_tbd_idx == (CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS-1))
+ {
+ priv->tbd[priv->last_tbd_idx].sr =
+ (AT91_EMAC_TBD_SR_USED|AT91_EMAC_TBD_SR_WRAP);
+ priv->last_tbd_idx = 0;
+ }
+ else
+ {
+ priv->tbd[priv->last_tbd_idx].sr = AT91_EMAC_TBD_SR_USED;
+ priv->last_tbd_idx++;
+ }
+ }
+}
+
+
+//======================================================================
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32
+at91_eth_isr (cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ cyg_uint32 ret;
+ cyg_uint32 isr;
+
+ /* Get the interrupt status */
+ HAL_READ_UINT32(priv->base+AT91_EMAC_ISR,isr);
+
+ ret = CYG_ISR_HANDLED;
+
+ //TODO: We should probably be handling some of the error interrupts as well
+ if(isr & AT91_EMAC_ISR_TCOM)
+ {
+ ret = CYG_ISR_CALL_DSR;
+ }
+
+ if(isr & AT91_EMAC_ISR_RCOM)
+ {
+ ret = CYG_ISR_CALL_DSR;
+ }
+ cyg_interrupt_acknowledge(vector);
+ return(ret);
+}
+#endif
+
+static void
+at91_eth_deliver(struct eth_drv_sc *sc)
+{
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+
+ cyg_uint32 tsr;
+ cyg_uint32 rsr;
+
+ cyg_uint32 ctr;
+ cyg_uint32 cnt;
+ cyg_uint32 idx;
+
+ /* Get the Transmit Status */
+ HAL_READ_UINT32(priv->base+AT91_EMAC_TSR,tsr);
+ HAL_WRITE_UINT32(priv->base+AT91_EMAC_TSR,tsr);
+
+ /* Get the Receive Status */
+ HAL_READ_UINT32(priv->base+AT91_EMAC_RSR,rsr);
+ HAL_WRITE_UINT32(priv->base+AT91_EMAC_RSR,rsr);
+
+
+ //TODO: The interrupts other than RCOMP and TCOMP needs to be
+ // handled properly especially stuff like RBNA which could have
+ // serious effects on driver performance
+
+ /* Service the TX buffers */
+ if (tsr&AT91_EMAC_TSR_COL) //1
+ {
+ debug1_printf("AT91_ETH: Tx COL\n");
+ }
+
+ if (tsr&AT91_EMAC_TSR_RLE) //2
+ {
+ debug1_printf("AT91_ETH: Tx RLE\n");
+ }
+
+ if (tsr&AT91_EMAC_TSR_BNQ) //4
+ {
+ debug1_printf("AT91_ETH: Tx BEX\n");
+ }
+
+ if (tsr&AT91_EMAC_TSR_UND) //6
+ {
+ debug1_printf("AT91_ETH: Tx UND\n");
+ }
+
+ /* Check that the last transmission is completed */
+ if (tsr&AT91_EMAC_TSR_COMP) //5
+ {
+ at91_reset_tbd(priv);
+ _eth_drv_tx_done(sc,priv->curr_tx_key,0);
+ priv->tx_busy = false;
+ }
+
+ /* Service the RX buffers when we get something */
+ if (rsr&AT91_EMAC_RSR_REC)
+ {
+ /* Do this all until we find the first EMAC Buffer */
+ while (priv->rbd[priv->curr_rbd_idx].addr & AT91_EMAC_RBD_ADDR_OWNER_SW)
+ {
+
+ //Firstly walk through to either the first buffer that belongs
+ // to the controller or the first SOF
+ while ((priv->rbd[priv->curr_rbd_idx].addr &
+ AT91_EMAC_RBD_ADDR_OWNER_SW) &&
+ !(priv->rbd[priv->curr_rbd_idx].sr &
+ AT91_EMAC_RBD_SR_SOF))
+ {
+ priv->rbd[priv->curr_rbd_idx].addr &=
+ ~(AT91_EMAC_RBD_ADDR_OWNER_SW);
+ priv->curr_rbd_idx++;
+ if (priv->curr_rbd_idx >= CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS)
+ {
+ priv->curr_rbd_idx = 0;
+ }
+ }
+
+ /* Check that we did find a SOF*/
+ if ((priv->rbd[priv->curr_rbd_idx].addr &
+ AT91_EMAC_RBD_ADDR_OWNER_SW) &&
+ (priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_SOF))
+ {
+ cnt = 0;
+ for (ctr=0;ctr<CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS;ctr++)
+ {
+ idx = (ctr+priv->curr_rbd_idx)%CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS;
+ cnt += (priv->rbd[idx].sr & AT91_EMAC_RBD_SR_LEN_MASK);
+ if (priv->rbd[idx].sr & AT91_EMAC_RBD_SR_EOF)
+ {
+ /* The recv function will adjust the current buffer idx
+ after the buffer has been cleared
+ */
+ if (cnt)
+ _eth_drv_recv(sc,cnt);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (rsr&AT91_EMAC_RSR_BNA)
+ {
+ debug1_printf("AT91_ETH: Rx BNA\n");
+ }
+ if (rsr&AT91_EMAC_RSR_OVR)
+ {
+ debug1_printf("AT91_ETH: Rx OVR\n");
+ }
+
+}
+
+static void
+at91_eth_recv(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list,
+ int sg_len)
+{
+ at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
+ int i;
+ cyg_uint32 bytes_in_buffer;
+ cyg_uint32 bytes_in_list = 0;
+ cyg_uint32 bytes_needed_list = 0;
+ cyg_uint32 buffer_pos = 0;
+ cyg_uint8 * sg_buf;
+ cyg_uint32 total_bytes = 0;
+
+ for(i = 0;i<sg_len;i++)
+ {
+ while(bytes_in_list < sg_list[i].len)
+ {
+ bytes_needed_list = sg_list[i].len - bytes_in_list;
+
+ if(priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_EOF)
+ {
+ bytes_in_buffer =
+ ((priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_LEN_MASK)
+ - total_bytes) - buffer_pos;
+ }
+ else
+ {
+ bytes_in_buffer = AT91_EMAC_RX_BUFF_SIZE - buffer_pos;
+ }
+
+ sg_buf = (cyg_uint8 *)(sg_list[i].buf);
+
+ if(bytes_needed_list < bytes_in_buffer)
+ {
+ if(sg_buf != NULL)
+ memcpy(&sg_buf[bytes_in_list],
+ &priv->rb[priv->curr_rbd_idx].rb[buffer_pos],
+ bytes_needed_list);
+ bytes_in_list += bytes_needed_list;
+ buffer_pos += bytes_needed_list;
+ total_bytes += bytes_needed_list;
+ }
+ else
+ {
+ if(sg_buf != NULL)
+ memcpy(&sg_buf[bytes_in_list],
+ &priv->rb[priv->curr_rbd_idx].rb[buffer_pos],
+ bytes_in_buffer);
+ bytes_in_list += bytes_in_buffer;
+ total_bytes += bytes_in_buffer;
+
+ /* Step our buffer on one */
+ priv->rbd[priv->curr_rbd_idx].addr &=
+ ~(AT91_EMAC_RBD_ADDR_OWNER_SW);
+ priv->curr_rbd_idx++;
+ if(priv->curr_rbd_idx >= CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS)
+ {
+ priv->curr_rbd_idx = 0;
+ }
+ buffer_pos = 0;
+ }
+ }
+ }
+}
+
+// routine called to handle ethernet controller in polled mode
+static void
+at91_eth_poll(struct eth_drv_sc *sc)
+{
+ /* Service the buffers */
+ at91_eth_deliver(sc);
+}
+
+static int
+at91_eth_int_vector(struct eth_drv_sc *sc)
+{
+ return(CYGNUM_HAL_INTERRUPT_EMAC);
+}
+
+at91_eth_priv_t at91_priv_data =
+{
+ .intr_vector = CYGNUM_HAL_INTERRUPT_EMAC,
+ .base = AT91_EMAC,
+ .phy = &at91_phy
+};
+
+ETH_DRV_SC(at91_sc,
+ &at91_priv_data, // Driver specific data
+ "eth0", // Name for this interface
+ at91_eth_start,
+ at91_eth_stop,
+ at91_eth_control,
+ at91_eth_can_send,
+ at91_eth_send,
+ at91_eth_recv,
+ at91_eth_deliver,
+ at91_eth_poll,
+ at91_eth_int_vector);
+
+NETDEVTAB_ENTRY(at91_netdev,
+ "at91",
+ at91_eth_init,
+ &at91_sc);
+
+// EOF if_at91.c
diff --git a/ecos/packages/devs/eth/arm/cerf/current/ChangeLog b/ecos/packages/devs/eth/arm/cerf/current/ChangeLog
new file mode 100644
index 0000000..e153f42
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/cerf/current/ChangeLog
@@ -0,0 +1,34 @@
+2002-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/cerf_eth_drivers.cdl: Don't define CYGHWR_NET_DRIVERS since it's
+ defined by the generic driver.
+
+2002-02-04 Gary Thomas <gthomas@redhat.com>
+
+ * include/devs_eth_arm_cerf.inl:
+ * doc/README:
+ * cdl/cerf_eth_drivers.cdl: New file(s). Port to Intrinsyc CerfCube.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/cerf/current/cdl/cerf_eth_drivers.cdl b/ecos/packages/devs/eth/arm/cerf/current/cdl/cerf_eth_drivers.cdl
new file mode 100644
index 0000000..63ae8cf
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/cerf/current/cdl/cerf_eth_drivers.cdl
@@ -0,0 +1,118 @@
+# ====================================================================
+#
+# cerf_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for Intrinsyc CerfCube
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov, ptruter
+# Date: 2000-01-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_CERF {
+ display "Crystal LAN ethernet driver for Cerf boards"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_SA11X0_CERF
+
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+ # implements CYGINT_DEVS_ETH_CL_CS8900A_STATIC_ESA
+
+ requires CYGPKG_DEVS_ETH_CL_CS8900A
+
+ include_dir cyg/io
+
+ description "Ethernet driver for Crystal LAN based Cerf
+ boards."
+
+ # FIXME: This really belongs in the CL CS8900A package
+ cdl_interface CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED {
+ display "CS8900A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_INL <cyg/io/devs_eth_arm_cerf.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_CFG <pkgconf/devs_eth_arm_cerf.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_CERF_ETH0 {
+ display "CERF ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ CERF port."
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+ implements CYGINT_DEVS_ETH_CL_CS8900A_STATIC_ESA
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_CERF_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_CERF_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ calculated 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_CERF_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+}
+
diff --git a/ecos/packages/devs/eth/arm/cerf/current/doc/README b/ecos/packages/devs/eth/arm/cerf/current/doc/README
new file mode 100644
index 0000000..568dba4
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/cerf/current/doc/README
@@ -0,0 +1,3 @@
+Preliminary documentation for Intrinsyc CerfCube Ethernet driver
+==================================================================
+
diff --git a/ecos/packages/devs/eth/arm/cerf/current/include/devs_eth_arm_cerf.inl b/ecos/packages/devs/eth/arm/cerf/current/include/devs_eth_arm_cerf.inl
new file mode 100644
index 0000000..7a57cd4
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/cerf/current/include/devs_eth_arm_cerf.inl
@@ -0,0 +1,207 @@
+//==========================================================================
+//
+// devs_eth_arm_cerf.inl
+//
+// CERF ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-11-14
+// Purpose: CERF ethernet defintions
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/cerf.h>
+
+#ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+# endif
+#endif
+
+#ifdef __WANT_CONFIG
+# define CS8900A_step 2
+#endif
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_ARM_CERF_ETH0
+
+#ifndef CYGSEM_DEVS_ETH_ARM_CERF_ETH0_SET_ESA
+# if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_ARM_CERF_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_ARM_CERF_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+# endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+// Note that this section *is* active in an application, outside RedBoot,
+// where the above section is not included.
+
+# include <cyg/hal/hal_if.h>
+
+# ifndef CONFIG_ESA
+# define CONFIG_ESA (6)
+# endif
+# ifndef CONFIG_BOOL
+# define CONFIG_BOOL (1)
+# endif
+
+cyg_bool
+_cerf_provide_eth0_esa(struct cs8900a_priv_data* cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa", &set_esa, CONFIG_BOOL);
+ if (ok && set_esa) {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data", cpd->esa, CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+
+# endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+#endif // ! CYGSEM_DEVS_ETH_ARM_CERF_ETH0_SET_ESA
+
+// ------------------------------------------------------------------------
+// EEPROM access functions
+//
+#define PP_ECR 0x0040
+#define PP_EE_READ_CMD 0x0200
+#define PP_EE_WRITE_CMD 0x0100
+#define PP_EE_DATA 0x0042
+#define PP_EE_ADDR_W0 0x001C
+#define PP_EE_ADDR_W1 0x001D
+#define PP_EE_ADDR_W2 0x001E
+
+static __inline__ cyg_uint16
+read_eeprom(cyg_addrword_t base, cyg_uint16 offset)
+{
+ while (get_reg(base, PP_SelfStat) & PP_SelfStat_SIBSY)
+ ;
+
+ put_reg(base, PP_ECR, (offset | PP_EE_READ_CMD));
+
+ while (get_reg(base, PP_SelfStat) & PP_SelfStat_SIBSY)
+ ;
+
+ return get_reg(base, PP_EE_DATA);
+}
+
+static __inline__ void
+copy_eeprom(cyg_addrword_t base)
+{
+ cyg_uint16 esa_word;
+ int i;
+ for (i = 0; i < 6; i += 2)
+ {
+ esa_word = read_eeprom(base, PP_EE_ADDR_W0 + (i/2));
+ put_reg(base, PP_IA+(i/2), esa_word);
+ }
+}
+
+static __inline__ void
+post_reset(cyg_addrword_t base)
+{
+ // Toggle A0 connected to the SBHE line on the Crystal chip.
+ *(char*)(0x20000000) = 1;
+ *(char*)(0x20000001) = 2;
+ *(char*)(0x20000000) = 3;
+ *(char*)(0x20000001) = 0;
+}
+
+#undef CYGHWR_CL_CS8900A_PLF_POST_RESET
+#define CYGHWR_CL_CS8900A_PLF_POST_RESET(base) post_reset(base)
+
+#undef CYGHWR_CL_CS8900A_PLF_RESET
+#define CYGHWR_CL_CS8900A_PLF_RESET(base) copy_eeprom(base)
+
+static cs8900a_priv_data_t cs8900a_eth0_priv_data = {
+ base : (cyg_addrword_t) 0xf0000300,
+ interrupt:SA1110_IRQ_GPIO_ETH,
+#ifdef CYGSEM_DEVS_ETH_ARM_CERF_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_ARM_CERF_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &_cerf_provide_eth0_esa,
+# else
+ provide_esa : NULL,
+# endif
+#endif
+
+};
+
+
+ETH_DRV_SC(cs8900a_sc,
+ &cs8900a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_CERF_ETH0_NAME,
+ cs8900a_start,
+ cs8900a_stop,
+ cs8900a_control,
+ cs8900a_can_send,
+ cs8900a_send,
+ cs8900a_recv,
+ cs8900a_deliver, // "pseudoDSR" called from fast net thread
+ cs8900a_poll, // poll function, encapsulates ISR and DSR
+ cs8900a_int_vector);
+
+NETDEVTAB_ENTRY(cs8900a_netdev,
+ "cs8900a_" CYGDAT_DEVS_ETH_ARM_CERF_ETH0_NAME,
+ cs8900a_init,
+ &cs8900a_sc);
+
+#endif // CYGPKG_DEVS_ETH_ARM_CERF_ETH0
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_arm_cerf.inl
diff --git a/ecos/packages/devs/eth/arm/cerfpda/current/ChangeLog b/ecos/packages/devs/eth/arm/cerfpda/current/ChangeLog
new file mode 100644
index 0000000..b5213cd
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/cerfpda/current/ChangeLog
@@ -0,0 +1,34 @@
+2002-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/cerfpda_eth_drivers.cdl: Don't define CYGHWR_NET_DRIVERS since
+ it's defined in the generic driver.
+
+2002-02-04 Gary Thomas <gthomas@redhat.com>
+
+ * include/devs_eth_arm_cerfpda.inl:
+ * doc/README:
+ * cdl/cerfpda_eth_drivers.cdl: New file(s). Port to CerfPDA.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/cerfpda/current/cdl/cerfpda_eth_drivers.cdl b/ecos/packages/devs/eth/arm/cerfpda/current/cdl/cerfpda_eth_drivers.cdl
new file mode 100644
index 0000000..9b01a79
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/cerfpda/current/cdl/cerfpda_eth_drivers.cdl
@@ -0,0 +1,118 @@
+# ====================================================================
+#
+# cerfpda_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for Intrinsyc CerfPDA
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov, ptruter
+# Date: 2000-01-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_CERFPDA {
+ display "Crystal LAN ethernet driver for Cerfpda"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_SA11X0_CERFPDA
+
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+ # implements CYGINT_DEVS_ETH_CL_CS8900A_STATIC_ESA
+
+ requires CYGPKG_DEVS_ETH_CL_CS8900A
+
+ include_dir cyg/io
+
+ description "Ethernet driver for Crystal LAN based Cerf
+ boards."
+
+ # FIXME: This really belongs in the CL CS8900A package
+ cdl_interface CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED {
+ display "CS8900A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_INL <cyg/io/devs_eth_arm_cerfpda.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_CFG <pkgconf/devs_eth_arm_cerfpda.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_CERFPDA_ETH0 {
+ display "CERFPDA ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ CERFPDA port."
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+ implements CYGINT_DEVS_ETH_CL_CS8900A_STATIC_ESA
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_CERFPDA_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_CERFPDA_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ calculated 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_CERFPDA_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+}
+
diff --git a/ecos/packages/devs/eth/arm/cerfpda/current/doc/README b/ecos/packages/devs/eth/arm/cerfpda/current/doc/README
new file mode 100644
index 0000000..44876b8
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/cerfpda/current/doc/README
@@ -0,0 +1,2 @@
+Preliminary documentation for Intrinsyc CerfPDA Ethernet driver
+==================================================================
diff --git a/ecos/packages/devs/eth/arm/cerfpda/current/include/devs_eth_arm_cerfpda.inl b/ecos/packages/devs/eth/arm/cerfpda/current/include/devs_eth_arm_cerfpda.inl
new file mode 100644
index 0000000..14ee08b
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/cerfpda/current/include/devs_eth_arm_cerfpda.inl
@@ -0,0 +1,207 @@
+//==========================================================================
+//
+// devs_eth_arm_cerfpda.inl
+//
+// CERFPDA ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-11-14
+// Purpose: CERFPDA ethernet defintions
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/cerfpda.h>
+
+#ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+# endif
+#endif
+
+#ifdef __WANT_CONFIG
+# define CS8900A_step 2
+#endif
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_ARM_CERFPDA_ETH0
+
+#ifndef CYGSEM_DEVS_ETH_ARM_CERFPDA_ETH0_SET_ESA
+# if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_ARM_CERFPDA_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_ARM_CERFPDA_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+# endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+// Note that this section *is* active in an application, outside RedBoot,
+// where the above section is not included.
+
+# include <cyg/hal/hal_if.h>
+
+# ifndef CONFIG_ESA
+# define CONFIG_ESA (6)
+# endif
+# ifndef CONFIG_BOOL
+# define CONFIG_BOOL (1)
+# endif
+
+cyg_bool
+_cerfpda_provide_eth0_esa(struct cs8900a_priv_data* cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa", &set_esa, CONFIG_BOOL);
+ if (ok && set_esa) {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data", cpd->esa, CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+
+# endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+#endif // ! CYGSEM_DEVS_ETH_ARM_CERFPDA_ETH0_SET_ESA
+
+// ------------------------------------------------------------------------
+// EEPROM access functions
+//
+#define PP_ECR 0x0040
+#define PP_EE_READ_CMD 0x0200
+#define PP_EE_WRITE_CMD 0x0100
+#define PP_EE_DATA 0x0042
+#define PP_EE_ADDR_W0 0x001C
+#define PP_EE_ADDR_W1 0x001D
+#define PP_EE_ADDR_W2 0x001E
+
+static __inline__ cyg_uint16
+read_eeprom(cyg_addrword_t base, cyg_uint16 offset)
+{
+ while (get_reg(base, PP_SelfStat) & PP_SelfStat_SIBSY)
+ ;
+
+ put_reg(base, PP_ECR, (offset | PP_EE_READ_CMD));
+
+ while (get_reg(base, PP_SelfStat) & PP_SelfStat_SIBSY)
+ ;
+
+ return get_reg(base, PP_EE_DATA);
+}
+
+static __inline__ void
+copy_eeprom(cyg_addrword_t base)
+{
+ cyg_uint16 esa_word;
+ int i;
+ for (i = 0; i < 6; i += 2)
+ {
+ esa_word = read_eeprom(base, PP_EE_ADDR_W0 + (i/2));
+ put_reg(base, PP_IA+(i/2), esa_word);
+ }
+}
+
+static __inline__ void
+post_reset(cyg_addrword_t base)
+{
+ // Toggle A0 connected to the SBHE line on the Crystal chip.
+ *(char*)(0x20000000) = 1;
+ *(char*)(0x20000001) = 2;
+ *(char*)(0x20000000) = 3;
+ *(char*)(0x20000001) = 0;
+}
+
+#undef CYGHWR_CL_CS8900A_PLF_POST_RESET
+#define CYGHWR_CL_CS8900A_PLF_POST_RESET(base) post_reset(base)
+
+#undef CYGHWR_CL_CS8900A_PLF_RESET
+#define CYGHWR_CL_CS8900A_PLF_RESET(base) copy_eeprom(base)
+
+static cs8900a_priv_data_t cs8900a_eth0_priv_data = {
+ base : (cyg_addrword_t) 0xf0000300,
+ interrupt:SA1110_IRQ_GPIO_ETH,
+#ifdef CYGSEM_DEVS_ETH_ARM_CERFPDA_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_ARM_CERFPDA_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &_cerfpda_provide_eth0_esa,
+# else
+ provide_esa : NULL,
+# endif
+#endif
+
+};
+
+
+ETH_DRV_SC(cs8900a_sc,
+ &cs8900a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_CERFPDA_ETH0_NAME,
+ cs8900a_start,
+ cs8900a_stop,
+ cs8900a_control,
+ cs8900a_can_send,
+ cs8900a_send,
+ cs8900a_recv,
+ cs8900a_deliver, // "pseudoDSR" called from fast net thread
+ cs8900a_poll, // poll function, encapsulates ISR and DSR
+ cs8900a_int_vector);
+
+NETDEVTAB_ENTRY(cs8900a_netdev,
+ "cs8900a_" CYGDAT_DEVS_ETH_ARM_CERFPDA_ETH0_NAME,
+ cs8900a_init,
+ &cs8900a_sc);
+
+#endif // CYGPKG_DEVS_ETH_ARM_CERFPDA_ETH0
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_arm_cerfpda.inl
diff --git a/ecos/packages/devs/eth/arm/ebsa285/current/ChangeLog b/ecos/packages/devs/eth/arm/ebsa285/current/ChangeLog
new file mode 100644
index 0000000..33d0ed0
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ebsa285/current/ChangeLog
@@ -0,0 +1,448 @@
+2002-10-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/devs_eth_ebsa285.inl: EBSA has the ethernet devices
+ multiplexed onto one interrupt. This got losted when generalising
+ the driver.
+
+2002-05-14 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_ebsa285.inl: Fix warnings.
+
+2001-11-19 Hugo Tyson <hmt@redhat.com>
+2001-11-19 Anssi Pulkkinen <Anssi.Pulkkinen@ascom.ch>
+
+ * src/if_ebsa285.c (TxMachine): The test to see if there is a new
+ tx to start must also say "go" if the tx queue is full. Normally,
+ if the txqueue is full, a tx will be occurring at all times - so
+ one will complete soon, so the tx queue full flag will soon be
+ cleared, and this condition will recover. I suspect a subtle race
+ which effectively means a new tx is queued and fills the queue in
+ between two tx's, so no TxDone() follows, causes the hang which we
+ get without this extra test under high load. [CASE 106686]
+
+2001-08-31 Hugo Tyson <hmt@redhat.com>
+2001-08-31 Sanjay Bisen <sanjay.bisen@ascom.ch>
+
+ * src/if_ebsa285.c (TxDone): Check from prev change is moved to
+ the logical driver. Also, we zero the key in global state before
+ the callback - this should make no difference, but again it's good
+ practice, and ASCOM's tests indicate a benefit for CASE 106059.
+
+2001-08-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_ebsa285.c:
+ printf() is no longer a part of RedBoot. Thus all programs
+ must use diag_printf() and related functions instead.
+
+2001-06-08 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_ebsa285.c (TxDone): Defensive programming: only call
+ tx_done with new/unique key values.
+
+2001-03-12 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_ebsa285.c: Make device config more consistent with that
+ used in other 82559 platforms, and fix a typo.
+
+2001-02-20 Hugo Tyson <hmt@redhat.com>
+2001-02-15 Martin Buck <martin.buck@ascom.ch>
+
+ * src/if_ebsa285.c: Configure i82559 not to drop oversized frames.
+ This is required for VLAN support (because the maximum frame size
+ including the VLAN tag is 1518 instead of 1514) and shouldn't
+ hurt otherwise. To do this, we now always configure the chip when
+ i82559_start is called, instead of relying on the default
+ configuration if promiscuous mode is off. Another advantage is that
+ we're now able to turn promiscuous mode off again after it was
+ enabled once.
+
+2001-01-02 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_ebsa285.c (find_82559s_match_func): New func to match
+ complex PCI device requirements.
+ (pci_init_find_82559s): Use it, and the new PCI API to correctly
+ match a disparate bunch of devices on the one board.
+
+2000-12-21 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_ebsa285.c (pci_init_find_82559s): Also check for the PCI
+ device whose name is ... 0x1209; "82559ER". Thanks to Martin Buck
+ <martin.buck@ascom.ch> for the ID for that.
+
+2000-11-19 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_ebsa285.c (pci_init_find_82559s): Intel has at least
+ two devices equivalent to the 82559. Support both (0x1229, 0x01030).
+
+2000-10-05 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_ebsa285.c: Deal with device interrupts in a nested
+ fashion - disable/restore is the semantics now, rather than
+ unconditionally unmasking. Also go directly to the 21285 PIC's
+ interrupt control registers to gain atomicity for these. Poll for
+ ready received packets when acknowledging an interrupt in the
+ tranmitting world; a race here could lose an Rx interrupt. Which
+ doesn't matter on a busy system, but in quieter times... there
+ will always be such a race because of the vague way the i82559's
+ status bits reflect how it's yanking the interrupt line; you have
+ to poll until the interrupt is gone before returning else spurious
+ interrupt failures occur. The issue is to close the window as
+ tightly as possible, which this change achieves at a minor cost in
+ performance - because of the time spent polling when not required.
+
+2000-09-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_poll): Only diddle the interface we
+ were asked to. This is more correct in terms of the intent of the
+ API, though it shouldn't really be necessary.
+
+2000-09-06 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (pci_init_find_82559s): Add asserts and an
+ unconditional check that the PCI window as configured matches the
+ address and size of the pci_window region from the MLT. This is
+ here because at present the MLT and CT cannot intercommunicate
+ enough. The separation of the PCI window is needed because
+ otherwise the malloc heap will eat all memory. [This is related
+ to CR 902624-CR, "MLT needs to be configuration aware"]
+
+2000-09-01 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * OVERVIEW: This is part of the change to the network stack to
+ greatly reduce latencies both of (other) DSRs and of thread
+ scheduling. All the work that the network stack *and* individual
+ ether drivers used to do in DSRs (including alarm callbacks and
+ data copies to/from the device memory) is moved into a "fast
+ network thread" instead. It calls a device's "deliver" function
+ to do the work that was previously in the DSR. This is a separate
+ thread so that it can be set higher priority than application
+ threads in order to minimize packet loss (depending on the
+ driver), if required (the application threads presumed to be
+ higher priority in turn than the network thread). A crucial
+ consequence of this is that we are no longer locking against DSRs,
+ so a plain mutex can be used rather than the global scheduler
+ lock, thus simplifying all the splfoo/splx() style functions.
+
+ * src/if_ebsa285.c: Minor: fix the big assert in i82559_send()
+ which suffered a race condition when called from the fast thread
+ rather than from a DSR. Major: Add a "deliver" entry to the
+ interface record for the "fast thread" implementation of the
+ network internal comms system. Provide a pass-up DSR to the
+ logical ether driver's DSR and appropriate delivery routine(s).
+ i82559_poll() now calls i82559_deliver() rather than the DSR. Add
+ valid data for mux'd DSR to pass on up.
+
+2000-09-01 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/test_net_realtime.h: Tighten up the latency requirements
+ by a factor of 5; it all seems happy, so committed.
+
+2000-08-25 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_ioctl): A little further diddling; have
+ a bool to say whether the dot3 info is filled in.
+
+2000-08-24 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Do not export a symbol for the
+ device info file (include/ebsa285_info.h) since nobody needs
+ (portably) to include it now.
+
+ * src/if_ebsa285.c (i82559_ioctl): Handle new ioctl calls
+ ETH_DRV_GET_IF_STATS_UD and ETH_DRV_GET_IF_STATS to get loads of
+ statistical information out. _UD means update. The nonUD one can
+ be used instead mostly, if we find the performance hit too large.
+ This should allow SNMP (a) to not explode, (b) to get useful info
+ out of other device implementations than this one.
+
+ * include/ebsa285_info.h: Remove all the macro cruft for feature
+ detecting of lots of individual statistics; we now just have a
+ catch-all struct that SNMP uses, defined in the common ether
+ driver environment.
+
+2000-08-15 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (PacketRxReady): Put back the check for very
+ small packets into the driver; the layer above checks for that
+ (defensive programming) but only *after* asserting that the size
+ is large enough, to help detect that scenario from other drivers.
+ I believe we only have struct ether_header available if CYGPKG_NET
+ but I could be wrong.
+ [CASE 104353]
+
+2000-08-08 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (eth_set_promiscuous_mode):
+ - ccs->config_bytes[18]=0x70;
+ + ccs->config_bytes[18]=0x72; // Keep the Padding Enable bit
+ ...otherwise short frame sends don't work in promisc mode.
+ [CASE 104289]
+
+2000-08-07 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_ebsa285.c (pciwindow_mem_alloc): Take out very noisy debug.
+
+2000-08-03 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_ebsa285.c: Changes for stand-alone mode.
+
+ * cdl/ebsa285_eth_drivers.cdl: Ethernet driver package hierarchy changed.
+ Add option to control number of interfaces.
+
+2000-07-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (PacketRxReady): Do not attempt to forward
+ short packets; eth_drv.c assumes there is at least a header there.
+ (i82559_recv): Also be more careful and ASSERTive about -ve buffer
+ sizes; be more defensive about sglists. [CASE 104206]
+
+2000-07-26 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_ebsa285.c: Update for new eth_drv interfaces.
+
+2000-07-18 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_poll): Fill in the flesh of this, it
+ just calls ISR and DSR repeatedly.
+ (i82559_start): Look in the device record for promiscuous mode
+ flag; it should be passed though the common layer, but it's not
+ [yet] - this change from Andrew Lunn/ASCOM. Also a fix and delay
+ to the promisc mode code per se.
+
+2000-07-17 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_poll): New function, just to fill in
+ the interface record; not used.
+
+2000-06-27 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Add sesquipedalian option
+ CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS in (now)
+ component CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_STATISTICS to control
+ keeping (well, harvesting really) the i82559's internal stats.
+ Reputedly, it doesn't service the net whilst this is happening, so
+ it could be viewed a bad thing. Hence the option.
+
+ * include/ebsa285_info.h: Only describe the I82559_COUNTERS
+ i82559_counters[2]; structs if full stats are to be kept.
+
+ * src/if_ebsa285.c (update_statistics): Only include this if full
+ stats are to be kept.
+
+2000-06-27 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (ResetRxRing): Re-do the management of the
+ RxRing; have an end-of-list flag (EL) in the last entry, and as
+ you unload filled slots, drag it round after you.
+
+2000-06-14 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Add option to control statistics
+ keeping.
+
+ * include/ebsa285_info.h: Act on it.
+
+2000-06-13 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Properly include the new header
+ file and define symbols to allow client code to get at it without
+ knowing the particular device driver name.
+
+ * include/ebsa285_info.h: New file: export various statistics
+ information about the driver for use by monitoring and
+ network-management systems. This requires exposing the
+ (otherwise) internal structures of the driver.
+
+ * src/if_ebsa285.c: remove a lot of structure definitions &c that
+ are now necessarily in the new header; add a couple of new
+ routines which provide status and update statistics from the
+ device into memory; tidy up control of whether stats-keeping is
+ enabled.
+
+2000-06-06 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl (define_proc): Add #define of
+ CYGDAT_DEVS_ETH_DESCRIPTION in the config file for information.
+
+2000-05-12 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/test_net_realtime.h (tnr_print_activity): New routine to
+ check the system is working, tidied up the API. It works!
+
+2000-05-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Added export of the test header
+ below, and config opts for controlling EEPROM writing and all the
+ status chatter as the device starts up.
+
+ * src/if_ebsa285.c: Reworked the code for reading and setting the
+ EEPROM that holds the MAC address. This is very ugly, but now
+ more reliable. Also tidied up printing cruft with neater
+ configury, and made it an option (for safety) whether it's
+ possible to write the EEPROM at all.
+
+ * tests/test_net_realtime.h: New file - it is intended to be used
+ by networking tests to verify that latency is not compromised by
+ the stack and driver. It's very platform specific, hence the
+ location in here. This is a preliminary version only.
+
+2000-04-27 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c: A serious re-write. This cuts out a lot of
+ code from the old version and improves the performance greatly.
+
+ The cruft was mainly doing lots of explicit event communication
+ between the ISR and DSR, when in fact all the state needed is
+ present in the tx/rx rings. So both ISRs and DSRs regard their
+ call as an opportunity to progress everything they can, rather
+ than only dealing with one interrupt cause at a time; the
+ connection between them is now rather looser.
+
+ Interrups can now be re-enabled after the ISR (in other words they
+ are not masked in the ISR), no need to wait for the DSR, but in
+ consequence some DSR code must mask/unmask intrs as it works.
+
+ The 82559 appears to be a little slow in reacting to commands and
+ state changes, so some interrupts were being lost - or persisting
+ beyond their desired life - so there's some kinda polling code to
+ deal with that also. We also rely on the foreground to kind of
+ poll in the same way, in the send/can_send calls - we know the
+ stack will re-try if necessary, though this is rare.
+
+ The driver now works (albeit at much reduced performance) with as
+ few as 6 rx and tx buffers - in other words the "queue full/out of
+ rx buffers" states have been tested and all is well. It works
+ generally fine with 8 buffers of each kind.
+
+ The mux ISR and DSR are now rather more polled than the old
+ versions; we just try to do things with both devices (if active)
+ by simply calling each unitary ISR/DSR respectively.
+
+ I also re-ordered some of the code, moving utilities to the end of
+ the file and grouping together Tx and Rx machines a bit better.
+
+2000-04-13 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c: Attribution to Ron Spence, Pacific Softworks
+ added as a contributor.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-03-29 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_recv): Be happy with NULLs in the
+ SGlist; it means the caller is out of memory so drop the packet on
+ the floor. Also remove a completely redundant test.
+
+2000-03-06 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_can_send): Update net driver to new
+ interface style. This is incomplete wrt promiscuous mode, but
+ that's probably about all.
+
+2000-02-14 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Update CDL to indicate multiple
+ interface support.
+
+2000-02-14 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (pci_init_find_82559s): Tidy comments somewhat
+ and set debug and stats collecting defines to most friendly
+ settings.
+
+2000-02-10 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (PacketRxReady): Fix bug; current descriptor
+ was not being write back for the callback to use. Hence asserts
+ on state of rfd were firing in busy times - that leading rfd had
+ already been drained.
+
+ Also rationalized meaning of DEBUG printy symbols a bit - it's now
+ chatty during startup/foreground manipulations but not in any
+ performance related activities ie. rx or tx.
+
+2000-02-09 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl:
+
+ Reparent under CYGPKG_NET_ETH_DRIVERS and tidy display strings.
+
+2000-02-08 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c: New File.
+ * cdl/ebsa285_eth_drivers.cdl: New File.
+
+ Initial Checkin of EBSA285 Ethernet driver.
+
+ It's one monolithic file at present, and should be split up into a
+ more generic Intel 82559 driver plus platform-specific parts (PCI
+ et al) plus eCos/Red-Hat-BSD-stack parts.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl b/ecos/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl
new file mode 100644
index 0000000..f18611d
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl
@@ -0,0 +1,153 @@
+# ====================================================================
+#
+# ebsa285_eth_drivers.cdl
+#
+# Ethernet drivers
+# Intel EBSA285 and PRO/100+ platform specific support
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): hmt
+# Original data: hmt
+# Contributors: gthomas
+# Date: 2000-02-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_EBSA285 {
+ display "Intel EBSA285 with PRO/100+ ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_EBSA285
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82559 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
+ display "Intel i82559 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_ebsa285.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_arm_ebsa285.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_EBSA285_ETH0 {
+ display "EBSA-285 ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ PCI ethernet network devices."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_EBSA285_ETH0_NAME {
+ display "Device name for the ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ first PCI ethernet card."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_EBSA285_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_EBSA285_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x11}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_EBSA285_ETH1 {
+ display "EBSA-285 ethernet port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ nanoBridge port 1 - that is the connector on the corner of
+ the board, far from the reset switch."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH1
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_EBSA285_ETH1_NAME {
+ display "Device name for the ethernet port 1 driver"
+ flavor data
+ default_value {"\"eth1\""}
+ description "
+ This option sets the name of the ethernet device for the
+ second PCI ethernet card."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_EBSA285_ETH1_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_EBSA285_ETH1_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x12}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
+
+# EOF ebsa285_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/arm/ebsa285/current/include/devs_eth_ebsa285.inl b/ecos/packages/devs/eth/arm/ebsa285/current/include/devs_eth_ebsa285.inl
new file mode 100644
index 0000000..94b0fda
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ebsa285/current/include/devs_eth_ebsa285.inl
@@ -0,0 +1,223 @@
+//==========================================================================
+//
+// devs/eth/arm/ebsa285/..../include/devs_eth_ebsa285.inl
+//
+// EBSA-285 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, hmt
+// Contributors: jskov, gthomas
+// Date: 2001-02-28
+// Purpose: EBSA285 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_...
+#include <pkgconf/hal_arm_ebsa285.h>
+#include <cyg/hal/hal_cache.h> // hal_virt_to_phys_address()
+
+// --------------------------------------------------------------
+// Platform specifics:
+
+// support SDRAM with gaps in it.
+#define CYGHWR_DEVS_ETH_INTEL_I82559_PCIMEM_DISCONTIGUOUS
+
+// Interrupts are multiplex onto one interrupt pin.
+#define CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT \
+ CYGNUM_HAL_INTERRUPT_PCI_IRQ
+
+// This brings on code to perform a selective reset on the device if the CU
+// wedges.
+
+#define CYGHWR_DEVS_ETH_INTEL_I82559_DEAD_TO (368640) // 0.1S of OS timer
+
+// The mask on an SA110 is really an enable: 1 => enabled, 0 => masked.
+// So to behave nestedly, we only need save the old value of the bits
+// of interest.
+
+#define CYGPRI_DEVS_ETH_INTEL_I82559_MASK_INTERRUPTS(p_i82559,old) \
+CYG_MACRO_START \
+ int cpu_intr; \
+ int mybits = \
+ (1 << (p_i82559->vector)) | \
+ (1 << CYGNUM_HAL_INTERRUPT_PCI_IRQ); \
+ \
+ HAL_DISABLE_INTERRUPTS( cpu_intr ); \
+ old = *SA110_IRQCONT_IRQENABLE; \
+ *SA110_IRQCONT_IRQENABLECLEAR = mybits; /* clear mybits */ \
+ HAL_RESTORE_INTERRUPTS( cpu_intr ); \
+CYG_MACRO_END
+
+// We must only unmask (enable) those which were unmasked before,
+// according to the bits in old.
+#define CYGPRI_DEVS_ETH_INTEL_I82559_UNMASK_INTERRUPTS(p_i82559,old) \
+CYG_MACRO_START \
+ *SA110_IRQCONT_IRQENABLESET = old & \
+ ((1 << (p_i82559->vector)) | \
+ (1 << CYGNUM_HAL_INTERRUPT_PCI_IRQ)); \
+CYG_MACRO_END
+
+#define CYGPRI_DEVS_ETH_INTEL_I82559_ACK_INTERRUPTS(p_i82559) \
+CYG_MACRO_START \
+CYG_MACRO_END
+
+
+// --------------------------------------------------------------
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE
+
+#define CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)_x_)
+static inline cyg_uint32 virt_to_bus(cyg_uint32 p_memory)
+{ return (p_memory - CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE); }
+
+// --------------------------------------------------------------
+// Construct the two interfaces
+
+#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_ETH0
+
+static I82559 i82559_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_ARM_EBSA285_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_ARM_EBSA285_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc0,
+ &i82559_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_EBSA285_ETH0_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev0,
+ "i82559_" CYGDAT_DEVS_ETH_ARM_EBSA285_ETH0_NAME,
+ i82559_init,
+ &i82559_sc0);
+
+#endif // CYGPKG_DEVS_ETH_ARM_EBSA285_ETH0
+
+#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_ETH1
+
+static I82559 i82559_eth1_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_ARM_EBSA285_ETH1_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_ARM_EBSA285_ETH1_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc1,
+ &i82559_eth1_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_EBSA285_ETH1_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev1,
+ "i82559_" CYGDAT_DEVS_ETH_ARM_EBSA285_ETH1_NAME,
+ i82559_init,
+ &i82559_sc1);
+
+#endif // CYGPKG_DEVS_ETH_ARM_EBSA285_ETH1
+
+// --------------------------------------------------------------
+// These arrays are used for sanity checking of pointers
+I82559 *
+i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_ETH0
+ &i82559_eth0_priv_data,
+#endif
+#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_ETH1
+ &i82559_eth1_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_ETH0
+ &i82559_netdev0,
+#endif
+#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_ETH1
+ &i82559_netdev1,
+#endif
+};
+
+struct eth_drv_sc *
+i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_ETH0
+ &i82559_sc0,
+#endif
+#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_ETH1
+ &i82559_sc1,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// --------------------------------------------------------------
+// Debugging
+
+//#define CYGDBG_DEVS_ETH_INTEL_I82559_CHATTER 1
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+#define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM 0
+#define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_MAC_ADJUST (1)
+
+// --------------------------------------------------------------
+
+// EOF devs_eth_ebsa285.inl
diff --git a/ecos/packages/devs/eth/arm/ebsa285/current/tests/test_net_realtime.h b/ecos/packages/devs/eth/arm/ebsa285/current/tests/test_net_realtime.h
new file mode 100644
index 0000000..fe36145
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ebsa285/current/tests/test_net_realtime.h
@@ -0,0 +1,293 @@
+#ifndef CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H
+#define CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H
+/*==========================================================================
+//
+// test_net_realtime.h
+//
+// Auxiliary test header file
+// Provide a thread that runs on EBSA only, which verifies that
+// realtime characteristics are preserved.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 2000-05-03
+// Description:
+//
+//####DESCRIPTIONEND####
+*/
+
+// This is the API to this file:
+
+#define TNR_OFF() tnr_active = 0
+#define TNR_ON() tnr_active = 1
+#define TNR_INIT() tnr_init()
+#define TNR_PRINT_ACTIVITY() tnr_print_activity()
+
+// Tests should use these if they are defined to test that the realtime
+// characteristics of the world are preserved during a test.
+//
+// It is accepted that printing stuff via diag_printf() (and the test
+// infra) disables interrupts for a long time. So invoke TNR_OFF/ON()
+// either side of diagnostic prints, to prevent boguf firings of the
+// realtime test.
+
+// ------------------------------------------------------------------------
+
+// This file rather assumes that the network is in use, and that therefore
+// there is also a kernel, and so on....
+
+#include <cyg/infra/testcase.h> // CYG_TEST_FAIL et al
+#include <cyg/infra/diag.h> // diag_printf()
+#include <cyg/kernel/kapi.h> // Thread API
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/hal/hal_intr.h> // Interrupt names
+#include <cyg/hal/hal_ebsa285.h> // Hardware definitions
+
+// The EBSA has 4 hardware timers; timer 3 is the kernel's realtime clock
+// because it is connected to a separate, indepenent 3.68MHz signal; timer
+// 4 can be used as a watchdog. So we have timers 1 and 2 to use.
+// Timers 1 and 2 have an input clock of 50MHz on fclk_in.
+// Timer 2 should be initialized for periodic interrupts per 500uS.
+// Timer 1 should be initialized for a one-shot interrupt after 1mS (1000uS).
+//
+// Timer 2's ISR examines the state of timer 1; if it has expired, the test
+// has failed. 7 out of 8 hits, timer 1 is reinitialized for the 1mS; on
+// the 8th event, timer1 is set for 2mS. The next timer 2 event calls its
+// DSR, which in turn signals a semaphore which awakens a real task, which
+// again checks and re-initializes timer1 in the same way.
+//
+// All this ensures that interrupts are never delayed by more than 500uS,
+// and that signalling a real task always takes less than 1500uS.
+//
+// This system, once activated, will run non-intrusively along with all
+// networking tests.
+//
+// Special care (aka a hack) may be needed to make it work with the
+// diagnostic channel; that disables interrupts typically for
+// 100[characters] * 8[bits/byte] / 38400[Baud] [Seconds] = 20mS.
+
+// Use the fclk_in divided-by 256 mode:
+#if 0 // Default, really 1mS, 2mS, 500uS
+#define TNR_TIMER1_PERIOD_1mS ((50 * 1000) >>8)
+#define TNR_TIMER1_PERIOD_2mS ((50 * 1000 * 2) >>8)
+#define TNR_TIMER2_PERIOD_500uS ((50 * 500) >>8)
+#else // pushing the envelope... 1/5 as much:
+#define FACTOR 200 // 1000 is "normal"
+#define TNR_TIMER1_PERIOD_1mS ((50 * FACTOR) >>8)
+#define TNR_TIMER1_PERIOD_2mS ((50 * FACTOR * 2) >>8)
+#define TNR_TIMER2_PERIOD_500uS ((50 * FACTOR / 2) >>8)
+#endif
+
+#define TNR_TIMER1_INIT (0x88) // Enabled, free running, fclk_in/256
+#define TNR_TIMER2_INIT (0xc8) // Enabled, periodic, fclk_in/256
+
+// This way, if timer1 is > TNR_TIMER1_PERIOD_2mS, then we know it has
+// wrapped; its full range is 85 seconds, one would hope to get back in
+// that time!
+
+static volatile int tnr_active = 0;
+static volatile int tnr_t2_counter = 0;
+
+static cyg_sem_t tnr_sema;
+
+static char tnr_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+static cyg_thread tnr_thread_data;
+static cyg_handle_t tnr_thread_handle;
+
+static cyg_interrupt tnr_t1_intr, tnr_t2_intr;
+static cyg_handle_t tnr_t1_inth, tnr_t2_inth;
+
+struct {
+ int timer1_isr;
+ int timer2_isr;
+ int timer2_isr_active;
+ int timer2_dsr;
+ int timer2_thd;
+ int timer2_thd_active;
+} tnr_activity_counts = { 0,0,0,0,0,0 };
+
+
+static cyg_uint32 tnr_timer1_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ tnr_activity_counts.timer1_isr++;
+
+ if ( tnr_active )
+ CYG_TEST_FAIL_EXIT( "test_net_realtime: Timer1 fired" );
+
+ *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt (Data: don't care)
+ HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_TIMER_1 );
+
+ return CYG_ISR_HANDLED;
+}
+
+static cyg_uint32 tnr_timer2_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ tnr_activity_counts.timer2_isr++;
+
+ *SA110_TIMER2_CLEAR = 0; // Clear any pending interrupt (Data: don't care)
+ HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_TIMER_2 );
+
+ if ( tnr_active ) {
+ tnr_activity_counts.timer2_isr_active++;
+ if ( (*SA110_TIMER1_VALUE) > (4 * TNR_TIMER1_PERIOD_1mS) ) {
+ // Then it has wrapped around, bad bad bad
+ CYG_TEST_FAIL_EXIT( "tnr_timer2_isr: Timer1 wrapped" );
+ }
+ }
+ tnr_t2_counter++;
+ // We go though each of the following states in turn:
+ switch ( tnr_t2_counter & 7 ) {
+ case 0:
+ // Then this is an 8th event:
+ *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_2mS;
+ return CYG_ISR_HANDLED;
+ case 1:
+ return CYG_ISR_CALL_DSR; // See how long to call a DSR &c..
+ // without resetting timer1: 1500uS left now
+ default:
+ // Reset timer1 again. By doing this in time every time it should
+ // never fire.
+ *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_1mS;
+ }
+ return CYG_ISR_HANDLED;
+}
+
+static void tnr_timer2_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ tnr_activity_counts.timer2_dsr++;
+
+ if ( CYGNUM_HAL_INTERRUPT_TIMER_2 != vector )
+ CYG_TEST_FAIL_EXIT( "tnr_timer2_dsr: Bad vector" );
+
+ cyg_semaphore_post( &tnr_sema );
+}
+
+static void tnr_timer2_service_thread( cyg_addrword_t param )
+{
+ while (1) {
+ cyg_semaphore_wait( &tnr_sema );
+ tnr_activity_counts.timer2_thd++;
+ if ( tnr_active ) {
+ tnr_activity_counts.timer2_thd_active++;
+ if ( (*SA110_TIMER1_VALUE) > (4 * TNR_TIMER1_PERIOD_1mS) ) {
+ // Then it has wrapped around, bad bad bad
+ CYG_TEST_FAIL_EXIT( "tnr_timer2_service_thread: Timer1 wrapped" );
+ }
+ }
+ // Reset timer1 again. By doing this in time every time it should
+ // never fire.
+ *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_1mS;
+ }
+}
+
+
+static void tnr_init( void )
+{
+ // init the semaphore
+ cyg_semaphore_init( &tnr_sema, 0 );
+
+ // create and start the thread
+ cyg_thread_create(2, // Priority - just a number
+ tnr_timer2_service_thread,
+ 0, // entry parameter
+ "Test Net Realtime tnr_timer2_service_thread",
+ &tnr_stack[0], // Stack
+ sizeof(tnr_stack), // Size
+ &tnr_thread_handle, // Handle
+ &tnr_thread_data // Thread data structure
+ );
+ cyg_thread_resume( tnr_thread_handle );
+
+ // set up and attach the interrupts et al...
+ cyg_interrupt_create(
+ CYGNUM_HAL_INTERRUPT_TIMER_2, /* Vector to attach to */
+ 0, /* Queue priority */
+ 0, /* Data pointer */
+ tnr_timer2_isr, /* Interrupt Service Routine */
+ tnr_timer2_dsr, /* Deferred Service Routine */
+ &tnr_t2_inth, /* returned handle */
+ &tnr_t2_intr /* put interrupt here */
+ );
+
+ cyg_interrupt_create(
+ CYGNUM_HAL_INTERRUPT_TIMER_1, /* Vector to attach to */
+ 0, /* Queue priority */
+ 0, /* Data pointer */
+ tnr_timer1_isr, /* Interrupt Service Routine */
+ tnr_timer2_dsr, /* re-use! */ /* Deferred Service Routine */
+ &tnr_t1_inth, /* returned handle */
+ &tnr_t1_intr /* put interrupt here */
+ );
+
+ cyg_interrupt_attach( tnr_t1_inth );
+ cyg_interrupt_attach( tnr_t2_inth );
+
+ *SA110_TIMER1_CONTROL = 0; // Disable while we are setting up
+ *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_2mS;
+ *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt
+ *SA110_TIMER1_CONTROL = TNR_TIMER1_INIT;
+ *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt again
+
+ *SA110_TIMER2_CONTROL = 0; // Disable while we are setting up
+ *SA110_TIMER2_LOAD = TNR_TIMER2_PERIOD_500uS;
+ *SA110_TIMER2_CLEAR = 0; // Clear any pending interrupt
+ *SA110_TIMER2_CONTROL = TNR_TIMER2_INIT;
+ *SA110_TIMER2_CLEAR = 0; // Clear any pending interrupt again
+
+ cyg_interrupt_unmask( CYGNUM_HAL_INTERRUPT_TIMER_2 );
+ cyg_interrupt_unmask( CYGNUM_HAL_INTERRUPT_TIMER_1 );
+}
+
+static void tnr_print_activity( void )
+{
+ int tmp = tnr_active;
+ tnr_active = 0;
+ diag_printf( "Test-net-realtime: interrupt activity log:\n" );
+ diag_printf( " timer1_isr %10d\n", tnr_activity_counts.timer1_isr );
+ diag_printf( " timer2_isr %10d\n", tnr_activity_counts.timer2_isr );
+ diag_printf( " (active) %10d\n", tnr_activity_counts.timer2_isr_active );
+ diag_printf( " timer2_dsr %10d\n", tnr_activity_counts.timer2_dsr );
+ diag_printf( " timer2_thd %10d\n", tnr_activity_counts.timer2_thd );
+ diag_printf( " (active) %10d\n", tnr_activity_counts.timer2_thd_active );
+ tnr_active = tmp;
+}
+
+#endif /* ifndef CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H */
+
+/* EOF test_net_realtime.h */
diff --git a/ecos/packages/devs/eth/arm/edb7xxx/current/ChangeLog b/ecos/packages/devs/eth/arm/edb7xxx/current/ChangeLog
new file mode 100644
index 0000000..da24d84
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/edb7xxx/current/ChangeLog
@@ -0,0 +1,209 @@
+2002-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/edb7xxx_eth_drivers.cdl: Don't define CYGHWR_NET_DRIVERS since
+ it's done by the generic driver.
+
+2002-02-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/edb7xxx_eth_drivers.cdl
+ (CYGSEM_DEVS_ETH_ARM_EDB7XXX_ETH0_SET_ESA): Can be set by user, so
+ don't use calculated.
+
+2001-11-20 Jesper Skov <jskov@redhat.com>
+ From hmt:
+ * include/devs_eth_arm_edb7xxx.inl (_edb7xxx_provide_eth0_esa):
+ Use VV calls to get this even from an application; config changed
+ accordingly to include this function even in an application.
+
+2001-11-14 Jesper Skov <jskov@redhat.com>
+
+ * cdl/edb7xxx_eth_drivers.cdl: Make use of the new generic Cirrus
+ Logic CS8900A driver.
+ * include/devs_eth_arm_edb7xxx.inl: Added.
+
+2001-10-18 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_edb7xxx.c (cs8900_TxEvent): Use cyg_io_eth_net_debug now,
+ conditionally on CYGDBG_IO_ETH_DRIVERS_DEBUG in common eth driver.
+ (cs8900_RxEvent): Ditto.
+
+2001-10-12 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/edb7xxx_eth_drivers.cdl: Clarify package description strings.
+
+2001-09-25 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c (edb7xxx_cs8900_init): Handle case where device
+ doesn't work - instead of just hanging.
+
+ * src/cs8900.h: New register layout on EDB7312 platforms.
+
+2001-08-15 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c (cs8900_send): Only start transmitter after
+ a full packet has been staged. This prevents lost Tx interrupts.
+
+2001-06-19 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_edb7xxx.c (edb7xxx_cs8900_init): Don't retrieve ESA if
+ it's been set in the config.
+
+2001-01-30 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c: New RedBoot config data layout.
+
+2001-01-01 David Geng <deli.geng@ncl.ac.uk>
+
+ * src/if_edb7xxx.c (cs8900_start): Set 'txbusy' false after reset
+ to prevent erroneous 'missed interrupt' error.
+
+2000-09-17 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c (cs8900_can_send): Add simple timeout on Tx.
+ Since this chip has to way to test "can send" and it seems to
+ sometimes loose Tx interrupts, this is necessary.
+
+2000-09-01 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_edb7xxx.c (edb7xxx_cs8900_init): Work with new fast net
+ thread to do all the copying work instead of loading up DSR time.
+ In detail:
+ o New "deliver" function in the interface record.
+ o The DSR changed to be that new function; its arg is now the sc
+ pointer already, no cast needed.
+ o In creating the interrupt, use eth_drv_dsr (from the logical
+ driver) instead of cs8900_dsr (which is gone).
+
+2000-08-23 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c: Add new function which returns the interrupt
+ vector used by a particular interface.
+
+2000-08-21 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/edb7xxx_eth_drivers.cdl: Add configury to set ESA.
+
+ * src/if_edb7xxx.c: Hardware address can come from various
+ sources, not just hardwired.
+
+2000-08-16 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c (cs8900_can_send): Can only send if the link
+ is OK. If the link is bad, the chip just stops...
+
+2000-08-14 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c: Changes to support stand-alone usage.
+
+2000-08-03 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/edb7xxx_eth_drivers.cdl: Ethernet driver package hierarchy changed.
+
+2000-07-26 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c: Update for new eth_drv interfaces.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c (cs8900_recv): Handle case where there were
+ no buffers (and thus the sg_list[] has NULL pointers).
+
+2000-03-06 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_edb7xxx.c: Use new driver API.
+
+2000-02-29 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/if_edb7xxx.c: Support new API - hardware support of 'ioctl'
+ and tagged output.
+
+2000-02-14 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/edb7xxx_eth_drivers.cdl: Add CDL magic to indicate availability
+ of 'eth0' interface.
+
+2000-02-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/edb7xxx_eth_drivers.cdl: Rename CDL file.
+
+2000-02-08 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/eth_drivers.cdl:
+
+ Tidy display strings.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/arm/edb7xxx/current/cdl/edb7xxx_eth_drivers.cdl b/ecos/packages/devs/eth/arm/edb7xxx/current/cdl/edb7xxx_eth_drivers.cdl
new file mode 100644
index 0000000..279ae3c
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/edb7xxx/current/cdl/edb7xxx_eth_drivers.cdl
@@ -0,0 +1,113 @@
+# ====================================================================
+#
+# edb7xxx_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for Cirrus Logic
+# EDB7xxx family of development boards
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov
+# Date: 2000-01-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_EDB7XXX {
+ display "Cirrus Logic ethernet driver for EP7xxx boards"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_EDB7XXX
+
+ include_dir cyg/io
+
+ description "Ethernet driver for Cirrus Logic EP7xxx based
+ development boards."
+
+ # FIXME: This really belongs in the CL CS8900A package
+ cdl_interface CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED {
+ display "Cirrus Logic CS8900A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_INL <cyg/io/devs_eth_arm_edb7xxx.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_CFG <pkgconf/devs_eth_arm_edb7xxx.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_EDB7XXX_ETH0 {
+ display "EDB7XXX ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ EDB7XXX port."
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_EDB7XXX_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_EDB7XXX_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_EDB7XXX_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+}
+
diff --git a/ecos/packages/devs/eth/arm/edb7xxx/current/doc/README b/ecos/packages/devs/eth/arm/edb7xxx/current/doc/README
new file mode 100644
index 0000000..641baac
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/edb7xxx/current/doc/README
@@ -0,0 +1,18 @@
+Preliminary documentation for Cirrus Logic EDB72xx Ethernet driver
+==================================================================
+
+This driver has been tested on both the EDB7211 (EDB7111-2) and
+EDB7209 boards.
+
+There is a problem with some EDB7209 boards which keeps the ethernet
+chip from generating interrupts. The following hardware change will
+allow this (and thus the driver to work), but it precludes the
+generation of interrupts when using the parallel port.
+
+ Remove resistor R168
+ Remove all jumpers from JP45
+
+This problem is known to exist at least through EDB7209-2B.0. It is
+unknown [by the eCos team] if later revisions from Cirrus Logic have
+fixed this problem.
+
diff --git a/ecos/packages/devs/eth/arm/edb7xxx/current/include/devs_eth_arm_edb7xxx.inl b/ecos/packages/devs/eth/arm/edb7xxx/current/include/devs_eth_arm_edb7xxx.inl
new file mode 100644
index 0000000..8dc4f0b
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/edb7xxx/current/include/devs_eth_arm_edb7xxx.inl
@@ -0,0 +1,155 @@
+//==========================================================================
+//
+// devs_eth_arm_edb7xxx.inl
+//
+// EDB7XXX ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-11-14
+// Purpose: EDB7XXX ethernet defintions
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_EINT3
+#include <cyg/hal/hal_if.h>
+
+#ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+# endif
+#endif
+
+#ifdef __WANT_CONFIG
+
+#ifndef __EDB7312
+# define CS8900A_step 4
+#endif
+
+#endif
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_ARM_EDB7XXX_ETH0
+
+#ifndef CYGSEM_DEVS_ETH_ARM_EDB7XXX_ETH0_SET_ESA
+# if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_ARM_EDB7XXX_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_ARM_EDB7XXX_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+# endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+// Note that this section *is* active in an application, outside RedBoot,
+// where the above section is not included.
+
+# include <cyg/hal/hal_if.h>
+
+# ifndef CONFIG_ESA
+# define CONFIG_ESA (6)
+# endif
+# ifndef CONFIG_BOOL
+# define CONFIG_BOOL (1)
+# endif
+
+cyg_bool
+_edb7xxx_provide_eth0_esa(struct cs8900a_priv_data* cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa", &set_esa, CONFIG_BOOL);
+ if (ok && set_esa) {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data", cpd->esa, CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+
+# endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+#endif // ! CYGSEM_DEVS_ETH_ARM_EDB7XXX_ETH0_SET_ESA
+
+static cs8900a_priv_data_t cs8900a_eth0_priv_data = {
+ base : (cyg_addrword_t) 0x20000000,
+ interrupt: CYGNUM_HAL_INTERRUPT_EINT3,
+#ifdef CYGSEM_DEVS_ETH_ARM_EDB7XXX_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_ARM_EDB7XXX_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &_edb7xxx_provide_eth0_esa,
+# else
+ provide_esa : NULL,
+# endif
+#endif
+};
+
+ETH_DRV_SC(cs8900a_sc,
+ &cs8900a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_EDB7XXX_ETH0_NAME,
+ cs8900a_start,
+ cs8900a_stop,
+ cs8900a_control,
+ cs8900a_can_send,
+ cs8900a_send,
+ cs8900a_recv,
+ cs8900a_deliver, // "pseudoDSR" called from fast net thread
+ cs8900a_poll, // poll function, encapsulates ISR and DSR
+ cs8900a_int_vector);
+
+NETDEVTAB_ENTRY(cs8900a_netdev,
+ "cs8900a_" CYGDAT_DEVS_ETH_ARM_EDB7XXX_ETH0_NAME,
+ cs8900a_init,
+ &cs8900a_sc);
+
+#endif // CYGPKG_DEVS_ETH_ARM_EDB7XXX_ETH0
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_arm_edb7xxx.inl
diff --git a/ecos/packages/devs/eth/arm/flexanet/current/ChangeLog b/ecos/packages/devs/eth/arm/flexanet/current/ChangeLog
new file mode 100644
index 0000000..416172c
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/flexanet/current/ChangeLog
@@ -0,0 +1,40 @@
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_flexanet.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2001-12-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/flexanet_eth_drivers.cdl (CYGDAT_DEVS_ETH_ARM_FLEXANET_ESA):
+ Ensure default ESA has a value that is both locally administered and
+ *not* broadcast.
+
+2001-07-27 Jordi Colomer <jco@ict.es>
+
+ * Initial version of support for LAN91CXX ethernet controller
+ on the BSE Flexanet/SA1110 board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/flexanet/current/cdl/flexanet_eth_drivers.cdl b/ecos/packages/devs/eth/arm/flexanet/current/cdl/flexanet_eth_drivers.cdl
new file mode 100644
index 0000000..201fad0
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/flexanet/current/cdl/flexanet_eth_drivers.cdl
@@ -0,0 +1,116 @@
+# ====================================================================
+#
+# flexanet_eth_drivers.cdl
+#
+# Ethernet drivers - support for LAN91CXX ethernet controller
+# on the BSE Flexanet/SA1110 board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Jordi Colomer <jco@ict.es>
+# Contributors: Jordi Colomer
+# Date: 2001-06-18
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_FLEXANET {
+
+ display "Flexanet SMC91C96 ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_SA11X0_FLEXANET
+
+ # chip wired in PCMCIA, 16-bit mode, no EEPROM
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
+ implements CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
+ implements CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
+
+ requires CYGPKG_DEVS_ETH_SMSC_LAN91CXX
+ description "Ethernet driver for Flexanet boards."
+
+ include_dir cyg/io
+ compile if_flexanet.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL <cyg/io/devs_eth_flexanet.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG <pkgconf/devs_eth_arm_flexanet.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+
+ cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
+ display "SMSC LAN91CXX driver required"
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_FLEXANET_NAME {
+ display "Device name for the ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ ethernet port."
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_FLEXANET_ESA {
+ display "The ethernet station address (MAC)"
+ flavor data
+ default_value {"{0x12, 0x13, 0x14, 0x15, 0x16, 0x17}"}
+ description "A static ethernet station address.
+ Caution: Booting two systems with the same MAC on the same
+ network, will cause severe conflicts."
+ active_if !CYGSEM_DEVS_ETH_ARM_FLEXANET_REDBOOT_ESA
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_ARM_FLEXANET_REDBOOT_ESA {
+ display "Use the RedBoot ESA (MAC address)"
+ default_value 0
+ flavor bool
+ description "
+ Use the ESA that is stored as a RedBoot variable instead of
+ a static ESA."
+ }
+
+}
+
+# EOF flexanet_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/arm/flexanet/current/include/devs_eth_flexanet.inl b/ecos/packages/devs/eth/arm/flexanet/current/include/devs_eth_flexanet.inl
new file mode 100644
index 0000000..05e298c
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/flexanet/current/include/devs_eth_flexanet.inl
@@ -0,0 +1,119 @@
+//==========================================================================
+//
+// devs/eth/arm/flexanet/..../include/devs_eth_flexanet.inl
+//
+// Flexanet ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Jordi Colomer <jco@ict.es>
+// Contributors: Jordi Colomer
+// Date: 2001-06-18
+// Purpose: Flexanet ethernet definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_arm_flexanet.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/flexanet.h>
+
+#define CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR 2
+
+// MAC address is stored as a Redboot config option
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+
+RedBoot_config_option("Network hardware address [MAC]",
+ flexanet_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif
+#endif
+
+// ESA address fetch function
+static void flexanet_get_ESA(struct lan91cxx_priv_data *cpd)
+{
+ // Fetch hardware address from RedBoot config
+#if defined(CYGSEM_DEVS_ETH_ARM_FLEXANET_REDBOOT_ESA)
+#if defined(CYGPKG_REDBOOT) && \
+ defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+ flash_get_config("flexanet_esa", cpd->enaddr, CONFIG_ESA);
+#else
+#error "No RedBoot flash configuration to store ESA"
+#endif
+#else
+ memcpy(cpd->enaddr, static_esa, 6);
+#endif
+}
+
+static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
+
+ config_enaddr : flexanet_get_ESA,
+#ifndef CYGSEM_DEVS_ETH_ARM_FLEXANET_REDBOOT_ESA
+ enaddr: CYGDAT_DEVS_ETH_ARM_FLEXANET_ESA,
+#endif
+ base : (unsigned short *) SA1110_FHH_ETH_IOBASE,
+ attbase : (unsigned char *) SA1110_FHH_ETH_MMBASE,
+ interrupt : SA1110_IRQ_GPIO_ETH
+};
+
+ETH_DRV_SC(lan91cxx_sc,
+ &lan91cxx_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_FLEXANET_NAME, // Name for device
+ lan91cxx_start,
+ lan91cxx_stop,
+ lan91cxx_control,
+ lan91cxx_can_send,
+ lan91cxx_send,
+ lan91cxx_recv,
+ lan91cxx_deliver,
+ lan91cxx_poll,
+ lan91cxx_int_vector
+);
+
+NETDEVTAB_ENTRY(lan91cxx_netdev,
+ "lan91cxx_" CYGDAT_DEVS_ETH_ARM_FLEXANET_NAME,
+ smsc_lan91cxx_init,
+ &lan91cxx_sc);
+
+//EOF devs_eth_flexanet.inl
+
+
diff --git a/ecos/packages/devs/eth/arm/flexanet/current/src/if_flexanet.c b/ecos/packages/devs/eth/arm/flexanet/current/src/if_flexanet.c
new file mode 100644
index 0000000..18d7328
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/flexanet/current/src/if_flexanet.c
@@ -0,0 +1,71 @@
+//==========================================================================
+//
+// devs/eth/arm/flexanet/if_flexanet.c
+//
+// Ethernet device driver for Flexanet using SMSC LAN91C96
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Jordi Colomer <jco@ict.es>
+// Contributors: jco,
+// Date: 2001-07-01
+// Purpose:
+// Description: hardware driver for Flexanet/SMSC LAN91CXX ethernet
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_arm_flexanet.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#if defined(CYGPKG_REDBOOT)
+#include <pkgconf/redboot.h>
+#endif
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+
+
+// ESA (Ethernet Station Address), when constant
+#ifndef CYGSEM_DEVS_ETH_ARM_FLEXANET_REDBOOT_ESA
+static unsigned char static_esa[] = CYGDAT_DEVS_ETH_ARM_FLEXANET_ESA;
+#endif
+
+
+
diff --git a/ecos/packages/devs/eth/arm/grg/i82559/current/ChangeLog b/ecos/packages/devs/eth/arm/grg/i82559/current/ChangeLog
new file mode 100644
index 0000000..19997b3
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/grg/i82559/current/ChangeLog
@@ -0,0 +1,39 @@
+2003-03-26 Mark Salter <msalter@redhat.com>
+
+ * cdl/grg_i82559_eth_driver.cdl: Default to off for
+ CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA.
+
+ * include/grg_i82559.inl: Fix commenting of copyright.
+
+2003-03-24 Mark Salter <msalter@redhat.com>
+
+ * cdl/grg_i82559_eth_driver.cdl: Fix copyright notice.
+ * include/grg_i82559.inl: Ditto.
+
+2003-02-07 Mark Salter <msalter@redhat.com>
+
+ * Initial checkin.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/grg/i82559/current/cdl/grg_i82559_eth_driver.cdl b/ecos/packages/devs/eth/arm/grg/i82559/current/cdl/grg_i82559_eth_driver.cdl
new file mode 100755
index 0000000..1876abd
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/grg/i82559/current/cdl/grg_i82559_eth_driver.cdl
@@ -0,0 +1,149 @@
+# ====================================================================
+#
+# grg_i82559_eth_driver.cdl
+#
+# Ethernet driver
+# GRG and Intel PRO/100+ platform specific support
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):
+# Original data: hmt
+# Contributors: gthomas
+# Date: 2002-04-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_GRG_I82559 {
+ display "GRG with Intel PRO/100+ (PCI) ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_XSCALE_GRG
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82559 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
+ display "Intel i82559 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/grg_i82559.inl>"
+
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_arm_grg_i82559.h>"
+
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_GRG_I82559_ETH0 {
+ display "GRG ethernet port driver for an I82559-based ethernet NIC card"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the GRG ethernet device driver for a
+ I82559-based ethernet PCI card."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_GRG_I82559_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for a
+ I82559-based ethernet NIC card."
+ }
+ }
+
+
+ # note that this option's name is NOT grg-specific, but i82559
+ # generic - other instantiations can set these also.
+ cdl_component CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 0
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+ description "Enabling this option will allow the ethernet
+ station address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually by the
+ 'Set the ethernet station address' option for each interface."
+
+ cdl_component CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_VARS {
+ display "Build-in flash config fields for ESAs"
+ flavor bool
+ default_value 1
+
+ active_if CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT_FLASH
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+
+ description "
+ This option controls the presence of RedBoot flash
+ configuration fields for the ESAs of the interfaces when you
+ are building RedBoot. It is independent of whether RedBoot
+ itself uses the network or any particular interface; this
+ support is more for the application to use than for RedBoot
+ itself, though the application gets at the data by vector
+ calls; this option cannot be enabled outside of building
+ RedBoot."
+
+ cdl_option CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 1
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_GRG_ETH0_DEFAULT_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0x03, 0x47, 0xdf, 0x32, 0xa8}"}
+ description "The default ethernet station address. This is the
+ address used as the default value in the RedBoot
+ flash configuration field."
+ }
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/arm/grg/i82559/current/include/grg_i82559.inl b/ecos/packages/devs/eth/arm/grg/i82559/current/include/grg_i82559.inl
new file mode 100755
index 0000000..5c31e9b
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/grg/i82559/current/include/grg_i82559.inl
@@ -0,0 +1,188 @@
+//==========================================================================
+//
+// grg_i82559.inl
+//
+// GRG ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):
+// Contributors:msalter
+// Date: 2003-02-05
+// Purpose: grg ethernet definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHERNET
+#include <cyg/hal/hal_cache.h> // HAL_DCACHE_LINE_SIZE
+#include <cyg/hal/plf_io.h> // CYGARC_UNCACHED_ADDRESS
+
+// Bus hardware takes care of IO endianess issues.
+#define CYGHWR_DEVS_ETH_INTEL_I82559_ENDIAN_NEUTRAL_IO 1
+
+// NB: Bus masters can only get to first 64MB SDRAM
+#define CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS( _x_ ) \
+ ((cyg_uint32)CYGARC_VIRT_TO_BUS(_x_))
+
+#define MAX_PACKET_SIZE 1536
+#define SIZEOF_DESCRIPTOR 16
+#define MISC_MEM 1128 // selftest, ioctl and statistics
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE \
+ (((MAX_PACKET_SIZE + SIZEOF_DESCRIPTOR) * \
+ (CYGNUM_DEVS_ETH_INTEL_I82559_MAX_TX_DESCRIPTORS + \
+ CYGNUM_DEVS_ETH_INTEL_I82559_MAX_RX_DESCRIPTORS)) + \
+ MISC_MEM)*CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT
+
+// The PCI Window is 64MB starting at 0x00000000, so as long as the bss
+// section is within addresses 0x00000000-0x04000000, pci_mem_buffer[] will be
+// in the true PCI Window. Because pci_mem_buffer[] is in the bss section,
+// wanted its size to be only as large as required so as to not waste memory.
+// Therefore, had to compute it's size in this file and not in the memory
+// layout files. So no __pci_window label was ever defined, therefore,
+// CYGMEM_SECTION_pci_window does not exist. Define CYGMEM_SECTION_pci_window
+// here in order to satisfy the ASSERT within if_i82559.c.
+static char pci_mem_buffer[CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE
+ + HAL_DCACHE_LINE_SIZE];
+
+#define CYGMEM_SECTION_pci_window (((unsigned)pci_mem_buffer \
+ + HAL_DCACHE_LINE_SIZE - 1) \
+ & ~(HAL_DCACHE_LINE_SIZE - 1))
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE \
+ (CYGARC_UNCACHED_ADDRESS(CYGMEM_SECTION_pci_window))
+
+
+#ifdef CYGPKG_DEVS_ETH_ARM_GRG_I82559_ETH0
+
+static I82559 i82559_eth0_priv_data = {
+ hardwired_esa: 0,
+#if defined(CYGPKG_REDBOOT) && defined(CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0)
+ mac_address: CYGDAT_DEVS_ETH_ARM_GRG_ETH0_DEFAULT_ESA
+#endif
+};
+
+ETH_DRV_SC(i82559_sc0,
+ &i82559_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_GRG_I82559_ETH0_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev0,
+ "i82559_" CYGDAT_DEVS_ETH_ARM_GRG_I82559_ETH0_NAME,
+ i82559_init,
+ &i82559_sc0);
+#endif // CYGPKG_DEVS_ETH_ARM_IXP425_I82559_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+I82559 *
+i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_GRG_I82559_ETH0
+ &i82559_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_GRG_I82559_ETH0
+ &i82559_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_GRG_I82559_ETH0
+ &i82559_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// Decide whether to have redboot config vars for it...
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#ifdef CYGPKG_REDBOOT_NETWORKING
+#include <redboot.h>
+#include <flash_config.h>
+
+#ifdef CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, i82559_eth0_priv_data.mac_address
+ );
+#endif
+
+#endif // CYGPKG_REDBOOT_NETWORKING
+#endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#endif // CYGPKG_REDBOOT
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+
+#include <cyg/hal/hal_if.h>
+
+#ifndef CONFIG_ESA
+#define CONFIG_ESA (6)
+#endif
+
+#define CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA( p_i82559, mac_address, ok ) \
+CYG_MACRO_START \
+ ok = false; \
+ if ( 0 == p_i82559->index ) \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa", mac_address, CONFIG_ESA); \
+ else if ( 1 == p_i82559->index ) \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth1_esa", mac_address, CONFIG_ESA); \
+CYG_MACRO_END
+
+#endif // CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
diff --git a/ecos/packages/devs/eth/arm/innovator/current/ChangeLog b/ecos/packages/devs/eth/arm/innovator/current/ChangeLog
new file mode 100644
index 0000000..55f5ebe
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/innovator/current/ChangeLog
@@ -0,0 +1,36 @@
+2003-02-14 Patrick Doyle <wpd@delcomsys.com>
+
+ * src/if_innovator.c (removed file)
+ * include/devs_eth_innovator.inl
+ * cdl/innovator_eth_drivers.cdl: Reworked to support flash, CDL,
+ and eeprom ESA assignment, in that priority.
+
+2003-02-05 Patrick Doyle <wpd@delcomsys.com>
+ * cdl/innovator_eth_drivers.cdl
+ * include/devs_eth_innovator.inl
+ * src/if_innovator.c: New package - support for Texas Instruments
+ Innovator board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/innovator/current/cdl/innovator_eth_drivers.cdl b/ecos/packages/devs/eth/arm/innovator/current/cdl/innovator_eth_drivers.cdl
new file mode 100644
index 0000000..93107fc
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/innovator/current/cdl/innovator_eth_drivers.cdl
@@ -0,0 +1,116 @@
+# ====================================================================
+#
+# innovator_eth_drivers.cdl
+#
+# Ethernet drivers - support for LAN91CXX ethernet controller
+# on the BSE Innovator/SA1110 board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Jordi Colomer <jco@ict.es>, Patrick Doyle <wpd@delcomsys.com>
+# Contributors: Patrick Doyle <wpd@delcomsys.com>
+# Date: 2001-06-18
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_INNOVATOR {
+ display "Innovator SMC91C96 ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_ARM9_INNOVATOR
+
+ include_dir cyg/io
+
+ description "Ethernet driver for Innovator boards."
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+
+ cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
+ display "SMSC LAN91CXX driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL <cyg/io/devs_eth_innovator.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG <pkgconf/devs_eth_arm_innovator.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_INNOVATOR_ETH0 {
+ display "Innovator ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ Innovator port."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_INNOVATOR_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_INNOVATOR_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_INNOVATOR_ETH0_ESA {
+ display "The ethernet station address (MAC)"
+ flavor data
+ default_value {"{0x12, 0x13, 0x14, 0x15, 0x16, 0x17}"}
+ description "A static ethernet station address.
+ Caution: Booting two systems with the same MAC on the same
+ network, will cause severe conflicts."
+ }
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/arm/innovator/current/include/devs_eth_innovator.inl b/ecos/packages/devs/eth/arm/innovator/current/include/devs_eth_innovator.inl
new file mode 100644
index 0000000..40f4274
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/innovator/current/include/devs_eth_innovator.inl
@@ -0,0 +1,143 @@
+//==========================================================================
+//
+// devs/eth/arm/innovator/..../include/devs_eth_innovator.inl
+//
+// Innovator ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Jordi Colomer <jco@ict.es>, Patrick Doyle <wpd@delcomsys.com>
+// Contributors: Patrick Doyle <wpd@delcomsys.com>
+// Date: 2001-06-18
+// Purpose: Innovator ethernet definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_arm_innovator.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/innovator.h>
+
+#ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+# endif
+#endif
+
+#ifdef CYGPKG_DEVS_ETH_ARM_INNOVATOR_ETH0
+
+#if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_ARM_INNOVATOR_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_ARM_INNOVATOR_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+#endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+// Note that this section *is* active in an application, outside RedBoot,
+// where the above section is not included.
+
+# include <cyg/hal/hal_if.h>
+
+# ifndef CONFIG_ESA
+# define CONFIG_ESA (6)
+# endif
+# ifndef CONFIG_BOOL
+# define CONFIG_BOOL (1)
+# endif
+
+cyg_bool
+_innovator_provide_eth0_esa(struct lan91cxx_priv_data* cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa", &set_esa, CONFIG_BOOL);
+ if (ok && set_esa) {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data", cpd->enaddr, CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
+ base : (unsigned short *) 0x08000300,
+#ifdef CYGSEM_DEVS_ETH_ARM_INNOVATOR_ETH0_SET_ESA
+ enaddr : CYGDAT_DEVS_ETH_ARM_INNOVATOR_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &_innovator_provide_eth0_esa,
+#else
+ provide_esa : NULL,
+#endif
+};
+
+ETH_DRV_SC(lan91cxx_sc,
+ &lan91cxx_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_INNOVATOR_ETH0_NAME, // Name for device
+ lan91cxx_start,
+ lan91cxx_stop,
+ lan91cxx_control,
+ lan91cxx_can_send,
+ lan91cxx_send,
+ lan91cxx_recv,
+ lan91cxx_deliver,
+ lan91cxx_poll,
+ lan91cxx_int_vector
+);
+
+NETDEVTAB_ENTRY(lan91cxx_netdev,
+ "lan91cxx_" CYGDAT_DEVS_ETH_ARM_INNOVATOR_ETH0_NAME,
+ smsc_lan91cxx_init,
+ &lan91cxx_sc);
+
+#endif // CYGPKG_DEVS_ETH_ARM_INNOVATOR_ETH0
+
+
+
diff --git a/ecos/packages/devs/eth/arm/integrator/current/ChangeLog b/ecos/packages/devs/eth/arm/integrator/current/ChangeLog
new file mode 100644
index 0000000..8604aad
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/integrator/current/ChangeLog
@@ -0,0 +1,41 @@
+2002-03-06 Nick Garnett <nickg@redhat.com>
+
+ * cdl/integrator_eth_drivers.cdl: Switched over to use generic
+ i82559 driver.
+
+ * include/devs_eth_arm_integrator_i82559.inl: File added to
+ configure generic i82559 driver.
+
+ * include/integrator_info.h:
+ * src/if_integrator.c:
+ Files removed. These were the old integrator-specific driver.
+
+2000-08-21 Philippe Robin
+ * adapted from ebsa285
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/arm/integrator/current/cdl/integrator_eth_drivers.cdl b/ecos/packages/devs/eth/arm/integrator/current/cdl/integrator_eth_drivers.cdl
new file mode 100644
index 0000000..70eae79
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/integrator/current/cdl/integrator_eth_drivers.cdl
@@ -0,0 +1,111 @@
+# ====================================================================
+#
+# integrator_eth_drivers.cdl
+#
+# Ethernet drivers
+# Intel PRO/100+ platform specific support for ARM Integrator
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Philippe Robin
+# Original data: hmt
+# Contributors:
+# Date: November 7, 2000
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_INTEGRATOR {
+ display "Integrator board ethernet driver"
+ description "Ethernet driver for Integrator."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_INTEGRATOR
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82559 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
+ display "Intel i82559 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_arm_integrator_i82559.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_arm_integrator.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0 {
+ display "Ethernet port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ i82559 ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x00, 0x00, 0x00, 0x00, 0x01}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
+
+# EOF integrator_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/arm/integrator/current/include/devs_eth_arm_integrator_i82559.inl b/ecos/packages/devs/eth/arm/integrator/current/include/devs_eth_arm_integrator_i82559.inl
new file mode 100644
index 0000000..445b27d
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/integrator/current/include/devs_eth_arm_integrator_i82559.inl
@@ -0,0 +1,117 @@
+//==========================================================================
+//
+// devs_eth_arm_integrator_i82559.inl
+//
+// Integrator i82559 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-01-25
+// Purpose: Integrator i82559 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#include <cyg/hal/hal_integrator.h>
+
+#ifdef CYGPKG_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE CYGARC_PHYSICAL_ADDRESS(CYGMEM_SECTION_pci_window)
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE CYGMEM_SECTION_pci_window_SIZE
+
+#define CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS( _x_ ) (((cyg_uint32)(_x_))|INTEGRATOR_HDR0_SDRAM_BASE)
+#define CYGHWR_INTEL_I82559_PCI_BUS_TO_VIRT( _x_ ) (((cyg_uint32)(_x_))&~INTEGRATOR_HDR0_SDRAM_BASE)
+
+static I82559 i82559_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc0,
+ &i82559_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev0,
+ "i82559_" CYGDAT_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0_NAME,
+ i82559_init,
+ &i82559_sc0);
+
+#endif // CYGPKG_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+I82559 *
+i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0
+ &i82559_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0
+ &i82559_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_INTEGRATOR_I82559_ETH0
+ &i82559_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// EOF devs_eth_arm_integrator_i82559.inl
diff --git a/ecos/packages/devs/eth/arm/iq80310/current/ChangeLog b/ecos/packages/devs/eth/arm/iq80310/current/ChangeLog
new file mode 100644
index 0000000..d4b7e88
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/iq80310/current/ChangeLog
@@ -0,0 +1,98 @@
+2002-11-12 Gary Thomas <gary@mlbassoc.com>
+
+ * cdl/iq80310_eth_drivers.cdl: Update for new Xscale package layout.
+
+2002-01-04 Mark Salter <msalter@redhat.com>
+
+ * cdl/iq80310_eth_drivers.cdl: Remove
+ CYGNUM_DEVS_ETH_ARM_IQ80310_MAX_TX_DESCRIPTORS and
+ CYGNUM_DEVS_ETH_ARM_IQ80310_MAX_RX_DESCRIPTORS.
+
+2002-01-03 Mark Salter <msalter@redhat.com>
+
+ * cdl/iq80310_eth_drivers.cdl: Rewrite to use generic i82559 driver.
+ * include/devs_eth_iq80310.inl: New file.
+ * src/if_iq80310.c: Remove.
+ * src/if_shmem.S: Remove.
+ * include/iq80310_info.h: Remove.
+
+2001-12-20 Mark Salter <msalter@redhat.com>
+
+ * cdl/iq80310_eth_drivers.cdl: Add "flavor data" (as pointed out by
+ hmt@redhat.com) to CYGNUM_DEVS_ETH_ARM_IQ80310_MAX_TX_DESCRIPTORS and
+ CYGNUM_DEVS_ETH_ARM_IQ80310_MAX_RX_DESCRIPTORS.
+
+2001-10-09 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/iq80310_info.h: Remove MAX_TX_DESCRIPTORS and
+ MAX_RX_DESCRIPTORS, to be replaced by...
+ * cdl/iq80310_eth_drivers.cdl: Add
+ CYGNUM_DEVS_ETH_ARM_IQ80310_MAX_TX_DESCRIPTORS and
+ CYGNUM_DEVS_ETH_ARM_IQ80310_MAX_RX_DESCRIPTORS.
+ * src/if_shmem.S: Use above definitions to calculate size of
+ shared mem.
+ * src/if_iq80310.c (CYGHWR_HAL_ARM_IQ80310_PCI_MEM_MAP_SIZE): Ditto.
+
+2001-10-09 Jesper Skov <jskov@redhat.com>
+
+ * src/if_iq80310.c: Made code build with assertions.
+
+2001-08-24 Mark Salter <msalter@redhat.com>
+
+ * src/if_iq80310.c (PacketRxReady): Break out of Rx loop after
+ one packet is delivered for RedBoot.
+
+2001-08-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_iq80310.c:
+ printf() is no longer a part of RedBoot. Thus all programs
+ must use diag_printf() and related functions instead.
+
+2001-08-15 Mark Salter <msalter@redhat.com>
+
+ * src/if_iq80310.c: Use 32-bit access to MDI. Problem discovered
+ by bruce.daly@spirentcom.com.
+
+2000-12-21 Mark Salter <msalter@redhat.com>
+
+ * src/if_iq80310.c (i82559_start): Fix syntax error when DEBUG defined.
+
+2000-11-22 Mark Salter <msalter@redhat.com>
+
+ * src/if_iq80310.c (pci_init_find_82559s): Don't install ISR handler or
+ unmask interrupt if CYGPKG_REDBOOT defined.
+
+2000-11-06 Mark Salter <msalter@redhat.com>
+
+ * src/if_iq80310.c: Add initialization of physical layer interface.
+ Turned off debugging messages.
+
+ * include/iq80310_info.h: Add definitions for ethernet physical
+ interface.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/arm/iq80310/current/cdl/iq80310_eth_drivers.cdl b/ecos/packages/devs/eth/arm/iq80310/current/cdl/iq80310_eth_drivers.cdl
new file mode 100644
index 0000000..2244bae
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/iq80310/current/cdl/iq80310_eth_drivers.cdl
@@ -0,0 +1,116 @@
+# ====================================================================
+#
+# iq80310_eth_drivers.cdl
+#
+# Ethernet drivers
+# Intel IQ80310 and PRO/100+ platform specific support
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): hmt
+# Original data: hmt
+# Contributors: gthomas
+# Date: 2000-02-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_XSCALE_IQ80310 {
+ display "Intel IQ80310 with PRO/100+ ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_XSCALE_IOP310
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82559 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
+ display "Intel i82559 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_iq80310.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_arm_xscale_iq80310.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_IQ80310_ETH0 {
+ display "IQ80310 builtin ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ IQ80310 builtin port."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_IQ80310_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ IQ80310 builtin port."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_IQ80310_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_IQ80310_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x11}"}
+ description "The ethernet station address"
+ }
+ }
+
+ }
+
+}
+
+# EOF iq80310_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/arm/iq80310/current/include/devs_eth_iq80310.inl b/ecos/packages/devs/eth/arm/iq80310/current/include/devs_eth_iq80310.inl
new file mode 100644
index 0000000..671e9a8
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/iq80310/current/include/devs_eth_iq80310.inl
@@ -0,0 +1,134 @@
+//==========================================================================
+//
+// devs/eth/arm/iq80310/include/devs_eth_arm_iq80310.inl
+//
+// IQ80310 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors:msalter
+// Date: 2001-12-20
+// Purpose: IQ80310 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHERNET
+#include <cyg/hal/hal_cache.h> // HAL_DCACHE_LINE_SIZE
+#include <cyg/hal/plf_io.h> // CYGARC_UNCACHED_ADDRESS
+
+#ifdef CYGPKG_DEVS_ETH_ARM_IQ80310_ETH0
+
+// Bus masters can get to all of SDRAM using direct mapping.
+#define CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS( _x_ ) ((cyg_uint32)CYGARC_VIRT_TO_BUS(_x_))
+
+#ifndef CYGSEM_DEVS_ETH_ARM_IQ80310_ETH0_SET_ESA
+# define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM 0
+# define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_WITHOUT_CRC
+#endif
+
+#define MAX_PACKET_SIZE 1536
+#define SIZEOF_DESCRIPTOR 16
+#define MISC_MEM 1128 // selftest, ioctl and statistics
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE \
+ (((MAX_PACKET_SIZE + SIZEOF_DESCRIPTOR) * \
+ (CYGNUM_DEVS_ETH_INTEL_I82559_MAX_TX_DESCRIPTORS + \
+ CYGNUM_DEVS_ETH_INTEL_I82559_MAX_RX_DESCRIPTORS)) + \
+ MISC_MEM)
+
+static char pci_mem_buffer[CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE + HAL_DCACHE_LINE_SIZE];
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE \
+ (CYGARC_UNCACHED_ADDRESS(((unsigned)pci_mem_buffer + HAL_DCACHE_LINE_SIZE - 1) & ~(HAL_DCACHE_LINE_SIZE - 1)))
+
+static I82559 i82559_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_ARM_IQ80310_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_ARM_IQ80310_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc0,
+ &i82559_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_IQ80310_ETH0_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev0,
+ "i82559_" CYGDAT_DEVS_ETH_ARM_IQ80310_ETH0_NAME,
+ i82559_init,
+ &i82559_sc0);
+
+#endif // CYGPKG_DEVS_ETH_ARM_IQ80310_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+I82559 *
+i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_IQ80310_ETH0
+ &i82559_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_IQ80310_ETH0
+ &i82559_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_IQ80310_ETH0
+ &i82559_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// EOF devs_eth_arm_iq80310.inl
diff --git a/ecos/packages/devs/eth/arm/iq80321/current/ChangeLog b/ecos/packages/devs/eth/arm/iq80321/current/ChangeLog
new file mode 100644
index 0000000..3b45e2e
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/iq80321/current/ChangeLog
@@ -0,0 +1,43 @@
+2002-01-30 Mark Salter <msalter@redhat.com>
+
+ * cdl/iq80321_eth_drivers.cdl: Change back default for
+ CYGSEM_DEVS_ETH_ARM_IQ80321_I82544_ETH0_SET_ESA now that diags
+ support setting of MAC address.
+
+2002-01-29 Nick Garnett <nickg@redhat.com>
+
+ * cdl/iq80321_eth_drivers.cdl: Changed default for
+ CYGSEM_DEVS_ETH_ARM_IQ80321_I82544_ETH0_SET_ESA from 0 to 1. Until
+ we get boards with properly populated EEPROMS we must supply the
+ MAC address in the configuration.
+
+2002-01-21 Mark Salter <msalter@redhat.com>
+
+ * Initial checkin.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/arm/iq80321/current/cdl/iq80321_eth_drivers.cdl b/ecos/packages/devs/eth/arm/iq80321/current/cdl/iq80321_eth_drivers.cdl
new file mode 100644
index 0000000..fdd3278
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/iq80321/current/cdl/iq80321_eth_drivers.cdl
@@ -0,0 +1,116 @@
+# ====================================================================
+#
+# iq80321_eth_drivers.cdl
+#
+# Ethernet drivers
+# Intel IQ80321 and i82544 Gigabit support
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): hmt
+# Original data: hmt
+# Contributors: gthomas
+# Date: 2000-02-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_IQ80321 {
+ display "Intel IQ80321 with i82544 ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_XSCALE_IQ80321
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82544 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82544_REQUIRED {
+ display "Intel i82544 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82544_INL <cyg/io/devs_eth_iq80321.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82544_CFG <pkgconf/devs_eth_arm_iq80321.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_IQ80321_I82544_ETH0 {
+ display "IQ80321 builtin ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ IQ80321 builtin port."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82544_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_IQ80321_I82544_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ IQ80321 builtin port."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_IQ80321_I82544_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_IQ80321_I82544_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x11}"}
+ description "The ethernet station address"
+ }
+ }
+
+ }
+
+}
+
+# EOF iq80321_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/arm/iq80321/current/include/devs_eth_iq80321.inl b/ecos/packages/devs/eth/arm/iq80321/current/include/devs_eth_iq80321.inl
new file mode 100644
index 0000000..84da648
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/iq80321/current/include/devs_eth_iq80321.inl
@@ -0,0 +1,129 @@
+//==========================================================================
+//
+// devs/eth/arm/iq80321/include/devs_eth_arm_iq80321.inl
+//
+// IQ80321 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors:msalter
+// Date: 2002-01-10
+// Purpose: IQ80321 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHERNET
+#include <cyg/hal/hal_cache.h> // HAL_DCACHE_LINE_SIZE
+#include <cyg/hal/plf_io.h> // CYGARC_UNCACHED_ADDRESS
+
+#ifdef CYGPKG_DEVS_ETH_ARM_IQ80321_I82544_ETH0
+
+// Use auto speed detection
+#define CYGHWR_DEVS_ETH_INTEL_I82544_USE_ASD
+
+#define CYGHWR_INTEL_I82544_PCI_VIRT_TO_BUS( _x_ ) ((cyg_uint32)CYGARC_VIRT_TO_BUS(_x_))
+#define CYGHWR_INTEL_I82544_PCI_BUS_TO_VIRT( _x_ ) ((cyg_uint32)CYGARC_BUS_TO_VIRT(_x_))
+
+#define MAX_PACKET_SIZE 1536
+#define SIZEOF_DESCRIPTOR 16
+
+#define CYGHWR_INTEL_I82544_PCI_MEM_MAP_SIZE \
+ (((MAX_PACKET_SIZE + SIZEOF_DESCRIPTOR) * \
+ (MAX_TX_DESCRIPTORS + MAX_RX_DESCRIPTORS)) + 64)
+
+static char pci_mem_buffer[CYGHWR_INTEL_I82544_PCI_MEM_MAP_SIZE + HAL_DCACHE_LINE_SIZE];
+
+#define CYGHWR_INTEL_I82544_PCI_MEM_MAP_BASE \
+ (CYGARC_UNCACHED_ADDRESS(((unsigned)pci_mem_buffer + HAL_DCACHE_LINE_SIZE - 1) & ~(HAL_DCACHE_LINE_SIZE - 1)))
+
+static I82544 i82544_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_ARM_IQ80321_I82544_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_ARM_IQ80321_I82544_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82544_sc0,
+ &i82544_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_IQ80321_I82544_ETH0_NAME, // Name for device
+ i82544_start,
+ i82544_stop,
+ i82544_ioctl,
+ i82544_can_send,
+ i82544_send,
+ i82544_recv,
+ i82544_deliver,
+ i82544_poll,
+ i82544_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82544_netdev0,
+ "i82544_" CYGDAT_DEVS_ETH_ARM_IQ80321_I82544_ETH0_NAME,
+ i82544_init,
+ &i82544_sc0);
+
+#endif // CYGPKG_DEVS_ETH_ARM_IQ80321_I82544_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+I82544 *
+i82544_priv_array[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_IQ80321_I82544_ETH0
+ &i82544_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82544_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_IQ80321_I82544_ETH0
+ &i82544_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+i82544_sc_array[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_IQ80321_I82544_ETH0
+ &i82544_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// EOF devs_eth_arm_iq80321.inl
diff --git a/ecos/packages/devs/eth/arm/ixdp425/i82559/current/ChangeLog b/ecos/packages/devs/eth/arm/ixdp425/i82559/current/ChangeLog
new file mode 100644
index 0000000..fb7a67d
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ixdp425/i82559/current/ChangeLog
@@ -0,0 +1,44 @@
+2003-03-26 Mark Salter <msalter@redhat.com>
+
+ * cdl/ixdp425_i82559_eth_driver.cdl: Default to off for
+ CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA.
+
+ * include/ixdp425_i82559.inl: Fix commenting of copyright.
+
+2003-03-24 Mark Salter <msalter@redhat.com>
+
+ * cdl/ixdp425_i82559_eth_driver.cdl: Fix copyright notice.
+ * include/ixdp425_i82559.inl: Ditto.
+
+2003-02-07 Mark Salter <msalter@redhat.com>
+
+ * cdl/ixdp425_i82559_eth_driver.cdl: CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA.
+ * include/ixdp425_i82559.inl: Support ESA in RedBoot flash.
+
+2002-12-17 Mark Salter <msalter@redhat.com>
+
+ * include/ixdp425_i82559.inl: Define CYGHWR_DEVS_ETH_INTEL_I82559_ENDIAN_NEUTRAL_IO.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/ixdp425/i82559/current/cdl/ixdp425_i82559_eth_driver.cdl b/ecos/packages/devs/eth/arm/ixdp425/i82559/current/cdl/ixdp425_i82559_eth_driver.cdl
new file mode 100755
index 0000000..c79650c
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ixdp425/i82559/current/cdl/ixdp425_i82559_eth_driver.cdl
@@ -0,0 +1,149 @@
+# ====================================================================
+#
+# ixdp425_i82559_eth_driver.cdl
+#
+# Ethernet driver
+# IXDP425 and Intel PRO/100+ platform specific support
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):
+# Original data: hmt
+# Contributors: gthomas
+# Date: 2002-04-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_IXDP425_I82559 {
+ display "IXDP425 with Intel PRO/100+ (PCI) ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_XSCALE_IXDP425
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82559 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
+ display "Intel i82559 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/ixdp425_i82559.inl>"
+
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_arm_ixdp425_i82559.h>"
+
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_IXDP425_I82559_ETH0 {
+ display "IXDP425 ethernet port driver for an I82559-based ethernet NIC card"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the IXDP425 ethernet device driver for a
+ I82559-based ethernet PCI card."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_IXDP425_I82559_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for a
+ I82559-based ethernet NIC card."
+ }
+ }
+
+
+ # note that this option's name is NOT ixdp-specific, but i82559
+ # generic - other instantiations can set these also.
+ cdl_component CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 0
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+ description "Enabling this option will allow the ethernet
+ station address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually by the
+ 'Set the ethernet station address' option for each interface."
+
+ cdl_component CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_VARS {
+ display "Build-in flash config fields for ESAs"
+ flavor bool
+ default_value 1
+
+ active_if CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT_FLASH
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+
+ description "
+ This option controls the presence of RedBoot flash
+ configuration fields for the ESAs of the interfaces when you
+ are building RedBoot. It is independent of whether RedBoot
+ itself uses the network or any particular interface; this
+ support is more for the application to use than for RedBoot
+ itself, though the application gets at the data by vector
+ calls; this option cannot be enabled outside of building
+ RedBoot."
+
+ cdl_option CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 1
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_IXDP425_ETH0_DEFAULT_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0x03, 0x47, 0xdf, 0x32, 0xa8}"}
+ description "The default ethernet station address. This is the
+ address used as the default value in the RedBoot
+ flash configuration field."
+ }
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/arm/ixdp425/i82559/current/include/ixdp425_i82559.inl b/ecos/packages/devs/eth/arm/ixdp425/i82559/current/include/ixdp425_i82559.inl
new file mode 100755
index 0000000..b52afba
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ixdp425/i82559/current/include/ixdp425_i82559.inl
@@ -0,0 +1,188 @@
+//==========================================================================
+//
+// ixdp425_i82559.inl
+//
+// IXDP425 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):
+// Contributors:msalter
+// Date: 2002-05-14
+// Purpose: ixdp425 ethernet definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHERNET
+#include <cyg/hal/hal_cache.h> // HAL_DCACHE_LINE_SIZE
+#include <cyg/hal/plf_io.h> // CYGARC_UNCACHED_ADDRESS
+
+// Bus hardware takes care of IO endianess issues.
+#define CYGHWR_DEVS_ETH_INTEL_I82559_ENDIAN_NEUTRAL_IO 1
+
+// NB: Bus masters can only get to first 64MB SDRAM
+#define CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS( _x_ ) \
+ ((cyg_uint32)CYGARC_VIRT_TO_BUS(_x_))
+
+#define MAX_PACKET_SIZE 1536
+#define SIZEOF_DESCRIPTOR 16
+#define MISC_MEM 1128 // selftest, ioctl and statistics
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE \
+ (((MAX_PACKET_SIZE + SIZEOF_DESCRIPTOR) * \
+ (CYGNUM_DEVS_ETH_INTEL_I82559_MAX_TX_DESCRIPTORS + \
+ CYGNUM_DEVS_ETH_INTEL_I82559_MAX_RX_DESCRIPTORS)) + \
+ MISC_MEM)*CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT
+
+// The PCI Window is 64MB starting at 0x00000000, so as long as the bss
+// section is within addresses 0x00000000-0x04000000, pci_mem_buffer[] will be
+// in the true PCI Window. Because pci_mem_buffer[] is in the bss section,
+// wanted its size to be only as large as required so as to not waste memory.
+// Therefore, had to compute it's size in this file and not in the memory
+// layout files. So no __pci_window label was ever defined, therefore,
+// CYGMEM_SECTION_pci_window does not exist. Define CYGMEM_SECTION_pci_window
+// here in order to satisfy the ASSERT within if_i82559.c.
+static char pci_mem_buffer[CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE
+ + HAL_DCACHE_LINE_SIZE];
+
+#define CYGMEM_SECTION_pci_window (((unsigned)pci_mem_buffer \
+ + HAL_DCACHE_LINE_SIZE - 1) \
+ & ~(HAL_DCACHE_LINE_SIZE - 1))
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE \
+ (CYGARC_UNCACHED_ADDRESS(CYGMEM_SECTION_pci_window))
+
+
+#ifdef CYGPKG_DEVS_ETH_ARM_IXDP425_I82559_ETH0
+
+static I82559 i82559_eth0_priv_data = {
+ hardwired_esa: 0,
+#if defined(CYGPKG_REDBOOT) && defined(CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0)
+ mac_address: CYGDAT_DEVS_ETH_ARM_IXDP425_ETH0_DEFAULT_ESA
+#endif
+};
+
+ETH_DRV_SC(i82559_sc0,
+ &i82559_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_IXDP425_I82559_ETH0_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev0,
+ "i82559_" CYGDAT_DEVS_ETH_ARM_IXDP425_I82559_ETH0_NAME,
+ i82559_init,
+ &i82559_sc0);
+#endif // CYGPKG_DEVS_ETH_ARM_IXP425_I82559_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+I82559 *
+i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_IXDP425_I82559_ETH0
+ &i82559_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_IXDP425_I82559_ETH0
+ &i82559_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_IXDP425_I82559_ETH0
+ &i82559_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// Decide whether to have redboot config vars for it...
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#ifdef CYGPKG_REDBOOT_NETWORKING
+#include <redboot.h>
+#include <flash_config.h>
+
+#ifdef CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, i82559_eth0_priv_data.mac_address
+ );
+#endif
+
+#endif // CYGPKG_REDBOOT_NETWORKING
+#endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#endif // CYGPKG_REDBOOT
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+
+#include <cyg/hal/hal_if.h>
+
+#ifndef CONFIG_ESA
+#define CONFIG_ESA (6)
+#endif
+
+#define CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA( p_i82559, mac_address, ok ) \
+CYG_MACRO_START \
+ ok = false; \
+ if ( 0 == p_i82559->index ) \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa", mac_address, CONFIG_ESA); \
+ else if ( 1 == p_i82559->index ) \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth1_esa", mac_address, CONFIG_ESA); \
+CYG_MACRO_END
+
+#endif // CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/ChangeLog b/ecos/packages/devs/eth/arm/ks32c5000/current/ChangeLog
new file mode 100644
index 0000000..2a9dc4d
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/ChangeLog
@@ -0,0 +1,134 @@
+2003-10-09 Roland Cassebohm <roland.cassebohm@visionsystems.de>
+
+ * src/rtl8201.c: New file. Added RTL8201 PHY support.
+ * cdl/ks32c5000_eth.cdl: CDL to allow configuration of the above.
+
+2003-10-09 Roland Cassebohm <roland.cassebohm@visionsystems.de>
+
+ * src/ks5000_ether.c: Set ifStats.description only one time while
+ initialization, it will never change.
+ Set ifStats.supports_dot3 to 1, to support snmp mib dot3.
+ Set ifStats.snmp_chipset to be interpreted as "nullobjid" in the
+ snmp dot3 agent. It is not a string it is an oid as byte array.
+ The link status of the phy are read while initializion and in the
+ command ETH_DRV_GET_IF_STATS to be up to date without phy interrupt
+ support.
+ Change firstTime in installInterrupts() to be static to be sure
+ interrupts will only one time be installed.
+
+2003-06-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/ks5000_ether.c: Some tidies of the previous changes.
+ * cdl/ks32c5000_eth.cdl: Clarify option description and rename
+ CYGVAR_DEVS_ETH_ARM_KS32C5000_REDBOOT_HOLDS_ESA_ETH0 to
+ CYGSEM_DEVS_ETH_ARM_KS32C5000_REDBOOT_HOLDS_ESA_ETH0.
+
+2003-05-26 Chris Garry <cgarry@sweeneydesign.co.uk>
+
+ * cdl/ks32c5000_eth.cdl: Added support for MAC address to be used
+ from RedBoot's FLASH configuration data.
+ * src/ks5000_ether.c: Updated driver to work with LWIP stack as
+ well as the BSD stack. Added support for MAC address to be used
+ from RedBoot's FLASH configuration data.
+
+2003-04-08 Michael Checky <Michael_Checky@Thermoking.com>
+
+ * cdl/ks32c5000_eth.cdl: CYGINT_DEVS_ETH_ARM_KS32C5000_PHY can now
+ be zero or one to allow for no PHY station management control.
+ * src/ks5000_ether.c: Changed '#if HavePHY' to
+ '#if CYGINT_DEVS_ETH_ARM_KS32C5000_PHY'
+
+2003-03-27 Jay Foster <jay@systech.com>
+
+ * src/ics1890.c: Added configurable PHY MII address.
+ * src/lxt970.c: Added configurable PHY MII address.
+ * src/lxt972.c: Added configurable PHY MII address.
+ * cdl/ks32c5000_eth.cdl: CDL to allow configuration of the PHY
+ MII address. Documented support for ICS1893AF PHY.
+ * src/ks5000_ether.c: Added configurable PHY MII address.
+ Fixed local definition of eth_drv_init() macro (produces no code
+ change). Fixed strncpy()s for the ETH_DRV_GET_IF_STATS IOCTL to
+ leave room for the NUL termination character and use parenthesis
+ with the 'sizeof' operator. Added ETH_DRV_SET_MAC_ADDRESS IOCTL
+ support to allow setting the MAC (ESA) address from the application.
+ Fixed to only attach the CYGNUM_HAL_INTERRUPT_EXT0 if the
+ HavePHYinterrupt conditional is defined. This prevents unhandled
+ interrupts from getting through when HavePHYinterrupt is not defined.
+
+2003-03-26 Chris Garry <cgarry@sweeneydesign.co.uk>
+
+ * cdl/ks32c5000_eth.cdl
+ * src/ks5000_ether.c: Added CDL control for level of driver
+ debug output.
+
+2003-03-20 Chris Garry <cgarry@sweeneydesign.co.uk>
+
+ * src/ks5000_ether.c:
+ Added volatile to *rxReadPointer, *txDonePointer and
+ *txWritePointer's definitions.
+
+2003-02-20 Chris Garry <cgarry@sweeneydesign.co.uk>
+
+ * src/ks5000_ether.c:
+ Removed line setting up programmable I/O pins as debug outputs.
+
+2002-11-05 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ks32c5000_eth.cdl: Ensure exactly 1 PHY enabled.
+
+2002-11-05 Chris Garry <cgarry@sweeneydesign.co.uk>
+
+ * src/lxt972.c: New file. Added LXT972 PHY support.
+ * cdl/ks32c5000_eth.cdl: CDL to allow configuration of the above.
+
+ * src/ks5000_ether.c: (CYG_BYTEORDER == CYG_MSBFIRST) used to swap
+ endian in BDMARxConfigVar declaration and txWritePointer transmit
+ descriptor reserved fields setup.
+ (ks32c5000_eth_poll): Added call to BDMA Rx isr routine.
+
+2002-10-10 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/ks32c5000_eth.cdl
+ * src/ks5000_ether.c (ks32c5000_eth_get_recv_buffer): Use the
+ cyg_crc32 function in the CRC package.
+
+2002-07-10 Gary Thomas <gary@chez-thomas.org>
+2002-07-10 Simon Sudler <sudlersn@iis.fhg.de>
+
+ * src/ks5000_ether.c: Fix problems with interrupt names (spelling).
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/ks5000_ether.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-05-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/ks5000_ether.c (ks32c5000_eth_send): Conditionalize on
+ CYGPKG_KERNEL for presence of thread delay function.
+ (ks32c5000_eth_init): No need conditionalizing unmask on CYGPKG_NET.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/cdl/ks32c5000_eth.cdl b/ecos/packages/devs/eth/arm/ks32c5000/current/cdl/ks32c5000_eth.cdl
new file mode 100644
index 0000000..8d2bee9
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/cdl/ks32c5000_eth.cdl
@@ -0,0 +1,222 @@
+#==========================================================================
+#
+# ks32c5000_eth.cdl
+#
+# Ethernet drivers for Samsung KS32C5000/S3C4510
+#
+#==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov
+# Grant Edwards <grante@visi.com>
+# Date: 2001-07-31
+# Purpose:
+# Description:
+#
+#####DESCRIPTIONEND####
+#
+#========================================================================*/
+
+
+cdl_package CYGPKG_DEVS_ETH_ARM_KS32C5000 {
+ display "Samsung KS32C5000/S3C4510 ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ requires (CYGPKG_CRC || (!(CYG_HAL_CPUTYPE == \"KS32C5000A\" )))
+ requires (CYGINT_DEVS_ETH_ARM_KS32C5000_PHY <= 1)
+
+ include_dir net
+ description "Ethernet driver for Samsung KS32C5000"
+ compile -library=libextras.a ks5000_ether.c
+
+
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_KS32C5000_OPTIONS {
+ display "Samsung ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_interface CYGINT_DEVS_ETH_ARM_KS32C5000_PHY {
+ display "PHY Station Management support"
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_KS32C5000_DEBUG_LEVEL {
+ display "KS32C5000 device driver debug output level"
+ flavor data
+ legal_values {0 1 2}
+ default_value 1
+ description "
+ This option specifies the level of debug data output by the
+ KS32C5000 device driver. A value of 0 signifies no debug data
+ output; 1 signifies normal debug data output; and 2 signifies
+ maximum debug data output (not suitable when GDB and
+ application are sharing an ethernet port)."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_ICS1890 {
+ display "ICS1890 PHY support"
+ flavor bool
+ default_value 0
+ implements CYGINT_DEVS_ETH_ARM_KS32C5000_PHY
+ compile -library=libextras.a ics1890.c
+ description "This component provides support for the ICS1890 and
+ ICS1893AF PHY"
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT970 {
+ display "LXT970 PHY support"
+ flavor bool
+ default_value 1
+ implements CYGINT_DEVS_ETH_ARM_KS32C5000_PHY
+ compile -library=libextras.a lxt970.c
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT972 {
+ display "LXT972 PHY support"
+ flavor bool
+ default_value 0
+ implements CYGINT_DEVS_ETH_ARM_KS32C5000_PHY
+ compile -library=libextras.a lxt972.c
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT972_LED1 {
+ display "LED 1 mode"
+ flavor data
+ legal_values {"LINK_SPEED" "TX_ACTIVITY" "RX_ACTIVITY" "COLLISION_STATUS" "LINK_STATUS" "DUPLEX_STATUS"
+ "LINK_ACTIVITY" "LINK_STATUS_RX_STATUS_COMBINED" "LINK_STATUS_LINK_ACTIVITY_COMBINED"
+ "DUPLEX_STATUS_COLLISION_STATUS_COMBINED" "TEST_ON" "TEST_OFF" "TEST_BLINK_FAST"
+ "TEST_BLINK_SLOW"}
+ default_value {"LINK_STATUS"}
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT972_LED2 {
+ display "LED 2 mode"
+ flavor data
+ legal_values {"LINK_SPEED" "TX_ACTIVITY" "RX_ACTIVITY" "COLLISION_STATUS" "LINK_STATUS" "DUPLEX_STATUS"
+ "LINK_ACTIVITY" "LINK_STATUS_RX_STATUS_COMBINED" "LINK_STATUS_LINK_ACTIVITY_COMBINED"
+ "DUPLEX_STATUS_COLLISION_STATUS_COMBINED" "TEST_ON" "TEST_OFF" "TEST_BLINK_FAST"
+ "TEST_BLINK_SLOW"}
+ default_value {"LINK_SPEED"}
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT972_LED3 {
+ display "LED 3 mode"
+ flavor data
+ legal_values {"LINK_SPEED" "TX_ACTIVITY" "RX_ACTIVITY" "COLLISION_STATUS" "LINK_STATUS" "DUPLEX_STATUS"
+ "LINK_ACTIVITY" "LINK_STATUS_RX_STATUS_COMBINED" "LINK_STATUS_LINK_ACTIVITY_COMBINED"
+ "DUPLEX_STATUS_COLLISION_STATUS_COMBINED" "TEST_ON" "TEST_OFF" "TEST_BLINK_FAST"
+ "TEST_BLINK_SLOW"}
+ default_value {"LINK_ACTIVITY"}
+ }
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_RTL8201 {
+ display "RTL8201 PHY support"
+ flavor bool
+ default_value 0
+ implements CYGINT_DEVS_ETH_ARM_KS32C5000_PHY
+ compile -library=libextras.a rtl8201.c
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR {
+ display "PHY MII address"
+ flavor data
+ legal_values 0 to 31
+ default_value 1
+ description "This option specifies the MII address of the PHY"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_KS32C5000_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 0
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ active_if (CYGPKG_REDBOOT || CYGSEM_HAL_USE_ROM_MONITOR)
+
+ description "Enabling this option will allow the ethernet
+ station address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually by the
+ 'Set the ethernet station address' option for each interface."
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_KS32C5000_REDBOOT_HOLDS_ESA_VARS {
+ display "Export RedBoot command to set ESA in FLASH config"
+ flavor none
+ no_define
+
+ description "
+ This component contains options which, when enabled, allow
+ RedBoot to support the setting of the ESA in the FLASH
+ configuration. This can then subsequently be accessed by
+ applications using virtual vector calls if those applications
+ are also built with
+ CYGPKG_DEVS_ETH_ARM_KS32C5000_REDBOOT_HOLDS_ESA enabled."
+
+ cdl_option CYGSEM_DEVS_ETH_ARM_KS32C5000_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 1
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+ }
+ }
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_KS32C5000_MACADDR {
+ display "Ethernet station (MAC) address for eth0"
+ flavor data
+ default_value {"0x08, 0x88, 0x12, 0x34, 0x56, 0x78"}
+ description "The default ethernet station address. This is the
+ MAC address used when no value is found in the
+ RedBoot FLASH configuration field."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_KS32C5000_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Samsung KS32C5000 ethernet driver package.
+ These flags are used in addition to the set of global flags."
+ }
+ }
+}
+
+# EOF ks32c5000_eth.cdl
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/src/ics1890.c b/ecos/packages/devs/eth/arm/ks32c5000/current/src/ics1890.c
new file mode 100755
index 0000000..dba5426
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/src/ics1890.c
@@ -0,0 +1,103 @@
+//==========================================================================
+//
+// ics1890.c
+//
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Grant Edwards <grante@visi.com>
+// Date: 2001-07-31
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include "std.h"
+#include "ks5000_regs.h"
+#include "phy.h"
+
+#define PHY_CNTL_REG 0x00
+#define PHY_STATUS_REG 0x01
+#define PHY_ID_REG1 0x02
+#define PHY_ID_REG2 0x03
+#define PHY_ANA_REG 0x04
+#define PHY_ANLPAR_REG 0x05
+#define PHY_ANE_REG 0x06
+#define PHY_ECNTL_REG1 0x10
+#define PHY_QPDS_REG 0x11
+#define PHY_10BOP_REG 0x12
+#define PHY_ECNTL_REG2 0x13
+
+#ifdef CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
+#define PHYHWADDR CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
+#else
+#define PHYHWADDR 1
+#endif
+
+#define Bit(n) (1<<(n))
+
+#define RESET_PHY Bit(15)
+#define ENABLE_LOOPBACK Bit(14)
+#define DR_100MB Bit(13)
+#define ENABLE_AN Bit(12)
+#define PHY_MAC_ISOLATE Bit(10)
+#define RESTART_AN Bit(9)
+#define PHY_FULLDUPLEX Bit(8)
+#define PHY_COL_TEST Bit(7)
+
+void PhyReset(void)
+{
+ MiiStationWrite(PHY_CNTL_REG, PHYHWADDR, RESET_PHY ) ;
+ MiiStationWrite(PHY_CNTL_REG, PHYHWADDR, ENABLE_AN | RESTART_AN) ;
+}
+
+unsigned PhyStatus(void)
+{
+ unsigned status = MiiStationRead(PHY_QPDS_REG,PHYHWADDR);
+ unsigned r = 0;
+ if (status & Bit(0))
+ r |= PhyStatus_LinkUp;
+ if (status & Bit(14))
+ r |= PhyStatus_FullDuplex;
+ if (status & Bit(15))
+ r |= PhyStatus_100Mb;
+ return r;
+}
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.c b/ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.c
new file mode 100755
index 0000000..34d899e
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.c
@@ -0,0 +1,1479 @@
+//==========================================================================
+//
+// ks5000_ether.c
+//
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Grant Edwards <grante@visi.com>
+// Date: 2001-07-31
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_arm_ks32c5000.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <errno.h>
+#if defined(CYGPKG_IO)
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#endif
+// need to provide fake values for errno?
+#ifndef EIO
+# define EIO 1
+#endif
+#ifndef EINVAL
+# define EINVAL 2
+#endif
+
+#include <cyg/infra/cyg_type.h> // Common type definitions and support
+ // including endian-ness
+#include <cyg/infra/diag.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/eth_drv_stats.h>
+#include <cyg/hal/hal_intr.h>
+
+#if defined(CYGPKG_REDBOOT)
+#include <pkgconf/redboot.h>
+#endif
+
+#ifndef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+#define cyg_drv_interrupt_unmask(v) /* noop */
+#define cyg_drv_interrupt_mask(v) /* noop */
+#define cyg_drv_isr_lock() /* noop */
+#define cyg_drv_isr_unlock() /* noop */
+#define cyg_drv_mutex_init(m) /* noop */
+#define cyg_drv_mutex_lock(m) /* noop */
+#define cyg_drv_mutex_unlock(m) /* noop */
+#define cyg_drv_dsr_lock() /* noop */
+#define cyg_drv_dsr_unlock() /* noop */
+#endif
+
+#define HavePHYinterrupt 0
+
+#include "std.h"
+#include "ks5000_regs.h"
+#include "ks5000_ether.h"
+
+#if CYGINT_DEVS_ETH_ARM_KS32C5000_PHY
+#include "phy.h"
+#endif
+
+// Set up the level of debug output
+#if CYGPKG_DEVS_ETH_ARM_KS32C5000_DEBUG_LEVEL > 0
+#define debug1_printf(args...) diag_printf(args)
+#else
+#define debug1_printf(args...) /* noop */
+#endif
+#if CYGPKG_DEVS_ETH_ARM_KS32C5000_DEBUG_LEVEL > 1
+#define debug2_printf(args...) diag_printf(args)
+#else
+#define debug2_printf(args...) /* noop */
+#endif
+
+#define Bit(n) (1<<(n))
+
+// enable/disable software verification of rx CRC
+// should be moved to user-controlled valud in CDL file
+
+#if defined(CYG_HAL_CPUTYPE_KS32C5000A)
+#define SoftwareCRC 1
+#include <cyg/crc/crc.h>
+#else
+#define SoftwareCRC 0
+#endif
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// Decide whether to have redboot config vars for it...
+#if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGPKG_REDBOOT_NETWORKING)
+#include <redboot.h>
+#include <flash_config.h>
+
+#ifdef CYGSEM_DEVS_ETH_ARM_KS32C5000_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa_data,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0);
+#endif
+
+#endif // CYGPKG_REDBOOT_NETWORKING && CYGSEM_REDBOOT_FLASH_CONFIG
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_ARM_KS32C5000_REDBOOT_HOLDS_ESA
+
+#include <cyg/hal/hal_if.h>
+
+#ifndef CONFIG_ESA
+#define CONFIG_ESA (6)
+#endif
+
+#define CYGHWR_DEVS_ETH_ARM_KS32C5000_GET_ESA( mac_address, ok ) \
+CYG_MACRO_START \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa_data", mac_address, CONFIG_ESA); \
+CYG_MACRO_END
+
+#endif // CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+
+
+#if CYGINT_DEVS_ETH_ARM_KS32C5000_PHY
+// functions to read/write Phy chip registers via MII interface
+// on 32c5000. These need to be non-static since they're used
+// by PHY-specific routines in a different file.
+#define PHYREGWRITE 0x0400
+#define MiiStart 0x0800
+
+void MiiStationWrite(U32 RegAddr, U32 PhyAddr, U32 PhyWrData)
+{
+ STADATA = PhyWrData ;
+ STACON = RegAddr | (PhyAddr<<5) | MiiStart | PHYREGWRITE ;
+ while (STACON & MiiStart)
+ ;
+ //debug1_printf("PHY Wr %x:%02x := %04x\n",PhyAddr, RegAddr, PhyWrData) ;
+}
+
+U32 MiiStationRead(U32 RegAddr, U32 PhyAddr)
+{
+ U32 PhyRdData;
+ STACON = RegAddr | (PhyAddr<<5) | MiiStart;
+ while (STACON & MiiStart)
+ ;
+ PhyRdData = STADATA;
+ //debug1_printf("PHY Rd %x:%02x %04x\n",PhyAddr,RegAddr,PhyRdData) ;
+ return PhyRdData ;
+}
+#endif
+
+// miscellaneous data structures
+
+typedef BYTE ETH_ADDR[6] __attribute__((packed));
+
+typedef struct tagETH_HEADER
+{
+ ETH_ADDR daddr __attribute__((packed));
+ ETH_ADDR saddr __attribute__((packed));
+ WORD type __attribute__((packed));
+} ETH_HEADER __attribute__((packed));
+
+#define ETH_HEADER_SIZE 14
+
+// Tx/Rx common descriptor structure
+typedef struct tagFRAME_DESCRIPTOR
+{
+ LWORD FrameDataPtr;
+ LWORD Reserved; /* cf: RX-reserved, TX-Reserved(25bits) + Control bits(7bits) */
+ LWORD StatusAndFrameLength;
+ struct tagFRAME_DESCRIPTOR *NextFD;
+} FRAME_DESCRIPTOR;
+
+typedef struct
+{
+ U8 DestinationAddr[6];
+ U8 SourceAddr[6];
+ U8 LengthOrType[2];
+ U8 LLCData[1506];
+} MAC_FRAME;
+
+#if defined(CYGPKG_NET)
+struct ether_drv_stats ifStats;
+#endif
+
+#if defined(CYGINT_IO_ETH_INT_SUPPORT_REQUIRED)
+static cyg_drv_mutex_t txMutex;
+#endif
+
+typedef struct
+{
+ LWORD BTxNLErr;
+ LWORD BTxNOErr;
+ LWORD BTxEmptyErr;
+} BDMA_TX_ERR;
+
+typedef struct
+{
+ LWORD BRxNLErr;
+ LWORD BRxNOErr;
+ LWORD BRxMSOErr;
+ LWORD BRxEmptyErr;
+ LWORD sBRxSEarly;
+ LWORD noBufferAvail;
+ LWORD queueOverflow;
+ LWORD bad;
+} BDMA_RX_ERR;
+
+
+// interrupt entry counters
+U32 ks5000_MAC_Rx_Cnt;
+U32 ks5000_MAC_Tx_Cnt;
+U32 ks5000_MAC_Phy_Cnt;
+U32 ks5000_BDMA_Tx_Isr_Cnt;
+U32 ks5000_BDMA_Tx_Dsr_Cnt;
+U32 ks5000_BDMA_Rx_Isr_Cnt;
+U32 ks5000_BDMA_Rx_Dsr_Cnt;
+
+
+// packet and byte counters
+static U32 MAC_Tx_Pkts;
+static U32 MAC_Tx_Octets;
+// static U32 BDMA_Rx_Pkts;
+// static U32 BDMA_Rx_Octets;
+
+// configuration values
+static volatile U32 MACConfigVar;
+static volatile U32 CAMConfigVar = CAMCON_COMP_EN | CAMCON_BROAD_ACC;
+static volatile U32 MACTxConfigVar =
+ /* MACTXCON_EN_UNDER | */
+ MACTXCON_EN_DEFER |
+ MACTXCON_EN_NCARR |
+ MACTXCON_EN_EXCOLL |
+ MACTXCON_EN_LATE_COLL |
+ MACTXCON_ENTX_PAR |
+ MACTXCON_EN_COMP;
+static volatile U32 MACRxConfigVar =
+ MACRXCON_RX_EN |
+ MACRXCON_EN_ALIGN |
+ MACRXCON_EN_CRC_ERR |
+ MACRXCON_EN_OVER |
+ MACRXCON_EN_LONG_ERR |
+ MACRXCON_EN_RX_PAR;
+
+static volatile U32 BDMATxConfigVar =
+ BDMATXCON_MSL111 |
+ BDMATXCON_STP_SKP |
+ 3; /* burst size - 1 */
+
+#define EtherFramePadding 2
+
+#if EtherFramePadding == 0
+#define BDMARXCON_ALIGN BDMARXCON_WA00
+#elif EtherFramePadding == 1
+#define BDMARXCON_ALIGN BDMARXCON_WA01
+#elif EtherFramePadding == 2
+#define BDMARXCON_ALIGN BDMARXCON_WA10
+#elif EtherFramePadding == 3
+#define BDMARXCON_ALIGN BDMARXCON_WA11
+#else
+#error "EtherFramePadding must be 0,1,2 or 3"
+#endif
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST) // Big endian
+static volatile U32 BDMARxConfigVar =
+ BDMARXCON_DIE |
+ BDMARXCON_EN |
+ BDMARXCON_BIG |
+ BDMARXCON_MA_INC |
+ BDMARXCON_NOIE |
+ BDMARXCON_ALIGN |
+ BDMARXCON_STP_SKP |
+ 15; /* burst size - 1 */
+
+#else // Little endian
+static volatile U32 BDMARxConfigVar =
+ BDMARXCON_DIE |
+ BDMARXCON_EN |
+ BDMARXCON_LITTLE |
+ BDMARXCON_MA_INC |
+ BDMARXCON_NOIE |
+ BDMARXCON_ALIGN |
+ BDMARXCON_STP_SKP |
+ 15; /* burst size - 1 */
+#endif
+
+
+/* Global variables For BDMA Error Report */
+
+static BDMA_TX_ERR BDMATxErrCnt = {0,0,0};
+static BDMA_RX_ERR BDMARxErrCnt = {0,0,0,0,0};
+
+
+static void Init_TxFrameDescriptorArray(void);
+static void Init_RxFrameDescriptorArray(void);
+
+// number of ethernet buffers should be enough to keep both rx
+// and tx queues full plus some extras for in-process packets
+
+#if defined(CYGPKG_REDBOOT)
+#define NUM_ETH_BUFFERS 10
+#define MAX_RX_FRAME_DESCRIPTORS 4 // Max number of Rx Frame Descriptors
+#define MAX_TX_FRAME_DESCRIPTORS 4 // Max number of Tx Frame Descriptors
+#else
+#define NUM_ETH_BUFFERS 80
+#define MAX_RX_FRAME_DESCRIPTORS 32 // Max number of Rx Frame Descriptors
+#define MAX_TX_FRAME_DESCRIPTORS 32 // Max number of Tx Frame Descriptors
+#endif
+
+static FRAME_DESCRIPTOR _rxFrameDescrArray[MAX_RX_FRAME_DESCRIPTORS] __attribute__((aligned(16)));
+static FRAME_DESCRIPTOR _txFrameDescrArray[MAX_TX_FRAME_DESCRIPTORS] __attribute__((aligned(16)));
+
+/* define aliases that will set the no-cache bit */
+#define rxFrameDescrArray ((FRAME_DESCRIPTOR*)(((unsigned)_rxFrameDescrArray)|0x4000000))
+#define txFrameDescrArray ((FRAME_DESCRIPTOR*)(((unsigned)_txFrameDescrArray)|0x4000000))
+
+static volatile FRAME_DESCRIPTOR *rxReadPointer;
+static volatile FRAME_DESCRIPTOR *txDonePointer;
+static volatile FRAME_DESCRIPTOR *txWritePointer;
+
+static cyg_drv_mutex_t oldRxMutex;
+static cyg_drv_cond_t oldRxCond;
+
+
+static bool configDone;
+
+/*----------------------------------------------------------------------
+ * Data structures used to manage ethernet buffers
+ */
+#define MAX_ETH_FRAME_SIZE 1520
+
+typedef struct tEthBufferTag
+{
+ unsigned char data[MAX_ETH_FRAME_SIZE+8];
+ unsigned length;
+ unsigned userData;
+ struct tEthBufferTag *next;
+ struct tEthBufferTag *prev;
+}tEthBuffer;
+
+
+typedef struct
+{
+ tEthBuffer *head;
+ tEthBuffer *tail;
+}tEthBufQueue;
+
+#define EmptyQueue {NULL,NULL}
+
+static void ethBufQueueClear(tEthBufQueue *q)
+{
+ q->head = NULL;
+ q->tail = NULL;
+}
+
+static tEthBuffer *ethBufQueueGet(tEthBufQueue *q)
+{
+ tEthBuffer *r;
+
+ r = q->head;
+
+ if (r)
+ q->head = r->next;
+
+ return r;
+}
+
+static void ethBufQueuePut(tEthBufQueue *q, tEthBuffer *b)
+{
+ b->next = NULL;
+
+ if (!q->head)
+ {
+ q->head = b;
+ q->tail = b;
+ }
+ else
+ {
+ q->tail->next = b;
+ q->tail = b;
+ }
+}
+
+#if 0
+// not used at the moment
+static bool ethBufQueueEmpty(tEthBufQueue *q)
+{
+ return q->head != NULL;
+}
+#endif
+
+/*----------------------------------------------------------------------
+ * Free pool and routines to manipulate it.
+ */
+
+static tEthBuffer __bufferPool[NUM_ETH_BUFFERS] __attribute__((aligned(16)));
+#define bufferPool ((tEthBuffer*)((unsigned)__bufferPool|0x4000000))
+
+static tEthBufQueue freeList;
+static int freeCount;
+
+// do not call from ISR routine
+static void freeBuffer(tEthBuffer *b)
+{
+ cyg_drv_isr_lock();
+ ++freeCount;
+ ethBufQueuePut(&freeList,b);
+ cyg_drv_isr_unlock();
+}
+
+static int allocFail;
+
+void bufferListError(void)
+{
+ while (1)
+ ;
+}
+
+// do not call from ISR routine
+static tEthBuffer *allocBuffer(void)
+{
+ tEthBuffer *r;
+ cyg_drv_isr_lock();
+ r = ethBufQueueGet(&freeList);
+ cyg_drv_isr_unlock();
+ if (r)
+ --freeCount;
+ else
+ {
+ ++allocFail;
+ if (freeCount)
+ bufferListError();
+ }
+ return r;
+}
+
+// call only from ISR routine or init
+static void isrFreeBuffer(tEthBuffer *b)
+{
+ ++freeCount;
+ ethBufQueuePut(&freeList,b);
+}
+
+#if 0
+// not used at the moment
+
+// call only from ISR routine or init
+static tEthBuffer *isrAllocBuffer(void)
+{
+ tEthBuffer *r;
+ r = ethBufQueueGet(&freeList);
+ if (r)
+ --freeCount;
+ else
+ {
+ ++allocFail;
+ if (freeCount)
+ bufferListError();
+ }
+ return r;
+}
+#endif
+
+static void initFreeList(void)
+{
+ int i;
+ ethBufQueueClear(&freeList);
+ freeCount = 0;
+ for (i=0; i<NUM_ETH_BUFFERS; ++i)
+ isrFreeBuffer(bufferPool+i);
+}
+
+
+//----------------------------------------------------------------------
+// queue a buffer for transmit
+//
+// returns true if buffer was queued.
+
+static int ks32c5000_eth_buffer_send(tEthBuffer *buf)
+{
+#if defined(CYGINT_IO_ETH_INT_SUPPORT_REQUIRED)
+ while (!configDone)
+ cyg_thread_delay(10);
+#endif
+
+ if (txWritePointer->FrameDataPtr & FRM_OWNERSHIP_BDMA)
+ {
+ // queue is full! make sure transmit is running
+ BDMATXCON |= BDMATXCON_EN;
+ MACTXCON |= MACTXCON_TX_EN;
+ return 0;
+ }
+
+ cyg_drv_mutex_lock(&txMutex);
+
+ // free old buffer if we need to
+
+ cyg_drv_isr_lock();
+ if (txWritePointer->FrameDataPtr)
+ {
+ freeBuffer((tEthBuffer*)txWritePointer->FrameDataPtr);
+ txWritePointer->FrameDataPtr = 0;
+ }
+ cyg_drv_isr_unlock();
+
+ MAC_Tx_Pkts += 1;
+ MAC_Tx_Octets += buf->length;
+
+ // fill in the packet descriptor
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST) // Big endian
+ txWritePointer->Reserved = (TXFDCON_PADDING_MODE | TXFDCON_CRC_MODE |
+ TXFDCON_SRC_ADDR_INC | TXFDCON_BIG_ENDIAN |
+ TXFDCON_WIDGET_ALIGN00 | TXFDCON_MAC_TX_INT_EN);
+#else // Little endian
+ txWritePointer->Reserved = (TXFDCON_PADDING_MODE | TXFDCON_CRC_MODE |
+ TXFDCON_SRC_ADDR_INC | TXFDCON_LITTLE_ENDIAN |
+ TXFDCON_WIDGET_ALIGN00 | TXFDCON_MAC_TX_INT_EN);
+#endif
+
+ txWritePointer->StatusAndFrameLength = buf->length;
+ txWritePointer->FrameDataPtr = ((unsigned)buf | FRM_OWNERSHIP_BDMA);
+
+ txWritePointer = txWritePointer->NextFD;
+
+ cyg_drv_mutex_unlock(&txMutex);
+
+ // start transmit
+
+#if defined(CYGPKG_NET)
+ ++ifStats.tx_count;
+#endif
+
+ BDMATXCON |= BDMATXCON_EN;
+ MACTXCON |= MACTXCON_TX_EN;
+ return 1;
+}
+
+
+//======================================================================
+// check to see if there's a frame waiting
+
+static int rx_frame_avail(void)
+{
+ if (rxReadPointer->FrameDataPtr & FRM_OWNERSHIP_BDMA)
+ {
+ // queue is empty -- make sure Rx is running
+ if (!(BDMARXCON & BDMARXCON_EN))
+ {
+ ++BDMARxErrCnt.queueOverflow;
+ BDMARXCON |= BDMARXCON_EN;
+ }
+ return 0;
+ }
+ else
+ return 1;
+}
+
+
+//======================================================================
+// de-queue a receive buffer
+static tEthBuffer *ks32c5000_eth_get_recv_buffer(void)
+{
+ unsigned RxStatusAndLength;
+ tEthBuffer *RxBufPtr;
+ tEthBuffer *emptyBuf;
+#if SoftwareCRC
+ unsigned crc, crclen;
+ int crcOK;
+#else
+# define crcOK 1
+#endif
+
+ while (1)
+ {
+ if (rxReadPointer->FrameDataPtr & FRM_OWNERSHIP_BDMA)
+ {
+ // queue is empty -- make sure Rx is running
+ if (!(BDMARXCON & BDMARXCON_EN))
+ {
+ ++BDMARxErrCnt.queueOverflow;
+ BDMARXCON |= BDMARXCON_EN;
+ }
+ return NULL;
+ }
+
+ RxBufPtr = (tEthBuffer*)rxReadPointer->FrameDataPtr;
+ RxStatusAndLength = rxReadPointer->StatusAndFrameLength;
+
+ // counting on short-circuit && evaluation below to only
+ // allocate a fresh buffer if rx packet is good!!
+
+#if defined (CYGPKG_NET)
+ ++ifStats.rx_count;
+#endif
+
+#if SoftwareCRC
+ crclen = (RxStatusAndLength & 0xffff) - 4;
+ crc = cyg_ether_crc32(RxBufPtr->data+2,crclen);
+ crcOK = ((U08)(crc>>0) == RxBufPtr->data[2+crclen+0] &&
+ (U08)(crc>>8) == RxBufPtr->data[2+crclen+1] &&
+ (U08)(crc>>16) == RxBufPtr->data[2+crclen+2] &&
+ (U08)(crc>>24) == RxBufPtr->data[2+crclen+3]);
+#endif
+ if ((RxStatusAndLength & (RXFDSTAT_GOOD<<16))
+ && crcOK
+ && (emptyBuf = allocBuffer()))
+ {
+ // good packet and we've got a fresh buffer to take
+ // it's place in the receive queue
+ rxReadPointer->FrameDataPtr = (unsigned)emptyBuf | FRM_OWNERSHIP_BDMA;
+ rxReadPointer = rxReadPointer->NextFD;
+ RxBufPtr->length = RxStatusAndLength & 0xffff;
+#if defined(CYGPKG_NET)
+ ++ifStats.rx_deliver;
+#endif
+ return RxBufPtr;
+ }
+ else
+ {
+ // bad packet or out of buffers. either way we
+ // ignore this packet, and reuse the buffer
+#if defined(CYGPKG_NET)
+ if (RxStatusAndLength & (RXFDSTAT_GOOD<<16) && crcOK)
+ ++ifStats.rx_resource;
+ else
+ ++ifStats.rx_crc_errors;
+#endif
+ rxReadPointer->FrameDataPtr |= FRM_OWNERSHIP_BDMA;
+ rxReadPointer = rxReadPointer->NextFD;
+ }
+ }
+}
+
+//======================================================================
+static int EthInit(U08* mac_address)
+{
+#if CYGINT_DEVS_ETH_ARM_KS32C5000_PHY && defined(CYGPKG_NET)
+ unsigned linkStatus;
+#endif
+
+ if (mac_address)
+ debug2_printf("EthInit(%02x:%02x:%02x:%02x:%02x:%02x)\n",
+ mac_address[0],mac_address[1],mac_address[2],
+ mac_address[3],mac_address[4],mac_address[5]);
+ else
+ debug2_printf("EthInit(NULL)\n");
+
+#if CYGINT_DEVS_ETH_ARM_KS32C5000_PHY
+ PhyReset();
+#endif
+
+ /* Set the initial condition of the BDMA. */
+ BDMARXCON = BDMARXCON_RESET;
+ BDMATXCON = BDMATXCON_RESET;
+ BDMARXLSZ = MAX_ETH_FRAME_SIZE;
+
+ BDMARXPTR = (U32)rxReadPointer;
+ BDMATXPTR = (U32)txWritePointer;
+
+ MACCON = MACON_SW_RESET;
+ MACCON = MACConfigVar;
+
+ CAMCON = CAMConfigVar;
+
+ // set up our MAC address
+ if (mac_address)
+ {
+ *((volatile U32*)CAM_BaseAddr) =
+ (mac_address[0]<<24) |
+ (mac_address[1]<<16) |
+ (mac_address[2]<< 8) |
+ (mac_address[3]<< 0);
+ *((volatile U16*)(CAM_BaseAddr+4)) =
+ (mac_address[4]<< 8) |
+ (mac_address[5]<< 0);
+ }
+
+ // CAM Enable
+ CAMEN = 0x0001;
+
+ // update the Configuration of BDMA and MAC to begin Rx/Tx
+
+ BDMARXCON = BDMARxConfigVar;
+ MACRXCON = MACRxConfigVar;
+
+ BDMATXCON = BDMATxConfigVar;
+ MACTXCON = MACTxConfigVar;
+
+ debug2_printf("ks32C5000 eth: %02x:%02x:%02x:%02x:%02x:%02x ",
+ *((volatile unsigned char*)CAM_BaseAddr+0),
+ *((volatile unsigned char*)CAM_BaseAddr+1),
+ *((volatile unsigned char*)CAM_BaseAddr+2),
+ *((volatile unsigned char*)CAM_BaseAddr+3),
+ *((volatile unsigned char*)CAM_BaseAddr+4),
+ *((volatile unsigned char*)CAM_BaseAddr+5));
+
+#if CYGINT_DEVS_ETH_ARM_KS32C5000_PHY && defined(CYGPKG_NET)
+ // Read link status to be up to date
+ linkStatus = PhyStatus();
+ if (linkStatus & PhyStatus_FullDuplex)
+ ifStats.duplex = 3;
+ else
+ ifStats.duplex = 2;
+
+ if (linkStatus & PhyStatus_LinkUp)
+ ifStats.operational = 3;
+ else
+ ifStats.operational = 2;
+
+ if (linkStatus & PhyStatus_100Mb)
+ ifStats.speed = 100000000;
+ else
+ ifStats.speed = 10000000;
+#endif
+
+#if SoftwareCRC
+ debug2_printf("Software CRC\n");
+#else
+ debug2_printf("Hardware CRC\n");
+#endif
+
+ return 0;
+}
+
+//======================================================================
+static void Init_TxFrameDescriptorArray(void)
+{
+ FRAME_DESCRIPTOR *pFrameDescriptor;
+ int i;
+
+ // Each Frame Descriptor's frame data pointer points is NULL
+ // if not in use, otherwise points to an ethBuffer
+
+ pFrameDescriptor = txFrameDescrArray;
+
+ for(i=0; i < MAX_TX_FRAME_DESCRIPTORS; i++)
+ {
+ pFrameDescriptor->FrameDataPtr = 0;
+ pFrameDescriptor->Reserved = 0;
+ pFrameDescriptor->StatusAndFrameLength = 0;
+ pFrameDescriptor->NextFD = pFrameDescriptor+1;
+ pFrameDescriptor++;
+ }
+
+ // fix up the last pointer to loop back to the first
+
+ txFrameDescrArray[MAX_TX_FRAME_DESCRIPTORS-1].NextFD = txFrameDescrArray;
+
+ txDonePointer = txWritePointer = txFrameDescrArray;
+
+ return;
+}
+
+
+//======================================================================
+static void Init_RxFrameDescriptorArray(void)
+{
+ FRAME_DESCRIPTOR *pFrameDescriptor;
+ int i;
+
+ // Each Frame Descriptor's frame data pointer points to
+ // an ethBuffer struct
+
+ pFrameDescriptor = rxFrameDescrArray;
+
+ for(i=0; i < MAX_RX_FRAME_DESCRIPTORS; i++)
+ {
+ pFrameDescriptor->FrameDataPtr = ((unsigned)allocBuffer() | FRM_OWNERSHIP_BDMA);
+ pFrameDescriptor->Reserved = 0;
+ pFrameDescriptor->StatusAndFrameLength = 0;
+ pFrameDescriptor->NextFD = pFrameDescriptor+1;
+ pFrameDescriptor++;
+ }
+
+ // fix up the last pointer to loop back to the first
+
+ rxFrameDescrArray[MAX_RX_FRAME_DESCRIPTORS-1].NextFD = rxFrameDescrArray;
+
+ rxReadPointer = rxFrameDescrArray;
+
+ return;
+}
+
+#if CYGINT_DEVS_ETH_ARM_KS32C5000_PHY
+
+#if HavePHYinterrupt
+static unsigned linkStatus;
+
+static cyg_uint32 MAC_Phy_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_drv_interrupt_acknowledge(vector);
+ PhyInterruptAck();
+ ++ks5000_MAC_Phy_Cnt;
+ linkStatus = PhyStatus();
+ if (linkStatus & PhyStatus_FullDuplex)
+ MACConfigVar |= (MACON_FULL_DUP);
+ else
+ MACConfigVar &= ~(MACON_FULL_DUP);
+
+#if defined(CYGPKG_NET)
+ if (linkStatus & PhyStatus_FullDuplex)
+ ifStats.duplex = 3;
+ else
+ ifStats.duplex = 2;
+
+ if (linkStatus & PhyStatus_LinkUp)
+ ifStats.operational = 3;
+ else
+ ifStats.operational = 2;
+
+ if (linkStatus & PhyStatus_100Mb)
+ ifStats.speed = 100000000;
+ else
+ ifStats.speed = 10000000;
+#endif
+
+ MACCON = MACConfigVar;
+ return CYG_ISR_HANDLED;
+}
+#endif
+#endif
+
+static void ks32c5000_handle_tx_complete(void)
+{
+
+ // record status and then free any buffers we're done with
+
+ while (txDonePointer->FrameDataPtr && !(txDonePointer->FrameDataPtr & FRM_OWNERSHIP_BDMA))
+ {
+#if defined(CYGPKG_NET)
+ U32 txStatus;
+
+ txStatus = txDonePointer->StatusAndFrameLength>>16;
+
+ ++ks5000_MAC_Tx_Cnt;
+ ++ifStats.interrupts;
+
+ if (txStatus & MACTXSTAT_COMP)
+ ++ifStats.tx_complete;
+
+ if (txStatus & (MACTXSTAT_EX_COLL | MACTXSTAT_DEFFERED |
+ MACTXSTAT_UNDER | MACTXSTAT_DEFER |
+ MACTXSTAT_NCARR | MACTXSTAT_SIG_QUAL |
+ MACTXSTAT_LATE_COLL | MACTXSTAT_PAR |
+ MACTXSTAT_PAUSED | MACTXSTAT_HALTED))
+ {
+ // transmit failed, log errors
+ if (txStatus & MACTXSTAT_EX_COLL)
+ ++ifStats.tx_max_collisions;
+ if (txStatus & MACTXSTAT_DEFFERED)
+ ++ifStats.tx_deferred;
+ if (txStatus & MACTXSTAT_UNDER)
+ ++ifStats.tx_underrun;
+ if (txStatus & MACTXSTAT_DEFER)
+ ;
+ if (txStatus & MACTXSTAT_NCARR)
+ ++ifStats.tx_carrier_loss;
+ if (txStatus & MACTXSTAT_SIG_QUAL)
+ ++ifStats.tx_sqetesterrors;
+ if (txStatus & MACTXSTAT_LATE_COLL)
+ ++ifStats.tx_late_collisions;
+ if (txStatus & MACTXSTAT_PAR)
+ ;
+ if (txStatus & MACTXSTAT_PAUSED)
+ ;
+ if (txStatus & MACTXSTAT_HALTED)
+ ;
+ }
+ else
+ {
+ // transmit OK
+ int collisionCnt = txStatus & 0x0f;
+ ++ifStats.tx_good;
+ if (collisionCnt)
+ {
+ if (collisionCnt == 1)
+ ++ifStats.tx_single_collisions;
+ else
+ ++ifStats.tx_mult_collisions;
+ ifStats.tx_total_collisions += collisionCnt;
+ }
+ }
+#endif
+ isrFreeBuffer((tEthBuffer*)txDonePointer->FrameDataPtr);
+ txDonePointer->FrameDataPtr = 0;
+ txDonePointer = txDonePointer->NextFD;
+ }
+}
+
+
+//======================================================================
+static cyg_uint32 MAC_Tx_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_drv_interrupt_acknowledge(vector);
+ ks32c5000_handle_tx_complete();
+ return CYG_ISR_HANDLED;
+}
+
+static unsigned accumulatedMaxRxStatus=0;
+
+//======================================================================
+static cyg_uint32 MAC_Rx_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ U32 IntMACRxStatus;
+
+ cyg_drv_interrupt_acknowledge(vector);
+
+ IntMACRxStatus = MACRXSTAT;
+ MACRXSTAT = IntMACRxStatus;
+
+ accumulatedMaxRxStatus |= IntMACRxStatus;
+
+ ++ks5000_MAC_Rx_Cnt;
+
+#if defined(CYGPKG_NET)
+
+ ++ifStats.interrupts;
+
+ if (IntMACRxStatus & MACRXSTAT_GOOD)
+ {
+ ++ifStats.rx_good;
+
+ if (IntMACRxStatus & MACRXSTAT_CTL_RECD)
+ ; // we don't do anything with control packets
+
+ return CYG_ISR_HANDLED;
+ }
+
+ if (IntMACRxStatus & (MACRXSTAT_ALLIGN_ERR | MACRXSTAT_CRC_ERR |
+ MACRXSTAT_OVERFLOW | MACRXSTAT_LONG_ERR |
+ MACRXSTAT_PAR | MACRXSTAT_HALTED) )
+ {
+ if (IntMACRxStatus & MACRXSTAT_ALLIGN_ERR)
+ ++ifStats.rx_align_errors;
+ if (IntMACRxStatus & MACRXSTAT_CRC_ERR)
+ ++ifStats.rx_crc_errors;
+ if (IntMACRxStatus & MACRXSTAT_OVERFLOW)
+ ++ifStats.rx_overrun_errors;
+ if (IntMACRxStatus & MACRXSTAT_LONG_ERR)
+ ++ifStats.rx_too_long_frames;
+ if (IntMACRxStatus & MACRXSTAT_PAR)
+ ++ifStats.rx_symbol_errors;
+ if (IntMACRxStatus & MACRXSTAT_HALTED)
+ ;
+ }
+#endif
+ return CYG_ISR_HANDLED;
+}
+
+
+
+//======================================================================
+// This interrupt only happens when errors occur
+static cyg_uint32 BDMA_Tx_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ U32 IntBDMATxStatus;
+
+ cyg_drv_interrupt_acknowledge(vector);
+
+ IntBDMATxStatus = BDMASTAT;
+ BDMASTAT = IntBDMATxStatus;
+
+ ++ks5000_BDMA_Tx_Isr_Cnt;
+#if defined(CYGPKG_NET)
+ ++ifStats.interrupts;
+#endif
+ if (IntBDMATxStatus & BDMASTAT_TX_CCP)
+ {
+ debug1_printf("+-- Control Packet Transfered : %x\r",ERMPZCNT);
+ debug1_printf(" Tx Control Frame Status : %x\r",ETXSTAT);
+ }
+
+ if (IntBDMATxStatus & (BDMASTAT_TX_NL|BDMASTAT_TX_NO|BDMASTAT_TX_EMPTY) )
+ {
+ if (IntBDMATxStatus & BDMASTAT_TX_NL)
+ BDMATxErrCnt.BTxNLErr++;
+ if (IntBDMATxStatus & BDMASTAT_TX_NO)
+ BDMATxErrCnt.BTxNOErr++;
+ if (IntBDMATxStatus & BDMASTAT_TX_EMPTY)
+ BDMATxErrCnt.BTxEmptyErr++;
+ }
+
+ // free any buffers we're done with
+
+ while (txDonePointer->FrameDataPtr && !(txDonePointer->FrameDataPtr & FRM_OWNERSHIP_BDMA))
+ {
+ freeBuffer((tEthBuffer*)txDonePointer->FrameDataPtr);
+ txDonePointer->FrameDataPtr = 0;
+ txDonePointer = txDonePointer->NextFD;
+ }
+
+ // don't call tx dsr for now -- it has nothing to do
+
+ return CYG_ISR_HANDLED;
+}
+
+
+static void BDMA_Tx_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ ++ks5000_BDMA_Tx_Dsr_Cnt;
+}
+
+
+
+//======================================================================
+static cyg_uint32 BDMA_Rx_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ U32 IntBDMARxStatus;
+
+ cyg_drv_interrupt_acknowledge(vector);
+
+ IntBDMARxStatus = BDMASTAT;
+ BDMASTAT = IntBDMARxStatus;
+
+ ++ks5000_BDMA_Rx_Isr_Cnt;
+#if defined(CYGPKG_NET)
+ ++ifStats.interrupts;
+#endif
+ if (IntBDMARxStatus & (BDMASTAT_RX_NL | BDMASTAT_RX_NO |
+ BDMASTAT_RX_MSO | BDMASTAT_RX_EMPTY |
+ BDMASTAT_RX_SEARLY) )
+ {
+// printf("RxIsr %u\r\n", (unsigned)cyg_current_time());
+ if (IntBDMARxStatus & BDMASTAT_RX_NL)
+ BDMARxErrCnt.BRxNLErr++;
+ if (IntBDMARxStatus & BDMASTAT_RX_NO)
+ BDMARxErrCnt.BRxNOErr++;
+ if (IntBDMARxStatus & BDMASTAT_RX_MSO)
+ BDMARxErrCnt.BRxMSOErr++;
+ if (IntBDMARxStatus & BDMASTAT_RX_EMPTY)
+ BDMARxErrCnt.BRxEmptyErr++;
+ if (IntBDMARxStatus & BDMASTAT_RX_SEARLY)
+ BDMARxErrCnt.sBRxSEarly++;
+ }
+
+ return CYG_ISR_HANDLED|CYG_ISR_CALL_DSR;
+}
+
+static void eth_handle_recv_buffer(tEthBuffer*);
+
+static cyg_handle_t bdmaRxIntrHandle;
+static cyg_handle_t bdmaTxIntrHandle;
+static cyg_handle_t macRxIntrHandle;
+static cyg_handle_t macTxIntrHandle;
+
+static cyg_interrupt bdmaRxIntrObject;
+static cyg_interrupt bdmaTxIntrObject;
+static cyg_interrupt macRxIntrObject;
+static cyg_interrupt macTxIntrObject;
+
+static int ethernetRunning;
+
+#if HavePHYinterrupt
+static cyg_handle_t macPhyIntrHandle;
+static cyg_interrupt macPhyIntrObject;
+#endif
+
+static void ks32c5000_eth_deliver(struct eth_drv_sc *sc)
+{
+ unsigned short p;
+ tEthBuffer *rxBuffer;
+ extern void cyg_interrupt_post_dsr(CYG_ADDRWORD intr_obj);
+
+ ++ks5000_BDMA_Rx_Dsr_Cnt;
+
+ while (1)
+ {
+ if (!rx_frame_avail())
+ {
+ // no more frames
+ return;
+ }
+
+ if (!(rxBuffer=ks32c5000_eth_get_recv_buffer()))
+ {
+ // no buffers available
+ return;
+ }
+
+ p = *((unsigned short*)(rxBuffer->data+EtherFramePadding+ETH_HEADER_SIZE-2));
+
+ if (ethernetRunning)
+ eth_handle_recv_buffer(rxBuffer);
+ else
+ freeBuffer(rxBuffer);
+ }
+}
+
+
+static void installInterrupts(void)
+{
+ extern struct eth_drv_sc ks32c5000_sc;
+ static bool firstTime=true;
+
+ debug1_printf("ks5000_ether: installInterrupts()\n");
+
+ if (!firstTime)
+ return;
+ firstTime = false;
+
+ initFreeList();
+ Init_RxFrameDescriptorArray();
+ Init_TxFrameDescriptorArray();
+
+ BDMARXPTR = (U32)rxReadPointer;
+ BDMATXPTR = (U32)txWritePointer;
+
+ cyg_drv_mutex_init(&txMutex);
+ cyg_drv_mutex_init(&oldRxMutex);
+ cyg_drv_cond_init(&oldRxCond,&oldRxMutex);
+
+ cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_ETH_BDMA_RX,0,(unsigned)&ks32c5000_sc,BDMA_Rx_isr,eth_drv_dsr,&bdmaRxIntrHandle,&bdmaRxIntrObject);
+ cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_ETH_BDMA_TX,0,0,BDMA_Tx_isr,BDMA_Tx_dsr,&bdmaTxIntrHandle,&bdmaTxIntrObject);
+ cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_ETH_MAC_RX,0,0,MAC_Rx_isr,NULL,&macRxIntrHandle,&macRxIntrObject);
+ cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_ETH_MAC_TX,0,0,MAC_Tx_isr,NULL,&macTxIntrHandle,&macTxIntrObject);
+#if HavePHYinterrupt
+ cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_EXT0,0,0,MAC_Phy_isr,NULL,&macPhyIntrHandle,&macPhyIntrObject);
+ cyg_drv_interrupt_attach(macPhyIntrHandle);
+#endif
+
+ cyg_drv_interrupt_attach(bdmaRxIntrHandle);
+ cyg_drv_interrupt_attach(bdmaTxIntrHandle);
+ cyg_drv_interrupt_attach(macRxIntrHandle);
+ cyg_drv_interrupt_attach(macTxIntrHandle);
+
+#if HavePHYinterrupt
+ cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_EXT0);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EXT0);
+#endif
+}
+
+//======================================================================
+// Driver code that interfaces to the TCP/IP stack via the common
+// Ethernet interface.
+
+
+// don't have any private data, but if we did, this is where it would go
+typedef struct
+{
+ int j;
+}ks32c5000_priv_data_t;
+
+ks32c5000_priv_data_t ks32c5000_priv_data;
+
+#define eth_drv_tx_done(sc,key,retval) (sc)->funs->eth_drv->tx_done(sc,key,retval)
+#define eth_drv_init(sc,enaddr) ((sc)->funs->eth_drv->init)(sc, enaddr)
+#define eth_drv_recv(sc,len) ((sc)->funs->eth_drv->recv)(sc, len)
+
+static bool ks32c5000_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ unsigned char myMacAddr[6] = { CYGPKG_DEVS_ETH_ARM_KS32C5000_MACADDR };
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ bool ok;
+
+#ifdef CYGHWR_DEVS_ETH_ARM_KS32C5000_GET_ESA
+ // Get MAC address from RedBoot configuration variables
+ CYGHWR_DEVS_ETH_ARM_KS32C5000_GET_ESA(&myMacAddr[0], ok);
+ // If this call fails myMacAddr is unchanged and MAC address from CDL is used
+#endif
+
+ debug1_printf("ks32c5000_eth_init()\n");
+ debug1_printf(" MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",myMacAddr[0],myMacAddr[1],myMacAddr[2],myMacAddr[3],myMacAddr[4],myMacAddr[5]);
+#if defined(CYGPKG_NET)
+ ifStats.duplex = 1; //unknown
+ ifStats.operational = 1; //unknown
+ ifStats.tx_queue_len = MAX_TX_FRAME_DESCRIPTORS;
+ strncpy(ifStats.description,"Ethernet device",sizeof(ifStats.description));
+ ifStats.snmp_chipset[0] = 0;
+ ifStats.supports_dot3 = 1; // support dot3
+#endif
+ installInterrupts();
+ EthInit(myMacAddr);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_ETH_BDMA_RX);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_ETH_BDMA_TX);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_ETH_MAC_RX);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_ETH_MAC_TX);
+ configDone = 1;
+ ethernetRunning = 1;
+ eth_drv_init(sc, myMacAddr);
+ return true;
+}
+
+static void ks32c5000_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ debug2_printf("ks32c5000_eth_start()\n");
+ if (!ethernetRunning)
+ {
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_ETH_BDMA_RX);
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_ETH_BDMA_TX);
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_ETH_MAC_RX);
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_ETH_MAC_TX);
+ EthInit(enaddr);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_ETH_BDMA_RX);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_ETH_BDMA_TX);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_ETH_MAC_RX);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_ETH_MAC_TX);
+ ethernetRunning = 1;
+ }
+}
+
+static void ks32c5000_eth_stop(struct eth_drv_sc *sc)
+{
+ debug1_printf("ks32c5000_eth_stop()\n");
+ ethernetRunning = 0;
+}
+
+static int ks32c5000_eth_control(struct eth_drv_sc *sc,
+ unsigned long cmd,
+ void *data,
+ int len)
+{
+ switch (cmd)
+ {
+#if defined(CYGPKG_NET)
+ case ETH_DRV_GET_IF_STATS_UD:
+ case ETH_DRV_GET_IF_STATS:
+ {
+ struct ether_drv_stats *p = (struct ether_drv_stats*)data;
+
+#if CYGINT_DEVS_ETH_ARM_KS32C5000_PHY
+ unsigned linkStatus;
+
+ // Read link status to be up to date
+ linkStatus = PhyStatus();
+ if (linkStatus & PhyStatus_FullDuplex)
+ ifStats.duplex = 3;
+ else
+ ifStats.duplex = 2;
+
+ if (linkStatus & PhyStatus_LinkUp)
+ ifStats.operational = 3;
+ else
+ ifStats.operational = 2;
+
+ if (linkStatus & PhyStatus_100Mb)
+ ifStats.speed = 100000000;
+ else
+ ifStats.speed = 10000000;
+#endif
+
+ *p = ifStats;
+ return 0;
+ }
+#endif
+ case ETH_DRV_SET_MAC_ADDRESS: {
+ int act;
+
+ if (ETHER_ADDR_LEN != len)
+ return -1;
+ debug1_printf("ks32c5000_eth_control: ETH_DRV_SET_MAC_ADDRESS.\n");
+ act = ethernetRunning;
+ ks32c5000_eth_stop(sc);
+ ks32c5000_eth_start(sc, data, 0);
+ ethernetRunning = act;
+ return 0;
+ }
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS: {
+ if (len < ETHER_ADDR_LEN)
+ return -1;
+ debug1_printf("ks32c5000_eth_control: ETH_DRV_GET_MAC_ADDRESS.\n");
+ memcpy(data, (void *)CAM_BaseAddr, ETHER_ADDR_LEN);
+ return 0;
+ }
+#endif
+ default:
+ return -1;
+ }
+}
+
+static int ks32c5000_eth_can_send_count=0;
+static int ks32c5000_eth_can_send_count_OK=0;
+
+// In case there are multiple Tx frames waiting, we should
+// return how many empty Tx spots we have. For now we just
+// return 0 or 1.
+static int ks32c5000_eth_can_send(struct eth_drv_sc *sc)
+{
+ FRAME_DESCRIPTOR *TxFp, *StartFp;
+
+ // find the next unused spot in the queue
+
+ ++ks32c5000_eth_can_send_count;
+
+ StartFp = TxFp = (FRAME_DESCRIPTOR*)BDMATXPTR;
+
+ while (TxFp->FrameDataPtr & FRM_OWNERSHIP_BDMA)
+ {
+ TxFp = TxFp->NextFD;
+ if (TxFp == StartFp)
+ return 0;
+ }
+ ++ks32c5000_eth_can_send_count_OK;
+ return 1;
+}
+
+static int ks5000_eth_send_count=0;
+
+static void ks32c5000_eth_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list,
+ int sg_len,
+ int total_len,
+ unsigned long key)
+{
+ unsigned char *dest;
+ unsigned len;
+ tEthBuffer *buf;
+
+ if (total_len >= MAX_ETH_FRAME_SIZE)
+ {
+ eth_drv_tx_done(sc,key,-EINVAL);
+ return;
+ }
+
+ ++ks5000_eth_send_count;
+
+ // allocate buffer
+
+ buf = allocBuffer();
+ if (!buf)
+ {
+ // out of buffers
+ eth_drv_tx_done(sc,key,-EIO);
+ return;
+ }
+
+ // copy data from scatter/gather list into BDMA data buffer
+
+ len = 0;
+ dest = buf->data;
+
+ while (sg_len)
+ {
+ memcpy(dest,(unsigned char*)sg_list->buf,sg_list->len);
+ len += sg_list->len;
+ dest += sg_list->len;
+ ++sg_list;
+ --sg_len;
+ }
+
+ buf->length = len;
+
+ // tell upper layer that we're done with this sglist
+
+ eth_drv_tx_done(sc,key,0);
+
+ // queue packet for transmit
+
+ while(!ks32c5000_eth_buffer_send(buf))
+ {
+#if defined(CYGPKG_KERNEL)
+ // wait a tick and try again.
+ cyg_thread_delay(1);
+#else
+ // toss it.
+ freeBuffer(buf);
+ break;
+#endif
+ }
+
+}
+
+
+static int ks5000_eth_rcv_count=0;
+static tEthBuffer *tcpIpRxBuffer;
+
+// called from DSR
+static void eth_handle_recv_buffer(tEthBuffer* rxBuffer)
+{
+ extern struct eth_drv_sc ks32c5000_sc;
+ tcpIpRxBuffer = rxBuffer;
+ eth_drv_recv(&ks32c5000_sc,tcpIpRxBuffer->length-4); // discard 32-bit CRC
+}
+
+static void ks32c5000_eth_recv(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list,
+ int sg_len)
+{
+ unsigned char *source;
+
+ ++ks5000_eth_rcv_count;
+
+ if (!tcpIpRxBuffer)
+ return; // no packet waiting, shouldn't be here!
+
+ // copy data from eth buffer into scatter/gather list
+
+ source = tcpIpRxBuffer->data + EtherFramePadding;
+
+ while (sg_len)
+ {
+ if (sg_list->buf)
+ memcpy((unsigned char*)sg_list->buf,source,sg_list->len);
+ source += sg_list->len;
+ ++sg_list;
+ --sg_len;
+ }
+
+ freeBuffer(tcpIpRxBuffer);
+ tcpIpRxBuffer = NULL;
+ return;
+}
+
+// routine called to handle ethernet controller in polled mode
+static void ks32c5000_eth_poll(struct eth_drv_sc *sc)
+{
+ BDMA_Rx_isr(CYGNUM_HAL_INTERRUPT_ETH_BDMA_RX, 0); // Call ISR routine
+ ks32c5000_eth_deliver(sc); // handle rx frames
+ ks32c5000_handle_tx_complete();
+}
+
+static int ks32c5000_eth_int_vector(struct eth_drv_sc *sc)
+{
+ return CYGNUM_HAL_INTERRUPT_ETH_BDMA_RX;
+}
+
+
+ETH_DRV_SC(ks32c5000_sc,
+ &ks32c5000_priv_data, // Driver specific data
+ "eth0", // Name for this interface
+ ks32c5000_eth_start,
+ ks32c5000_eth_stop,
+ ks32c5000_eth_control,
+ ks32c5000_eth_can_send,
+ ks32c5000_eth_send,
+ ks32c5000_eth_recv,
+ ks32c5000_eth_deliver,
+ ks32c5000_eth_poll,
+ ks32c5000_eth_int_vector
+ );
+
+NETDEVTAB_ENTRY(ks32c5000_netdev,
+ "ks32c5000",
+ ks32c5000_eth_init,
+ &ks32c5000_sc);
+
+// EOF ks5000_ether.c
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.h b/ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.h
new file mode 100644
index 0000000..400fa00
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_ether.h
@@ -0,0 +1,271 @@
+//==========================================================================
+//
+// ks5000_ether.h
+//
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Grant Edwards <grante@visi.com>
+// Date: 2001-07-31
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#ifndef KS32C5000_ETHER_H
+#define KS32C5000_ETHER_H
+
+// Tx Frame Descriptor's control bits -- Refer the KS32C5000 Manual Page 7-15
+#define FRM_OWNERSHIP_BDMA 0x80000000 // 0:CPU, 1:BDMA
+#define FRM_OWNERSHIP_CPU 0x7fffffff // 0:CPU, 1:BDMA
+
+#define TXFDCON_PADDING_MODE 0x00
+#define TXFDCON_NO_PADDING_MODE 0x01
+#define TXFDCON_NO_CRC_MODE 0x02
+#define TXFDCON_CRC_MODE 0x00
+#define TXFDCON_MAC_TX_INT_EN 0x04
+#define TXFDCON_LITTLE_ENDIAN 0x08
+#define TXFDCON_BIG_ENDIAN 0x00
+#define TXFDCON_SRC_ADDR_DEC 0x00
+#define TXFDCON_SRC_ADDR_INC 0x10
+#define TXFDCON_WIDGET_ALIGN00 0x00 // No Invalid bytes
+#define TXFDCON_WIDGET_ALIGN01 0x01 // 1 Invalid byte
+#define TXFDCON_WIDGET_ALIGN10 0x10 // 2 Invalid bytes
+#define TXFDCON_WIDGET_ALIGN11 0x11 // 3 Invalid bytes
+
+// Tx Frame descriptor's Status
+#define TXFDSTAT_EX_COLL 0x0010 // Excessive Collision
+#define TXFDSTAT_DEFFER 0x0020 // Transmit deffered
+#define TXFDSTAT_PAUSED 0x0040 // Paused : holding data transmission DMA to MAC
+#define TXFDSTAT_INT_TX 0x0080 // Interrupt on Transmit
+#define TXFDSTAT_UNDER 0x0100 // Underrun */
+#define TXFDSTAT_DEFER 0x0200 // Mac defers for Max_DEFERRAL:=0.32768ms
+ // for 100Mbits/s, := 3.2768ms for 10Mbits/s
+#define TXFDSTAT_NCARR 0x0400 // No Carrier sense is detected during the
+ // entire transmission of a packet from SFD
+ // to CRC
+#define TXFDSTAT_SQ_ERR 0x0800 // fake collision signal didn't come from
+ // PHY for 1.6us.
+#define TXFDSTAT_LATE_COLL 0x1000 // Late collision
+#define TXFDSTAT_PAR 0x2000 // Transmit Parity Error
+#define TXFDSTAT_COMP 0x4000 // MAC transmit or discards one packet
+#define TXFDSTAT_HALTED 0x8000 // Transmission was halted by clearing MACTXCON_TX_EN..
+
+// Rx Frame descriptor's Status
+#define RXFDSTAT_OV_MAX 0x0008 // Over Maximum Size
+#define RXFDSTAT_CTL_RECD 0x0020 // set if packet received is a
+ // MAC control frame.
+#define RXFDSTAT_INT_RX 0x0040 // Interrupt on Receive
+#define RXFDSTAT_10STAT 0x0080 // set if packet was received via the
+ // 10bits interface reset if packet
+ // was received via MII
+#define RXFDSTAT_ALIGN_ERR 0x0100 // Alignment Error
+#define RXFDSTAT_CRC_ERR 0x0200 // CRC error
+#define RXFDSTAT_OVERFLOW 0x0400 // MAC receive FIFO was full when it
+ // needed to store a received byte
+
+#define RXFDSTAT_LONG_ERR 0x0800 // received a frame longer than 1518bytes
+#define RXFDSTAT_PAR 0x2000 // MAC receive FIFO has detected a parity error
+#define RXFDSTAT_GOOD 0x4000 // successfully received a packet with no errors
+#define RXFDSTAT_HALTED 0x8000 // Transmission was halted by clearing MACTXCON_TX_EN...
+
+// BDMARXCON : 0x9004
+// Buffered DMA Receiver Control Register
+#define BDMARXCON_BRST 0x00001F // BDMA Rx Burst Size * BDMARXCON_BRST
+#define BDMARXCON_STP_SKP 0x00020 // BDMA Rx Stop/Skip Frame or Interrupt(=1)
+#define BDMARXCON_MA_INC 0x00040 // BDMA Rx Memory Address Inc/Dec
+#define BDMARXCON_DIE 0x00080 // BDMA Rx Every Received Frame Interrupt Enable
+#define BDMARXCON_NLIE 0x00100 // BDMA Rx NULL List Interrupt Enable
+#define BDMARXCON_NOIE 0x00200 // BDMA Rx Not Owner Interrupt Enable
+#define BDMARXCON_MSOIE 0x00400 // BDMA Rx Maximum Size over Interrupr Enable
+#define BDMARXCON_LITTLE 0x00800 // BDMA Rx Big/Little Endian
+#define BDMARXCON_BIG 0x00000 // BDMA Rx Big/Little Endian
+#define BDMARXCON_WA00 0x00000 // BDMA Rx Word Alignment- no invalid byte
+#define BDMARXCON_WA01 0x01000 // BDMA Rx Word Alignment- one invalid byte
+#define BDMARXCON_WA10 0x02000 // BDMA Rx Word Alignment- two invalid byte
+#define BDMARXCON_WA11 0x03000 // BDMA Rx Word Alignment- three invalid byte
+#define BDMARXCON_EN 0x04000 // BDMA Rx Enable
+#define BDMARXCON_RESET 0x08000 // BDMA Rx Reset
+#define BDMARXCON_RX_EMPT 0x10000 // BDMA Rx Buffer empty interrupt
+#define BDMARXCON_EARLY 0x20000 // BDMA Rx Early notify Interrupt
+
+// BDMATXCON : 0x9000
+// Buffered DMA Trasmit Control Register
+#define BDMATXCON_BRST 0x000F // BDMA Tx Burst Size = 16
+#define BDMATXCON_STP_SKP 0x0020 // BDMA Tx Stop/Skip Frame or Interrupt in case
+ // of not Owner the current frame
+#define BDMATXCON_CPIE 0x0080 // BDMA Tx Complete to send control
+ // packet Enable
+#define BDMATXCON_NOIE 0x0200 // BDMA Tx Buffer Not Owner
+#define BDMATXCON_TX_EMPTY 0x0400 // BDMA Tx Buffer Empty Interrupt
+#define BDMATXCON_TX_NOIE 0x0200 // BDMA Tx not owner (queue empty)
+#define BDMATXCON_TX_NULL 0x0100 // BDMA dscr pointer null
+
+// BDMA Tx buffer can be moved to the MAC Tx IO
+// when the new frame comes in.
+#define BDMATXCON_MSL000 0x00000 // No wait to fill the BDMA
+#define BDMATXCON_MSL001 0x00800 // wait to fill 1/8 of the BDMA
+#define BDMATXCON_MSL010 0x01000 // wait to fill 2/8 of the BDMA
+#define BDMATXCON_MSL011 0x01800 // wait to fill 3/8 of the BDMA
+#define BDMATXCON_MSL100 0x02000 // wait to fill 4/8 of the BDMA
+#define BDMATXCON_MSL101 0x02800 // wait to fill 5/8 of the BDMA
+#define BDMATXCON_MSL110 0x03000 // wait to fill 6/8 of the BDMA
+#define BDMATXCON_MSL111 0x03800 // wait to fill 7/8 of the BDMA
+#define BDMATXCON_EN 0x04000 // BDMA Tx Enable
+#define BDMATXCON_RESET 0x08000 // BDMA Rx Reset
+
+// BDMASTAT : 0x9014
+// Buffered DMA Status Register
+#define BDMASTAT_RX_RDF 0x00001 // BDMA Rx Done Every Received Frame
+#define BDMASTAT_RX_NL 0x00002 // BDMA Rx NULL List
+#define BDMASTAT_RX_NO 0x00004 // BDMA Rx Not Owner
+#define BDMASTAT_RX_MSO 0x00008 // BDMA Rx Maximum Size Over
+#define BDMASTAT_RX_EMPTY 0x00010 // BDMA Rx Buffer Empty
+#define BDMASTAT_RX_SEARLY 0x00020 // Early Notify
+#define BDMASTAT_RX_FRF 0x00080 // One more frame data in BDMA receive buffer
+#define BDMASTAT_TX_CCP 0x10000 // BDMA Tx Complete to send Control Packet
+#define BDMASTAT_TX_NL 0x20000 // BDMA Tx Null List
+#define BDMASTAT_TX_NO 0x40000 // BDMA Tx Not Owner
+#define BDMASTAT_TX_EMPTY 0x100000// BDMA Tx Buffer Empty
+
+// MACON : 0xa000
+// MAC Control Register
+#define MACON_HALT_REG 0x0001 // stop transmission and reception
+ // after completion of ant current packets
+#define MACON_HALT_IMM 0x0002 // Stop transmission and reception immediately
+#define MACON_SW_RESET 0x0004 // reset all Ethernet controller state machines
+ // and FIFOs
+#define MACON_FULL_DUP 0x0008 // allow transmission to begin while reception
+ // is occurring
+#define MACON_MAC_LOOP 0x0010 // MAC loopback
+#define MACON_CONN_M00 0x0000 // Automatic-default
+#define MACON_CONN_M01 0x0020 // Force 10Mbits endec
+#define MACON_CONN_M10 0x0040 // Force MII (rate determined by MII clock
+#define MACON_LOOP10 0x0080 // Loop 10Mbps
+#define MACON_MISS_ROLL 0x0400 // Missed error counter rolled over
+#define MACON_EN_MISS_ROLL 0x2000 // Interrupt when missed error counter rolls
+ // over
+#define MACON_LINK10 0x8000 // Link status 10Mbps
+
+// CAMCON : 0xa004
+// CAM control register
+#define CAMCON_STATION_ACC 0x0001 // Accept any packet with a unicast station
+ // address
+#define CAMCON_GROUP_ACC 0x0002 // Accept any packet with multicast-group
+ // station address
+#define CAMCON_BROAD_ACC 0x0004 // Accept any packet with a broadcast station
+ // address
+#define CAMCON_NEG_CAM 0x0008 // 0: Accept packets CAM recognizes,
+ // reject others
+ // 1: reject packets CAM recognizes,
+ // accept others
+#define CAMCON_COMP_EN 0x0010 // Compare Enable mode
+
+// MACTXCON : 0xa008
+// Transmit Control Register
+#define MACTXCON_TX_EN 0x0001 // transmit Enable
+#define MACTXCON_TX_HALT 0x0002 // Transmit Halt Request
+#define MACTXCON_NO_PAD 0x0004 // suppress Padding
+#define MACTXCON_NO_CRC 0x0008 // Suppress CRC
+#define MACTXCON_FBACK 0x0010 // Fast Back-off
+#define MACTXCON_NO_DEF 0x0020 // Disable the defer counter
+#define MACTXCON_SD_PAUSE 0x0040 // Send Pause
+#define MACTXCON_MII10_EN 0x0080 // MII 10Mbps mode enable
+#define MACTXCON_EN_UNDER 0x0100 // Enable Underrun
+#define MACTXCON_EN_DEFER 0x0200 // Enable Deferral
+#define MACTXCON_EN_NCARR 0x0400 // Enable No Carrier
+#define MACTXCON_EN_EXCOLL 0x0800 // interrupt if 16 collision occur
+ // in the same packet
+#define MACTXCON_EN_LATE_COLL 0x1000 // interrupt if collision occurs after
+ // 512 bit times(64 bytes times)
+#define MACTXCON_ENTX_PAR 0x2000 // interrupt if the MAC transmit FIFO
+ // has a parity error
+#define MACTXCON_EN_COMP 0x4000 // interrupt when the MAC transmits or
+ // discards one packet
+// MACTXSTAT : 0xa00c
+// Transmit Status Register
+#define MACTXSTAT_EX_COLL 0x0010 // Excessive collision
+#define MACTXSTAT_DEFFERED 0x0020 // set if 16 collisions occur for same packet
+#define MACTXSTAT_PAUSED 0x0040 // packet waited because of pause during
+ // transmission
+#define MACTXSTAT_INT_TX 0x0080 // set if transmission of packet causes an
+ // interrupt condiftion
+#define MACTXSTAT_UNDER 0x0100 // MAC transmit FIFO becomes empty during
+ // transmission
+#define MACTXSTAT_DEFER 0x0200 // MAC defers for MAC deferral
+#define MACTXSTAT_NCARR 0x0400 // No carrier sense detected during the
+ // transmission of a packet
+#define MACTXSTAT_SIG_QUAL 0x0800 // Signal Quality Error
+#define MACTXSTAT_LATE_COLL 0x1000 // a collision occures after 512 bit times
+#define MACTXSTAT_PAR 0x2000 // MAC transmit FIFO has detected a parity error
+#define MACTXSTAT_COMP 0x4000 // MAC transmit or discards one packet
+#define MACTXSTAT_HALTED 0x8000 // Transmission was halted by clearing
+ // MACTXCON_TX_EN or Halt immedite
+// MACRXCON : 0xa010
+// Receive Control Register
+#define MACRXCON_RX_EN 0x0001
+#define MACRXCON_HALT 0x0002
+#define MACRXCON_LONG_EN 0x0004
+#define MACRXCON_SHORT_EN 0x0008
+#define MACRXCON_STRIP_CRC 0x0010
+#define MACRXCON_PASS_CTL 0x0020
+#define MACRXCON_IGNORE_CRC 0x0040
+#define MACRXCON_EN_ALIGN 0x0100
+#define MACRXCON_EN_CRC_ERR 0x0200
+#define MACRXCON_EN_OVER 0x0400
+#define MACRXCON_EN_LONG_ERR 0x0800
+#define MACRXCON_EN_RX_PAR 0x2000
+#define MACRXCON_EN_GOOD 0x4000
+
+// MACRXSTAT : 0xa014
+// Receive Status Register
+#define MACRXSTAT_CTL_RECD 0x0020
+#define MACRXSTAT_INT_RX 0x0040
+#define MACRXSTAT_10STAT 0x0080
+#define MACRXSTAT_ALLIGN_ERR 0x0100
+#define MACRXSTAT_CRC_ERR 0x0200
+#define MACRXSTAT_OVERFLOW 0x0400
+#define MACRXSTAT_LONG_ERR 0x0800
+#define MACRXSTAT_PAR 0x2000
+#define MACRXSTAT_GOOD 0x4000
+#define MACRXSTAT_HALTED 0x8000
+
+#endif
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_regs.h b/ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_regs.h
new file mode 100644
index 0000000..302ec54
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/src/ks5000_regs.h
@@ -0,0 +1,226 @@
+//==========================================================================
+//
+// ks5000_regs.h
+//
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Grant Edwards <grante@visi.com>
+// Date: 2001-07-31
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+/*------------------------------------------------------------------------
+ name : ks5000.h
+ purpose : This is the header file that will define all the
+ registers for the ks5000 processor. It will contain
+ the addresses for the registers and some values for
+ those registers.
+========================================================================*/
+#ifndef _KS5000_REGS_H_
+#define _KS5000_REGS_H_
+
+#include "std.h"
+
+#define BD_LAN_STOP {}
+#define DEBUG 0 /* DEBUG mode */
+
+#define VPint(a) (*((volatile unsigned int*)(a)))
+#define VPshort(a) (*((volatile unsigned short int*)(a)))
+#define VPchar(a) (*((volatile unsigned char*)(a)))
+
+#define Base_Addr 0x7ff0000
+
+#define INTADDR (Reset_Addr+0x20)
+#define SPSTR (VPint(Base_Addr))
+
+// System Manager Register
+#define SYSCFG (VPint(Base_Addr+0x0000))
+#define CLKCON (VPint(Base_Addr+0x3000))
+#define EXTACON0 (VPint(Base_Addr+0x3008))
+#define EXTACON1 (VPint(Base_Addr+0x300c))
+#define EXTDBWTH (VPint(Base_Addr+0x3010))
+#define ROMCON0 (VPint(Base_Addr+0x3014))
+#define ROMCON1 (VPint(Base_Addr+0x3018))
+#define ROMCON2 (VPint(Base_Addr+0x301c))
+#define ROMCON3 (VPint(Base_Addr+0x3020))
+#define ROMCON4 (VPint(Base_Addr+0x3024))
+#define ROMCON5 (VPint(Base_Addr+0x3028))
+#define DRAMCON0 (VPint(Base_Addr+0x302c))
+#define DRAMCON1 (VPint(Base_Addr+0x3030))
+#define DRAMCON2 (VPint(Base_Addr+0x3034))
+#define DRAMCON3 (VPint(Base_Addr+0x3038))
+#define REFEXTCON (VPint(Base_Addr+0x303c))
+
+// Ethernet BDMA Register
+#define BDMATXCON (VPint(Base_Addr+0x9000))
+#define BDMARXCON (VPint(Base_Addr+0x9004))
+#define BDMATXPTR (VPint(Base_Addr+0x9008))
+#define BDMARXPTR (VPint(Base_Addr+0x900c))
+#define BDMARXLSZ (VPint(Base_Addr+0x9010))
+#define BDMASTAT (VPint(Base_Addr+0x9014))
+
+#define CAM_BASE (VPint(Base_Addr+0x9100))
+#define BDMATXBUF (VPint(Base_Addr+0x9200))
+#define BDMARXBUF (VPint(Base_Addr+0x9800))
+#define CAM_BaseAddr (Base_Addr+0x9100)
+
+// Ethernet MAC Register
+#define MACCON (VPint(Base_Addr+0xa000))
+#define CAMCON (VPint(Base_Addr+0xa004))
+#define MACTXCON (VPint(Base_Addr+0xa008))
+#define MACTXSTAT (VPint(Base_Addr+0xa00c))
+#define MACRXCON (VPint(Base_Addr+0xa010))
+#define MACRXSTAT (VPint(Base_Addr+0xa014))
+#define STADATA (VPint(Base_Addr+0xa018))
+#define STACON (VPint(Base_Addr+0xa01c))
+#define CAMEN (VPint(Base_Addr+0xa028))
+#define EMISSCNT (VPint(Base_Addr+0xa03c))
+#define EPZCNT (VPint(Base_Addr+0xa040))
+#define ERMPZCNT (VPint(Base_Addr+0xa044))
+#define ETXSTAT (VPint(Base_Addr+0xa048))
+#define MACRXDESTR (VPint(Base_Addr+0xa064))
+#define MACRXSTATEM (VPint(Base_Addr+0xa090))
+
+// HDLC Channel A
+#define HCON0A (VPint(Base_Addr+0x7000))
+#define HCON1A (VPint(Base_Addr+0x7004))
+#define HSTATA (VPint(Base_Addr+0x7008))
+#define HINTENA (VPint(Base_Addr+0x700c))
+#define HTXFIFOCA (VPint(Base_Addr+0x7010))
+#define HTXFIFOTA (VPint(Base_Addr+0x7014))
+#define HRXFIFOA (VPint(Base_Addr+0x7018))
+#define HSADRA (VPint(Base_Addr+0x701c))
+#define HBRGTCA (VPint(Base_Addr+0x7020))
+#define HPRMBA (VPint(Base_Addr+0x7024))
+#define HDMATXMAA (VPint(Base_Addr+0x7028))
+#define HDMARXMAA (VPint(Base_Addr+0x702c))
+#define HDMATXCNTA (VPint(Base_Addr+0x7030))
+#define HDMARXCNTA (VPint(Base_Addr+0x7034))
+#define HDMARXBCNTA (VPint(Base_Addr+0x7038))
+
+// HDLC Channel B
+#define HCON0B (VPint(Base_Addr+0x8000))
+#define HCON1B (VPint(Base_Addr+0x8004))
+#define HSTATB (VPint(Base_Addr+0x8008))
+#define HINTENB (VPint(Base_Addr+0x800c))
+#define HTXFIFOCB (VPint(Base_Addr+0x8010))
+#define HTXFIFOTB (VPint(Base_Addr+0x8014))
+#define HRXFIFOB (VPint(Base_Addr+0x8018))
+#define HSADRB (VPint(Base_Addr+0x801c))
+#define HBRGTCB (VPint(Base_Addr+0x8020))
+#define HPRMBB (VPint(Base_Addr+0x8024))
+#define HDMATXMAB (VPint(Base_Addr+0x8028))
+#define HDMARXMAB (VPint(Base_Addr+0x802c))
+#define HDMATXCNTB (VPint(Base_Addr+0x8030))
+#define HDMARXCNTB (VPint(Base_Addr+0x8034))
+#define HDMARXBCNTB (VPint(Base_Addr+0x8038))
+
+// I2C Bus Register
+#define IICCON (VPint(Base_Addr+0xf000))
+#define IICBUF (VPint(Base_Addr+0xf004))
+#define IICPS (VPint(Base_Addr+0xf008))
+#define IICCOUNT (VPint(Base_Addr+0xf00c))
+
+// GDMA 0
+#define GDMACON0 (VPint(Base_Addr+0xb000))
+#define GDMASRC0 (VPint(Base_Addr+0xb004))
+#define GDMADST0 (VPint(Base_Addr+0xb008))
+#define GDMACNT0 (VPint(Base_Addr+0xb00c))
+
+// GDMA 1
+#define GDMACON1 (VPint(Base_Addr+0xc000))
+#define GDMASRC1 (VPint(Base_Addr+0xc004))
+#define GDMADST1 (VPint(Base_Addr+0xc008))
+#define GDMACNT1 (VPint(Base_Addr+0xc00c))
+
+// UART 0
+#define UART0_LCR (VPint(Base_Addr+0xd000)) // line control register
+#define UART0_CTRL (VPint(Base_Addr+0xd004)) // uart control register
+#define UART0_LST (VPint(Base_Addr+0xd008)) // line status register
+#define UART0_THR (VPint(Base_Addr+0xd00c)) // transmit holding reg.
+#define UART0_RDR (VPint(Base_Addr+0xd010)) // receive data register
+#define UART0_BRD (VPint(Base_Addr+0xd014)) // baud rate divisor
+
+// UART 1
+#define UART1_LCR (VPint(Base_Addr+0xe000)) // line control register
+#define UART1_CTRL (VPint(Base_Addr+0xe004)) // uart control register
+#define UART1_LST (VPint(Base_Addr+0xe008)) // line status register
+#define UART1_THR (VPint(Base_Addr+0xe00c)) // transmit holding reg.
+#define UART1_RDR (VPint(Base_Addr+0xe010)) // receive data register
+#define UART1_BRD (VPint(Base_Addr+0xe014)) // baud rate divisor
+
+// Timer Register
+#define TMOD (VPint(Base_Addr+0x6000))
+#define TDATA0 (VPint(Base_Addr+0x6004))
+#define TDATA1 (VPint(Base_Addr+0x6008))
+#define TCNT0 (VPint(Base_Addr+0x600c))
+#define TCNT1 (VPint(Base_Addr+0x6010))
+
+// Timer Mode Register
+#define TM0_RUN 0x01 /* Timer 0 enable */
+#define TM0_TOGGLE 0x02 /* 0, interval mode */
+#define TM0_OUT_1 0x04 /* Timer 0 Initial TOUT0 value */
+#define TM1_RUN 0x08 /* Timer 1 enable */
+#define TM1_TOGGLE 0x10 /* 0, interval mode */
+#define TM1_OUT_1 0x20 /* Timer 0 Initial TOUT0 value */
+
+// I/O Port Interface
+#define IOPMOD (VPint(Base_Addr+0x5000))
+#define IOPCON (VPint(Base_Addr+0x5004))
+#define IOPDATA (VPint(Base_Addr+0x5008))
+
+// Interrupt Controller Register
+#define INTMODE (VPint(Base_Addr+0x4000))
+#define INTPEND (VPint(Base_Addr+0x4004))
+#define INTMASK (VPint(Base_Addr+0x4008))
+
+#define INTPRI0 (VPint(Base_Addr+0x400c))
+#define INTPRI1 (VPint(Base_Addr+0x4010))
+#define INTPRI2 (VPint(Base_Addr+0x4014))
+#define INTPRI3 (VPint(Base_Addr+0x4018))
+#define INTPRI4 (VPint(Base_Addr+0x401c))
+#define INTPRI5 (VPint(Base_Addr+0x4020))
+#define INTOFFSET (VPint(Base_Addr+0x4024))
+
+#endif
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/src/lxt970.c b/ecos/packages/devs/eth/arm/ks32c5000/current/src/lxt970.c
new file mode 100644
index 0000000..8130141
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/src/lxt970.c
@@ -0,0 +1,160 @@
+//==========================================================================
+//
+// lxt970.c
+//
+// Driver for LXT970 PHY
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Grant Edwards <grante@visi.com>
+// Date: 2001-07-31
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include "std.h"
+#include "phy.h"
+
+// address of the LX970 phy
+#ifdef CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
+#define LX970_ADDR CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
+#else
+#define LX970_ADDR 1
+#endif
+
+// LX970 register offsets
+#define LX970_CNTL_REG 0x00
+#define LX970_STATUS_REG 0x01
+#define LX970_ID_REG1 0x02
+#define LX970_ID_REG2 0x03
+#define LX970_ANA_REG 0x04
+#define LX970_ANLPAR_REG 0x05
+#define LX970_ANE_REG 0x06
+#define LX970_MIRROR_REG 0x10
+#define LX970_INTEN_REG 0x11
+#define LX970_INTSTAT_REG 0x12
+#define LX970_CONFIG_REG 0x13
+#define LX970_CHIPSTAT_REG 0x14
+
+// LX970 Control register bit defines
+#define LX970_CNTL_RESET 0x8000
+#define LX970_CNTL_LOOPBACK 0x4000
+#define LX970_CNTL_SPEED 0x2000 // 1=100Meg, 0=10Meg
+#define LX970_CNTL_AN 0x1000 // 1=Enable auto negotiation, 0=disable it
+#define LX970_CNTL_PWRDN 0x0800 // 1=Enable power down
+#define LX970_CNTL_ISOLATE 0x0400 // 1=Isolate from MII
+#define LX970_CNTL_RSTRT_AN 0x0200 // 1=Restart Auto Negotioation process
+#define LX970_CNTL_FULL_DUP 0x0100 // 1=Enable full duplex mode, 0=half dup
+#define LX970_CNTL_TST_COLL 0x0080 // 1=Enable collision test
+
+#define Bit(n) (1<<(n))
+
+#define LX970_ANA_PAUSE_ENA Bit(10)
+#define LX970_ANA_100T4 Bit(9)
+#define LX970_ANA_100TX_FULL Bit(8)
+#define LX970_ANA_100TX Bit(7)
+#define LX970_ANA_10T_FULL Bit(6)
+#define LX970_ANA_10T Bit(5)
+#define LX970_ANA_SEL_802_3 Bit(0)
+
+#define LX970_CHIPSTAT_LINKUP Bit(13)
+#define LX970_CHIPSTAT_FULLDUP Bit(12)
+#define LX970_CHIPSTAT_100M Bit(11)
+#define LX970_CHIPSTAT_ANEG_DONE Bit(9)
+#define LX970_CHIPSTAT_PAGE_RX Bit(8)
+#define LX970_CHIPSTAT_LOWVOLT Bit(2)
+
+// phy functions for Level1 PHY LXT970
+
+void PhyReset(void)
+{
+ // first software reset the LX970
+ MiiStationWrite(LX970_CNTL_REG, LX970_ADDR, LX970_CNTL_RESET);
+ MiiStationWrite(LX970_CNTL_REG, LX970_ADDR, 0);
+
+ // set low level drive for MII lines, enable interrupt output
+ MiiStationWrite(17, LX970_ADDR, BIT3+BIT1);
+
+ // default values for 100M encryption are wrong, so fix them
+ // and configure LEDC to be activity indicator
+ MiiStationWrite(19, LX970_ADDR, BIT7);
+
+ // initialize auto-negotiation capabilities
+ MiiStationWrite(LX970_ANA_REG,LX970_ADDR,
+ LX970_ANA_PAUSE_ENA+
+ LX970_ANA_100T4+
+ LX970_ANA_100TX_FULL+
+ LX970_ANA_100TX+
+ LX970_ANA_10T_FULL+
+ LX970_ANA_10T+
+ LX970_ANA_SEL_802_3);
+#if 1
+ // Now start an auto negotiation
+ MiiStationWrite(LX970_CNTL_REG, LX970_ADDR,
+ LX970_CNTL_AN+
+ LX970_CNTL_RSTRT_AN);
+#else
+ // force to 10M full duplex
+ MiiStationWrite(LX970_CNTL_REG, LX970_ADDR,
+ LX970_CNTL_FULL_DUP);
+#endif
+}
+
+unsigned PhyStatus(void)
+{
+ unsigned lxt970Status = MiiStationRead(LX970_CHIPSTAT_REG,LX970_ADDR);
+ unsigned r = 0;
+ if (lxt970Status & LX970_CHIPSTAT_LINKUP)
+ r |= PhyStatus_LinkUp;
+ if (lxt970Status & LX970_CHIPSTAT_FULLDUP)
+ r |= PhyStatus_FullDuplex;
+ if (lxt970Status & LX970_CHIPSTAT_100M)
+ r |= PhyStatus_100Mb;
+ return r;
+}
+
+void PhyInterruptAck(void)
+{
+ MiiStationRead(1,LX970_ADDR);
+ MiiStationRead(18,LX970_ADDR);
+}
+
+// EOF lxt970.c
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/src/lxt972.c b/ecos/packages/devs/eth/arm/ks32c5000/current/src/lxt972.c
new file mode 100644
index 0000000..d6d1682
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/src/lxt972.c
@@ -0,0 +1,234 @@
+//==========================================================================
+//
+// lxt972.c
+//
+// Driver for LXT972 PHY
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): cgarry
+// Contributors: Based on code from: gthomas, jskov
+// Grant Edwards <grante@visi.com>
+// Date: 2002-10-18
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/devs_eth_arm_ks32c5000.h>
+
+#include "std.h"
+#include "phy.h"
+
+#define Bit(n) (1<<(n))
+
+// address of the LX972 phy
+#ifdef CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
+#define LX972_ADDR CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
+#else
+#define LX972_ADDR 0
+#endif
+
+// LX972 register offsets
+#define LX972_CTRL_REG 0x00
+#define LX972_STATUS1_REG 0x01
+#define LX972_PHY_ID1_REG 0x02
+#define LX972_PHY_ID2_REG 0x03
+#define LX972_AN_ADVRT_REG 0x04
+#define LX972_AN_LPAR_REG 0x05
+#define LX972_AN_EXP_REG 0x06
+#define LX972_AN_NEXTPAGE_REG 0x07
+#define LX972_AN_LPAR_NP_REG 0x08
+#define LX972_PORT_CONFIG_REG 0x10
+#define LX972_STATUS2_REG 0x11
+#define LX972_INT_ENAB_REG 0x12
+#define LX972_INT_STAT_REG 0x13
+#define LX972_LED_CONFIG_REG 0x14
+#define LX972_DIG_CONFIG_REG 0x1A
+#define LX972_TX_CTRL2_REG 0x1E
+
+// LX972 Control register bit defines
+#define LX972_CTRL_RESET 0x8000
+#define LX972_CTRL_LOOPBACK 0x4000
+#define LX972_CTRL_SPEED 0x2000 // 1=100Meg, 0=10Meg
+#define LX972_CTRL_AN 0x1000 // 1=Enable auto negotiation, 0=disable it
+#define LX972_CTRL_PWRDN 0x0800 // 1=Enable power down
+#define LX972_CTRL_ISOLATE 0x0400 // 1=Isolate from MII
+#define LX972_CTRL_RSTRT_AN 0x0200 // 1=Restart Auto Negotioation process
+#define LX972_CTRL_FULL_DUP 0x0100 // 1=Enable full duplex mode, 0=half dup
+#define LX972_CTRL_TST_COLL 0x0080 // 1=Enable collision test
+
+// LX972 Interrupt enable register bit defines
+#define LX972_INT_ENAB_ANMSK Bit(7)
+#define LX972_INT_ENAB_SPEEDMSK Bit(6)
+#define LX972_INT_ENAB_DUPLEXMSK Bit(5)
+#define LX972_INT_ENAB_LINKMSK Bit(4)
+#define LX972_INT_ENAB_INTEN Bit(1)
+#define LX972_INT_ENAB_TINT Bit(0)
+
+// Map LED values from CDL file to reg defines
+#define LINK_SPEED LX972_LED_CONFIG_SPEED_STATUS
+#define TX_ACTIVITY LX972_LED_CONFIG_TX_STATUS
+#define RX_ACTIVITY LX972_LED_CONFIG_RX_STATUS
+#define COLLISION_STATUS LX972_LED_CONFIG_COLLISION_STATUS
+#define DUPLEX_STATUS LX972_LED_CONFIG_DUPLEX_STATUS
+#define LINK_ACTIVITY LX972_LED_CONFIG_RXTX_ACTIVITY
+#define LINK_STATUS_RX_STATUS_COMBINED LX972_LED_CONFIG_LINK_RX_COMB
+#define LINK_STATUS_LINK_ACTIVITY_COMBINED LX972_LED_CONFIG_LINK_ACT_COMB
+#define DUPLEX_STATUS_COLLISION_STATUS_COMBINED LX972_LED_CONFIG_DUPLEX_COLL_COMB
+#define LINK_STATUS LX972_LED_CONFIG_LINK_STATUS
+#define TEST_ON LX972_LED_CONFIG_TEST_ON
+#define TEST_OFF LX972_LED_CONFIG_TEST_OFF
+#define TEST_BLINK_FAST LX972_LED_CONFIG_BLINK_FAST
+#define TEST_BLINK_SLOW LX972_LED_CONFIG_BLINK_SLOW
+
+// LX972 LED Config register bit defines
+#define LX972_LED_CONFIG_LED1SHIFT 12
+#define LX972_LED_CONFIG_LED2SHIFT 8
+#define LX972_LED_CONFIG_LED3SHIFT 4
+#define LX972_LED_CONFIG_SPEED_STATUS 0x0
+#define LX972_LED_CONFIG_TX_STATUS 0x1
+#define LX972_LED_CONFIG_RX_STATUS 0x2
+#define LX972_LED_CONFIG_COLLISION_STATUS 0x3
+#define LX972_LED_CONFIG_LINK_STATUS 0x4
+#define LX972_LED_CONFIG_DUPLEX_STATUS 0x5
+#define LX972_LED_CONFIG_RXTX_ACTIVITY 0x7
+#define LX972_LED_CONFIG_TEST_ON 0x8
+#define LX972_LED_CONFIG_TEST_OFF 0x9
+#define LX972_LED_CONFIG_BLINK_FAST 0xA
+#define LX972_LED_CONFIG_BLINK_SLOW 0xB
+#define LX972_LED_CONFIG_LINK_RX_COMB 0xC
+#define LX972_LED_CONFIG_LINK_ACT_COMB 0xD
+#define LX972_LED_CONFIG_DUPLEX_COLL_COMB 0xE
+#define LX972_LED_CONFIG_STRETCH_100MS 0x8
+#define LX972_LED_CONFIG_ENAB_LED_STRETCH Bit(1)
+
+// LX972 Auto Negotiation Advertisement register bit defines
+#define LX972_AN_ADVRT_NEXT_PAGE Bit(15)
+#define LX972_AN_ADVRT_PAUSE_ENA Bit(10)
+#define LX972_AN_ADVRT_100T4 Bit(9)
+#define LX972_AN_ADVRT_100TX_FULL Bit(8)
+#define LX972_AN_ADVRT_100TX Bit(7)
+#define LX972_AN_ADVRT_10T_FULL Bit(6)
+#define LX972_AN_ADVRT_10T Bit(5)
+#define LX972_AN_ADVRT_SEL_802_3 Bit(0)
+
+// LX972 Status register #2 bit defines
+#define LX972_STATUS2_100M Bit(14)
+#define LX972_STATUS2_LINKUP Bit(10)
+#define LX972_STATUS2_FULLDUP Bit(9)
+#define LX972_STATUS2_ANEG_DONE Bit(7)
+
+// phy functions for Level1 PHY LXT972
+
+void PhyReset(void)
+{
+ unsigned CtrlRegData;
+ // First software reset the LX972
+ MiiStationWrite(LX972_CTRL_REG, LX972_ADDR, LX972_CTRL_RESET);
+ MiiStationWrite(LX972_CTRL_REG, LX972_ADDR, 0);
+
+ // Wait until the LX972 reset cycle has completed
+ // The Control register will read 0x7FFF until the reset cycle has completed
+ CtrlRegData = 0x7FFF;
+ while (CtrlRegData == 0x7FFF)
+ {
+ CtrlRegData = MiiStationRead(LX972_CTRL_REG, LX972_ADDR);
+ }
+
+ // Set up the LEDs' modes
+ MiiStationWrite(LX972_LED_CONFIG_REG, LX972_ADDR,
+ (CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT972_LED1 << LX972_LED_CONFIG_LED1SHIFT)
+ | (CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT972_LED2 << LX972_LED_CONFIG_LED2SHIFT)
+ | (CYGPKG_DEVS_ETH_ARM_KS32C5000_PHY_LXT972_LED3 << LX972_LED_CONFIG_LED3SHIFT)
+ | LX972_LED_CONFIG_STRETCH_100MS
+ | LX972_LED_CONFIG_ENAB_LED_STRETCH);
+
+ // Set MII drive strength
+ MiiStationWrite(LX972_DIG_CONFIG_REG, LX972_ADDR, 0);
+
+ // Enable interrupts
+ MiiStationWrite(LX972_INT_ENAB_REG, LX972_ADDR,
+ LX972_INT_ENAB_ANMSK
+ | LX972_INT_ENAB_SPEEDMSK
+ | LX972_INT_ENAB_DUPLEXMSK
+ | LX972_INT_ENAB_LINKMSK
+ | LX972_INT_ENAB_INTEN);
+
+ // Initialize auto-negotiation capabilities
+ // Next page not enabled
+ MiiStationWrite(LX972_AN_ADVRT_REG, LX972_ADDR,
+ LX972_AN_ADVRT_PAUSE_ENA
+ | LX972_AN_ADVRT_100T4
+ | LX972_AN_ADVRT_100TX_FULL
+ | LX972_AN_ADVRT_100TX
+ | LX972_AN_ADVRT_10T_FULL
+ | LX972_AN_ADVRT_10T
+ | LX972_AN_ADVRT_SEL_802_3);
+#if 1
+ // Now start an auto negotiation
+ MiiStationWrite(LX972_CTRL_REG, LX972_ADDR,
+ LX972_CTRL_AN
+ | LX972_CTRL_RSTRT_AN);
+#else
+ // force to 10M full duplex
+ MiiStationWrite(LX972_CTRL_REG, LX972_ADDR,
+ LX972_CTRL_FULL_DUP);
+#endif
+}
+
+unsigned PhyStatus(void)
+{
+ unsigned lxt972Status = MiiStationRead(LX972_STATUS2_REG,LX972_ADDR);
+ unsigned r = 0;
+ if (lxt972Status & LX972_STATUS2_LINKUP)
+ r |= PhyStatus_LinkUp;
+ if (lxt972Status & LX972_STATUS2_FULLDUP)
+ r |= PhyStatus_FullDuplex;
+ if (lxt972Status & LX972_STATUS2_100M)
+ r |= PhyStatus_100Mb;
+ return r;
+}
+
+void PhyInterruptAck(void)
+{
+ MiiStationRead(LX972_STATUS1_REG, LX972_ADDR);
+ MiiStationRead(LX972_INT_STAT_REG, LX972_ADDR);
+}
+
+// EOF lxt972.c
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/src/phy.h b/ecos/packages/devs/eth/arm/ks32c5000/current/src/phy.h
new file mode 100644
index 0000000..3b89efc
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/src/phy.h
@@ -0,0 +1,67 @@
+//==========================================================================
+//
+// phy.h
+//
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Grant Edwards <grante@visi.com>
+// Date: 2001-07-31
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#if !defined(_PHY_H)
+#define _PHY_H
+
+void MiiStationWrite(U32 RegAddr, U32 PhyAddr, U32 PhyWrData);
+U32 MiiStationRead(U32 RegAddr, U32 PhyAddr);
+
+void PhyReset(void);
+unsigned PhyStatus(void);
+void PhyInterruptAck(void);
+
+#define PhyStatus_LinkUp 0x0001
+#define PhyStatus_FullDuplex 0x0002
+#define PhyStatus_100Mb 0x0004
+
+#endif
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/src/rtl8201.c b/ecos/packages/devs/eth/arm/ks32c5000/current/src/rtl8201.c
new file mode 100644
index 0000000..3c3c8a9
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/src/rtl8201.c
@@ -0,0 +1,208 @@
+//==========================================================================
+//
+// rtl8201.c
+//
+// Driver for RTL8201 PHY
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributoris: rcassebohm, gthomas, jskov
+// Grant Edwards <grante@visi.com>
+// Date: 2001-07-31
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_if.h>
+
+#include <pkgconf/devs_eth_arm_ks32c5000.h>
+
+#include <cyg/infra/diag.h>
+
+#include "std.h"
+#include "phy.h"
+
+// Set up the level of debug output
+#if CYGPKG_DEVS_ETH_ARM_KS32C5000_DEBUG_LEVEL > 0
+#define debug1_printf(args...) diag_printf(args)
+#else
+#define debug1_printf(args...) /* noop */
+#endif
+#if CYGPKG_DEVS_ETH_ARM_KS32C5000_DEBUG_LEVEL > 1
+#define debug2_printf(args...) diag_printf(args)
+#else
+#define debug2_printf(args...) /* noop */
+#endif
+
+// address of the RTL8201 phy
+#ifdef CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
+#define RTL8201_ADDR CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
+#else
+#error no Phy addr set
+#endif
+
+// RTL8201 register offsets
+#define RTL8201_CNTL_REG 0x00
+#define RTL8201_STATUS_REG 0x01
+#define RTL8201_ID_REG1 0x02
+#define RTL8201_ID_REG2 0x03
+#define RTL8201_ANA_REG 0x04
+#define RTL8201_ANLPA_REG 0x05
+#define RTL8201_ANE_REG 0x06
+#define RTL8201_NSR_REG 0x10
+#define RTL8201_LBREMR_REG 0x11
+#define RTL8201_RXER_REG 0x12
+#define RTL8201_10M_NIC_REG 0x13
+#define RTL8201_PHY1_1_REG 0x14
+#define RTL8201_PHY1_2_REG 0x15
+#define RTL8201_PHY2_REG 0x16
+#define RTL8201_TWISTER1_REG 0x17
+#define RTL8201_TWISTER2_REG 0x18
+#define RTL8201_TEST_REG 0x19
+
+// RTL8201 Control register bit defines
+#define RTL8201_CNTL_RESET 0x8000
+#define RTL8201_CNTL_LOOPBACK 0x4000
+#define RTL8201_CNTL_SPEED 0x2000 // 1=100Meg, 0=10Meg
+#define RTL8201_CNTL_AN 0x1000 // 1=Enable auto negotiation, 0=disable it
+#define RTL8201_CNTL_PWRDN 0x0800 // 1=Enable power down
+#define RTL8201_CNTL_RSTRT_AN 0x0200 // 1=Restart Auto Negotioation process
+#define RTL8201_CNTL_FULL_DUP 0x0100 // 1=Enable full duplex mode, 0=half dup
+
+#define Bit(n) (1<<(n))
+
+#define RTL8201_STATUS_100T4 Bit(15)
+#define RTL8201_STATUS_100TX_FULL Bit(14)
+#define RTL8201_STATUS_100TX Bit(13)
+#define RTL8201_STATUS_10T_FULL Bit(12)
+#define RTL8201_STATUS_10T Bit(11)
+#define RTL8201_STATUS_AN_COMLETE Bit(5)
+#define RTL8201_STATUS_LINKUP Bit(2)
+
+#define RTL8201_ANA_PAUSE_ENA Bit(10)
+#define RTL8201_ANA_100T4 Bit(9)
+#define RTL8201_ANA_100TX_FULL Bit(8)
+#define RTL8201_ANA_100TX Bit(7)
+#define RTL8201_ANA_10T_FULL Bit(6)
+#define RTL8201_ANA_10T Bit(5)
+#define RTL8201_ANA_SEL_802_3 Bit(0)
+
+#define RTL8201_TEST_LINK_10 Bit(1)
+#define RTL8201_TEST_LINK_100 Bit(0)
+#define RTL8201_TEST_PHY_ADR (0x1f<<8)
+
+void PhyReset(void)
+{
+ static int init_done=0;
+ unsigned Status;
+
+ if (init_done)
+ return;
+
+ init_done=1;
+
+ debug2_printf("Phy addr %d\n",RTL8201_ADDR);
+ // first software reset the RTL8201
+ MiiStationWrite(RTL8201_CNTL_REG, RTL8201_ADDR, RTL8201_CNTL_RESET);
+ MiiStationWrite(RTL8201_CNTL_REG, RTL8201_ADDR, 0);
+
+ // initialize auto-negotiation capabilities
+ MiiStationWrite(RTL8201_ANA_REG,RTL8201_ADDR,
+ RTL8201_ANA_100TX_FULL+
+ RTL8201_ANA_100TX+
+ RTL8201_ANA_10T_FULL+
+ RTL8201_ANA_10T+
+ RTL8201_ANA_SEL_802_3);
+ // Now start an auto negotiation
+ debug1_printf("Start auto negotiation\n");
+ MiiStationWrite(RTL8201_CNTL_REG, RTL8201_ADDR,
+ RTL8201_CNTL_AN+
+ RTL8201_CNTL_RSTRT_AN);
+}
+
+unsigned PhyStatus(void)
+{
+ unsigned Status;
+ unsigned r = 0, count=0;
+
+ debug2_printf("Wait\n");
+
+ // Wait for auto negotiation to get completed
+ do
+ {
+ Status = MiiStationRead(RTL8201_STATUS_REG,RTL8201_ADDR);
+ CYGACC_CALL_IF_DELAY_US(10000);
+ count++;
+ }
+ while (!(Status&RTL8201_STATUS_AN_COMLETE) && count<500);
+ //If it takes longer then 5 sec stop waiting
+
+ debug2_printf("Wait finished\n");
+
+ debug1_printf("PhyStatus is ");
+ Status = MiiStationRead(RTL8201_STATUS_REG,RTL8201_ADDR);
+ if (Status & RTL8201_STATUS_LINKUP)
+ {
+ r |= PhyStatus_LinkUp;
+ debug1_printf("LINK ");
+ }
+ Status = MiiStationRead(RTL8201_CNTL_REG,RTL8201_ADDR);
+ if (Status & RTL8201_CNTL_FULL_DUP)
+ {
+ r |= PhyStatus_FullDuplex;
+ debug1_printf("FDX ");
+ }
+ Status = MiiStationRead(RTL8201_TEST_REG,RTL8201_ADDR);
+ if (Status & RTL8201_TEST_LINK_100)
+ {
+ r |= PhyStatus_100Mb;
+ debug1_printf("100MBit ");
+ }
+ else if (r & PhyStatus_LinkUp)
+ debug2_printf("10MBit ");
+ debug1_printf("(0x%x)\n",r);
+
+ return r;
+}
+
+void PhyInterruptAck(void)
+{
+}
diff --git a/ecos/packages/devs/eth/arm/ks32c5000/current/src/std.h b/ecos/packages/devs/eth/arm/ks32c5000/current/src/std.h
new file mode 100644
index 0000000..f10059c
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/ks32c5000/current/src/std.h
@@ -0,0 +1,106 @@
+#ifndef _STD_H_
+#define _STD_H_
+
+#ifndef BYTE
+#define BYTE unsigned char
+#endif
+
+#ifndef WORD
+#define WORD unsigned short
+#endif
+
+#ifndef LWORD
+#define LWORD unsigned long
+#endif
+
+#ifndef DWORD
+#define DWORD unsigned long
+#endif
+
+#ifndef VLWORD
+#define VLWORD volatile unsigned long
+#endif
+
+#ifndef BOOLEAN
+#define BOOLEAN BYTE
+#endif
+
+#ifndef BOOL
+#define BOOL BYTE
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define S8 signed char
+#define S08 signed char
+#define S16 signed short
+#define S32 signed long
+#define U8 unsigned char
+#define U08 unsigned char
+#define U16 unsigned short
+#define U32 unsigned long
+#define REG8 volatile unsigned char
+#define REG16 volatile unsigned short
+#define REG32 volatile unsigned long
+
+#define UINT unsigned int
+
+#define std_Local static
+#define std_Void void
+
+#define STD_YES 1
+#define STD_NO 0
+
+#define STD_TRUE STD_YES
+#define STD_FALSE STD_NO
+
+#define STD_OK STD_YES
+#define STD_ERROR STD_NO
+
+#define STD_ON STD_YES
+#define STD_OFF STD_NO
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+#endif
diff --git a/ecos/packages/devs/eth/arm/lpc2xxx/current/ChangeLog b/ecos/packages/devs/eth/arm/lpc2xxx/current/ChangeLog
new file mode 100644
index 0000000..f7b54ed
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/lpc2xxx/current/ChangeLog
@@ -0,0 +1,39 @@
+2011-21-21 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/lpc2xxx_eth.cdl, src/if_lpc2xxx.c: Fixed interrupt priority.
+ [Bugzilla 1001432 ]
+
+2011-02-01 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/lpc2xxx_eth.cdl, src/if_lpc2xxx.c: Added support for
+ LPC17xx CPUs.
+
+2008-09-09 Uwe Kindler <uwe_kindler@web.de>
+
+ * LPC2xxx ethernet driver package created
+ * cdl/lpc2xxx_eth.cdl
+ * src/if_lpc2xxx.c
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/lpc2xxx/current/cdl/lpc2xxx_eth.cdl b/ecos/packages/devs/eth/arm/lpc2xxx/current/cdl/lpc2xxx_eth.cdl
new file mode 100755
index 0000000..c6af3e6
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/lpc2xxx/current/cdl/lpc2xxx_eth.cdl
@@ -0,0 +1,194 @@
+#==========================================================================
+#
+# lpc2xxx_eth.cdl
+#
+# Ethernet driver for NXP LPC2xxx Cores
+#
+#==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors: ilijak
+# Date: 2008-08-05
+#
+#####DESCRIPTIONEND####
+#
+#========================================================================*/
+
+cdl_package CYGPKG_DEVS_ETH_ARM_LPC2XXX {
+ display "NXP LPC2xxx ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ include_dir net
+ description "
+ Ethernet driver for NXP LPC2xxx core. This has been tested with the
+ LPC2468, but should be easy to get to work on other LPC2xxx cores that
+ have the EMAC peripheral."
+
+ compile -library=libextras.a if_lpc2xxx.c
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_LPC2XXX_DEBUG_LEVEL {
+ display "Driver debug output level"
+ flavor data
+ legal_values {0 1 2 3}
+ default_value 1
+ description "
+ This option specifies the level of debug data output by
+ the LPC2XXX ethernet device driver. A value of 0 signifies
+ no debug data output; 1 signifies normal debug data
+ output; and 2 signifies maximum debug data output (not
+ suitable when GDB and application are sharing an ethernet
+ port). Debug level 3 is a special kind of debug level.
+ It prints the same debug messages like level 2 but it forces
+ the debug output to the second serial port. This is
+ required for debugging the ethernet driver if the stand-alone
+ network stack from redboot is used. It is possible to print
+ debug messages while an application is loaded and run via GDB
+ TCP/IP connection"
+ }
+
+ # For backward compatibility with LPC24xx platforms
+ # that do not have CYGNUM_HAL_IRQ_PRIORITY_MIN defined.
+ cdl_option CYGNUM_DEVS_ETH_IRQ_PRIORITY_MIN {
+ display "Interrupt priority levels"
+ flavor data
+ calculated { CYGNUM_HAL_IRQ_PRIORITY_MIN ? CYGNUM_HAL_IRQ_PRIORITY_MIN : 15 }
+ description "
+ For backward compatibility with LPC 24XX plarforms that do
+ not have CYGNUM_HAL_IRQ_PRIORITY_MIN defined."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_LPC2XXX_INTPRIO {
+ display "Interrupt priority"
+ flavor data
+ legal_values 0 to CYGNUM_DEVS_ETH_IRQ_PRIORITY_MIN
+ default_value CYGNUM_DEVS_ETH_IRQ_PRIORITY_MIN
+ description "
+ This option selects the interrupt priority for the EMAC
+ interrupts. The reset value
+ of these registers defaults all interrupts to the lowest
+ priority, allowing a single write to elevate the priority
+ of an individual interrupt."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ARM_LPC2XXX_RX_BUFS {
+ display "Number of RX buffers"
+ flavor data
+ default_value 4
+ legal_values 2 to 4
+ description "
+ Number of receive buffers. The number of receive buffers defines
+ the number of descriptors in the descriptor array. Each receive
+ descriptor element in the descriptor array has an associated status
+ field which consists of the HashCRC word and Status Information
+ word. Because of a device errata the status words are updated
+ incorrectly if the number of descriptors set is greater than or
+ equal to 5. Therefore the Rx buffers are limited to a maximum
+ of 4. Each buffer is 1536 (0x600) bytes in size"
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ARM_LPC2XXX_TX_BUFS {
+ display "Number of TX descriptors"
+ flavor data
+ default_value 10
+ legal_values 2 to 10
+ description "
+ Number of transmit buffer descriptors. We need one descriptor
+ for each element in the scatter/gather list."
+ }
+
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_LPC2XXX_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 0
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ active_if (CYGPKG_REDBOOT || CYGSEM_HAL_USE_ROM_MONITOR)
+
+ description "
+ Enabling this option will allow the ethernet station
+ address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually
+ by the 'Set the ethernet station address' option for each
+ interface."
+
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_LPC2XXX_REDBOOT_HOLDS_ESA_VARS {
+ display "Export RedBoot command to set ESA in FLASH config"
+ flavor none
+ no_define
+ description "
+ This component contains options which, when enabled, allow
+ RedBoot to support the setting of the ESA in the FLASH
+ configuration. This can then subsequently be accessed by
+ applications using virtual vector calls if those applications
+ are also built with
+ CYGPKG_DEVS_ETH_ARM_LPC2XXX_REDBOOT_HOLDS_ESA enabled."
+
+ cdl_option CYGSEM_DEVS_ETH_ARM_LPC2XXX_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 1
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+ }
+ }
+ }
+ cdl_option CYGPKG_DEVS_ETH_ARM_LPC2XXX_MACADDR {
+ display "Ethernet station (MAC) address for eth0"
+ flavor data
+ default_value {"0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC"}
+ description "The default ethernet station address. This is the
+ MAC address used when no value is found in the
+ RedBoot FLASH configuration field."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_LPC2XXX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Atmel LPC2XXX ethernet driver package.
+ These flags are used in addition to the set of global flags."
+ }
+}
+
+# EOF LPC2XXX_eth.cdl
diff --git a/ecos/packages/devs/eth/arm/lpc2xxx/current/doc/readme.txt b/ecos/packages/devs/eth/arm/lpc2xxx/current/doc/readme.txt
new file mode 100755
index 0000000..6051062
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/lpc2xxx/current/doc/readme.txt
@@ -0,0 +1,35 @@
+Important note:
+--------------
+
+The LPC2xxx EMAC driver was tested with the LPC2468 OEM board from Embedded
+Artists. The driver was tested with the lwIP TCP/IP stack and with Redboot.
+
+While the driver works fine for the lwIP TCP/IP stack and in Redboot, it
+is not possible to debug eCos applications via GDB ethernet connection or
+run eCos applications from Redboot command line if you are connected to
+Redboot via TCP/IP. You can test this, if you run or debug the tm_basic
+test. The tm_basic test crashes, as soon as cyg_thread_delay() is executed
+from the main thread (line 1678 in tm_basic.cxx). This call would cause a
+context switch.
+
+I did a lot of debugging to identify the reason for this strange behaviour
+but could not get a final result. The EMAC driver contains a lot of debug
+messages. From reading the debug messages I'm quite sure that there is
+no memory or stack violation from the ethernet driver. The multi-threaded
+lwIP TCP echo test works without any poblems and also the programm upload
+via GDB or the Redboot communication vi TCP/IP works fine.
+
+It is no problem to start the tm_basic test from the Redboot command line
+if you are connected via serial line. If you are connected via TCP/IP then
+the tm_basic test crashes as soon as it comes to the cyg_thread_delay()
+in line 1687. If the tm_basic test is started from Redboot (connected
+via TCP/IP) with the -n option that forces Redboot to stop the ethernet
+driver, then the test does not crash. So there seems to be a problem if
+the TCP/IP stack is active if Redboot starts a RAM application. I did a
+lot of JTAG debugging to find the reason for this behaviour but was not
+succesful.
+
+I decided to release the driver because I'm quite sure that the driver
+itself works well. Maybe this is a board related issue or a startup code
+related issue. Maybe someone will find the reason.
+
diff --git a/ecos/packages/devs/eth/arm/lpc2xxx/current/src/if_lpc2xxx.c b/ecos/packages/devs/eth/arm/lpc2xxx/current/src/if_lpc2xxx.c
new file mode 100755
index 0000000..9f0265c
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/lpc2xxx/current/src/if_lpc2xxx.c
@@ -0,0 +1,1314 @@
+//==========================================================================
+//
+// if_lpc2xxx.c
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: ilijak
+// Date: 2008-08-10
+// Description: Hardware driver for LPC2xxx on-chip EMAC peripheral
+//
+// This driver was originally written for LPC2468 and may
+// require some modifications to work on other LPC2xxx
+// variants as well.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_eth_arm_lpc2xxx.h>
+#include <pkgconf/io_eth_drivers.h>
+#if defined(CYGPKG_REDBOOT)
+ #include <pkgconf/redboot.h>
+#endif
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/eth_drv_stats.h>
+#include <cyg/io/eth_phy.h>
+#include <errno.h>
+#include <string.h>
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <net/if.h> /* Needed for struct ifnet */
+#endif
+#include <cyg/io/eth/eth_drv_stats.h>
+
+
+//===========================================================================
+// DEFINES
+//===========================================================================
+#ifndef CYGARC_HAL_LPC2XXX_REG_EMAC_BASE
+#error "CYGARC_HAL_LPC2XXX_REG_EMAC_BASE not defined by varaint/platform."
+#else
+#define EMAC_BASE CYGARC_HAL_LPC2XXX_REG_EMAC_BASE
+#endif
+
+//
+// MAC registers
+//
+#define EMAC_MAC1 (EMAC_BASE + 0x0000)
+#define EMAC_MAC2 (EMAC_BASE + 0x0004)
+#define EMAC_IPGT (EMAC_BASE + 0x0008)
+#define EMAC_IPGR (EMAC_BASE + 0x000C)
+#define EMAC_CLRT (EMAC_BASE + 0x0010)
+#define EMAC_MAXF (EMAC_BASE + 0x0014)
+#define EMAC_SUPP (EMAC_BASE + 0x0018)
+#define EMAC_TEST (EMAC_BASE + 0x001C)
+#define EMAC_MCFG (EMAC_BASE + 0x0020)
+#define EMAC_MCMD (EMAC_BASE + 0x0024)
+#define EMAC_MADR (EMAC_BASE + 0x0028)
+#define EMAC_MWTD (EMAC_BASE + 0x002C)
+#define EMAC_MRDD (EMAC_BASE + 0x0030)
+#define EMAC_MIND (EMAC_BASE + 0x0034)
+#define EMAC_SA0 (EMAC_BASE + 0x0040)
+#define EMAC_SA1 (EMAC_BASE + 0x0044)
+#define EMAC_SA2 (EMAC_BASE + 0x0048)
+
+//
+// Control registers
+//
+#define EMAC_CMD (EMAC_BASE + 0x0100)
+#define EMAC_STAT (EMAC_BASE + 0x0104)
+#define EMAC_RXDESC (EMAC_BASE + 0x0108)
+#define EMAC_RXSTAT (EMAC_BASE + 0x010C)
+#define EMAC_RXDESC_NUM (EMAC_BASE + 0x0110)
+#define EMAC_RX_PROD_IDX (EMAC_BASE + 0x0114)
+#define EMAC_RX_CONSUME_IDX (EMAC_BASE + 0x0118)
+#define EMAC_TXDESC (EMAC_BASE + 0x011C)
+#define EMAC_TXSTAT (EMAC_BASE + 0x0120)
+#define EMAC_TXDESC_NUM (EMAC_BASE + 0x0124)
+#define EMAC_TX_PROD_IDX (EMAC_BASE + 0x0128)
+#define EMAC_TX_CONSUME_IDX (EMAC_BASE + 0x012C)
+#define EMAC_TSV0 (EMAC_BASE + 0x0158)
+#define EMAC_TSV1 (EMAC_BASE + 0x015C)
+#define EMAC_RSV (EMAC_BASE + 0x0160)
+#define EMAC_FLOWCTRL_CNT (EMAC_BASE + 0x0170)
+#define EMAC_FLOWCTRL_STAT (EMAC_BASE + 0x0174)
+
+//
+// Rx filter registers
+//
+#define EMAC_RXFILT_CTRL (EMAC_BASE + 0x0200)
+#define EMAC_RXFILT_WOL_STAT (EMAC_BASE + 0x0204)
+#define EMAC_RXFILT_WOL_CLR (EMAC_BASE + 0x0204)
+#define EMAC_HASH_FILT_L (EMAC_BASE + 0x0210)
+#define EMAC_HASH_FILT_H (EMAC_BASE + 0x0214)
+
+//
+// Module control registers
+//
+#define EMAC_INT_STATUS (EMAC_BASE + 0x0FE0)
+#define EMAC_INT_EN (EMAC_BASE + 0x0FE4)
+#define EMAC_INT_CLR (EMAC_BASE + 0x0FE8)
+#define EMAC_INT_SET (EMAC_BASE + 0x0FEC)
+#define EMAC_POWER_DOWN (EMAC_BASE + 0x0FF4)
+#define EMAC_MODULE_ID (EMAC_BASE + 0x0FFC)
+
+//
+// Register bits MCMD
+//
+#define MCMD_WRITE 0x00
+#define MCMD_READ 0x01
+
+//
+// Register bits COMMAND register
+//
+#define CMD_RX_ENABLE (1 << 0)
+#define CMD_TX_ENABLE (1 << 1)
+#define CMD_REG_RESET (1 << 3)
+#define CMD_TX_RESET (1 << 4)
+#define CMD_RX_RESET (1 << 5)
+#define CMD_PASS_RUNT_FRAME (1 << 6)
+#define CMD_PASS_RX_FILTER (1 << 7)
+#define CMD_TX_FLOW_CONTROL (1 << 8)
+#define CMD_RMII (1 << 9)
+#define CMD_FULL_DUPLEX (1 << 10)
+
+//
+// Register bits SUPP register
+//
+#define SUPP_SPEED_100MB (1 << 8)
+
+#define EMAC_OLD_MODULE_ID ((0x3902 << 16) | 0x2000)
+
+//
+// Register bits MAC1
+//
+#define MAC1_RX_EN (1 << 0)
+#define MAC1_PASS_ALL_RX_FRAMES (1 << 1)
+#define MAC1_RX_FLOW_CTRL (1 << 2)
+#define MAC1_TX_FLOW_CTRL (1 << 3)
+#define MAC1_LOOPBACK (1 << 4)
+#define MAC1_RESET_TX (1 << 8)
+#define MAC1_RESET_MCS_TX (1 << 9)
+#define MAC1_RESET_RX (1 << 10)
+#define MAC1_RESET_MCS_RX (1 << 11)
+#define MAC1_RESET_SIM (1 << 14)
+#define MAC1_SOFT_RESET (1 << 15)
+
+//
+// Register bits MAC2
+//
+#define MAC2_FDX (1 << 0)
+#define MAC2_FRAME_LEN_CHECK (1 << 1)
+#define MAC2_HUGE_FRAME_EN (1 << 2)
+#define MAC2_DELAYED_CRC (1 << 3)
+#define MAC2_CRC_EN (1 << 4)
+#define MAC2_PAD_CRC_EN (1 << 5)
+#define MAC2_VLAN_PAD_EN (1 << 6)
+#define MAC2_AUTO_DETECT_PAD_EN (1 << 7)
+#define MAC2_PURE_PREAMBLE (1 << 8)
+#define MAC2_LONG_PREAMBLE (1 << 9)
+#define MAC2_NO_BACKOFF (1 << 12)
+#define MAC2_BACK_PRESS (1 << 13)
+#define MAC2_EXCESS_DEFER (1 << 14)
+
+//
+// Register bits RXFILT_CTRL
+//
+#define RXFILT_CTRL_ACC_UNICAST (1 << 0)
+#define RXFILT_CTRL_ACC_BROADCAST (1 << 1)
+#define RXFILT_CTRL_ACC_MULTICAST (1 << 2)
+#define RXFILT_CTRL_ACC_UNICAST_HASH (1 << 3)
+#define RXFILT_CTRL_ACC_MULTICAST_HASH (1 << 4)
+#define RXFILT_CTRL_ACC_PERFECT (1 << 5)
+#define RXFILT_CTRL_MAGIG_PKT_WOL (1 << 12)
+#define RXFILT_CTRL_RXFILT_WOL (1 << 13)
+
+//
+// Register bits MCFG
+//
+#define MCFG_SCAN_INCR (1 << 0)
+#define MCFG_SUPP_PREAMBLE (1 << 1)
+#define MCFG_RESET_MII_MGMT (1 << 15)
+
+//
+// Register bits MIND
+//
+#define MIND_BUSY (1 << 0)
+#define MIND_SCANNING (1 << 1)
+#define MIND_NOT_VALID (1 << 2)
+#define MIND_LINK_FAIL (1 << 3)
+
+//
+// EMAC interrupts
+//
+#define EMAC_INT_RXOVERRUN (1 << 0)
+#define EMAC_INT_RXERROR (1 << 1)
+#define EMAC_INT_RXFINISHED (1 << 2)
+#define EMAC_INT_RXDONE (1 << 3)
+#define EMAC_INT_TXUNDERRUN (1 << 4)
+#define EMAC_INT_TXERROR (1 << 5)
+#define EMAC_INT_TXFINISHED (1 << 6)
+#define EMAC_INT_TXDONE (1 << 7)
+#define EMAC_INT_SOFTINT (1 << 12)
+#define EMAC_INT_WOL (1 << 13)
+
+
+//===========================================================================
+// ETHERNET RAM AND DMA CONFIGURATION
+//===========================================================================
+#ifdef CYGHWR_HAL_LPC_EMAC_RAM_AHB
+# include <cyg/infra/cyg_type.h>
+# define EMAC_RAM_MEM_SECTION CYGBLD_ATTRIB_SECTION(CYGHWR_HAL_LPC_EMAC_MEM_SECTION)
+# define EMAC_RAM_BASE (&emac_ahb_ram)
+# define EMAC_RAM_SIZE sizeof(emac_ahb_ram)
+# define EMAC_BLOCK_SIZE CYGHWR_HAL_LPC_EMAC_BLOCK_SIZE
+#else // Backward compatibility
+# define EMAC_RAM_BASE 0x7FE00000
+# define EMAC_RAM_SIZE 0x00004000
+# define EMAC_BLOCK_SIZE 0x600
+#endif // CYGHWR_HAL_LPC_EMAC_RAM_AHB
+
+//
+// EMAC Descriptor TX and RX Control fields
+//
+#define EMAC_TX_DESC_INT 0x80000000
+#define EMAC_TX_DESC_LAST 0x40000000
+#define EMAC_TX_DESC_CRC 0x20000000
+#define EMAC_TX_DESC_PAD 0x10000000
+#define EMAC_TX_DESC_HUGE 0x08000000
+#define EMAC_TX_DESC_OVERRIDE 0x04000000
+#define EMAC_RX_DESC_INT 0x80000000
+
+//
+// EMAC Descriptor status related definition
+//
+#define TX_DESC_STATUS_ERR 0x80000000
+#define TX_DESC_STATUS_NODESC 0x40000000
+#define TX_DESC_STATUS_UNDERRUN 0x20000000
+#define TX_DESC_STATUS_LCOL 0x10000000
+#define TX_DESC_STATUS_ECOL 0x08000000
+#define TX_DESC_STATUS_EDEFER 0x04000000
+#define TX_DESC_STATUS_DEFER 0x02000000
+#define TX_DESC_STATUS_COLCNT 0x01E00000
+
+#define RX_DESC_STATUS_ERR 0x80000000
+#define RX_DESC_STATUS_LAST 0x40000000
+#define RX_DESC_STATUS_NODESC 0x20000000
+#define RX_DESC_STATUS_OVERRUN 0x10000000
+#define RX_DESC_STATUS_ALGNERR 0x08000000
+#define RX_DESC_STATUS_RNGERR 0x04000000
+#define RX_DESC_STATUS_LENERR 0x02000000
+#define RX_DESC_STATUS_SYMERR 0x01000000
+#define RX_DESC_STATUS_CRCERR 0x00800000
+#define RX_DESC_STATUS_BCAST 0x00400000
+#define RX_DESC_STATUS_MCAST 0x00200000
+#define RX_DESC_STATUS_FAILFLT 0x00100000
+#define RX_DESC_STATUS_VLAN 0x00080000
+#define RX_DESC_STATUS_CTLFRAM 0x00040000
+
+#define DESC_SIZE_MASK 0x000007FF
+
+//
+// This type defines a descriptor
+//
+typedef struct descriptor_st
+{
+ cyg_uint32 packet;
+ cyg_uint32 control;
+} descriptor_t;
+
+//
+// This type defines a rx status
+// (double word aligned)
+//
+typedef struct rx_status_st
+{
+ cyg_uint32 info;
+ cyg_uint32 hash_crc;
+} rx_status_t;
+
+//
+// This type defines a tx status
+//
+typedef cyg_uint32 tx_status_t;
+typedef union eth_buf_st
+{
+ cyg_uint32 dwords[EMAC_BLOCK_SIZE / sizeof(cyg_uint32)];
+ cyg_uint8 bytes[EMAC_BLOCK_SIZE];
+} eth_buf_t;
+
+
+//
+// Ethernet RAM and buffer configuration type
+// The descriptors and statuses require a certain alignment. By defining each
+// data type we assure this alignment.
+// The TX descriptor array, the TX status array and the RX descriptor array
+// need to be aligned on a 4 Byte (32 bit) address boundary. The RX status
+// array need to be aligned on a 8 Byte (64 bit) address boundary.
+//
+typedef struct eth_ram_cfg_st
+{
+ volatile rx_status_t rx_status[CYGNUM_DEVS_ETH_ARM_LPC2XXX_RX_BUFS];
+ volatile descriptor_t rx_descr[CYGNUM_DEVS_ETH_ARM_LPC2XXX_RX_BUFS];
+ volatile tx_status_t tx_status[CYGNUM_DEVS_ETH_ARM_LPC2XXX_TX_BUFS];
+ volatile descriptor_t tx_descr[CYGNUM_DEVS_ETH_ARM_LPC2XXX_TX_BUFS];
+ volatile eth_buf_t rx_buf[CYGNUM_DEVS_ETH_ARM_LPC2XXX_RX_BUFS];
+} eth_ram_cfg_t;
+
+#ifdef CYGHWR_HAL_LPC_EMAC_RAM_AHB
+volatile static eth_ram_cfg_t emac_ahb_ram EMAC_RAM_MEM_SECTION;
+#endif
+
+#if CYGPKG_DEVS_ETH_ARM_LPC2XXX_DEBUG_LEVEL < 3
+#if CYGPKG_DEVS_ETH_ARM_LPC2XXX_DEBUG_LEVEL > 0
+ #define debug1_printf(args...) diag_printf(args)
+#else
+ #define debug1_printf(args...)
+#endif
+#if CYGPKG_DEVS_ETH_ARM_LPC2XXX_DEBUG_LEVEL > 1
+ #define debug2_printf(args...) diag_printf(args)
+#else
+ #define debug2_printf(args...)
+#endif
+#else // CYGPKG_DEVS_ETH_ARM_LPC2XXX_DEBUG_LEVEL > 3
+//
+// Debug level 3 is a special kind of debug level. It prints the same debug
+// messages like level 2 but it forces the debug output to the second serial
+// port. This may be necessary for debugging the ethernet driver if the
+// stand-alone network stack from redboot is used. It is possible to
+// print debug messages while an application is loaded and run via GDB
+// TCP/IP connection
+//
+static int cur;
+#define debug1_printf(args...) \
+{ \
+ cur = \
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);\
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(1); \
+ diag_printf(args); \
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); \
+}
+#define debug2_printf(args...) \
+{ \
+ cur = \
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);\
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(1); \
+ diag_printf(args); \
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); \
+}
+#endif // CYGPKG_DEVS_ETH_ARM_LPC2XXX_DEBUG_LEVEL > 3
+
+
+//Driver interface callbacks
+#define _eth_drv_init(sc,mac) \
+ (sc->funs->eth_drv->init)(sc,(unsigned char *)mac)
+#define _eth_drv_tx_done(sc,key,status) \
+ (sc->funs->eth_drv->tx_done)(sc,key,status)
+#define _eth_drv_recv(sc,len) \
+ (sc->funs->eth_drv->recv)(sc,len)
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32
+lpc2xxx_eth_isr (cyg_vector_t vector, cyg_addrword_t data);
+#endif
+
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// Decide whether to have redboot config vars for it...
+#if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGPKG_REDBOOT_NETWORKING)
+#include <redboot.h>
+#include <flash_config.h>
+
+#ifdef CYGSEM_DEVS_ETH_ARM_LPC2XXX_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa_data,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0);
+#endif // CYGSEM_DEVS_ETH_ARM_LPC2XXX_REDBOOT_HOLDS_ESA_ETH0
+#endif // CYGPKG_REDBOOT_NETWORKING && CYGSEM_REDBOOT_FLASH_CONFIG
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_ARM_LPC2XXX_REDBOOT_HOLDS_ESA
+#include <cyg/hal/hal_if.h>
+#ifndef CONFIG_ESA
+ #define CONFIG_ESA (6)
+#endif
+
+#define CYGHWR_DEVS_ETH_ARM_LPC2XXX_GET_ESA( mac_address, ok ) \
+ CYG_MACRO_START \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa_data", \
+ mac_address, \
+ CONFIG_ESA); \
+ CYG_MACRO_END
+#endif // CYGPKG_DEVS_ETH_ARM_LPC2XXX_REDBOOT_HOLDS_ESA
+
+//
+// LPC2xxx Ethernet private data
+// The LPC2468 has a single on-chip ethernet device, so all device-specific
+// data could be held in statics. However, in case this driver ever gets
+// re-used for a chip with multiple ethernet devices that data is held
+// in a driver-specific structure.
+//
+typedef struct lpc2xxx_eth_priv_s
+{
+ cyg_uint32 intr_vector;
+ cyg_uint8 *enaddr;
+ cyg_uint32 base; // Base address of device
+ eth_phy_access_t *phy;
+ cyg_uint32 cur_tx_key;
+ cyg_uint32 total_len;
+ cyg_uint8 iterator;
+ cyg_bool tx_busy;
+ volatile eth_ram_cfg_t *ram;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_interrupt intr;
+ cyg_handle_t intr_handle;
+#endif
+} lpc2xxx_eth_priv_t;
+
+
+//===========================================================================
+// PHY SPECIFIC STUFF
+//===========================================================================
+
+
+//===========================================================================
+// Write one of the PHY registers via the MII bus
+//===========================================================================
+static void
+lpc2xxx_write_phy(int reg_addr, int phy_addr, unsigned short data)
+{
+ cyg_uint32 regval;
+
+ HAL_WRITE_UINT32(EMAC_MCMD, MCMD_WRITE);
+ regval = (phy_addr << 8) | reg_addr;
+ HAL_WRITE_UINT32(EMAC_MADR, regval);
+ HAL_WRITE_UINT32(EMAC_MWTD, data);
+
+ do
+ {
+ HAL_READ_UINT32(EMAC_MIND, regval);
+ }
+ while (regval != 0);
+}
+
+
+//===========================================================================
+// Read one of the PHY registers via the MII bus
+//===========================================================================
+static bool
+lpc2xxx_read_phy(int reg_addr, int phy_addr, unsigned short *data)
+{
+ cyg_uint32 regval;
+
+ HAL_WRITE_UINT32(EMAC_MCMD, 0);
+ regval = (phy_addr << 8) | reg_addr;
+ HAL_WRITE_UINT32(EMAC_MADR, regval);
+ HAL_WRITE_UINT32(EMAC_MCMD, MCMD_READ);
+
+ do
+ {
+ HAL_READ_UINT32(EMAC_MIND, regval);
+ }
+ while ((regval & ~MIND_LINK_FAIL) != 0);
+
+ if (regval & MIND_LINK_FAIL)
+ {
+ debug1_printf("LPC2XXX_ETH: PHY link fail\n");
+ }
+
+ HAL_WRITE_UINT32(EMAC_MCMD, 0x0000);
+ HAL_READ_UINT32(EMAC_MRDD, regval);
+ debug2_printf("LPC2XXX_ETH: read result %08x\n", regval);
+ *data = regval & 0xFFFF;
+ return true;
+}
+
+
+//===========================================================================
+// Init device for phy access
+//===========================================================================
+static void lpc2xxx_init_phy(void)
+{
+ int i;
+ cyg_uint32 regval;
+
+ //
+ // host clock divided by 20, no suppress preamble, no scan increment
+ // Reset management hardware
+ //
+ HAL_WRITE_UINT32(EMAC_MCFG, 0x0018 | MCFG_RESET_MII_MGMT);
+ for (i = 0; i < 0x40; ++i)
+ {
+ asm volatile (" nop");
+ }
+ HAL_WRITE_UINT32(EMAC_MCFG, 0x0018);
+ HAL_WRITE_UINT32(EMAC_MCMD, MCMD_WRITE);
+
+ HAL_READ_UINT32(EMAC_CMD, regval);
+ HAL_WRITE_UINT32(EMAC_CMD, regval | CMD_RMII); // RMII configuration
+ HAL_WRITE_UINT32(EMAC_SUPP, 0x800 | SUPP_SPEED_100MB);
+ HAL_DELAY_US(50);
+ HAL_WRITE_UINT32(EMAC_SUPP, SUPP_SPEED_100MB);
+ HAL_DELAY_US(1000);
+}
+
+
+//===========================================================================
+// PHY specific data structures
+//===========================================================================
+ETH_PHY_REG_LEVEL_ACCESS_FUNS(lpc2xxx_phy,
+ lpc2xxx_init_phy,
+ NULL,
+ lpc2xxx_write_phy,
+ lpc2xxx_read_phy);
+
+
+//===========================================================================
+// Hardware driver specific data
+//===========================================================================
+lpc2xxx_eth_priv_t lpc2xxx_priv_data =
+{
+ .intr_vector = CYGNUM_HAL_INTERRUPT_ETH,
+ .base = EMAC_BASE,
+ .phy = &lpc2xxx_phy,
+ .ram = (volatile eth_ram_cfg_t*)EMAC_RAM_BASE,
+ .total_len = 0,
+ .iterator = 0,
+ .tx_busy = false
+};
+
+
+//===========================================================================
+// Initialize TX descriptors
+// To avoid copy operations the higher-level sg_list entries will be
+// directly put into the device's TX descriptors (ring buffer).
+//===========================================================================
+static void lpc2xxx_eth_txdesc_init(lpc2xxx_eth_priv_t * priv)
+{
+ int i;
+
+ debug1_printf("\nLPC2XXX_ETH: Initialising TX descriptors\n");
+ debug2_printf("&priv->ram->tx_descr[0]: 0x%08X\n",
+ (cyg_uint32)priv->ram->tx_descr);
+ debug2_printf("&priv->ram->tx_status[0]: 0x%08X\n",
+ (cyg_uint32)priv->ram->tx_descr);
+ debug2_printf("No of TX descr: %d\n",
+ CYGNUM_DEVS_ETH_ARM_LPC2XXX_TX_BUFS);
+
+ //
+ // Init status for all TX descriptors
+ //
+ for (i = 0; i < CYGNUM_DEVS_ETH_ARM_LPC2XXX_TX_BUFS; i++)
+ {
+ priv->ram->tx_status[i] = 0;
+ }
+
+ //
+ // Initialise TX pointers
+ //
+ HAL_WRITE_UINT32(EMAC_TXDESC, (cyg_uint32)priv->ram->tx_descr);
+ HAL_WRITE_UINT32(EMAC_TXSTAT, (cyg_uint32)priv->ram->tx_status);
+ HAL_WRITE_UINT32(EMAC_TXDESC_NUM, CYGNUM_DEVS_ETH_ARM_LPC2XXX_TX_BUFS - 1);
+ HAL_WRITE_UINT32(EMAC_TX_PROD_IDX, 0);
+}
+
+
+//===========================================================================
+// Initialize RX descriptors
+// The driver currently supports up to 4 rx buffers. In the current
+// implementation the size of the RX buffers is fixed to 1536 (0x600) bytes.
+// Incoming frames are then copied to higher-level's code sg lists.
+//===========================================================================
+static void lpc2xxx_eth_rxdesc_init(lpc2xxx_eth_priv_t * priv)
+{
+ int i;
+
+ debug1_printf("\nLPC2XXX_ETH: Initialising RX descriptors\n");
+ debug2_printf("&priv->ram->rx_descr[0]: 0x%08X\n",
+ (cyg_uint32)priv->ram->rx_descr);
+ debug2_printf("&priv->ram->rx_status[0]: 0x%08X\n",
+ (cyg_uint32)priv->ram->rx_status);
+ debug2_printf("No of TX descr: %d\n", CYGNUM_DEVS_ETH_ARM_LPC2XXX_RX_BUFS);
+
+ //
+ // Initialise RX descriptors - store pointers to receive buffers and
+ // RX status, two words, status info. and status hash CRC.
+ //
+ for (i = 0; i < CYGNUM_DEVS_ETH_ARM_LPC2XXX_RX_BUFS; ++i)
+ {
+ priv->ram->rx_descr[i].packet = (cyg_uint32)priv->ram->rx_buf[i].bytes;
+ debug2_printf("priv->ram->rx_descr[%d].packet (0x%08X) "
+ "= &priv->ram->rx_buf[%d].bytes[0] (0x%08X)\n",
+ i, (cyg_uint32)&priv->ram->rx_descr[i].packet,
+ i, (cyg_uint32)priv->ram->rx_buf[i].bytes);
+ priv->ram->rx_descr[i].control = (EMAC_RX_DESC_INT
+ | ((EMAC_BLOCK_SIZE - 1)
+ & DESC_SIZE_MASK));
+ debug2_printf("priv->ram->rx_descr[%d].control (0x%08X) = 0x%08X\n",
+ i, (cyg_uint32)&priv->ram->rx_descr[i].control,
+ priv->ram->rx_descr[i].control);
+ priv->ram->rx_status[i].info = 0;
+ priv->ram->rx_status[i].hash_crc = 0;
+ }
+
+ //
+ // Initialise RX pointers
+ //
+ HAL_WRITE_UINT32(EMAC_RXDESC, (cyg_uint32)priv->ram->rx_descr);
+ HAL_WRITE_UINT32(EMAC_RXSTAT, (cyg_uint32)priv->ram->rx_status);
+ HAL_WRITE_UINT32(EMAC_RXDESC_NUM, CYGNUM_DEVS_ETH_ARM_LPC2XXX_RX_BUFS - 1);
+ HAL_WRITE_UINT32(EMAC_RX_CONSUME_IDX, 0);
+}
+
+
+//===========================================================================
+// Set a specific address match to a given address. Packets received which
+// match this address will be passed on.
+//===========================================================================
+static void lpc2xxx_set_mac(lpc2xxx_eth_priv_t * priv, cyg_uint8 * enaddr)
+{
+ HAL_WRITE_UINT32(EMAC_SA0, (enaddr[5] << 8 | enaddr[4]));
+ HAL_WRITE_UINT32(EMAC_SA1, (enaddr[3] << 8 | enaddr[2]));
+ HAL_WRITE_UINT32(EMAC_SA2, (enaddr[1] << 8 | enaddr[0]));
+}
+
+
+//===========================================================================
+// This function is called to stop the interface.
+//===========================================================================
+static void lpc2xxx_eth_stop(struct eth_drv_sc *sc)
+{
+ cyg_uint32 regval;
+
+ // Disable the receiver and transmitter
+ HAL_READ_UINT32(EMAC_MAC1, regval);
+ HAL_WRITE_UINT32(EMAC_MAC1, regval & ~MAC1_RX_EN);
+ HAL_READ_UINT32(EMAC_CMD, regval);
+ HAL_WRITE_UINT32(EMAC_CMD, regval & ~(CMD_RX_ENABLE | CMD_TX_ENABLE));
+}
+
+
+//===========================================================================
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running.
+//===========================================================================
+static void
+lpc2xxx_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ cyg_uint32 regval;
+
+ //
+ // To prevent overflow in the receive DMA engine the receive DMA engine
+ // should be enabled by setting the RxEnable bit in the Command register
+ // before enabling the receive datapath in the MAC by setting the
+ // RECEIVE ENABLE bit in the MAC1 register
+ //
+ HAL_READ_UINT32(EMAC_CMD, regval);
+ HAL_WRITE_UINT32(EMAC_CMD, regval | CMD_RX_ENABLE | CMD_TX_ENABLE);
+ HAL_READ_UINT32(EMAC_MAC1, regval);
+ HAL_WRITE_UINT32(EMAC_MAC1, regval | MAC1_RX_EN);
+}
+
+
+//===========================================================================
+// Enable and Disable of the receiver and transmitter.
+// Initialize the interface. This configures the interface ready for use.
+// Interrupts are grabbed etc. This means the start function has
+// little to do except enable the receiver
+//===========================================================================
+static bool lpc2xxx_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ lpc2xxx_eth_priv_t *priv = (lpc2xxx_eth_priv_t *)sc->driver_private;
+ bool esa_ok = false;
+ unsigned char enaddr[6] = { CYGPKG_DEVS_ETH_ARM_LPC2XXX_MACADDR};
+ unsigned short phy_state = 0;
+ cyg_uint32 regval;
+
+ debug1_printf("\nLPC2XXX_ETH: Initialising 0x%08X\n",priv->base);
+
+ //
+ // turn on the ethernet MAC clock in PCONP, bit 30 and then do
+ // a short delay
+ //
+ HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE +
+ CYGARC_HAL_LPC24XX_REG_PCONP, regval);
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE +
+ CYGARC_HAL_LPC24XX_REG_PCONP,
+ regval | CYGARC_HAL_LPC24XX_REG_PCONP_ENET);
+ HAL_DELAY_US(50);
+
+ //
+ // Because of a device errate in Rev '-' devices we need to check the
+ // module ID to setup the RMII mode properly
+ //
+ HAL_READ_UINT32(EMAC_MODULE_ID, regval);
+ if (EMAC_OLD_MODULE_ID == regval)
+ {
+ //
+ // On Rev. '-', EMAC_MODULE_ID should be equal to
+ // EMAC_OLD_MODULE_ID, P1.6 should be set -
+ // selects P1[0,1,4,6,8,9,10,14,15]
+ //
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_PIN_BASE +
+ CYGARC_HAL_LPC24XX_REG_PINSEL2, 0x50151105);
+ }
+ else
+ {
+ //
+ // on Rev. 'A', EMAC_MODULE_ID should not equal to
+ // OLD_EMAC_MODULE_ID, P1.6 should not be set.
+ // selects P1[0,1,4,8,9,10,14,15]
+ //
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_PIN_BASE +
+ CYGARC_HAL_LPC24XX_REG_PINSEL2, 0x50150105);
+
+ } // if (EMAC_OLD_MODULE_ID == regval)
+
+ // selects P1[17:16]
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_PIN_BASE +
+ CYGARC_HAL_LPC24XX_REG_PINSEL3, 0x00000005);
+ //
+ // reset MAC modules, tx, mcs_tx, rx, mcs_rx, simulation and soft reset,
+ // reset datapaths and host registers, disable Tx and RX and do a
+ // short delay
+ //
+ HAL_WRITE_UINT32(EMAC_MAC1, MAC1_RESET_TX
+ | MAC1_RESET_MCS_TX
+ | MAC1_RESET_RX
+ | MAC1_RESET_MCS_RX
+ | MAC1_RESET_SIM
+ | MAC1_SOFT_RESET);
+ HAL_WRITE_UINT32(EMAC_CMD, CMD_REG_RESET
+ | CMD_TX_RESET
+ | CMD_RX_RESET);
+ HAL_DELAY_US(10);
+ HAL_WRITE_UINT32(EMAC_MAC1, 0x0);
+ lpc2xxx_eth_stop(sc); // disable transmitter and receiver
+
+ HAL_WRITE_UINT32(EMAC_MAC2, 0); // initialize MAC2 register to default val.
+ HAL_WRITE_UINT32(EMAC_IPGR, 0x12); // manual recommends value 0x12
+ HAL_WRITE_UINT32(EMAC_CLRT, 0x370F); // Using recommended value from manual.
+ HAL_WRITE_UINT32(EMAC_MAXF, 0x0600); // manual recommends value 0x600
+
+#ifdef CYGHWR_DEVS_ETH_ARM_LPC2XXX_GET_ESA
+ // Get MAC address from RedBoot configuration variables
+ CYGHWR_DEVS_ETH_ARM_LPC2XXX_GET_ESA(&enaddr[0], esa_ok);
+ // If this call fails myMacAddr is unchanged and MAC address from
+ // CDL is used
+#endif
+
+ if (!esa_ok)
+ {
+ // Can't figure out ESA
+ debug1_printf("LPC2XXX_ETH - Warning! ESA unknown\n");
+ }
+ debug1_printf("LPC2XXX_ETH: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ enaddr[0],enaddr[1],enaddr[2],
+ enaddr[3],enaddr[4],enaddr[5]);
+
+ // Give the EMAC its address
+ lpc2xxx_set_mac(priv, enaddr);
+
+ // Setup the PHY
+ CYG_ASSERTC(priv->phy);
+ if (!_eth_phy_init(priv->phy))
+ {
+ return (false);
+ }
+
+ // Get the current mode and print it
+ phy_state = _eth_phy_state(priv->phy);
+ if (phy_state & ETH_PHY_STAT_LINK)
+ {
+ cyg_uint32 cmd;
+ HAL_READ_UINT32(EMAC_CMD, cmd);
+ cmd |= CMD_PASS_RUNT_FRAME;
+ HAL_READ_UINT32(EMAC_SUPP, regval);
+ if (phy_state & ETH_PHY_STAT_100MB)
+ {
+ HAL_WRITE_UINT32(EMAC_SUPP, regval | SUPP_SPEED_100MB);
+ debug1_printf("LPC2XXX_ETH: 100Mbyte/s");
+ }
+ else
+ {
+ HAL_WRITE_UINT32(EMAC_SUPP, regval &~ SUPP_SPEED_100MB);
+ debug1_printf("LPC2XXX_ETH: 10Mbyte/s");
+ }
+ if(phy_state & ETH_PHY_STAT_FDX)
+ {
+ HAL_WRITE_UINT32(EMAC_MAC2, MAC2_FDX | MAC2_CRC_EN
+ | MAC2_PAD_CRC_EN);
+ // manual recommends value of 0x15 for FDX
+ HAL_WRITE_UINT32(EMAC_IPGT, 0x15);
+ cmd |= CMD_FULL_DUPLEX;
+ debug1_printf(" Full Duplex\n");
+ }
+ else
+ {
+ HAL_WRITE_UINT32(EMAC_MAC2, MAC2_CRC_EN | MAC2_PAD_CRC_EN);
+ // manual recommends value of 0x12 for HDX
+ HAL_WRITE_UINT32(EMAC_IPGT, 0x12);
+ debug1_printf(" Half Duplex\n");
+ }
+ HAL_WRITE_UINT32(EMAC_CMD, cmd);
+ }
+ else
+ {
+ debug1_printf("LPC2XXX_ETH: No Link\n");
+ }
+
+ lpc2xxx_eth_txdesc_init(priv);
+ lpc2xxx_eth_rxdesc_init(priv);
+
+ // set up the Rx filter
+ // [0]-AllUnicast, [1]-AllBroadCast, [2]-AllMulticast, [3]-UnicastHash
+ // [4]-MulticastHash, [5]-Perfect, [12]-MagicPacketEnWoL,
+ // [13]-RxFilterEnWoL
+ HAL_WRITE_UINT32(EMAC_RXFILT_CTRL, RXFILT_CTRL_ACC_BROADCAST
+ | RXFILT_CTRL_ACC_PERFECT);
+ //
+ // If we are building an interrupt enabled version, install the
+ // interrupt handler
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ debug1_printf("LPC2XXX_ETH: Installing Interrupts on IRQ %d\n",
+ priv->intr_vector);
+ cyg_drv_interrupt_create(priv->intr_vector,
+ CYGPKG_DEVS_ETH_ARM_LPC2XXX_INTPRIO,
+ (cyg_addrword_t)sc,
+ lpc2xxx_eth_isr,
+ eth_drv_dsr,
+ &priv->intr_handle,
+ &priv->intr);
+
+ cyg_drv_interrupt_attach(priv->intr_handle);
+ cyg_drv_interrupt_unmask(priv->intr_vector);
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+ // Initialize the upper layer driver
+ _eth_drv_init(sc, enaddr);
+
+ // clear all interrupts
+ HAL_WRITE_UINT32(EMAC_INT_CLR, 0xFFFF);
+
+ //
+ // Enable the interrupts we are interested in (not SoftInt and WoL)
+ // We only want interrupts if a whole frame was transmitted so we
+ // enable only the TXFINISHED interrupt and not the TXDONE interrupt
+ //
+ HAL_WRITE_UINT32(EMAC_INT_EN, EMAC_INT_RXOVERRUN
+ | EMAC_INT_RXFINISHED
+ | EMAC_INT_RXDONE
+ | EMAC_INT_TXUNDERRUN
+ | EMAC_INT_TXERROR
+ | EMAC_INT_TXFINISHED);
+
+ return (true);
+}
+
+
+//===========================================================================
+// This function is called for low level "control" operations
+//===========================================================================
+static int
+lpc2xxx_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int length)
+{
+ lpc2xxx_eth_priv_t *priv = (lpc2xxx_eth_priv_t *)sc->driver_private;
+ switch (key)
+ {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ {
+ if(length >= ETHER_ADDR_LEN)
+ {
+ lpc2xxx_eth_stop(sc);
+
+ cyg_uint8 * enaddr = (cyg_uint8 *)data;
+ debug1_printf("LPC2XXX_ETH: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ enaddr[0],enaddr[1],enaddr[2],
+ enaddr[3],enaddr[4],enaddr[5]);
+
+ lpc2xxx_set_mac(priv, enaddr);
+ lpc2xxx_eth_start(sc,enaddr,0);
+ return 0;
+ }
+ return 1;
+ }
+
+#ifdef CYGPKG_NET
+ case ETH_DRV_GET_IF_STATS:
+ {
+ // todo
+ }
+#endif
+
+ default:
+ {
+ diag_printf("%s.%d: key %lx\n", __FUNCTION__, __LINE__, key);
+ return (1);
+ }
+ } // switch (key)
+}
+
+
+//===========================================================================
+// This function is called to see if another packet can be sent.
+// It should return the number of packets which can be handled.
+// Zero should be returned if the interface is busy and can not send
+// any more.
+//===========================================================================
+static int lpc2xxx_eth_can_send(struct eth_drv_sc *sc)
+{
+ int can_send;
+ lpc2xxx_eth_priv_t *priv = (lpc2xxx_eth_priv_t *)sc->driver_private;
+ if (priv->tx_busy)
+ {
+ can_send = 0;
+ }
+ else
+ {
+ can_send = 1;
+ }
+
+ debug2_printf("can_send: %d\n", can_send);
+ return (can_send);
+}
+
+//===========================================================================
+// This routine is called to send data to the hardware
+// For tx the current code supports a single outgoing transmission at a
+// time. This does limit outgoing bandwidth a bit, but only a bit, and
+// saves memory and complexity.
+//===========================================================================
+static void
+lpc2xxx_eth_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list,
+ int sg_len,
+ int total_len,
+ unsigned long key)
+{
+ cyg_uint32 tx_producer_idx;
+ cyg_uint32 tx_consumer_idx;
+ cyg_uint32 tx_desc_ctrl;
+ lpc2xxx_eth_priv_t *priv = (lpc2xxx_eth_priv_t *)sc->driver_private;
+ int i;
+
+ priv->tx_busy = true;
+ //
+ // Store addresses of entries in scatter/gather list into tx descriptors
+ //
+ HAL_READ_UINT32(EMAC_TX_PROD_IDX, tx_producer_idx);
+ HAL_READ_UINT32(EMAC_TX_CONSUME_IDX, tx_consumer_idx);
+ debug2_printf("TPI: %d TCI: %d\n", tx_producer_idx, tx_consumer_idx);
+ debug2_printf("TX: sg_len %d, total_len %d, key 0x%08lX\n",
+ sg_len, total_len, key);
+ for(i = 0; i < sg_len; i++)
+ {
+ priv->ram->tx_descr[tx_producer_idx].packet = sg_list[i].buf;
+ tx_desc_ctrl = (sg_list[i].len - 1) | EMAC_TX_DESC_INT;
+ if (i == (sg_len - 1))
+ {
+ tx_desc_ctrl |= EMAC_TX_DESC_LAST;
+ }
+ priv->ram->tx_descr[tx_producer_idx].control = tx_desc_ctrl;
+ priv->ram->tx_status[tx_producer_idx] = 0;
+
+ tx_producer_idx = (tx_producer_idx + 1) %
+ CYGNUM_DEVS_ETH_ARM_LPC2XXX_TX_BUFS;
+ }
+
+ debug2_printf("TPI: %d TCI: %d\n", tx_producer_idx, tx_consumer_idx);
+ // Store away the key for the time when the transmit has completed
+ // and we need to tell the stack which transmit has completed
+ // and then start the transmitter by incrementing the tx producer
+ // index
+ priv->cur_tx_key = key;
+ HAL_WRITE_UINT32(EMAC_TX_PROD_IDX, tx_producer_idx);
+}
+
+
+//===========================================================================
+// EMAC ISR
+//===========================================================================
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32
+lpc2xxx_eth_isr (cyg_vector_t vector, cyg_addrword_t data)
+{
+ debug2_printf("ISR\n");
+ cyg_drv_interrupt_mask(vector);
+ cyg_interrupt_acknowledge(vector);
+ return CYG_ISR_CALL_DSR;
+}
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+
+//===========================================================================
+// The high level DSR thaqt does all the work
+//===========================================================================
+static void lpc2xxx_eth_deliver(struct eth_drv_sc *sc)
+{
+ lpc2xxx_eth_priv_t *priv = (lpc2xxx_eth_priv_t *)sc->driver_private;
+ cyg_uint32 intstatus;
+
+ HAL_READ_UINT32(EMAC_INT_STATUS, intstatus);
+#ifndef CYGPKG_REDBOOT
+ //
+ // In redbot the ethernet driver is polled and this debug message would
+ // pollute the redboot console
+ //
+ debug2_printf("INT_STATUS: %x\n", intstatus);
+#endif // CYGPKG_REDBOOT
+
+ if (intstatus & EMAC_INT_RXOVERRUN)
+ {
+ HAL_WRITE_UINT32(EMAC_INT_CLR, EMAC_INT_RXOVERRUN);
+ debug1_printf("LPC2XXX_ETH: RX overrun\n");
+ }
+
+ if (intstatus & EMAC_INT_TXUNDERRUN)
+ {
+ HAL_WRITE_UINT32(EMAC_INT_CLR, EMAC_INT_TXUNDERRUN);
+ debug1_printf("LPC2XXX_ETH: TX underrun\n");
+ }
+
+ if (intstatus & EMAC_INT_TXERROR)
+ {
+ cyg_uint32 tx_consumer_idx;
+ HAL_WRITE_UINT32(EMAC_INT_CLR, EMAC_INT_TXERROR);
+ HAL_READ_UINT32(EMAC_TX_CONSUME_IDX, tx_consumer_idx);
+ debug1_printf("LPC2XXX_ETH: TX error, status %08x\n",
+ priv->ram->tx_status[tx_consumer_idx]);
+ }
+
+ if (intstatus & EMAC_INT_SOFTINT)
+ {
+ HAL_WRITE_UINT32(EMAC_INT_CLR, EMAC_INT_SOFTINT);
+ }
+
+ if (intstatus & EMAC_INT_WOL)
+ {
+ HAL_WRITE_UINT32(EMAC_INT_CLR, EMAC_INT_WOL);
+ debug1_printf("LPC2XXX_ETH: WOL\n");
+ }
+
+ //
+ // TxFinishedInt
+ // Interrupt triggered when all transmit descriptors have been
+ // processed i.e. on the transition to the situation where
+ // ProduceIndex == ConsumeIndex.
+ //
+ if (intstatus & EMAC_INT_TXFINISHED)
+ {
+ HAL_WRITE_UINT32(EMAC_INT_CLR, EMAC_INT_TXFINISHED);
+ _eth_drv_tx_done(sc, priv->cur_tx_key, 0);
+ debug2_printf("TX finished - key: 0x%08X\n", priv->cur_tx_key);
+ priv->tx_busy = false;
+ }
+
+ //
+ // RxDoneInt
+ // Interrupt triggered when a receive descriptor has been processed
+ // while the Interrupt bit in the Control field of the descriptor was set.
+ //
+ if (intstatus & (EMAC_INT_RXDONE | EMAC_INT_RXFINISHED))
+ {
+ cyg_uint32 rx_producer_idx;
+ cyg_uint32 rx_consumer_idx;
+
+ HAL_WRITE_UINT32(EMAC_INT_CLR, EMAC_INT_RXDONE);
+ HAL_WRITE_UINT32(EMAC_INT_CLR, EMAC_INT_RXFINISHED);
+ HAL_READ_UINT32(EMAC_RX_PROD_IDX, rx_producer_idx);
+ HAL_READ_UINT32(EMAC_RX_CONSUME_IDX, rx_consumer_idx);
+ debug2_printf("\n\nRPIdx %d RCIdx %d\n", rx_producer_idx,
+ rx_consumer_idx);
+
+ //
+ // Iterate through array of rx descriptors to check if the end of
+ // frame was received.
+ //
+ while (priv->iterator != rx_producer_idx)
+ {
+ priv->total_len += ((priv->ram->rx_status[priv->iterator].info
+ & DESC_SIZE_MASK) + 1);
+ debug2_printf("total_len %d rx_status[%d] = %x rx_len %d\n",
+ priv->total_len, priv->iterator,
+ priv->ram->rx_status[priv->iterator].info,
+ ((priv->ram->rx_status[priv->iterator].info
+ & DESC_SIZE_MASK) + 1));
+ if (priv->ram->rx_status[priv->iterator].info & RX_DESC_STATUS_LAST)
+ {
+ //
+ // We found the end of the frame and have something to receive
+ // so we can call _eth_drv_recv() now
+ //
+ if (priv->total_len)
+ {
+ _eth_drv_recv(sc, priv->total_len);
+ HAL_READ_UINT32(EMAC_RX_CONSUME_IDX, rx_consumer_idx);
+ debug2_printf("RPIdx %d RCIdx %d Iterator %d\n",
+ rx_producer_idx, rx_consumer_idx,
+ priv->iterator);
+ priv->total_len = 0;
+ } // if (total_len)
+ else
+ {
+ //
+ // If we do not call _eth_drv_recv then we need to set the
+ // consumer index here to indicate that the buffers are
+ // free for reception
+ //
+ HAL_WRITE_UINT32(EMAC_RX_CONSUME_IDX, priv->iterator);
+ } // if (priv->total_len)
+ } // if (priv->ram->rx_status[iterator].info & RX_DESC_STATUS_LAST)
+ priv->iterator = (priv->iterator + 1) %
+ CYGNUM_DEVS_ETH_ARM_LPC2XXX_RX_BUFS;
+ }//if (priv->ram->rx_status[priv->iterator].info & RX_DESC_STATUS_LAST)
+
+ } // if (intstatus & EMAC_INT_RXDONE)
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_unmask(priv->intr_vector);
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+}
+
+
+//===========================================================================
+// This routine is called to receive data from the hardware
+//===========================================================================
+static void lpc2xxx_eth_recv(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list,
+ int sg_len)
+{
+ lpc2xxx_eth_priv_t *priv = (lpc2xxx_eth_priv_t *)sc->driver_private;
+ int i;
+ cyg_uint32 rx_producer_idx;
+ cyg_uint32 rx_consumer_idx;
+ cyg_uint32 bytes_in_buffer;
+ cyg_uint32 bytes_in_list = 0;
+ cyg_uint32 bytes_needed_list = 0;
+ cyg_uint32 buffer_pos = 0;
+ cyg_uint32 total_bytes = 0;
+ cyg_uint8 *sg_buf;
+ cyg_uint8 *hw_rxbuf;
+
+ HAL_READ_UINT32(EMAC_RX_PROD_IDX, rx_producer_idx);
+ HAL_READ_UINT32(EMAC_RX_CONSUME_IDX, rx_consumer_idx);
+ debug2_printf("lpc2xxx_eth_recv: sg_len %d\n", sg_len);
+
+ for(i = 0; i < sg_len; ++i)
+ {
+ bytes_in_list = 0;
+ while (bytes_in_list < sg_list[i].len)
+ {
+ bytes_needed_list = sg_list[i].len - bytes_in_list;
+ debug2_printf("bil: %d sg_list[%d].len: %d bnl: %d\n",
+ bytes_in_list,
+ i,
+ sg_list[i].len,
+ bytes_needed_list);
+ bytes_in_buffer = (priv->ram->rx_status[rx_consumer_idx].info &
+ DESC_SIZE_MASK) + 1;
+ debug2_printf("bib: %d buffer_pos: %d\n", bytes_in_buffer,
+ buffer_pos);
+ bytes_in_buffer -= buffer_pos;
+ sg_buf = (cyg_uint8 *)(sg_list[i].buf);
+ hw_rxbuf = (cyg_uint8 *)priv->ram->rx_buf[rx_consumer_idx].bytes;
+ if(bytes_needed_list < bytes_in_buffer)
+ {
+ if(sg_buf)
+ {
+ debug2_printf("(1) memcpy(0x%08X, 0x%08X, %d) "
+ "[0x%08X - 0x%08X]\n",
+ (cyg_uint32)&sg_buf[bytes_in_list],
+ (cyg_uint32)&hw_rxbuf[buffer_pos],
+ bytes_needed_list,
+ (cyg_uint32)&sg_buf[bytes_in_list],
+ (cyg_uint32)&sg_buf[bytes_in_list] +
+ bytes_needed_list);
+
+ memcpy(&sg_buf[bytes_in_list],
+ (cyg_uint8 *)&hw_rxbuf[buffer_pos],
+ bytes_needed_list);
+ }
+ bytes_in_list += bytes_needed_list;
+ buffer_pos += bytes_needed_list;
+ total_bytes += bytes_needed_list;
+ }
+ else
+ {
+ if(sg_buf)
+ {
+ debug2_printf("(2) memcpy(0x%08X, 0x%08X, %d)"
+ "[0x%08X - 0x%08X]\n",
+ (cyg_uint32)&sg_buf[bytes_in_list],
+ (cyg_uint32)&hw_rxbuf[buffer_pos],
+ bytes_in_buffer,
+ (cyg_uint32)&sg_buf[bytes_in_list],
+ (cyg_uint32)&sg_buf[bytes_in_list] +
+ bytes_in_buffer);
+
+ memcpy(&sg_buf[bytes_in_list],
+ (cyg_uint8 *)&hw_rxbuf[buffer_pos],
+ bytes_in_buffer);
+ }
+ priv->ram->rx_status[rx_consumer_idx].info = 0;
+ priv->ram->rx_status[rx_consumer_idx].hash_crc = 0;
+ rx_consumer_idx = (rx_consumer_idx + 1) %
+ CYGNUM_DEVS_ETH_ARM_LPC2XXX_RX_BUFS;
+ HAL_WRITE_UINT32(EMAC_RX_CONSUME_IDX, rx_consumer_idx);
+ debug2_printf("RCIdx++ %d\n", rx_consumer_idx);
+ bytes_in_list += bytes_in_buffer;
+ total_bytes += bytes_in_buffer;
+ buffer_pos = 0;
+ if (bytes_in_list < sg_list[i].len)
+ {
+ debug2_printf("bytes_in_list < sg_list[i].len");
+ }
+ }
+ } // while (bytes_in_list < sg_list[i].len)
+ } // for(i = 0; i < sg_len; ++i)
+}
+
+
+//===========================================================================
+// routine called to handle ethernet controller in polled mode
+//===========================================================================
+static void lpc2xxx_eth_poll(struct eth_drv_sc *sc)
+{
+ lpc2xxx_eth_deliver(sc);
+}
+
+
+//===========================================================================
+// routine called to handle ethernet controller in polled mode
+//===========================================================================
+static int lpc2xxx_eth_int_vector(struct eth_drv_sc *sc)
+{
+ return CYGNUM_HAL_INTERRUPT_ETH;
+}
+
+
+//===========================================================================
+// Ethernet driver instance
+//===========================================================================
+ETH_DRV_SC(lpc2xxx_sc,
+ &lpc2xxx_priv_data, // Driver specific data
+ "eth0", // Name for this interface
+ lpc2xxx_eth_start,
+ lpc2xxx_eth_stop,
+ lpc2xxx_eth_control,
+ lpc2xxx_eth_can_send,
+ lpc2xxx_eth_send,
+ lpc2xxx_eth_recv,
+ lpc2xxx_eth_deliver,
+ lpc2xxx_eth_poll,
+ lpc2xxx_eth_int_vector);
+
+NETDEVTAB_ENTRY(lpc2xxx_netdev,
+ "lpc2xxx",
+ lpc2xxx_eth_init,
+ &lpc2xxx_sc);
+//---------------------------------------------------------------------------
+// EOF if_lpc2xxx.c
diff --git a/ecos/packages/devs/eth/arm/nano/current/ChangeLog b/ecos/packages/devs/eth/arm/nano/current/ChangeLog
new file mode 100644
index 0000000..5f98025
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/nano/current/ChangeLog
@@ -0,0 +1,78 @@
+2001-05-02 Hugo Tyson <hmt@redhat.com>
+
+ * include/devs_eth_nano.inl: Because we now arrange PCI window
+ memory distant from normal RAM, it can be scattered in physical
+ RAM. So define CYGHWR_DEVS_ETH_INTEL_I82559_PCIMEM_DISCONTIGUOUS.
+ This is not really needed by default with only 1Mb of PCI window,
+ but the overhead is small.
+
+2001-03-15 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/nano_eth_drivers.cdl: New component defined here because
+ it's platform dependent whether it's relevent, to control
+ additional variables in RedBoot's flash config system.
+ (CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA): the new component.
+ (CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0): and so on,
+ control whether we create flash config variables here.
+
+ * include/devs_eth_nano.inl: Define flash config variables, and
+ macro to access them from the generic driver, called
+ CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA(p_i82559,mac_address,ok).
+
+2001-03-13 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/nano_eth_drivers.cdl (CYGPKG_DEVS_ETH_ARM_NANO_ETH1):
+ enabled by default; full demux ability now supported in generic
+ device.
+
+2001-03-12 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/nano_eth_drivers.cdl (CYGPKG_DEVS_ETH_ARM_NANO_ETH1):
+ disabled by default. The DEMUXing stuff for dealing with the fact
+ that both devices are connected to GPIO0 is incomplete in the
+ generic driver.
+
+ * include/devs_eth_nano.inl: Add additional macros to get
+ platform-required behaviour:
+ (CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT): Poll for a missed
+ interrupt by examining the level-attached GPIO lines.
+ (CYGHWR_DEVS_ETH_INTEL_I82559_RESET_TIMEOUT):
+ (CYGHWR_DEVS_ETH_INTEL_I82559_TIMEOUT_FIRED): Set and test timing
+ compared to the ever-incrementing system OS timer *SA11X0_OSCR.
+ (CYGPRI_DEVS_ETH_INTEL_I82559_MASK_INTERRUPTS):
+ (CYGPRI_DEVS_ETH_INTEL_I82559_UNMASK_INTERRUPTS):
+ (CYGPRI_DEVS_ETH_INTEL_I82559_ACK_INTERRUPTS): Rename local
+ interrupt handing macros.
+
+2001-03-01 Hugo Tyson <hmt@redhat.com>
+
+ * include/devs_eth_nano.inl: New file.
+ * cdl/nano_eth_drivers.cdl: New file.
+ Platform specific information required to use the generic i82559
+ driver for the BSE nanoEngine/nanoBridge SA1110 platform.
+ This requires more configurability of the generic i82559
+ introduced on the same date.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/nano/current/cdl/nano_eth_drivers.cdl b/ecos/packages/devs/eth/arm/nano/current/cdl/nano_eth_drivers.cdl
new file mode 100644
index 0000000..c75dd37
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/nano/current/cdl/nano_eth_drivers.cdl
@@ -0,0 +1,208 @@
+# ====================================================================
+#
+# nano_eth_drivers.cdl
+#
+# Ethernet drivers - support for i82559 ethernet controller
+# on the BSE nanoEngine board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov, hmt
+# Date: 2001-02-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_NANO {
+ display "BSE nanoEngine ethernet driver"
+ description "
+ Ethernet driver for BSE nanoEngine board with one or two Intel
+ i82559 Ethernet controllers attached via the BSE nanoBridge PCI
+ glue chip."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_SA11X0_NANO
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82559 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
+ display "Intel i82559 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_nano.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_arm_nano.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_NANO_ETH0 {
+ display "Nano ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ nanoEngine or nanoBridge port 0 - that is the connector one
+ slot in from the corner of the board, or the only connector
+ depending on your particular hardware."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_NANO_ETH0_NAME {
+ display "Device name for the ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_NANO_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value !CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA, and if RedBoot's
+ flash configuration support is not available."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_NANO_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x11}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_NANO_ETH1 {
+ display "Nano ethernet port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ nanoBridge port 1 - that is the connector on the corner of
+ the board, far from the power jack and reset button."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH1
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_NANO_ETH1_NAME {
+ display "Device name for the ethernet port 1 driver"
+ flavor data
+ default_value {"\"eth1\""}
+ description "
+ This option sets the name of the ethernet device for the
+ ethernet port 1."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_NANO_ETH1_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value !CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA, and if RedBoot's
+ flash configuration support is not available."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_NANO_ETH1_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x12}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+
+ # note that this option's name is NOT nano-specific, but i82559
+ # generic - other instantiations can set these also.
+ cdl_component CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 1
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+ description "Enabling this option will allow the ethernet
+ station address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually by the
+ 'Set the ethernet station address' option for each interface."
+
+ cdl_component CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_VARS {
+ display "Build-in flash config fields for ESAs"
+ flavor bool
+ default_value 1
+
+ active_if CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT_FLASH
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+
+ description "
+ This option controls the presence of RedBoot flash
+ configuration fields for the ESAs of the interfaces when you
+ are building RedBoot. It is independent of whether RedBoot
+ itself uses the network or any particular interface; this
+ support is more for the application to use than for RedBoot
+ itself, though the application gets at the data by vector
+ calls; this option cannot be enabled outside of building
+ RedBoot."
+
+ cdl_option CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 1
+ }
+ cdl_option CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH1 {
+ display "RedBoot manages ESA for eth1"
+ flavor bool
+ default_value 1
+ }
+ }
+ }
+}
+
+# EOF nano_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/arm/nano/current/include/devs_eth_nano.inl b/ecos/packages/devs/eth/arm/nano/current/include/devs_eth_nano.inl
new file mode 100644
index 0000000..bf03642
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/nano/current/include/devs_eth_nano.inl
@@ -0,0 +1,288 @@
+//==========================================================================
+//
+// devs/eth/arm/nano/..../include/devs_eth_nano.inl
+//
+// nanoBridge ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, hmt
+// Contributors: jskov
+// Date: 2001-02-28
+// Purpose: nanoBridge ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_...
+
+// --------------------------------------------------------------
+// Platform specifics:
+
+#if 1 < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT
+#define CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+#endif // multiple devs, so demux_all needed
+
+// define multiple interrupt handling anyway:
+
+#define CYGHWR_DEVS_ETH_INTRS (SA11X0_GPIO_PIN_0 + SA11X0_GPIO_PIN_1)
+
+// This brings in code to ensure missed interrupts are properly
+// acknowledged so that another interrupt can occur in future.
+// Only a problem with edge-triggered systems.
+
+#define CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT(p_i82559) \
+ (CYGHWR_DEVS_ETH_INTRS != (CYGHWR_DEVS_ETH_INTRS & *SA11X0_GPIO_PIN_LEVEL))
+
+// This brings on code to perform a selective reset on the device if the CU
+// wedges.
+
+#define CYGHWR_DEVS_ETH_INTEL_I82559_DEAD_TO (368640) // 0.1S of OS timer
+
+#define CYGHWR_DEVS_ETH_INTEL_I82559_RESET_TIMEOUT( anon_uint ) \
+CYG_MACRO_START \
+ (anon_uint) = *SA11X0_OSCR; \
+CYG_MACRO_END
+
+#define CYGHWR_DEVS_ETH_INTEL_I82559_TIMEOUT_FIRED( anon_uint ) \
+ ((*SA11X0_OSCR - (anon_uint)) > CYGHWR_DEVS_ETH_INTEL_I82559_DEAD_TO)
+
+// The mask on an SA1110 is really an enable: 1 => enabled, 0 => masked.
+// So to behave nestedly, we only need save the old value of the bits
+// of interest.
+
+#define CYGPRI_DEVS_ETH_INTEL_I82559_MASK_INTERRUPTS(p_i82559,old) \
+CYG_MACRO_START \
+ int cpu; \
+ HAL_DISABLE_INTERRUPTS( cpu ); \
+ old = *SA11X0_ICMR; \
+ *SA11X0_ICMR = old & ~CYGHWR_DEVS_ETH_INTRS; \
+ old &= CYGHWR_DEVS_ETH_INTRS; /* old val */ \
+ HAL_RESTORE_INTERRUPTS( cpu ); \
+CYG_MACRO_END
+
+#define CYGPRI_DEVS_ETH_INTEL_I82559_UNMASK_INTERRUPTS(p_i82559,old) \
+CYG_MACRO_START \
+ int cpu; \
+ HAL_DISABLE_INTERRUPTS( cpu ); \
+ (*SA11X0_ICMR |= (old & CYGHWR_DEVS_ETH_INTRS)); \
+ HAL_RESTORE_INTERRUPTS( cpu ); \
+CYG_MACRO_END
+
+#define CYGPRI_DEVS_ETH_INTEL_I82559_ACK_INTERRUPTS(p_i82559) \
+CYG_MACRO_START \
+ /* Remove the latched edge in the PIC: */ \
+ *SA11X0_GPIO_EDGE_DETECT_STATUS = CYGHWR_DEVS_ETH_INTRS; \
+CYG_MACRO_END
+
+
+// --------------------------------------------------------------
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE CYGHWR_HAL_ARM_NANO_PCI_MEM_MAP_BASE
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE CYGHWR_HAL_ARM_NANO_PCI_MEM_MAP_SIZE
+
+#define CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS( _x_ ) \
+ (((cyg_uint32)(_x_)) - CYGHWR_HAL_ARM_NANO_PCI_MEM_MAP_BASE + cyg_pci_window_real_base)
+
+// support SDRAM with gaps in it cos of the way PCI window is laid out.
+#define CYGHWR_DEVS_ETH_INTEL_I82559_PCIMEM_DISCONTIGUOUS
+
+// --------------------------------------------------------------
+// Construct the two interfaces
+
+#ifdef CYGPKG_DEVS_ETH_ARM_NANO_ETH0
+
+static I82559 i82559_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_ARM_NANO_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_ARM_NANO_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc0,
+ &i82559_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_NANO_ETH0_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev0,
+ "i82559_" CYGDAT_DEVS_ETH_ARM_NANO_ETH0_NAME,
+ i82559_init,
+ &i82559_sc0);
+
+#endif // CYGPKG_DEVS_ETH_ARM_NANO_ETH0
+
+#ifdef CYGPKG_DEVS_ETH_ARM_NANO_ETH1
+
+static I82559 i82559_eth1_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_ARM_NANO_ETH1_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_ARM_NANO_ETH1_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc1,
+ &i82559_eth1_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_NANO_ETH1_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev1,
+ "i82559_" CYGDAT_DEVS_ETH_ARM_NANO_ETH1_NAME,
+ i82559_init,
+ &i82559_sc1);
+
+#endif // CYGPKG_DEVS_ETH_ARM_NANO_ETH1
+
+// --------------------------------------------------------------
+// These arrays are used for sanity checking of pointers
+I82559 *
+i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_NANO_ETH0
+ &i82559_eth0_priv_data,
+#endif
+#ifdef CYGPKG_DEVS_ETH_ARM_NANO_ETH1
+ &i82559_eth1_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_NANO_ETH0
+ &i82559_netdev0,
+#endif
+#ifdef CYGPKG_DEVS_ETH_ARM_NANO_ETH1
+ &i82559_netdev1,
+#endif
+};
+
+struct eth_drv_sc *
+i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_NANO_ETH0
+ &i82559_sc0,
+#endif
+#ifdef CYGPKG_DEVS_ETH_ARM_NANO_ETH1
+ &i82559_sc1,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// --------------------------------------------------------------
+// Debugging
+
+//#define CYGDBG_DEVS_ETH_INTEL_I82559_CHATTER 1
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// tell the driver there is no EEPROM on this board
+#define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+
+// Decide whether to have redboot config vars for it...
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#ifdef CYGPKG_REDBOOT_NETWORKING
+#include <redboot.h>
+#include <flash_config.h>
+
+#ifdef CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif
+
+#ifdef CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH1
+RedBoot_config_option("Network hardware address [MAC] for eth1",
+ eth1_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif
+
+#endif
+#endif
+#endif
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+
+#include <cyg/hal/hal_if.h>
+
+#ifndef CONFIG_ESA
+#define CONFIG_ESA (6)
+#endif
+
+#define CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA( p_i82559, mac_address, ok ) \
+CYG_MACRO_START \
+ ok = false; \
+ if ( 0 == p_i82559->index ) \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa", mac_address, CONFIG_ESA); \
+ else if ( 1 == p_i82559->index ) \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth1_esa", mac_address, CONFIG_ESA); \
+CYG_MACRO_END
+
+#endif // CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+
+// --------------------------------------------------------------
+
+// EOF devs_eth_nano.inl
diff --git a/ecos/packages/devs/eth/arm/netarm/current/ChangeLog b/ecos/packages/devs/eth/arm/netarm/current/ChangeLog
new file mode 100644
index 0000000..ef97c0d
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/ChangeLog
@@ -0,0 +1,34 @@
+2005-11-17 Harald Brandl <Harald.Brandl@fh-joanneum.at>
+
+ * Fixed data alignment problems. Cleaned up the naming of
+ functions to avoid name space pollution. Us the HAL macros to
+ access the hardware.
+
+2005-06-12 Harald Brandl <Harald.Brandl@fh-joanneum.at>
+
+ * First import of an ethernet device driver for the NETARM
+ processors.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/netarm/current/cdl/netarm_eth_driver.cdl b/ecos/packages/devs/eth/arm/netarm/current/cdl/netarm_eth_driver.cdl
new file mode 100755
index 0000000..2c3cbf3
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/cdl/netarm_eth_driver.cdl
@@ -0,0 +1,137 @@
+# ====================================================================
+#
+# netarm_eth_driver.cdl
+#
+# Ethernet driver
+# NET+ARM ethernet interface
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Harald Brandl (harald.brandl@fh-joanneum.at)
+# Original data:
+# Contributors:
+# Date: 01.08.2004
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_NETARM {
+ display "NetSilicon board ethernet driver"
+ description "Ethernet driver for NET+ARM."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+
+
+ compile -library=libextras.a MII.c netarm_eth_drv.c eeprom.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NETARM_CFG <pkgconf/devs_eth_arm_netarm.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_interface CYGSEM_DEVS_ETH_ARM_NETARM_ETH0_ESA {
+ no_define
+ requires 1 == CYGSEM_DEVS_ETH_ARM_NETARM_ETH0_ESA
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_NETARM_ETH0 {
+ display "Ethernet port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_NETARM_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ netarm ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_NETARM_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 1
+ implements CYGSEM_DEVS_ETH_ARM_NETARM_ETH0_ESA
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_NETARM_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0x40, 0xaf, 0x77, 0xe0, 0x80}"}
+ description "The ethernet station address"
+ }
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_NETARM_ETH0_ESA_EEPROM {
+ display "Read ethernet station address from eeprom"
+ flavor bool
+ default_value 0
+ implements CYGSEM_DEVS_ETH_ARM_NETARM_ETH0_ESA
+ description "Read ethernet station address from eeprom (I2C)"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_NETARM_OPTIONS {
+ display "NETARM ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_ARM_NETARM_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the NETARM ethernet driver
+ package. These flags are used in addition to the set of
+ global flags."
+ }
+ }
+ }
+}
+
+# EOF netarm_eth_driver.cdl
diff --git a/ecos/packages/devs/eth/arm/netarm/current/doc/netarm_hal.patch b/ecos/packages/devs/eth/arm/netarm/current/doc/netarm_hal.patch
new file mode 100755
index 0000000..f653e8a
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/doc/netarm_hal.patch
@@ -0,0 +1,535 @@
+diff -Naur orig/hal/arm/netarm/current/cdl/hal_arm_netarm.cdl new/hal/arm/netarm/current/cdl/hal_arm_netarm.cdl
+--- orig/hal/arm/netarm/current/cdl/hal_arm_netarm.cdl 2004-11-29 17:35:46.000000000 +0100
++++ new/hal/arm/netarm/current/cdl/hal_arm_netarm.cdl 2005-03-10 14:54:13.903367200 +0100
+@@ -18,6 +18,26 @@
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_arm_netarm.h>"
+ }
+
++ cdl_option CYGSEM_HAL_INSTRUCTION_CACHE_SETS {
++ display "Sets for Instruction Cache"
++ parent CYGPKG_HAL_CACHE_CONTROL
++ active_if CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
++ flavor data
++ legal_values 0 to 15
++ default_value 0xc
++ description "MSB: SET1 | SET2 | SET3 | SET4"
++ }
++
++ cdl_option CYGSEM_HAL_DATA_CACHE_SETS {
++ display "Sets for Data Cache"
++ parent CYGPKG_HAL_CACHE_CONTROL
++ active_if CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
++ flavor data
++ legal_values 0 to 15
++ default_value 0x3
++ description "MSB: SET1 | SET2 | SET3 | SET4"
++ }
++
+ cdl_component CYG_HAL_STARTUP {
+ display "Startup type"
+ flavor data
+diff -Naur orig/hal/arm/netarm/current/include/hal_cache.h new/hal/arm/netarm/current/include/hal_cache.h
+--- orig/hal/arm/netarm/current/include/hal_cache.h 2004-11-29 17:35:46.000000000 +0100
++++ new/hal/arm/netarm/current/include/hal_cache.h 2005-03-10 14:41:51.032173600 +0100
+@@ -19,25 +19,57 @@
+ #define HAL_ICACHE_WAYS 4 // Associativity of the cache
+ #define HAL_ICACHE_LINE_SIZE 4 // Size of a cache line
+
+-#define HAL_ICACHE_BASE 0x08000000
+-#define HAL_ICACHE_MASK 0xfe000000
++#if defined(CYG_HAL_STARTUP_ROMRAM) || defined(CYG_HAL_STARTUP_RAM)
++ #define HAL_ICACHE_BASE 0x04000000
++ #define HAL_DCACHE_BASE 0x08000000
++#else
++ #define HAL_ICACHE_BASE 0x02000000
++ #define HAL_DCACHE_BASE 0x04000000
++#endif
++
++#define HAL_ICACHE_MASK 0xff000000
++#define HAL_DCACHE_MASK 0xff000000
++
++
++#ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
++ #define HAL_ICACHE_ENABLE() \
++ { \
++ *(CCR0)=(HAL_ICACHE_BASE) | \
++ (HAL_ICACHE_MASK >> 8) | \
++ (CCR_ENABLE) | \
++ (1 << 11) | \
++ (CYGSEM_HAL_INSTRUCTION_CACHE_SETS); \
++ }
++#else
++ #define HAL_ICACHE_ENABLE() (*(CCR0)=0)
++#endif
+
+-#define HAL_ICACHE_ENABLE() \
++#ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
++ #define HAL_DCACHE_ENABLE() \
++ { \
++ *(CCR1)=(HAL_DCACHE_BASE) | \
++ (HAL_DCACHE_MASK >> 8) | \
++ (CCR_ENABLE) | \
++ (1 << 11) | \
++ (CYGSEM_HAL_DATA_CACHE_SETS); \
++ }
++#else
++ #define HAL_DCACHE_ENABLE() (*(CCR1)=0)
++#endif
++
++#define HAL_CACHE_ENABLE() \
+ { \
+ unsigned int *p; \
+ int i; \
+ \
+ *(SYSCON)|=SYSCON_CINIT|SYSCON_CACHE; \
+ p=(unsigned int *)0xfff00000; \
+- for(i=0;i<(0x2000/4);i++,p++) \
++ for(i=0;i<(0x4000/4);i++,p++) \
+ *p=0; \
+ \
+- *(SYSCON)&=~(SYSCON_CINIT); \
+- *(CCR0)=(HAL_ICACHE_BASE) | \
+- (HAL_ICACHE_MASK >> 8) | \
+- (CCR_ENABLE) | \
+- (CCR_SET1 | CCR_SET2 | CCR_SET3 | CCR_SET4); \
+- *(CCR1)=0; \
++ HAL_ICACHE_ENABLE(); \
++ HAL_DCACHE_ENABLE(); \
++ \
+ *(SYSCON)|=SYSCON_CACHE; \
+ *(SYSCON)&=~SYSCON_WB; \
+ }
+@@ -45,17 +77,25 @@
+ #define HAL_ICACHE_DISABLE() \
+ { \
+ *(CCR0)=0; \
+- *(SYSCON)&=~SYSCON_CACHE; \
++ if (HAL_DCACHE_IS_ENABLED == 0) \
++ *(SYSCON)&=~SYSCON_CACHE; \
+ }
+
+-#define HAL_ICACHE_IS_ENABLED(_state_) _state_ = ((*(CCR0) & CCR_ENABLE) >> 15)
++#define HAL_DCACHE_DISABLE() \
++{ \
++ *(CCR1)=0; \
++ if (HAL_ICACHE_IS_ENABLED == 0) \
++ *(SYSCON)&=~SYSCON_CACHE; \
++}
++
++#define HAL_ICACHE_IS_ENABLED ((*(CCR0) & CCR_ENABLE) >> 15)
+
+-#define HAL_ICACHE_INVALIDATE_ALL() \
++#define HAL_CACHE_INVALIDATE_ALL() \
+ { \
+ unsigned *p; \
+ *(SYSCON)|=SYSCON_CINIT; \
+ for(p=(unsigned int*)0xfff00000; \
+- (unsigned int)p<0xfff02000; \
++ (unsigned int)p<0xfff04000; \
+ p++) \
+ *p=0; \
+ \
+@@ -64,25 +104,13 @@
+
+ #define HAL_ICACHE_SYNC()
+
+-#define HAL_ICACHE_PURGE_ALL() HAL_ICACHE_INVALIDATE_ALL()
+-
+-#define HAL_DCACHE_LINE_SIZE 0
+-#define HAL_DCACHE_WAYS 0
+-#define HAL_DCACHE_SETS 0
+-
+-#define HAL_DCACHE_ENABLE()
++#define HAL_CACHE_PURGE_ALL() HAL_ICACHE_INVALIDATE_ALL()
+
+-#define HAL_DCACHE_DISABLE()
+-
+-#define HAL_DCACHE_INVALIDATE_ALL()
++#define HAL_DCACHE_LINE_SIZE 4
++#define HAL_DCACHE_WAYS 4
+
+ #define HAL_DCACHE_SYNC()
+
+-#define HAL_DCACHE_IS_ENABLED(_state_) 0
+-
+-#define HAL_DCACHE_FLUSH( _base_ , _size_ )
+-
+-#define HAL_DCACHE_STORE( _base_ , _size_ )
++#define HAL_DCACHE_IS_ENABLED ((*(CCR1) & CCR_ENABLE) >> 15)
+
+ #endif
+-
+diff -Naur orig/hal/arm/netarm/current/include/hal_platform_setup.h new/hal/arm/netarm/current/include/hal_platform_setup.h
+--- orig/hal/arm/netarm/current/include/hal_platform_setup.h 2004-11-29 17:35:46.000000000 +0100
++++ new/hal/arm/netarm/current/include/hal_platform_setup.h 2005-03-15 12:20:27.760534400 +0100
+@@ -19,7 +19,7 @@
+ // Usage: #include <cyg/hal/hal_platform_setup.h>
+ //
+ //####DESCRIPTIONEND####
+-//
++//
+ //===========================================================================*/
+
+ #include <pkgconf/system.h> // System-wide configuration info
+@@ -34,15 +34,31 @@
+ bic r0,r0, #((\x & 3)<<1); \
+ str r0,[r1]
+
+-#if defined(CYG_HAL_STARTUP_ROMRAM)
++#if defined(CYG_HAL_STARTUP_ROMRAM)
+ #define HAL_FLASH_PHYS_ADDR 0x02000000
+-#define UNMAPPED(x) ((x)-0x08000000)
++#define UNMAPPED(x) ((x)-0x04000000)
+ #elif defined(CYG_HAL_STARTUP_ROM)
+ #define HAL_FLASH_PHYS_ADDR 0x02000000
+ #define UNMAPPED(x) ((x)-0x02000000)
+ #endif
+ .macro PLATFORM_SETUP1
+-
++
++ ldr r1,=0xffb0000c // software reset
++ ldr r0,=0x00000123
++ str r0,[r1]
++ ldr r0,=0x00000321
++ str r0,[r1]
++
++ mov r0,#1000
++loop:
++ sub r0,r0,#1
++ cmp r0,#0
++ bne loop
++
++ ldr r0,=0x00000123
++ str r0,[r1]
++ ldr r0,=0x00000321
++ str r0,[r1]
+
+ #if defined(CYG_HAL_STARTUP_ROMRAM) || defined(CYG_HAL_STARTUP_ROM)
+ mov r1,#0xff000000
+@@ -51,7 +67,11 @@
+ ldr r0,=0x4004a800 /* System control register */
+ str r0,[r1]
+
+- mov r0,#0 /* PLL config */
++#ifdef CYG_HAL_STARTUP_ROM /* PLL config */
++ mov r0,#0
++#else
++ ldr r0,=0x09000e1e
++#endif
+ str r0,[r1,#8]
+
+ ldr r0,=0xfff00000 /* PORT A mode & dir */
+@@ -64,7 +84,7 @@
+ str r0,[r1,#0x28]
+
+ add r1,r1,#0x100000 /* Setup MEM Module base addr */
+-
++
+ ldr r0,=0x148C0000 /* Memory Module Config register */
+ str r0,[r1]
+
+@@ -79,7 +99,7 @@
+ ldr r0,=0xf3f00304 /* CS0 Option register */
+ str r0,[r1,#0x14]
+
+- ldr r0,=0x02000001 /* CS0 Base Address register */
++ ldr r0,=0x02000001 /* CS0 Base Address register */
+ str r0,[r1,#0x10]
+
+ mov pc,r2 /* Jump to new flash base */
+@@ -92,7 +112,7 @@
+
+ /* Configure SDRAM */
+
+- ldr r0,=0xf38000b0 /* CS1 Option register, BLEN=11 */
++ ldr r0,=0xf3000070 /* CS1 Option register, BLEN=11 */
+ str r0,[r1,#0x24]
+
+ ldr r0,=0x0000022d /* CS1 Base Address register */
+@@ -110,7 +130,7 @@
+ #if defined(CYG_HAL_STARTUP_ROMRAM)
+ mov r1,#0
+ mov r2,#HAL_FLASH_PHYS_ADDR
+- ldr r3,=(__heap1 - 0x04000000 + HAL_FLASH_PHYS_ADDR)
++ ldr r3,=(__heap1 - 0x08000000 + HAL_FLASH_PHYS_ADDR)
+
+ mov r4,#0
+ mov r6,#0
+@@ -129,11 +149,11 @@
+ nop
+ nop
+ nop
+-30:
++30:
+ #endif
+
+ #endif
+ .endm
+-
++
+ #endif
+
+diff -Naur orig/hal/arm/netarm/current/include/pkgconf/mlt_arm_netarm_ram.ldi new/hal/arm/netarm/current/include/pkgconf/mlt_arm_netarm_ram.ldi
+--- orig/hal/arm/netarm/current/include/pkgconf/mlt_arm_netarm_ram.ldi 2004-11-29 17:35:46.000000000 +0100
++++ new/hal/arm/netarm/current/include/pkgconf/mlt_arm_netarm_ram.ldi 2005-03-10 14:56:07.137708600 +0100
+@@ -3,34 +3,32 @@
+ MEMORY
+ {
+ noncacheram : ORIGIN = 0, LENGTH = 16*1024*1024
+- dataram : ORIGIN = 0x4000000, LENGTH = 16*1024*1024
+- codecacheram : ORIGIN = 0x8000000, LENGTH = 16*1024*1024
++ codecacheram : ORIGIN = 0x4000000, LENGTH = 16*1024*1024
++ datacacheram : ORIGIN = 0x8000000, LENGTH = 16*1024*1024
+ }
+
+ SECTIONS
+ {
+ SECTIONS_BEGIN
+- _dataram = 0x4000000;
++ _dataram = 0x8000000;
+ SECTION_rom_vectors (nocacheram, 0x0, LMA_EQ_VMA)
+ SECTION_fixed_vectors (nocacheram, ALIGN (0x4), LMA_EQ_VMA)
+- code_start = . + 0x8000000;
+- SECTION_text (codecacheram, code_start, AT (code_start - 0x8000000))
++ code_start = . + 0x4000000;
++ SECTION_text (codecacheram, code_start, AT (code_start - 0x4000000))
+ fini = .;
+- SECTION_fini (codecacheram, ALIGN (0x4), AT (fini - 0x8000000))
++ SECTION_fini (codecacheram, ALIGN (0x4), AT (fini - 0x4000000))
+ rodata = .;
+- SECTION_rodata (codecacheram, ALIGN (0x4), AT (rodata - 0x8000000))
++ SECTION_rodata (codecacheram, ALIGN (0x4), AT (rodata - 0x4000000))
+ rodata1 = .;
+- SECTION_rodata1 (codecacheram, ALIGN (0x4), AT (rodata1 - 0x8000000))
++ SECTION_rodata1 (codecacheram, ALIGN (0x4), AT (rodata1 - 0x4000000))
+ fixup = .;
+- SECTION_fixup (codecacheram, ALIGN (0x4), AT (fixup - 0x8000000))
++ SECTION_fixup (codecacheram, ALIGN (0x4), AT (fixup - 0x4000000))
+ gcc_except_table =.;
+- SECTION_gcc_except_table (codecacheram, ALIGN (0x4), AT (gcc_except_table - 0x8000000))
+- data_start = ALIGN(0x4) - 0x4000000;
+- SECTION_data (dataram, data_start, AT (data_start - 0x4000000))
++ SECTION_gcc_except_table (codecacheram, ALIGN (0x4), AT (gcc_except_table - 0x4000000))
++ data_start = ALIGN(0x4) + 0x4000000;
++ SECTION_data (datacacheram, data_start, AT (data_start - 0x8000000))
+ bss = .;
+- SECTION_bss (dataram, ALIGN (0x4), AT (bss - 0x4000000))
++ SECTION_bss (datacacheram, ALIGN (0x4), AT (bss - 0x8000000))
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+ }
+-
+-
+diff -Naur orig/hal/arm/netarm/current/include/pkgconf/mlt_arm_netarm_romram.ldi new/hal/arm/netarm/current/include/pkgconf/mlt_arm_netarm_romram.ldi
+--- orig/hal/arm/netarm/current/include/pkgconf/mlt_arm_netarm_romram.ldi 2004-11-29 17:35:46.000000000 +0100
++++ new/hal/arm/netarm/current/include/pkgconf/mlt_arm_netarm_romram.ldi 2005-03-10 14:56:18.184583600 +0100
+@@ -3,34 +3,32 @@
+ MEMORY
+ {
+ noncacheram : ORIGIN = 0, LENGTH = 16*1024*1024
+- dataram : ORIGIN = 0x4000000, LENGTH = 16*1024*1024
+- codecacheram : ORIGIN = 0x8000000, LENGTH = 16*1024*1024
++ codecacheram : ORIGIN = 0x4000000, LENGTH = 16*1024*1024
++ datacacheram : ORIGIN = 0x8000000, LENGTH = 16*1024*1024
+ }
+
+ SECTIONS
+ {
+ SECTIONS_BEGIN
+- _dataram = 0x4000000;
++ _dataram = 0x8000000;
+ SECTION_rom_vectors (nocacheram, 0x0, LMA_EQ_VMA)
+ SECTION_fixed_vectors (nocacheram, ALIGN (0x4), LMA_EQ_VMA)
+- code_start = . + 0x8000000;
+- SECTION_text (codecacheram, code_start, AT (code_start - 0x8000000))
++ code_start = . + 0x4000000;
++ SECTION_text (codecacheram, code_start, AT (code_start - 0x4000000))
+ fini = .;
+- SECTION_fini (codecacheram, ALIGN (0x4), AT (fini - 0x8000000))
++ SECTION_fini (codecacheram, ALIGN (0x4), AT (fini - 0x4000000))
+ rodata = .;
+- SECTION_rodata (codecacheram, ALIGN (0x4), AT (rodata - 0x8000000))
++ SECTION_rodata (codecacheram, ALIGN (0x4), AT (rodata - 0x4000000))
+ rodata1 = .;
+- SECTION_rodata1 (codecacheram, ALIGN (0x4), AT (rodata1 - 0x8000000))
++ SECTION_rodata1 (codecacheram, ALIGN (0x4), AT (rodata1 - 0x4000000))
+ fixup = .;
+- SECTION_fixup (codecacheram, ALIGN (0x4), AT (fixup - 0x8000000))
+- gcc_except_table = .;
+- SECTION_gcc_except_table (codecacheram, ALIGN (0x4), AT (gcc_except_table - 0x8000000))
+- data_start = . - 0x4000000;
+- SECTION_data (dataram, data_start, AT (data_start - 0x4000000))
++ SECTION_fixup (codecacheram, ALIGN (0x4), AT (fixup - 0x4000000))
++ gcc_except_table =.;
++ SECTION_gcc_except_table (codecacheram, ALIGN (0x4), AT (gcc_except_table - 0x4000000))
++ data_start = ALIGN(0x4) + 0x4000000;
++ SECTION_data (datacacheram, data_start, AT (data_start - 0x8000000))
+ bss = .;
+- SECTION_bss (dataram, ALIGN (0x4), AT (bss - 0x4000000))
++ SECTION_bss (datacacheram, ALIGN (0x4), AT (bss - 0x8000000))
+ CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
+ SECTIONS_END
+ }
+-
+-
+diff -Naur orig/hal/arm/netarm/current/include/plf_mmap.h new/hal/arm/netarm/current/include/plf_mmap.h
+--- orig/hal/arm/netarm/current/include/plf_mmap.h 1970-01-01 01:00:00.000000000 +0100
++++ new/hal/arm/netarm/current/include/plf_mmap.h 2005-04-01 11:13:23.378304500 +0200
+@@ -0,0 +1,64 @@
++#ifndef CYGONCE_HAL_NETARM_PLATFORM_PLF_MMAP_H
++#define CYGONCE_HAL_NETARM_PLATFORM_PLF_MMAP_H
++//==========================================================================
++//
++// plf_mmap.h
++//
++// Platform specific memory map support
++//
++//==========================================================================
++// ####ECOSGPLCOPYRIGHTBEGIN####
++// -------------------------------------------
++// This file is part of eCos, the Embedded Configurable Operating System.
++// Copyright (C) 2005 Free Software Foundation, Inc.
++//
++// eCos is free software; you can redistribute it and/or modify it under
++// the terms of the GNU General Public License as published by the Free
++// Software Foundation; either version 2 or (at your option) any later
++// version.
++//
++// eCos is distributed in the hope that it will be useful, but WITHOUT
++// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++// for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with eCos; if not, write to the Free Software Foundation, Inc.,
++// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
++//
++// As a special exception, if other files instantiate templates or use
++// macros or inline functions from this file, or you compile this file
++// and link it with other works to produce a work based on this file,
++// this file does not by itself cause the resulting work to be covered by
++// the GNU General Public License. However the source code for this file
++// must still be made available in accordance with section (3) of the GNU
++// General Public License v2.
++//
++// This exception does not invalidate any other reasons why a work based
++// on this file might be covered by the GNU General Public License.
++// -------------------------------------------
++// ####ECOSGPLCOPYRIGHTEND####
++//==========================================================================
++//#####DESCRIPTIONBEGIN####
++//
++// Author(s): Harald Brandl (harald.brandl@fh-joanneum.at)
++// Contributors: Harald Brandl
++// Date: 01.04.2005
++// Purpose: NET+ARM memory map macro
++// Description:
++//
++//####DESCRIPTIONEND####
++//
++//==========================================================================
++
++
++extern unsigned int _dataram;
++
++
++#define HAL_CACHED_TO_UNCACHED_ADDRESS( caddr, uaddr, type ) CYG_MACRO_START \
++ uaddr = (type)((cyg_uint32)caddr - (cyg_uint32)(&_dataram)); \
++CYG_MACRO_END
++
++//---------------------------------------------------------------------------
++#endif // CYGONCE_HAL_NETARM_PLATFORM_PLF_MMAP_H
+diff -Naur orig/hal/arm/netarm/current/src/netarm_misc.c new/hal/arm/netarm/current/src/netarm_misc.c
+--- orig/hal/arm/netarm/current/src/netarm_misc.c 2004-11-29 17:35:48.000000000 +0100
++++ new/hal/arm/netarm/current/src/netarm_misc.c 2005-02-22 11:57:58.296703200 +0100
+@@ -7,15 +7,15 @@
+ //==========================================================================
+ //==========================================================================
+ //#####DESCRIPTIONBEGIN####
+-//
++//
+ // Author(s): Peter De Schrijver (p2@mind.be)
+ // Contributors: Peter De Schrijver (p2@mind.be)
+ // Date: 2002-10-25
+ // Purpose: HAL board support
+ // Description: Implementations of HAL board interfaces
+-//
++//
+ //####DESCRIPTIONEND####
+-//
++//
+ //========================================================================*/
+
+ #include <pkgconf/hal.h>
+@@ -29,7 +29,7 @@
+ #include <cyg/hal/hal_io.h> // IO macros
+ #include <cyg/hal/hal_arch.h> // Register state info
+ #include <cyg/hal/hal_diag.h>
+-#include <cyg/hal/hal_intr.h> // Interrupt names
++#include <cyg/hal/hal_intr.h> // Interrupt names
+ #include <cyg/hal/hal_cache.h>
+ #include <cyg/hal/hal_netarm.h> // Hardware definitions
+ #include <cyg/hal/hal_if.h> // calling interface API
+@@ -74,9 +74,9 @@
+ void hal_clock_read(cyg_uint32 *pvalue) {
+
+ static cyg_uint32 clock_val;
+-
+- clock_val=*TIMERSTAT1 & 0x1ff;
+- *pvalue = (cyg_uint32)(_period - clock_val);
++
++ clock_val=*TIMERSTAT1 & 0x1ff;
++ *pvalue = (cyg_uint32)(_period - clock_val);
+
+ }
+
+@@ -97,24 +97,19 @@
+
+ void hal_hardware_init(void) {
+
++#if defined (CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP) || \
++ defined (CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP)
+
+-#ifdef ENABLECACHE
+- /* CS1 BSIZE = 4 */
+- *OR1&=~(3 << 4);
+- *OR1|=1 << 4;
+-
+- HAL_ICACHE_ENABLE();
+-#endif /* ENABLECACHE */
++ HAL_CACHE_ENABLE();
+
++#endif /* ENABLECACHE */
+
+ *INTENABLE_CLR=0xffffffff;
+-
++
+ hal_clock_initialize(CYGNUM_HAL_RTC_PERIOD);
+
+ hal_if_init();
+
+-// HAL_ICACHE_DISABLE();
+-
+ }
+
+ int hal_spurious_ints;
+@@ -125,8 +120,8 @@
+ int i;
+
+ stat=*INTSTATUS;
+-
+- for(i=0;i<CYGNUM_HAL_ISR_MAX;i++)
++
++ for(i=0;i<CYGNUM_HAL_ISR_MAX;i++)
+ if(stat & (1<<i))
+ return i+1;
+
+@@ -154,7 +149,7 @@
+
+ if((vector>=CYGNUM_HAL_INTERRUPT_C0) && (vector<=CYGNUM_HAL_INTERRUPT_C3)) {
+ *PORTC|=1<< (vector+23);
+- if(up)
++ if(up)
+ *PORTC|=1<< (vector+15);
+ else
+ *PORTC&=~(1<< (vector+15));
diff --git a/ecos/packages/devs/eth/arm/netarm/current/doc/readme b/ecos/packages/devs/eth/arm/netarm/current/doc/readme
new file mode 100755
index 0000000..551bef2
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/doc/readme
@@ -0,0 +1,4 @@
+The HAL for the ARM NET+50 can be downloaded at ftp.mind.be
+
+To support data and instruction caching I made some modification
+to the HAL that are available as patch. \ No newline at end of file
diff --git a/ecos/packages/devs/eth/arm/netarm/current/src/MII.c b/ecos/packages/devs/eth/arm/netarm/current/src/MII.c
new file mode 100755
index 0000000..8bec1f9
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/src/MII.c
@@ -0,0 +1,236 @@
+//==========================================================================
+//
+// MII.c
+//
+// NetSilion NET+ARM PHY chip configuration
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors: Harald Brandl
+// Date: 01.08.2004
+// Purpose: PHY chip configuration
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "eth_regs.h"
+
+
+#define PHYS(_i_) (0x800 | _i_)
+
+#define SysReg (unsigned *)0xffb00004 // System Status Register
+
+/* Function: void cyg_netarm_mii_poll_busy (void)
+ *
+ * Description:
+ * This routine is responsible for waiting for the current PHY
+ * operation to complete.
+ *
+ * Parameters:
+ * none
+ */
+
+static void
+mii_poll_busy(void)
+{
+ unsigned reg;
+ /* check to see if PHY is busy with read or write */
+ do
+ {
+ HAL_READ_UINT32(MIIIR, reg);
+ }while (reg & 1);
+}
+
+/* Function: void cyg_netarm_mii_reset (void)
+ *
+ * Description:
+ *
+ * This routine resets the PHY.
+ *
+ * Return Values:
+ * none
+ */
+
+void
+cyg_netarm_mii_reset(void)
+{
+ HAL_WRITE_UINT32(MIIAR, PHYS(0)); // select command register
+ HAL_WRITE_UINT32(MIIWDR, 0x8000); // reset
+ mii_poll_busy();
+}
+
+/* Function: cyg_bool cyg_netarm_mii_negotiate (void)
+ *
+ * Description:
+ * This routine is responsible for causing the external Ethernet PHY
+ * to begin the negotatiation process.
+ *
+ * Parameters:
+ * none
+ *
+ * Return Value:
+ * 0: SUCCESS
+ * 1: ERROR
+ */
+
+cyg_bool
+cyg_netarm_mii_negotiate(void)
+{
+ unsigned timeout = 100000, reg;
+
+ HAL_WRITE_UINT32(MIIAR, PHYS(4));
+
+ mii_poll_busy();
+
+ HAL_WRITE_UINT32(MIIAR, PHYS(0));
+ HAL_OR_UINT32(MIIWDR, 0x1200);
+
+ mii_poll_busy();
+
+ while(timeout)
+ {
+ HAL_WRITE_UINT32(MIIAR, PHYS(1));
+ HAL_WRITE_UINT32(MIICR, 1);
+
+ mii_poll_busy();
+
+ HAL_READ_UINT32(MIIRDR, reg);
+
+ if(0x24 == (reg & 0x24))
+ return 0;
+ else
+ timeout--;
+ }
+
+ return 1;
+}
+
+
+/* Function: void cyg_netarm_mii_set_speed (cyg_bool speed, cyg_bool duplex)
+ *
+ * Description:
+ *
+ * This routine will set the speed and duplex of the external PHY.
+ *
+ * Parameters:
+ * Speed
+ * 0: 10Mbit
+ * 1: 100Mbit
+ * Duplex
+ * 0: Half
+ * 1: Full
+ *
+ * Return Values:
+ * none
+ */
+
+void
+cyg_netarm_mii_set_speed(cyg_uint32 speed, cyg_bool duplex)
+{
+ unsigned timeout = 1000000, reg;
+
+ HAL_WRITE_UINT32(MIIAR, PHYS(0)); // select command register
+ HAL_WRITE_UINT32(MIIWDR, (speed << 13) | (duplex << 8)); // set speed and duplex
+ mii_poll_busy();
+
+ while(timeout)
+ {
+ HAL_WRITE_UINT32(MIIAR, PHYS(1)); // select status register
+ HAL_WRITE_UINT32(MIICR, 1);
+ mii_poll_busy();
+ HAL_READ_UINT32(MIIRDR, reg);
+ if(reg & 0x4)
+ break;
+ timeout--;
+ }
+}
+
+/* Function: cyg_bool cyg_netarm_mii_check_speed
+ *
+ * Description:
+ *
+ * This routine will check the operating speed of the ethernet
+ * interface.
+ *
+ * Parameters:
+ * none
+ *
+ * Return Values:
+ * 0: 10Mbit Speed
+ * 1: 100Mbit Speed
+ */
+
+cyg_uint32
+cyg_netarm_mii_check_speed(void)
+{
+ unsigned reg;
+
+ HAL_WRITE_UINT32(MIIAR, PHYS(17));
+ HAL_WRITE_UINT32(MIICR, 1);
+ mii_poll_busy();
+ HAL_READ_UINT32(MIIRDR, reg);
+ return (reg >> 14) & 1;
+}
+
+/* Function: void cyg_netarm_mii_check_duplex
+ *
+ * Description:
+ *
+ * This routine will check the operating duplex of the ethernet
+ * interface.
+ *
+ * Parameters:
+ * none
+ *
+ * Return Values:
+ * 0: Half Duplex
+ * 1: Full Duplex
+ */
+
+cyg_bool
+cyg_netarm_mii_check_duplex(void)
+{
+ unsigned reg;
+
+ HAL_WRITE_UINT32(MIIAR, PHYS(17));
+ HAL_WRITE_UINT32(MIICR, 1);
+ mii_poll_busy();
+ HAL_READ_UINT32(MIIRDR, reg);
+ return (reg >> 9) & 1;
+}
diff --git a/ecos/packages/devs/eth/arm/netarm/current/src/MII.h b/ecos/packages/devs/eth/arm/netarm/current/src/MII.h
new file mode 100755
index 0000000..407b72a
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/src/MII.h
@@ -0,0 +1,60 @@
+#ifndef CYGONCE_DEVS_ETH_ARM_NETARM_MII_H
+#define CYGONCE_DEVS_ETH_ARM_NETARM_MII_H
+// ====================================================================
+//
+// MII.h
+//
+// PHY chip configuration
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors: Harald Brandl
+// Date: 01.08.2004
+// Purpose: Functions for PHY control
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+void cyg_netarm_mii_reset(void);
+void cyg_netarm_mii_set_speed (cyg_uint32 speed, cyg_bool duplex);
+cyg_uint32 cyg_netarm_mii_check_speed(void);
+cyg_bool cyg_netarm_mii_check_duplex(void);
+cyg_bool cyg_netarm_mii_negotiate(void);
+
+#endif // CYGONCE_DEVS_ETH_ARM_NETARM_MII_H
diff --git a/ecos/packages/devs/eth/arm/netarm/current/src/eeprom.c b/ecos/packages/devs/eth/arm/netarm/current/src/eeprom.c
new file mode 100755
index 0000000..20f8775
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/src/eeprom.c
@@ -0,0 +1,227 @@
+// ====================================================================
+//
+// eeprom.c
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors: Harald Brandl
+// Date: 10.03.2005
+// Purpose: EEPROM I/O
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+#include <cyg/hal/hal_modnet50.h>
+#include "eth_regs.h"
+
+static void wait(int time)
+{
+ int i;
+
+ for(i=0; i < time; i++);
+}
+
+/* send i2c stop condition */
+static void i2cStop(void)
+{
+ HAL_OR_UINT32(PORTC, 0x00c00000);
+ HAL_AND_UINT32(PORTC, ~0x000000c0); // SDA = 0, SLK = 0
+ wait(5);
+ HAL_OR_UINT32(PORTC, 0x00000040); // SLK = 1
+ wait(5);
+ HAL_OR_UINT32(PORTC, 0x00000080); // SDA = 1
+}
+
+/* send i2c start condition */
+static void i2cStart(void)
+{
+ HAL_OR_UINT32(PORTC, 0x00c000c0); // SDA = 1, SLK = 1
+ wait(5);
+ HAL_AND_UINT32(PORTC, ~0x00000080); // SDA = 0
+ wait(5);
+ HAL_AND_UINT32(PORTC, ~0x00000040); // SLK = 0
+}
+
+static void i2cPutByte(char byte)
+{
+ int i, bit, reg;
+
+ HAL_OR_UINT32(PORTC, 0x00c00000);
+
+ for(i=7; i >= 0; i--)
+ {
+ bit = (byte >> i) & 1;
+ HAL_READ_UINT32(PORTC, reg);
+ HAL_WRITE_UINT32(PORTC, (reg & ~0x80) | (bit << 7)); // SDA = data
+ HAL_OR_UINT32(PORTC, 0x00000040); // SLK = 1
+ wait(5);
+ HAL_AND_UINT32(PORTC, ~0x00000040); // SLK = 0
+ wait(5);
+ }
+ HAL_OR_UINT32(PORTC, 0x00000080); // SDA = 1
+}
+
+static char i2cGetByte(void)
+{
+ int i, reg;
+ char byte = 0;
+
+ HAL_AND_UINT32(PORTC, ~0x00800000);
+ for(i=7; i >= 0; i--)
+ {
+ HAL_OR_UINT32(PORTC, 0x00000040); // SLK = 1
+ HAL_READ_UINT32(PORTC, reg);
+ byte |= ((reg & 0x80) >> 7) << i; // data = SDA
+ wait(5);
+ HAL_AND_UINT32(PORTC, ~0x00000040); // SLK = 0
+ wait(5);
+ }
+ HAL_OR_UINT32(PORTC, 0x00800080); // SDA = 1
+ return byte;
+}
+
+/* acknowledge received bytes */
+static void i2cGiveAck(void)
+{
+ HAL_OR_UINT32(PORTC, 0x00c00000);
+ HAL_AND_UINT32(PORTC, ~0x00000080); // SDA = 0
+ wait(5);
+ HAL_OR_UINT32(PORTC, 0x00000040); // SLK = 1
+ wait(5);
+ HAL_AND_UINT32(PORTC, ~0x00000040); // SLK = 0
+ wait(5);
+ HAL_OR_UINT32(PORTC, 0x00000080); // SDA = 1
+ wait(5);
+}
+
+/* wait for acknowledge from slaves */
+static void i2cGetAck(void)
+{
+ unsigned reg;
+
+ HAL_AND_UINT32(PORTC, ~0x00800000); // SDA in
+ HAL_OR_UINT32(PORTC, 0x00400040); // SLK = 1
+ do
+ {
+ HAL_READ_UINT32(PORTC, reg);
+ }while(reg & 0x80); // wait for SDA = 1
+ HAL_AND_UINT32(PORTC, ~0x00000040); // SLK = 0
+}
+
+void cyg_netarm_initI2C(void)
+{
+ HAL_AND_UINT32(PORTC, ~0xc0000000); // mode GPIO
+ i2cStop();
+}
+
+/* wait until eeprom's internal write cycle has finished */
+void cyg_netarm_eepromPollAck(int deviceAddr)
+{
+ unsigned reg;
+
+ deviceAddr <<= 1;
+
+ HAL_OR_UINT32(PORTC, 0x00400040); // SLK = 1
+ while(1)
+ {
+ i2cStart();
+ i2cPutByte(deviceAddr);
+ HAL_AND_UINT32(PORTC, ~0x00800000); // SDA in
+ HAL_OR_UINT32(PORTC, 0x00400040); // SLK = 1
+ HAL_READ_UINT32(PORTC, reg);
+ if((reg & 0x80) == 0)
+ {
+ HAL_AND_UINT32(PORTC, ~0x00000040); // SLK = 0
+ break;
+ }
+ HAL_AND_UINT32(PORTC, ~0x00000040); // SLK = 0
+ }
+}
+
+/* reads numBytes from eeprom starting at readAddr into buf */
+void cyg_netarm_eepromRead(int deviceAddr, int readAddr, char *buf, int numBytes)
+{
+ int i;
+
+ deviceAddr <<= 1;
+ i2cStart();
+ i2cPutByte(deviceAddr);
+ i2cGetAck();
+ i2cPutByte(readAddr >> 8);
+ i2cGetAck();
+ i2cPutByte(readAddr & 0xff);
+ i2cGetAck();
+ i2cStart();
+ i2cPutByte(deviceAddr | 1); // set read flag
+ i2cGetAck();
+
+ for(i=0;i<numBytes;i++)
+ {
+ buf[i] = i2cGetByte();
+ if(i < numBytes - 1)
+ i2cGiveAck();
+ }
+
+ i2cStop();
+}
+
+/* writes up to a page of 32 bytes from buf into eeprom;
+max. number of bytes depends on the offset within a page, indexed by the
+lower 5 bits of writeAddr and equals 32 - offset */
+void cyg_netarm_eepromWrite(int deviceAddr, int writeAddr, char *buf, int numBytes)
+{
+ int i;
+
+ deviceAddr <<= 1;
+ i2cStart();
+ i2cPutByte(deviceAddr);
+ i2cGetAck();
+ i2cPutByte(writeAddr >> 8);
+ i2cGetAck();
+ i2cPutByte(writeAddr & 0xff);
+ i2cGetAck();
+
+ for(i=0; i<numBytes; i++)
+ {
+ i2cPutByte(buf[i]);
+ i2cGetAck();
+ }
+
+ i2cStop();
+}
diff --git a/ecos/packages/devs/eth/arm/netarm/current/src/eeprom.h b/ecos/packages/devs/eth/arm/netarm/current/src/eeprom.h
new file mode 100755
index 0000000..0bf1e90
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/src/eeprom.h
@@ -0,0 +1,62 @@
+#ifndef CYGONCE_DEVS_ETH_ARM_NETARM_ETH_DR_EEPROM_H
+#define CYGONCE_DEVS_ETH_ARM_NETARM_ETH_DR_EEPROM_H
+
+// ====================================================================
+//
+// eeprom.h
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors: Harald Brandl
+// Date: 10.03.2005
+// Purpose: EEPROM interface
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+
+/* a block of max. 32 bytes can be written at once */
+void cyg_netarm_eepromWrite(int deviceAddr, int writeAddr, char *buf, int numBytes);
+/* reads out as many bytes as desired */
+void cyg_netarm_eepromRead(int deviceAddr, int readAddr, char *buf, int numBytes);
+/* blocks until the internal write cycle, initiated after eepromWrite, completes */
+void cyg_netarm_eepromPollAck(int deviceAddr);
+void cyg_netarm_initI2C(void);
+
+#endif // CYGONCE_DEVS_ETH_ARM_NETARM_ETH_DR_EEPROM_H
diff --git a/ecos/packages/devs/eth/arm/netarm/current/src/eth_regs.h b/ecos/packages/devs/eth/arm/netarm/current/src/eth_regs.h
new file mode 100755
index 0000000..8969e39
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/src/eth_regs.h
@@ -0,0 +1,149 @@
+#ifndef CYGONCE_DEVS_ETH_ARM_NETARM_ETH_REGS_H
+#define CYGONCE_DEVS_ETH_ARM_NETARM_ETH_REGS_H
+
+// ====================================================================
+//
+// eth_regs.h
+//
+// Address mappings for ethernet and DMA controller registers
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors: Harald Brandl
+// Date: 01.08.2004
+// Purpose: Ethernet and DMA controller registers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_io.h>
+
+
+#ifndef HAL_OR_UINT32
+#define HAL_OR_UINT32( _register_, _value_ ) \
+ CYG_MACRO_START \
+ cyg_uint32 _i_; \
+ HAL_READ_UINT32( _register_, _i_ ); \
+ _i_ |= _value_; \
+ HAL_WRITE_UINT32( _register_, _i_ ); \
+ CYG_MACRO_END
+#endif
+
+#ifndef HAL_AND_UINT32
+#define HAL_AND_UINT32( _register_, _value_ ) \
+ CYG_MACRO_START \
+ cyg_uint32 _i_; \
+ HAL_READ_UINT32( _register_, _i_ ); \
+ _i_ &= _value_; \
+ HAL_WRITE_UINT32( _register_, _i_ ); \
+ CYG_MACRO_END
+#endif
+
+// Ethernet
+
+#define EthGenCR (unsigned *)0xff800000
+#define EthGenSR (unsigned *)0xff800004
+#define EthFIFODR (unsigned *)0xff800008
+#define EthFIFODRkickoff (unsigned *)0xff80000c
+#define EthTxSR (unsigned *)0xff800010
+#define EthRxSR (unsigned *)0xff800014
+#define MACCR (unsigned *)0xff800400
+#define MACTR (unsigned *)0xff800404
+#define PCSCR (unsigned *)0xff800408
+#define PCSTR (unsigned *)0xff80040c
+#define STLCR (unsigned *)0xff800410
+#define STLTR (unsigned *)0xff800414
+#define BtBIPGGapTimerR (unsigned *)0xff800440
+#define NonBtBIPGGapTimerR (unsigned *)0xff800444
+#define CollWinR (unsigned *)0xff800448
+#define TxPNCR (unsigned *)0xff800460
+#define TxBCR (unsigned *)0xff800464
+#define ReTxBCR (unsigned *)0xff800468
+#define TxRNG (unsigned *)0xff80046c
+#define TxMRN (unsigned *)0xff800470
+#define TxCDec (unsigned *)0xff800474
+#define TOTxC (unsigned *)0xff800478
+#define RxBC (unsigned *)0xff800480
+#define RxCDec (unsigned *)0xff800484
+#define TORxC (unsigned *)0xff800488
+#define LnFC (unsigned *)0xff8004c0
+#define JC10M (unsigned *)0xff800500
+#define LoCC10M (unsigned *)0xff800504
+#define MIICR (unsigned *)0xff800540
+#define MIIAR (unsigned *)0xff800544
+#define MIIWDR (unsigned *)0xff800548
+#define MIIRDR (unsigned *)0xff80054c
+#define MIIIR (unsigned *)0xff800550
+#define CRCEC (unsigned *)0xff800580
+#define AEC (unsigned *)0xff800584
+#define CEC (unsigned *)0xff800588
+#define LFC (unsigned *)0xff80058c
+#define SFC (unsigned *)0xff800590
+#define LCC (unsigned *)0xff800594
+#define EDC (unsigned *)0xff800598
+#define MCC (unsigned *)0xff80059c
+#define SAFR (unsigned *)0xff8005c0
+#define SAR1 (unsigned *)0xff8005c4
+#define SAR2 (unsigned *)0xff8005c8
+#define SAR3 (unsigned *)0xff8005cc
+#define SAMHT1 (unsigned *)0xff8005d0
+#define SAMHT2 (unsigned *)0xff8005d4
+#define SAMHT3 (unsigned *)0xff8005d8
+#define SAMHT4 (unsigned *)0xff8005dc
+
+// DMA
+
+#define DMA1A_BDP (unsigned *)0xff900000
+#define DMA1A_CR (unsigned *)0xff900010
+#define DMA1A_SR (unsigned *)0xff900014
+#define DMA1B_BDP (unsigned *)0xff900020
+#define DMA1B_CR (unsigned *)0xff900030
+#define DMA1B_SR (unsigned *)0xff900034
+#define DMA1C_BDP (unsigned *)0xff900040
+#define DMA1C_CR (unsigned *)0xff900050
+#define DMA1C_SR (unsigned *)0xff900054
+#define DMA1D_BDP (unsigned *)0xff900060
+#define DMA1D_CR (unsigned *)0xff900070
+#define DMA1D_SR (unsigned *)0xff900074
+#define DMA2_BDP (unsigned *)0xff900080
+#define DMA2_CR (unsigned *)0xff900090
+#define DMA2_SR (unsigned *)0xff900094
+
+#endif // CYGONCE_DEVS_ETH_ARM_NETARM_ETH_REGS_H
diff --git a/ecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.c b/ecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.c
new file mode 100755
index 0000000..f727d36
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.c
@@ -0,0 +1,711 @@
+//==========================================================================
+//
+// netarm_eth_drv.c
+//
+// NetSilion NET+ARM Ethernet Driver (DMA driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors: Harald Brandl
+// Date: 01.08.2004
+// Purpose: NET+ARM Ethernet Driver (DMA driven)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#include <pkgconf/devs_eth_arm_netarm.h>
+#include <cyg/hal/hal_platform_ints.h>
+#include <cyg/hal/plf_mmap.h>
+#include "eth_regs.h"
+#include "MII.h"
+#include "netarm_eth_drv.h"
+#include "eeprom.h"
+
+
+#define BufferSizeA 128
+#define BufferSizeB 512
+#define BufferSizeC 1524
+
+#define NumA 16
+#define NumB 8
+#define NumC 8
+
+#define EEPROM_MAC 0 // location of MAC address inside eeprom
+
+
+static cyg_mutex_t Key_Mutex;
+static private_data_t driver_private;
+
+static unsigned char RxBufferA[NumA][BufferSizeA] __attribute__ ((aligned (4)));
+static unsigned char RxBufferB[NumB][BufferSizeB] __attribute__ ((aligned (4)));
+static unsigned char RxBufferC[NumC][BufferSizeC] __attribute__ ((aligned (4)));
+
+static unsigned char TxBuffer[1518] __attribute__ ((aligned (4)));
+
+static BDP_t RxBDP_A[NumA];
+static BDP_t RxBDP_B[NumB];
+static BDP_t RxBDP_C[NumC];
+
+static BDP_t TxBDP;
+
+// relocation pointer for data accessed by DMA to enable caching
+static unsigned char *pRxBufferA = (unsigned char *)RxBufferA,
+ *pRxBufferB = (unsigned char *)RxBufferB,
+ *pRxBufferC = (unsigned char *)RxBufferC;
+static unsigned char *pTxBuffer = TxBuffer;
+
+static BDP_t *pRxBDP_A = RxBDP_A, *pRxBDP_B = RxBDP_B, *pRxBDP_C = RxBDP_C;
+static BDP_t *pTxBDP = &TxBDP;
+
+
+ETH_DRV_SC(netarm_sc,
+ (void *)&driver_private, // driver specific data
+ "eth0", // name for this interface
+ netarm_start,
+ netarm_stop,
+ netarm_control,
+ netarm_can_send,
+ netarm_send,
+ netarm_recv,
+ netarm_deliver,
+ netarm_poll,
+ netarm_int_vector);
+
+
+NETDEVTAB_ENTRY(netarm_netdev,
+ "ETH_DRV",
+ netarm_init,
+ &netarm_sc);
+
+
+#ifdef __thumb__
+ #define fastcopy memcpy
+#else
+static void
+fastcopy(void *buf, void *data, unsigned long len)
+{
+ asm volatile(
+
+ "STMDB SP!, {R11};"
+
+ "TST R1, #2;" // test if aligned
+ "LDRNEH R3, [R1], #2;"
+ "STRNEH R3, [R0], #2;"
+ "SUBNE R2, R2, #2;"
+ "TST R1, #1;"
+ "LDRNEB R3, [R1], #1;"
+ "STRNEB R3, [R0], #1;"
+ "SUBNE R2, R2, #1;"
+
+ ".START%=:"
+
+ "CMP R2, #44;"
+ "BLT .LASTBYTES%=;"
+ "LDMIA R1!, {R3 - R12, R14};"
+ "STMIA R0!, {R3 - R12, R14};"
+ "SUB R2, R2, #44;"
+
+ "CMP R2, #44;"
+ "BLT .LASTBYTES%=;"
+ "LDMIA R1!, {R3 - R12, R14};"
+ "STMIA R0!, {R3 - R12, R14};"
+ "SUB R2, R2, #44;"
+
+ "CMP R2, #44;"
+ "BLT .LASTBYTES%=;"
+ "LDMIA R1!, {R3 - R12, R14};"
+ "STMIA R0!, {R3 - R12, R14};"
+ "SUB R2, R2, #44;"
+
+ "CMP R2, #44;"
+ "BLT .LASTBYTES%=;"
+ "LDMIA R1!, {R3 - R12, R14};"
+ "STMIA R0!, {R3 - R12, R14};"
+ "SUB R2, R2, #44;"
+
+ "CMP R2, #44;"
+ "BLT .LASTBYTES%=;"
+ "LDMIA R1!, {R3 - R12, R14};"
+ "STMIA R0!, {R3 - R12, R14};"
+ "SUB R2, R2, #44;"
+
+ "CMP R2, #44;"
+ "BLT .LASTBYTES%=;"
+ "LDMIA R1!, {R3 - R12, R14};"
+ "STMIA R0!, {R3 - R12, R14};"
+ "SUB R2, R2, #44;"
+
+ "CMP R2, #44;"
+ "BLT .LASTBYTES%=;"
+ "LDMIA R1!, {R3 - R12, R14};"
+ "STMIA R0!, {R3 - R12, R14};"
+ "SUB R2, R2, #44;"
+
+ "CMP R2, #44;"
+ "BLT .LASTBYTES%=;"
+ "LDMIA R1!, {R3 - R12, R14};"
+ "STMIA R0!, {R3 - R12, R14};"
+ "SUB R2, R2, #44;"
+
+ "CMP R2, #44;"
+ "BLT .LASTBYTES%=;"
+ "LDMIA R1!, {R3 - R12, R14};"
+ "STMIA R0!, {R3 - R12, R14};"
+ "SUB R2, R2, #44;"
+
+ "CMP R2, #44;"
+ "BLT .LASTBYTES%=;"
+ "LDMIA R1!, {R3 - R12, R14};"
+ "STMIA R0!, {R3 - R12, R14};"
+ "SUB R2, R2, #44;"
+
+ "BGE .START%=;"
+
+
+ ".LASTBYTES%=:"
+
+ "AND R14, R2, #0xfffffffc;"
+ "LDR PC, [PC, R14];"
+ "NOP;"
+
+ ".SWITCH%=:"
+ ".word .CASE0%=;"
+ ".word .CASE1%=;"
+ ".word .CASE2%=;"
+ ".word .CASE3%=;"
+ ".word .CASE4%=;"
+ ".word .CASE5%=;"
+ ".word .CASE6%=;"
+ ".word .CASE7%=;"
+ ".word .CASE8%=;"
+ ".word .CASE9%=;"
+ ".word .CASE10%=;"
+
+ ".CASE0%=:"
+ "B .END%=;"
+
+ ".CASE1%=:"
+ "LDMIA R1!, {R3};"
+ "STMIA R0!, {R3};"
+ "B .END%=;"
+
+ ".CASE2%=:"
+ "LDMIA R1!, {R3, R4};"
+ "STMIA R0!, {R3, R4};"
+ "B .END%=;"
+
+ ".CASE3%=:"
+ "LDMIA R1!, {R3 - R5};"
+ "STMIA R0!, {R3 - R5};"
+ "B .END%=;"
+
+ ".CASE4%=:"
+ "LDMIA R1!, {R3 - R6};"
+ "STMIA R0!, {R3 - R6};"
+ "B .END%=;"
+
+ ".CASE5%=:"
+ "LDMIA R1!, {R3 - R7};"
+ "STMIA R0!, {R3 - R7};"
+ "B .END%=;"
+
+ ".CASE6%=:"
+ "LDMIA R1!, {R3 - R8};"
+ "STMIA R0!, {R3 - R8};"
+ "B .END%=;"
+
+ ".CASE7%=:"
+ "LDMIA R1!, {R3 - R9};"
+ "STMIA R0!, {R3 - R9};"
+ "B .END%=;"
+
+ ".CASE8%=:"
+ "LDMIA R1!, {R3 - R10};"
+ "STMIA R0!, {R3 - R10};"
+ "B .END%=;"
+
+ ".CASE9%=:"
+ "LDMIA R1!, {R3 - R11};"
+ "STMIA R0!, {R3 - R11};"
+ "B .END%=;"
+
+ ".CASE10%=:"
+ "LDMIA R1!, {R3 - R12};"
+ "STMIA R0!, {R3 - R12};"
+
+ ".END%=:"
+ "TST R2, #2;"
+ "LDRNEH R3, [R1], #2;"
+ "STRNEH R3, [R0], #2;"
+ "TST R2, #1;"
+ "LDRNEB R3, [R1], #1;"
+ "STRNEB R3, [R0], #1;"
+
+ "LDMIA SP!, {R11};"
+
+ :
+ : "r" (buf), "r" (data), "r" (len)
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14"
+ );
+}
+#endif
+
+static bool
+KeyBufferFull(private_data_t *pd)
+{
+ int tmp = 0;
+
+ cyg_drv_mutex_lock(&Key_Mutex);
+
+ if((pd->key_head + 1) % MaxKeys == pd->key_tail)
+ {
+ tmp = 1;
+ }
+
+ cyg_drv_mutex_unlock(&Key_Mutex);
+
+ return tmp;
+}
+
+
+static void
+AddKey(unsigned long key, private_data_t *pd)
+{
+
+ cyg_drv_mutex_lock(&Key_Mutex);
+
+ pd->KeyBuffer[pd->key_head] = key;
+ pd->key_head = (pd->key_head + 1) % MaxKeys;
+
+ cyg_drv_mutex_unlock(&Key_Mutex);
+}
+
+static unsigned
+GetKey(private_data_t *pd)
+{
+ unsigned key = 0;
+
+ cyg_drv_mutex_lock(&Key_Mutex);
+
+ if(pd->key_tail != pd->key_head)
+ {
+ key = pd->KeyBuffer[pd->key_tail];
+ pd->key_tail = (pd->key_tail + 1) % MaxKeys;
+ }
+
+ cyg_drv_mutex_unlock(&Key_Mutex);
+
+ return key;
+}
+
+
+static cyg_uint32
+dma_rx_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+
+ // block this interrupt until the dsr completes
+ cyg_drv_interrupt_mask(vector);
+
+ // tell ecos to allow further interrupt processing
+ cyg_drv_interrupt_acknowledge(vector);
+
+ return CYG_ISR_CALL_DSR; // call the dsr
+}
+
+static void
+dma_rx_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+
+ eth_drv_dsr( vector, count, data );
+
+ HAL_WRITE_UINT32(DMA1A_SR, 0x80000000); // acknowledge and mask interrupts
+ HAL_WRITE_UINT32(DMA1B_SR, 0x80000000);
+ HAL_WRITE_UINT32(DMA1C_SR, 0x80000000);
+
+ cyg_drv_interrupt_unmask(vector);
+}
+
+static cyg_uint32
+dma_tx_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+
+ // block this interrupt until the dsr completes
+ cyg_drv_interrupt_mask(vector);
+
+ // tell ecos to allow further interrupt processing
+ cyg_drv_interrupt_acknowledge(vector);
+
+ return CYG_ISR_CALL_DSR; // invoke the dsr
+}
+
+static void
+dma_tx_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+
+ eth_drv_dsr( vector, count, data );
+
+ HAL_OR_UINT32(DMA2_SR, 0x80000000); // acknowledge interrupt
+
+ cyg_drv_interrupt_unmask(vector);
+}
+
+static void
+setupDMA(void)
+{
+ int i;
+
+ /* map DMA shared data to non-cached ram */
+#ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
+ HAL_CACHED_TO_UNCACHED_ADDRESS(RxBufferA, pRxBufferA, unsigned char *);
+ HAL_CACHED_TO_UNCACHED_ADDRESS(RxBufferB, pRxBufferB, unsigned char *);
+ HAL_CACHED_TO_UNCACHED_ADDRESS(RxBufferC, pRxBufferC, unsigned char *);
+
+ HAL_CACHED_TO_UNCACHED_ADDRESS(TxBuffer, pTxBuffer, unsigned char *);
+
+ HAL_CACHED_TO_UNCACHED_ADDRESS(RxBDP_A, pRxBDP_A, BDP_t *);
+ HAL_CACHED_TO_UNCACHED_ADDRESS(RxBDP_B, pRxBDP_B, BDP_t *);
+ HAL_CACHED_TO_UNCACHED_ADDRESS(RxBDP_C, pRxBDP_C, BDP_t *);
+
+ HAL_CACHED_TO_UNCACHED_ADDRESS(TxBDP, pTxBDP, BDP_t * );
+#endif
+
+ HAL_OR_UINT32(SYSCON, 0x40); // reset DMA module
+
+ for(i = 0; i < NumA; i++)
+ {
+ pRxBDP_A[i].lo = ((unsigned)(pRxBufferA + i*BufferSizeA)) & 0x3fffffff;
+ pRxBDP_A[i].hi = BufferSizeA;
+ }
+
+ pRxBDP_A[i - 1].lo |= 0x80000000; // set W bit
+
+ for(i = 0; i < NumB; i++)
+ {
+ pRxBDP_B[i].lo = ((unsigned)(pRxBufferB + i*BufferSizeB)) & 0x3fffffff;
+ pRxBDP_B[i].hi = BufferSizeB;
+ }
+
+ pRxBDP_B[i - 1].lo |= 0x80000000;
+
+ for(i = 0; i < NumC; i++)
+ {
+ pRxBDP_C[i].lo = ((unsigned)(pRxBufferC + i*BufferSizeC)) & 0x3fffffff;
+ pRxBDP_C[i].hi = BufferSizeC;
+ }
+
+ pRxBDP_C[i - 1].lo |= 0x80000000;
+
+ HAL_AND_UINT32(SYSCON, ~0x40);
+
+ HAL_WRITE_UINT32(DMA1A_BDP, (unsigned)pRxBDP_A);
+ HAL_WRITE_UINT32(DMA1A_CR, 0x82000000); //burst transfer
+ HAL_WRITE_UINT32(DMA1A_SR, 0xa00000);
+
+ HAL_WRITE_UINT32(DMA1B_BDP, (unsigned)pRxBDP_B);
+ HAL_WRITE_UINT32(DMA1B_CR, 0x82000000); //burst transfer
+ HAL_WRITE_UINT32(DMA1B_SR, 0xa00000);
+
+ HAL_WRITE_UINT32(DMA1C_BDP, (unsigned)pRxBDP_C);
+ HAL_WRITE_UINT32(DMA1C_CR, 0x82000000); //burst transfer
+ HAL_WRITE_UINT32(DMA1C_SR, 0xa00000);
+
+
+ pTxBDP->lo = ((unsigned)pTxBuffer) & 0x3fffffff;
+ pTxBDP->lo |= 0xa0000000; // set W and L bit
+
+ HAL_WRITE_UINT32(DMA2_BDP, (unsigned)pTxBDP);
+ HAL_WRITE_UINT32(DMA2_CR, 0x86000000); //burst transfer
+ HAL_WRITE_UINT32(DMA2_SR, 0x800000);
+}
+
+
+static bool
+netarm_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ cyg_bool duplex;
+ static cyg_interrupt dma_rx_int_object, dma_tx_int_object;
+ static cyg_handle_t dma_rx_int_handle, dma_tx_int_handle;
+
+#ifdef CYGSEM_DEVS_ETH_ARM_NETARM_ETH0_SET_ESA
+
+ unsigned char esa[6] = CYGDAT_DEVS_ETH_ARM_NETARM_ETH0_ESA;
+#else
+ unsigned char esa[6];
+
+ cyg_netarm_initI2C();
+ cyg_netarm_eepromRead(0x50, EEPROM_MAC, esa, 6);
+#endif
+
+ // setup dma receiver
+ setupDMA();
+
+ cyg_netarm_mii_reset();
+ cyg_netarm_mii_negotiate(); // initialize PHY
+ duplex = cyg_netarm_mii_check_duplex();
+
+ // Ethernet Controller Initializatition
+
+ // auto CRC, late collision retry
+ HAL_WRITE_UINT32(MACCR, 0x1c | (duplex << 1));
+ // insert MAC source address into ethernet frame
+ HAL_WRITE_UINT32(STLCR, 0x3);
+ HAL_WRITE_UINT32(BtBIPGGapTimerR, 0x14); // standard values
+ HAL_WRITE_UINT32(NonBtBIPGGapTimerR, (0x9 << 7) | 0x11);// standard values
+ HAL_WRITE_UINT32(CollWinR, (0x37 << 8) | 0xf); // standard values
+ HAL_WRITE_UINT32(SAFR, 0x1); // broadcast mode
+ // dma mode, full duplex, enable pNA mode(needed for alignment)
+ HAL_WRITE_UINT32(EthGenCR, 0x40400400 | (duplex << 16));
+
+ cyg_drv_interrupt_create(
+ CYGNUM_HAL_INTERRUPT_DMA1, // Interrupt Vector
+ 0, // Interrupt Priority
+ (cyg_addrword_t)&netarm_sc, // Reference to Driver Instance
+ dma_rx_isr,
+ dma_rx_dsr,
+ &dma_rx_int_handle,
+ &dma_rx_int_object);
+
+ cyg_drv_interrupt_create(
+ CYGNUM_HAL_INTERRUPT_DMA2, // Interrupt Vector
+ 0, // Interrupt Priority
+ (cyg_addrword_t)&netarm_sc, // Reference to Driver Instance
+ dma_tx_isr,
+ dma_tx_dsr,
+ &dma_tx_int_handle,
+ &dma_tx_int_object);
+
+ cyg_drv_interrupt_attach(dma_rx_int_handle);
+
+ cyg_drv_interrupt_attach(dma_tx_int_handle);
+
+ cyg_mutex_init(&Key_Mutex);
+
+ sc->funs->eth_drv->init(sc, esa);
+
+ return true;
+}
+
+
+static void
+netarm_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ int i, len;
+ private_data_t *pd = (private_data_t *)(sc->driver_private);
+ unsigned char *data, *buf = pd->RxBuffer;
+
+ for (i = 0; i < sg_len; i++) {
+ data = (unsigned char *)(sg_list[i].buf);
+ len = sg_list[i].len;
+ if(len)
+ {
+ if(i == 1)
+ {
+ buf += 2;
+ }
+
+ fastcopy(data, buf, len);
+ buf += len;
+ }
+ }
+}
+
+
+static void
+netarm_deliver(struct eth_drv_sc *sc)
+{
+ static int a = 0, b = 0, c = 0;
+ unsigned key, rega, regb, regc;
+ private_data_t *pd = (private_data_t *)(sc->driver_private);
+
+
+ while((key = GetKey(pd)))
+ {
+ sc->funs->eth_drv->tx_done(sc, key, 0);
+ }
+
+ while(pRxBDP_A[a].hi & 0x8000)
+ {
+ pd->RxBuffer = (unsigned char *)(pRxBDP_A[a].lo & 0x1FFFFFFF);
+ HAL_REORDER_BARRIER();
+ sc->funs->eth_drv->recv(sc, pRxBDP_A[a].hi & 0x7FFF);
+ HAL_REORDER_BARRIER();
+ pRxBDP_A[a].hi = BufferSizeA;
+ HAL_REORDER_BARRIER();
+ a = (a + 1) % NumA;
+ }
+
+ while(pRxBDP_B[b].hi & 0x8000)
+ {
+ pd->RxBuffer = (unsigned char *)(pRxBDP_B[b].lo & 0x1FFFFFFF);
+ HAL_REORDER_BARRIER();
+ sc->funs->eth_drv->recv(sc, pRxBDP_B[b].hi & 0x7FFF);
+ HAL_REORDER_BARRIER();
+ pRxBDP_B[b].hi = BufferSizeB;
+ HAL_REORDER_BARRIER();
+ b = (b + 1) % NumB;
+ }
+
+ while(pRxBDP_C[c].hi & 0x8000)
+ {
+ pd->RxBuffer = (unsigned char *)(pRxBDP_C[c].lo & 0x1FFFFFFF);
+ HAL_REORDER_BARRIER();
+ sc->funs->eth_drv->recv(sc, pRxBDP_C[c].hi & 0x7FFF);
+ HAL_REORDER_BARRIER();
+ pRxBDP_C[c].hi = BufferSizeC;
+ HAL_REORDER_BARRIER();
+ c = (c + 1) % NumC;
+ }
+
+ HAL_READ_UINT32(DMA1A_SR, rega);
+ HAL_READ_UINT32(DMA1B_SR, regb);
+ HAL_READ_UINT32(DMA1C_SR, regc);
+
+ if((rega & 0x20000000) || (regb & 0x20000000) || (regc & 0x20000000))
+ {
+ HAL_AND_UINT32(EthGenCR, ~0xc0000000); // reset Rx FIFO
+ HAL_OR_UINT32(EthGenCR, 0xc0000000);
+ }
+
+ HAL_WRITE_UINT32(DMA1A_SR, 0x20a00000);
+ HAL_WRITE_UINT32(DMA1B_SR, 0x20a00000);
+ HAL_WRITE_UINT32(DMA1C_SR, 0x20a00000);
+}
+
+
+static int
+netarm_can_send(struct eth_drv_sc *sc)
+{
+ private_data_t *pd = (private_data_t *)(sc->driver_private);
+
+ if((pTxBDP->hi & 0x8000) || KeyBufferFull(pd))
+ return 0;
+
+ return 1;
+}
+
+static void
+netarm_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
+ int sg_len, int total_len, unsigned long key)
+{
+ private_data_t *pd = (private_data_t *)(sc->driver_private);
+ int i, len;
+ unsigned char *data, *buf = pTxBuffer;
+
+ AddKey(key, pd);
+
+ // Put data into buffer
+ for(i = 0; i < sg_len; i++) {
+ data = (unsigned char *)sg_list[i].buf;
+ len = sg_list[i].len;
+
+ if(len)
+ {
+ if(((unsigned)buf & 0x3) != ((unsigned)data & 0x3))
+ {
+ memcpy(buf, data, len);
+ }
+ else
+ {
+ fastcopy(buf, data, len);
+ }
+
+ buf += len;
+ }
+ }
+
+cyg_drv_dsr_lock();
+ pTxBDP->hi = total_len | 0x8000;
+HAL_REORDER_BARRIER();
+ HAL_OR_UINT32(DMA2_SR, 0xf0000000);
+cyg_drv_dsr_unlock();
+}
+
+
+static void
+netarm_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ setMAC(enaddr); // set MAC address
+HAL_REORDER_BARRIER();
+ HAL_OR_UINT32(EthGenCR, 0x80800000); // enable Rx und Tx FIFO
+HAL_REORDER_BARRIER();
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_DMA1);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_DMA2);
+}
+
+static void
+netarm_stop(struct eth_drv_sc *sc)
+{
+ HAL_AND_UINT32(EthGenCR, 0x7f7fffff);
+HAL_REORDER_BARRIER();
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_DMA1);
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_DMA2);
+}
+
+static int
+netarm_control(struct eth_drv_sc *sc, unsigned long key, void *data, int len)
+{
+ return -1;
+}
+
+static void
+netarm_poll(struct eth_drv_sc *sc)
+{
+}
+
+static int
+netarm_int_vector(struct eth_drv_sc *sc)
+{
+ return CYGNUM_HAL_INTERRUPT_DMA1;
+}
+
+static void
+setMAC(unsigned char *esa)
+{
+ HAL_WRITE_UINT32(SAR1, (esa[1] << 8) | esa[0]); // set MAC address
+ HAL_WRITE_UINT32(SAR2, (esa[3] << 8) | esa[2]);
+ HAL_WRITE_UINT32(SAR3, (esa[5] << 8) | esa[4]);
+}
diff --git a/ecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.h b/ecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.h
new file mode 100755
index 0000000..e0e9ab1
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.h
@@ -0,0 +1,88 @@
+#ifndef CYGONCE_DEVS_ETH_ARM_NETARM_ETH_DR_H
+#define CYGONCE_DEVS_ETH_ARM_NETARM_ETH_DR_H
+
+// ====================================================================
+//
+// netarm_eth_drv.h
+//
+// Device I/O - Description of NET+ARM ethernet hardware functions
+// and data structures
+//
+// ====================================================================
+
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors: Harald Brandl
+// Date: 01.08.2004
+// Purpose: Internal interfaces and data structures
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+#define MaxKeys 20
+
+typedef struct
+{
+ unsigned char *RxBuffer;
+ unsigned short key_head, key_tail;
+ unsigned KeyBuffer[MaxKeys];
+}private_data_t;
+
+typedef struct
+{
+ unsigned lo;
+ unsigned hi;
+}BDP_t;
+
+
+static bool netarm_init(struct cyg_netdevtab_entry *tab);
+
+static void netarm_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len);
+static void netarm_deliver(struct eth_drv_sc *sc);
+static int netarm_can_send(struct eth_drv_sc *sc);
+static void netarm_send(
+ struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len, int total_len, unsigned long key);
+static void netarm_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags);
+static void netarm_stop(struct eth_drv_sc *sc);
+static int netarm_control(struct eth_drv_sc *sc, unsigned long key, void *data, int len);
+static void netarm_poll(struct eth_drv_sc *sc);
+static int netarm_int_vector(struct eth_drv_sc *sc);
+
+static void setMAC(unsigned char *esa);
+
+#endif // CYGONCE_DEVS_ETH_ARM_NETARM_ETH_DR_H
diff --git a/ecos/packages/devs/eth/arm/npwr/current/ChangeLog b/ecos/packages/devs/eth/arm/npwr/current/ChangeLog
new file mode 100644
index 0000000..2ffeefc
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/npwr/current/ChangeLog
@@ -0,0 +1,29 @@
+2002-11-12 Gary Thomas <gary@mlbassoc.com>
+
+ * include/devs_eth_npwr.inl:
+ * cdl/npwr_eth_drivers.cdl: New package - 1GHz ethernet drivers
+ on Team ASA NPWR Linux Engine.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/npwr/current/cdl/npwr_eth_drivers.cdl b/ecos/packages/devs/eth/arm/npwr/current/cdl/npwr_eth_drivers.cdl
new file mode 100644
index 0000000..0d17403
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/npwr/current/cdl/npwr_eth_drivers.cdl
@@ -0,0 +1,116 @@
+# ====================================================================
+#
+# npwr_eth_drivers.cdl
+#
+# Ethernet drivers
+# Intel NPWR and PRO/100+ platform specific support
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): hmt
+# Original data: hmt
+# Contributors: gthomas
+# Date: 2000-02-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_XSCALE_NPWR {
+ display "NPWR Linux Engine with PRO/100+ ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_XSCALE_NPWR
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82544 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82544_REQUIRED {
+ display "Intel i82544 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82544_INL <cyg/io/devs_eth_npwr.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82544_CFG <pkgconf/devs_eth_arm_xscale_npwr.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_NPWR_I82544_ETH0 {
+ display "NPWR builtin ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ NPWR builtin port."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82544_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_NPWR_I82544_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ NPWR builtin port."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_NPWR_I82544_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_NPWR_I82544_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x11}"}
+ description "The ethernet station address"
+ }
+ }
+
+ }
+
+}
+
+# EOF npwr_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/arm/npwr/current/include/devs_eth_npwr.inl b/ecos/packages/devs/eth/arm/npwr/current/include/devs_eth_npwr.inl
new file mode 100644
index 0000000..65affac
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/npwr/current/include/devs_eth_npwr.inl
@@ -0,0 +1,129 @@
+//==========================================================================
+//
+// devs/eth/arm/npwr/include/devs_eth_arm_npwr.inl
+//
+// NPWR ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors:msalter, gthomas
+// Date: 2002-01-10
+// Purpose: NPWR ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHERNET
+#include <cyg/hal/hal_cache.h> // HAL_DCACHE_LINE_SIZE
+#include <cyg/hal/hal_io.h> // CYGARC_UNCACHED_ADDRESS
+
+#ifdef CYGPKG_DEVS_ETH_ARM_NPWR_I82544_ETH0
+
+// Use auto speed detection
+#define CYGHWR_DEVS_ETH_INTEL_I82544_USE_ASD
+
+#define CYGHWR_INTEL_I82544_PCI_VIRT_TO_BUS( _x_ ) ((cyg_uint32)CYGARC_VIRT_TO_BUS(_x_))
+#define CYGHWR_INTEL_I82544_PCI_BUS_TO_VIRT( _x_ ) ((cyg_uint32)CYGARC_BUS_TO_VIRT(_x_))
+
+#define MAX_PACKET_SIZE 1536
+#define SIZEOF_DESCRIPTOR 16
+
+#define CYGHWR_INTEL_I82544_PCI_MEM_MAP_SIZE \
+ (((MAX_PACKET_SIZE + SIZEOF_DESCRIPTOR) * \
+ (MAX_TX_DESCRIPTORS + MAX_RX_DESCRIPTORS)) + 64)
+
+static char pci_mem_buffer[CYGHWR_INTEL_I82544_PCI_MEM_MAP_SIZE + HAL_DCACHE_LINE_SIZE];
+
+#define CYGHWR_INTEL_I82544_PCI_MEM_MAP_BASE \
+ (CYGARC_UNCACHED_ADDRESS(((unsigned)pci_mem_buffer + HAL_DCACHE_LINE_SIZE - 1) & ~(HAL_DCACHE_LINE_SIZE - 1)))
+
+static I82544 i82544_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_ARM_NPWR_I82544_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_ARM_NPWR_I82544_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82544_sc0,
+ &i82544_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_NPWR_I82544_ETH0_NAME, // Name for device
+ i82544_start,
+ i82544_stop,
+ i82544_ioctl,
+ i82544_can_send,
+ i82544_send,
+ i82544_recv,
+ i82544_deliver,
+ i82544_poll,
+ i82544_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82544_netdev0,
+ "i82544_" CYGDAT_DEVS_ETH_ARM_NPWR_I82544_ETH0_NAME,
+ i82544_init,
+ &i82544_sc0);
+
+#endif // CYGPKG_DEVS_ETH_ARM_NPWR_I82544_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+I82544 *
+i82544_priv_array[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_NPWR_I82544_ETH0
+ &i82544_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82544_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_NPWR_I82544_ETH0
+ &i82544_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+i82544_sc_array[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_ARM_NPWR_I82544_ETH0
+ &i82544_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// EOF devs_eth_arm_npwr.inl
diff --git a/ecos/packages/devs/eth/arm/olpce2294/current/ChangeLog b/ecos/packages/devs/eth/arm/olpce2294/current/ChangeLog
new file mode 100644
index 0000000..e81a460
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/olpce2294/current/ChangeLog
@@ -0,0 +1,30 @@
+2008-08-31 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * Ethernet driver for LPC-E2294 development board
+ * cdl/olpce2294_eth_drivers.cdl
+ * include/devs_eth_arm_olpce2294.h
+ * include/devs_eth_arm_olpce2294.inl
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/olpce2294/current/cdl/olpce2294_eth_drivers.cdl b/ecos/packages/devs/eth/arm/olpce2294/current/cdl/olpce2294_eth_drivers.cdl
new file mode 100644
index 0000000..487317e
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/olpce2294/current/cdl/olpce2294_eth_drivers.cdl
@@ -0,0 +1,126 @@
+# ====================================================================
+#
+# olpce2294_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for OLPCE2294
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Sergei Gavrikov
+# Contributors: Sergei Gavrikov
+# Date: 2008-08-31
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_OLPCE2294 {
+ display "LAN ethernet driver for Olimex LPC-E2294"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_LPC2XXX_OLPCE2294
+
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+
+ requires CYGPKG_DEVS_ETH_CL_CS8900A
+
+ # Olimex LPC-E2294 development board has Cirrus Logic CS8900A ethernet
+ # controller had been wired in a dumb 8-bit mode.
+ requires CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT
+
+ include_dir cyg/io
+
+ description "
+ Ethernet driver for Olimex LPC-E2294 board."
+
+ cdl_interface CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED {
+ display "CL CS8900A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_INL <cyg/io/devs_eth_arm_olpce2294.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_CFG <pkgconf/devs_eth_arm_olpce2294.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_CL_CS8900A_NOINTS {
+ display "Interrupts are not supported"
+ calculated 1
+ description "
+ Interrups are not supported in 8-bit mode. Polled mode must
+ be used."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_OLPCE2294_ETH0 {
+ display "OLPCE2294 ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ OLPCE2294 port."
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+ implements CYGINT_DEVS_ETH_CL_CS8900A_DATABUS_8BIT
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_OLPCE2294_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_OLPCE2294_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ calculated 1
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_OLPCE2294_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/arm/olpce2294/current/doc/README b/ecos/packages/devs/eth/arm/olpce2294/current/doc/README
new file mode 100644
index 0000000..23a19a1
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/olpce2294/current/doc/README
@@ -0,0 +1,14 @@
+Olimex LPC-E2294 development board has a Cirrus Logic CS8900A ethernet
+controller had been wired to MPU in 8-bit mode. This mode does have a
+few limitations:
+
+ Interrupts are not supported. Polled mode must be used;
+
+ The DMA engine only uses 16 bit memory access and does not
+ support 8 bit transfers;
+
+ The packet page pointer has an auto increment feature that
+ cannot be used in 8-bit mode;
+
+ EEPROM is not supported.
+
diff --git a/ecos/packages/devs/eth/arm/olpce2294/current/include/devs_eth_arm_olpce2294.h b/ecos/packages/devs/eth/arm/olpce2294/current/include/devs_eth_arm_olpce2294.h
new file mode 100644
index 0000000..81eb91c
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/olpce2294/current/include/devs_eth_arm_olpce2294.h
@@ -0,0 +1,57 @@
+#ifndef _CYGONCE_DEVS_ETH_ARM_OLPCE2294_H
+#define _CYGONCE_DEVS_ETH_ARM_OLPCE2294_H
+//==========================================================================
+//
+// devs_eth_arm_olpce2294.h
+//
+// OLPCE2294 ethernet configuration
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Sergei Gavrikov
+// Contributors: Sergei Gavrikov
+// Date: 2008-08-31
+// Purpose: OLPCE2294 ethernet configuration
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+
+#endif // _CYGONCE_DEVS_ETH_ARM_OLPCE2294_H
+//--------------------------------------------------------------------------
+// EOF devs_eth_arm_olpce2294.h
diff --git a/ecos/packages/devs/eth/arm/olpce2294/current/include/devs_eth_arm_olpce2294.inl b/ecos/packages/devs/eth/arm/olpce2294/current/include/devs_eth_arm_olpce2294.inl
new file mode 100644
index 0000000..75a3f23
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/olpce2294/current/include/devs_eth_arm_olpce2294.inl
@@ -0,0 +1,175 @@
+//==========================================================================
+//
+// devs_eth_arm_olpce2294.inl
+//
+// OLPCE2294 ethernet I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Sergei Gavrikov
+// Contributors: Sergei Gavrikov
+// Date: 2008-08-31
+// Purpose: OLPCE2294 ethernet definitions
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_if.h>
+
+#ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+# endif
+#endif
+
+#ifdef __WANT_CONFIG
+//#define DEBUG 0xf
+
+// This is done by reading the low order byte first
+#define CS_IN( _b_, _o_, _d_) \
+ CYG_MACRO_START \
+ cyg_uint8 x, y; \
+ HAL_READ_UINT8 ((cyg_addrword_t)(_b_)+(_o_), x); \
+ _d_ = x; \
+ HAL_READ_UINT8 ((cyg_addrword_t)(_b_)+(_o_)+1, y); \
+ _d_ |= y << 8; \
+ CYG_MACRO_END
+
+// This is done by writing the low order byte first
+#define CS_OUT( _b_, _o_, _d_) \
+ CYG_MACRO_START \
+ HAL_WRITE_UINT8 ((cyg_addrword_t)(_b_)+(_o_), _d_); \
+ HAL_WRITE_UINT8 ((cyg_addrword_t)(_b_)+(_o_)+1, (_d_) >> 8);\
+ CYG_MACRO_END
+
+#endif // __WANT_CONFIG
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_ARM_OLPCE2294_ETH0
+
+#ifndef CYGSEM_DEVS_ETH_ARM_OLPCE2294_ETH0_SET_ESA
+#if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_ARM_OLPCE2294_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_ARM_OLPCE2294_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+#endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+// Note that this section *is* active in an application, outside RedBoot,
+// where the above section is not included.
+
+# include <cyg/hal/hal_if.h>
+
+# ifndef CONFIG_ESA
+# define CONFIG_ESA (6)
+# endif
+# ifndef CONFIG_BOOL
+# define CONFIG_BOOL (1)
+# endif
+
+cyg_bool
+_olpce2294_provide_eth0_esa(struct cs8900a_priv_data* cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa", &set_esa, CONFIG_BOOL);
+ if (ok && set_esa) {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data",
+ cpd->esa, CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+
+# endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+#endif // ! CYGSEM_DEVS_ETH_ARM_OLPCE2294_ETH0_SET_ESA
+
+static cs8900a_priv_data_t cs8900a_eth0_priv_data = {
+ base : (cyg_addrword_t) 0x82000000,
+ interrupt : CYGNUM_HAL_INTERRUPT_NONE,
+#ifdef CYGSEM_DEVS_ETH_ARM_OLPCE2294_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_ARM_OLPCE2294_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &_olpce2294_provide_eth0_esa,
+# else
+ provide_esa : NULL,
+# endif
+#endif
+};
+
+ETH_DRV_SC(cs8900a_sc,
+ &cs8900a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_OLPCE2294_ETH0_NAME,
+ cs8900a_start,
+ cs8900a_stop,
+ cs8900a_control,
+ cs8900a_can_send,
+ cs8900a_send,
+ cs8900a_recv,
+ cs8900a_deliver, // "pseudoDSR" called from fast net thread
+ cs8900a_poll, // poll function, encapsulates ISR and DSR
+ cs8900a_int_vector);
+
+NETDEVTAB_ENTRY(cs8900a_netdev,
+ "cs8900a_" CYGDAT_DEVS_ETH_ARM_OLPCE2294_ETH0_NAME,
+ cs8900a_init,
+ &cs8900a_sc);
+
+#endif // CYGPKG_DEVS_ETH_ARM_OLPCE2294_ETH0
+
+#endif // __WANT_DEVS
+
+// indent: --indent-level4 -br -nut; vim: expandtab tabstop=4 shiftwidth=4
+//--------------------------------------------------------------------------
+// EOF devs_eth_arm_olpce2294.inl
+
diff --git a/ecos/packages/devs/eth/arm/olpcl2294/current/ChangeLog b/ecos/packages/devs/eth/arm/olpcl2294/current/ChangeLog
new file mode 100644
index 0000000..e505378
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/olpcl2294/current/ChangeLog
@@ -0,0 +1,31 @@
+2008-08-31 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * Ethernet driver for LPC-L2294 development board
+ * cdl/olpcl2294_eth_drivers.cdl
+ * include/devs_eth_arm_olpcl2294.h
+ * include/devs_eth_arm_olpcl2294.inl
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
diff --git a/ecos/packages/devs/eth/arm/olpcl2294/current/cdl/olpcl2294_eth_drivers.cdl b/ecos/packages/devs/eth/arm/olpcl2294/current/cdl/olpcl2294_eth_drivers.cdl
new file mode 100644
index 0000000..0509273
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/olpcl2294/current/cdl/olpcl2294_eth_drivers.cdl
@@ -0,0 +1,112 @@
+# ====================================================================
+#
+# olpcl2294_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for OLPCL2294
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Sergei Gavrikov
+# Contributors: Sergei Gavrikov
+# Date: 2008-08-31
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_OLPCL2294 {
+ display "LAN ethernet driver for Olimex LPC-L2294-1MB"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_LPC2XXX_OLPCL2294
+
+ include_dir cyg/io
+
+ description "
+ Ethernet driver for Olimex LPC-L2294-1MB board."
+
+ # FIXME: This really belongs in the CL CS8900A package
+ cdl_interface CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED {
+ display "Cirrus Logic CS8900A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_INL <cyg/io/devs_eth_arm_olpcl2294.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_CFG <pkgconf/devs_eth_arm_olpcl2294.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ARM_OLPCL2294_ETH0 {
+ display "OLPCL2294 ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ OLPCL2294 port."
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_OLPCL2294_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_OLPCL2294_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ calculated 1
+ description "
+ Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware
+ does not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_OLPCL2294_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/arm/olpcl2294/current/include/devs_eth_arm_olpcl2294.h b/ecos/packages/devs/eth/arm/olpcl2294/current/include/devs_eth_arm_olpcl2294.h
new file mode 100644
index 0000000..547e7b8
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/olpcl2294/current/include/devs_eth_arm_olpcl2294.h
@@ -0,0 +1,57 @@
+#ifndef _CYGONCE_DEVS_ETH_ARM_OLPCL2294_H
+#define _CYGONCE_DEVS_ETH_ARM_OLPCL2294_H
+//==========================================================================
+//
+// devs_eth_arm_olpcl2294.h
+//
+// OLPCL2294 ethernet configuration
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Sergei Gavrikov
+// Contributors: Sergei Gavrikov
+// Date: 2008-08-31
+// Purpose: OLPCL2294 ethernet configuration
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+
+#endif // _CYGONCE_DEVS_ETH_ARM_OLPCL2294_H
+//--------------------------------------------------------------------------
+// EOF devs_eth_arm_olpcl2294.h
diff --git a/ecos/packages/devs/eth/arm/olpcl2294/current/include/devs_eth_arm_olpcl2294.inl b/ecos/packages/devs/eth/arm/olpcl2294/current/include/devs_eth_arm_olpcl2294.inl
new file mode 100644
index 0000000..10bcc04
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/olpcl2294/current/include/devs_eth_arm_olpcl2294.inl
@@ -0,0 +1,169 @@
+//==========================================================================
+//
+// devs_eth_arm_olpcl2294.inl
+//
+// OLPCL2294 ethernet I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Sergei Gavrikov
+// Contributors: Sergei Gavrikov
+// Date: 2008-08-31
+// Purpose: OLPCL2294 ethernet definitions
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <cyg/hal/hal_var_ints.h>
+#include <cyg/hal/hal_if.h>
+
+#ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+# endif
+#endif
+
+#ifdef __WANT_CONFIG
+//#define DEBUG 0x0f
+#endif // __WANT_CONFIG
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_ARM_OLPCL2294_ETH0
+
+#ifndef CYGSEM_DEVS_ETH_ARM_OLPCL2294_ETH0_SET_ESA
+# if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_ARM_OLPCL2294_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_ARM_OLPCL2294_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+# endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+// Note that this section *is* active in an application, outside RedBoot,
+// where the above section is not included.
+
+# include <cyg/hal/hal_if.h>
+
+# ifndef CONFIG_ESA
+# define CONFIG_ESA (6)
+# endif
+# ifndef CONFIG_BOOL
+# define CONFIG_BOOL (1)
+# endif
+
+cyg_bool
+_olpcl2294_provide_eth0_esa(struct cs8900a_priv_data* cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa", &set_esa, CONFIG_BOOL);
+ if (ok && set_esa) {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data", cpd->esa, CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+
+# endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+#endif // ! CYGSEM_DEVS_ETH_ARM_OLPCL2294_ETH0_SET_ESA
+
+static __inline__ void
+post_reset(cyg_addrword_t base)
+{
+ // Toggle A0 connected to the SBHE# line
+ HAL_WRITE_UINT8( 0x82000000, 1 );
+ HAL_WRITE_UINT8( 0x82000001, 2 );
+ HAL_WRITE_UINT8( 0x82000000, 3 );
+ HAL_WRITE_UINT8( 0x82000001, 0 );
+}
+
+#undef CYGHWR_CL_CS8900A_PLF_POST_RESET
+#define CYGHWR_CL_CS8900A_PLF_POST_RESET(base) post_reset(base)
+
+static cs8900a_priv_data_t cs8900a_eth0_priv_data = {
+ base : (cyg_addrword_t) 0x82000000,
+ interrupt : CYGNUM_HAL_INTERRUPT_EINT2,
+#ifdef CYGSEM_DEVS_ETH_ARM_OLPCL2294_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_ARM_OLPCL2294_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &_olpcl2294_provide_eth0_esa,
+# else
+ provide_esa : NULL,
+# endif
+#endif
+};
+
+ETH_DRV_SC(cs8900a_sc,
+ &cs8900a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_ARM_OLPCL2294_ETH0_NAME,
+ cs8900a_start,
+ cs8900a_stop,
+ cs8900a_control,
+ cs8900a_can_send,
+ cs8900a_send,
+ cs8900a_recv,
+ cs8900a_deliver, // "pseudoDSR" called from fast net thread
+ cs8900a_poll, // poll function, encapsulates ISR and DSR
+ cs8900a_int_vector);
+
+NETDEVTAB_ENTRY(cs8900a_netdev,
+ "cs8900a_" CYGDAT_DEVS_ETH_ARM_OLPCL2294_ETH0_NAME,
+ cs8900a_init,
+ &cs8900a_sc);
+
+#endif // CYGPKG_DEVS_ETH_ARM_OLPCL2294_ETH0
+
+#endif // __WANT_DEVS
+
+// indent: --indent-level4 -br -nut; vim: expandtab tabstop=4 shiftwidth=4
+//--------------------------------------------------------------------------
+// EOF devs_eth_arm_olpcl2294.inl
+
diff --git a/ecos/packages/devs/eth/arm/phycore229x/current/ChangeLog b/ecos/packages/devs/eth/arm/phycore229x/current/ChangeLog
new file mode 100644
index 0000000..33132db
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/phycore229x/current/ChangeLog
@@ -0,0 +1,29 @@
+2008-01-01 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/phycore229x_eth_drivers.cdl:
+ * include/devs_eth_phycore229x.inl:
+ release of phyCORE-LPC229x ethernet driver package
+
+# ====================================================================
+## ####GPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 Free Software Foundation, Inc.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 or (at your option) any
+## later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the
+## Free Software Foundation, Inc., 51 Franklin Street,
+## Fifth Floor, Boston, MA 02110-1301, USA.
+## -------------------------------------------
+## ####GPLCOPYRIGHTEND####
+# ====================================================================
diff --git a/ecos/packages/devs/eth/arm/phycore229x/current/cdl/phycore229x_eth_drivers.cdl b/ecos/packages/devs/eth/arm/phycore229x/current/cdl/phycore229x_eth_drivers.cdl
new file mode 100755
index 0000000..d261f70
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/phycore229x/current/cdl/phycore229x_eth_drivers.cdl
@@ -0,0 +1,117 @@
+# ====================================================================
+#
+# phycore229x_eth_drivers.cdl
+#
+# Ethernet drivers - platform support for phyCORE-LPC229x
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors:
+# Date: 2007-11-24
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_PHYCORE229X {
+ display "LAN ethernet driver for phyCORE-LPC229x"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_LPC2XXX_PHYCORE229X
+
+ include_dir cyg/io
+
+ # 32-bit mode, with EEPROM
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
+
+ requires CYGPKG_DEVS_ETH_SMSC_LAN91CXX
+ requires CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO == CYGHWR_HAL_ARM_PHYCORE229X_ETH_INT_PRIO
+
+ description "This option includes the ethernet device driver for the
+ phyCORE-LPC229x board."
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL <cyg/io/devs_eth_phycore229x.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG <pkgconf/devs_eth_arm_phycore229x.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+
+ cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
+ display "SMSC LAN91CXX driver required"
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_PHYCORE229X_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ARM_PHYCORE229X_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "
+ Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA. The phyCORE
+ board contains an EEPROM so setting the ESA here is not
+ required. If RedBoot supports FLASH configuration then
+ the MAC address is configurable and a static MAC address
+ is not required."
+
+ cdl_option CYGDAT_DEVS_ETH_ARM_PHYCORE229X_ESA {
+ display "The ethernet station address (MAC)"
+ flavor data
+ default_value {"{0x12, 0x13, 0x14, 0x15, 0x16, 0x17}"}
+ description "
+ A static ethernet station address. Caution: Booting two systems
+ with the same MAC on the same network, will cause severe conflicts."
+ }
+ }
+}
+
+# EOF phycore229x_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/arm/phycore229x/current/include/devs_eth_phycore229x.inl b/ecos/packages/devs/eth/arm/phycore229x/current/include/devs_eth_phycore229x.inl
new file mode 100755
index 0000000..aac7cfa
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/phycore229x/current/include/devs_eth_phycore229x.inl
@@ -0,0 +1,203 @@
+#ifndef CYGONCE_DEVS_ETH_PHYCORE229X_INL
+#define CYGONCE_DEVS_ETH_PHYCORE229X_INL
+//==========================================================================
+//
+// devs_eth_phycore_229x.inl
+//
+// phyCORE-LPC229x ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors:
+// Date: 2007-11-24
+// Purpose:
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_arm_phycore229x.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGPKG_REDBOOT
+ #include <pkgconf/redboot.h>
+ #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+ #include <redboot.h>
+ #include <flash_config.h>
+ #endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#endif // CYGPKG_REDBOOT
+
+
+
+//--------------------------------------------------------------------------
+// Configure LAN91CXX driver
+//
+#define LAN91CXX_IS_LAN91C111 1
+#define LAN91CXX_FORCE_10MHZ 1 // due a PCB tracking problem only
+ // 10 MHz is possible
+#define LAN91CXX_32BIT_RX 1 // 32 bit access
+
+
+//--------------------------------------------------------------------------
+// RedBoot ESA Flash configuration options
+// When this option is enabled, RedBoot will keep configuration
+// data in a separate block of FLASH memory.
+//
+#if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_ARM_PHYCORE229X_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_ARM_PHYCORE229X_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+#endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+
+//--------------------------------------------------------------------------
+// Application ESA Flash configuration options
+// Note that this section *is* active in an application, outside
+// RedBoot, where the above section is not included.
+//
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+#include <cyg/hal/hal_if.h>
+
+#ifndef CONFIG_ESA
+ #define CONFIG_ESA (6)
+#endif
+#ifndef CONFIG_BOOL
+ #define CONFIG_BOOL (1)
+#endif
+
+
+//--------------------------------------------------------------------------
+// Provide ESA function
+// Returns true if ESA is configured by flash, else false
+//
+cyg_bool phycore229x_provide_esa(struct lan91cxx_priv_data *cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+
+
+ //
+ // first we check, if the ESA should be set according to flash
+ // configuration
+ //
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa",
+ &set_esa,
+ CONFIG_BOOL);
+ //
+ // if esa should be set by flash configuration, then we store the
+ // esa from flash in driver configuration data and return true
+ //
+ if (ok && set_esa)
+ {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data",
+ cpd->enaddr,
+ CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+
+//---------------------------------------------------------------------------
+// Stores configuration data for generic smsc91xxx driver
+//
+static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
+ base : (unsigned short *)(CYGHWR_HAL_ARM_PHYCORE229X_ETH_MEM_AREA
+ + 0x0300),
+ interrupt : ( CYGHWR_HAL_ARM_PHYCORE229X_ETH_EINT +
+ CYGNUM_HAL_INTERRUPT_EINT0) ,
+ //
+ // if user selects a hardwired ESA in configuration then
+ // we fill the ESA here
+ //
+#ifdef CYGSEM_DEVS_ETH_PHYCORE229X_SET_ESA
+ enaddr : CYGDAT_DEVS_ETH_PHYCORE229X_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &phycore229x_provide_esa,
+#else
+ provide_esa : NULL, // read MAC from associated EEPROM
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+}; // lan91cxx_priv_data
+
+
+//---------------------------------------------------------------------------
+// Driver configuration
+//
+ETH_DRV_SC(
+ lan91cxx_sc,
+ &lan91cxx_eth0_priv_data, // driver specific data
+ CYGDAT_DEVS_ETH_ARM_PHYCORE229X_NAME, // device name
+ lan91cxx_start,
+ lan91cxx_stop,
+ lan91cxx_control,
+ lan91cxx_can_send,
+ lan91cxx_send,
+ lan91cxx_recv,
+ lan91cxx_deliver,
+ lan91cxx_poll,
+ lan91cxx_int_vector
+);
+
+
+//---------------------------------------------------------------------------
+// Entry into net device table
+//
+NETDEVTAB_ENTRY(
+ lan91cxx_netdev,
+ "lan91cxx_" CYGDAT_DEVS_ETH_ARM_PHYCORE229X_NAME,
+ smsc_lan91cxx_init,
+ &lan91cxx_sc
+);
+
+//---------------------------------------------------------------------------
+#endif // CYGONCE_DEVS_ETH_PHYCORE229X_INL
diff --git a/ecos/packages/devs/eth/arm/picasso/current/ChangeLog b/ecos/packages/devs/eth/arm/picasso/current/ChangeLog
new file mode 100644
index 0000000..1231131
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/picasso/current/ChangeLog
@@ -0,0 +1,29 @@
+2003-08-22 Gary Thomas <gary@mind.be>
+
+ * include/devs_eth_picasso.inl:
+ * cdl/picasso_eth_drivers.cdl:
+ New package - support for NMI uEngine based "picasso" board
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/picasso/current/cdl/picasso_eth_drivers.cdl b/ecos/packages/devs/eth/arm/picasso/current/cdl/picasso_eth_drivers.cdl
new file mode 100644
index 0000000..e7e0d6c
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/picasso/current/cdl/picasso_eth_drivers.cdl
@@ -0,0 +1,130 @@
+# ====================================================================
+#
+# picasso_eth_drivers.cdl
+#
+# Ethernet drivers - support for PCI ethernet on NMI picasso
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov, hmt, gthomas
+# Date: 2001-02-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_XSCALE_PICASSO {
+ display "picasso ethernet driver"
+ description "
+ Ethernet drivers for NMI picasso board."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_PCI
+ requires CYGPKG_DEVS_ETH_NS_DP83902A
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the NS DP83902A package
+ cdl_interface CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED {
+ display "NS DP83902A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_INL <cyg/io/devs_eth_picasso.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_CFG <pkgconf/devs_eth_arm_xscale_picasso.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_PICASSO_ETH0 {
+ display "PCI ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for a
+ CF card."
+
+ implements CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_PICASSO_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_PICASSO_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_PICASSO_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_PICASSO_OPTIONS {
+ display "PCMCIA ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_PICASSO_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the PCMCIA ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
+
+# EOF picasso_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/arm/picasso/current/include/devs_eth_picasso.inl b/ecos/packages/devs/eth/arm/picasso/current/include/devs_eth_picasso.inl
new file mode 100644
index 0000000..3e4da19
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/picasso/current/include/devs_eth_picasso.inl
@@ -0,0 +1,231 @@
+//==========================================================================
+//
+// devs/eth/arm/picasso/..../include/devs_eth_picasso.inl
+//
+// NMI picasso ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, hmt, gthomas
+// Contributors: jskov
+// Date: 2001-02-28
+// Purpose: FRV400 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+#include <cyg/hal/hal_if.h>
+#include <cyg/io/pci.h>
+
+#ifdef __WANT_CONFIG
+
+#define CYGHWR_NS_DP83902A_PLF_RESET(_dp_) \
+ CYG_MACRO_START \
+ cyg_uint8 _t; \
+ HAL_READ_UINT8(_dp_->reset, _t); \
+ CYGACC_CALL_IF_DELAY_US(10); \
+ HAL_WRITE_UINT8(_dp_->reset, _t); \
+ CYGACC_CALL_IF_DELAY_US(10000); \
+ CYG_MACRO_END
+
+#define DP_IN(_b_, _o_, _d_) \
+ CYG_MACRO_START \
+ _d_ = pci_io_read_8((cyg_addrword_t)(_b_)+(_o_)); \
+ CYG_MACRO_END
+
+#define DP_OUT(_b_, _o_, _d_) \
+ CYG_MACRO_START \
+ pci_io_write_8((cyg_addrword_t)(_b_)+(_o_), _d_); \
+ CYG_MACRO_END
+
+#define DP_IN_DATA(_b_, _d_) \
+ CYG_MACRO_START \
+ _d_ = pci_io_read_16((cyg_addrword_t)(_b_)); \
+ CYG_MACRO_END
+
+#define DP_OUT_DATA(_b_, _d_) \
+ CYG_MACRO_START \
+ pci_io_write_16((cyg_addrword_t)(_b_), _d_); \
+ CYG_MACRO_END
+
+//#define CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+//#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
+
+#endif // __WANT_CONFIG
+
+#ifdef __WANT_DEVS
+
+#if defined(CYGSEM_DEVS_ETH_PICASSO_ETH0_SET_ESA)
+#if defined(CYGPKG_REDBOOT)
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+RedBoot_config_option("Network hardware address [MAC]",
+ lan_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#endif // CYGPKG_REDBOOT
+#include <cyg/hal/hal_if.h>
+#ifndef CONFIG_ESA
+#define CONFIG_ESA 6
+#endif
+#endif
+
+static cyg_bool
+find_rtl8029_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+{
+ return ((v == 0x10EC) && (d == 0x8029));
+}
+
+static void
+_picasso_eth_init(dp83902a_priv_data_t *dp)
+{
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+#if defined(CYGSEM_DEVS_ETH_PICASSO_ETH0_SET_ESA)
+ cyg_bool esa_ok;
+ unsigned char _esa[6];
+#else
+ unsigned char prom[32];
+ int i;
+#endif
+
+ devid = CYG_PCI_NULL_DEVID;
+ if (cyg_pci_find_matching( &find_rtl8029_match_func, NULL, &devid )) {
+ cyg_pci_get_device_info(devid, &dev_info);
+ cyg_pci_translate_interrupt(&dev_info, &dp->interrupt);
+ dp->base = (cyg_uint8 *)(dev_info.base_map[0] & ~1);
+ dp->data = dp->base + 0x10;
+ dp->reset = dp->base + 0x1F;
+#if 0
+ diag_printf("RTL8029 at %p, interrupt: %x\n", dp->base, dp->interrupt);
+#endif
+#if defined(CYGSEM_DEVS_ETH_PICASSO_ETH0_SET_ESA)
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "lan_esa", _esa, CONFIG_ESA);
+ if (esa_ok) {
+ memcpy(dp->esa, _esa, sizeof(_esa));
+ }
+#else
+ // Read ESA from EEPROM
+ DP_OUT(dp->base, DP_DCR, 0x49); // Wordwide access
+ DP_OUT(dp->base, DP_RBCH, 0); // Remote byte count
+ DP_OUT(dp->base, DP_RBCL, 0);
+ DP_OUT(dp->base, DP_ISR, 0xFF); // Clear any pending interrupts
+ DP_OUT(dp->base, DP_IMR, 0x00); // Mask all interrupts
+ DP_OUT(dp->base, DP_RCR, 0x20); // Monitor
+ DP_OUT(dp->base, DP_TCR, 0x02); // loopback
+ DP_OUT(dp->base, DP_RBCH, 32); // Remote byte count
+ DP_OUT(dp->base, DP_RBCL, 0);
+ DP_OUT(dp->base, DP_RSAL, 0); // Remote address
+ DP_OUT(dp->base, DP_RSAH, 0);
+ DP_OUT(dp->base, DP_CR, DP_CR_START|DP_CR_RDMA); // Read data
+ for (i = 0; i < 32; i++) {
+ cyg_uint16 _val;
+ HAL_READ_UINT16(dp->data, _val);
+ prom[i] = _val;
+ }
+ // Set ESA into chip
+ DP_OUT(dp->base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); // Select page 1
+ for (i = 0; i < 6; i++) {
+ DP_OUT(dp->base, DP_P1_PAR0+i, prom[i]);
+ }
+ DP_OUT(dp->base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); // Select page 0
+#endif
+ }
+}
+
+#undef CYGHWR_NS_DP83902A_PLF_INIT
+#define CYGHWR_NS_DP83902A_PLF_INIT(dp) _picasso_eth_init(dp)
+
+#ifndef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static void
+_picasso_eth_int_clear(dp83902a_priv_data_t *dp)
+{
+ cyg_drv_interrupt_acknowledge(dp->interrupt);
+}
+
+#undef CYGHWR_NS_DP83902A_PLF_INT_CLEAR
+#define CYGHWR_NS_DP83902A_PLF_INT_CLEAR(dp) _picasso_eth_int_clear(dp)
+#endif
+
+#ifdef CYGPKG_DEVS_ETH_PICASSO_ETH0
+
+static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
+ base : (cyg_uint8*) 0, //
+ data : (cyg_uint8*) 0, // Filled in at runtime
+ reset: (cyg_uint8*) 0, //
+ interrupt: 0, //
+ tx_buf1: 0x40, //
+ tx_buf2: 0x48, // Buffer layout - change with care
+ rx_buf_start: 0x50, //
+ rx_buf_end: 0x80, //
+#ifdef CYGSEM_DEVS_ETH_PICASSO_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_PICASSO_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+};
+
+ETH_DRV_SC(dp83902a_sc,
+ &dp83902a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_PICASSO_ETH0_NAME,
+ dp83902a_start,
+ dp83902a_stop,
+ dp83902a_control,
+ dp83902a_can_send,
+ dp83902a_send,
+ dp83902a_recv,
+ dp83902a_deliver, // "pseudoDSR" called from fast net thread
+ dp83902a_poll, // poll function, encapsulates ISR and DSR
+ dp83902a_int_vector);
+
+NETDEVTAB_ENTRY(dp83902a_netdev,
+ "dp83902a_" CYGDAT_DEVS_ETH_PICASSO_ETH0_NAME,
+ dp83902a_init,
+ &dp83902a_sc);
+
+#endif // CYGPKG_DEVS_ETH_PICASSO_ETH0
+
+#endif // __WANT_DEVS
+
+// --------------------------------------------------------------
+
+// EOF devs_eth_picasso.inl
diff --git a/ecos/packages/devs/eth/arm/uE250/current/ChangeLog b/ecos/packages/devs/eth/arm/uE250/current/ChangeLog
new file mode 100644
index 0000000..79b51cc
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/uE250/current/ChangeLog
@@ -0,0 +1,29 @@
+2003-02-04 Gary Thomas <gary@mind.be>
+
+ * include/devs_eth_uE250.inl:
+ * cdl/uE250_eth_drivers.cdl:
+ New package - support for NMI uE250 (Xscale PXA250).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/uE250/current/cdl/uE250_eth_drivers.cdl b/ecos/packages/devs/eth/arm/uE250/current/cdl/uE250_eth_drivers.cdl
new file mode 100644
index 0000000..94a1759
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/uE250/current/cdl/uE250_eth_drivers.cdl
@@ -0,0 +1,130 @@
+# ====================================================================
+#
+# ue250_eth_drivers.cdl
+#
+# Ethernet drivers - support for PCI ethernet on NMI uE250
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov, hmt, gthomas
+# Date: 2001-02-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_XSCALE_UE250 {
+ display "uE250 ethernet driver"
+ description "
+ Ethernet drivers for NMI uE250 board."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_PCI
+ requires CYGPKG_DEVS_ETH_NS_DP83902A
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the NS DP83902A package
+ cdl_interface CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED {
+ display "NS DP83902A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_INL <cyg/io/devs_eth_uE250.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_CFG <pkgconf/devs_eth_arm_xscale_ue250.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_UE250_ETH0 {
+ display "PCI ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for a
+ CF card."
+
+ implements CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_UE250_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_UE250_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_UE250_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_UE250_OPTIONS {
+ display "PCMCIA ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_UE250_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the PCMCIA ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
+
+# EOF ue250_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/arm/uE250/current/include/devs_eth_uE250.inl b/ecos/packages/devs/eth/arm/uE250/current/include/devs_eth_uE250.inl
new file mode 100644
index 0000000..af4c9dd
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/uE250/current/include/devs_eth_uE250.inl
@@ -0,0 +1,231 @@
+//==========================================================================
+//
+// devs/eth/arm/uE250/..../include/devs_eth_uE250.inl
+//
+// NMI uE250 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, hmt, gthomas
+// Contributors: jskov
+// Date: 2001-02-28
+// Purpose: FRV400 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+#include <cyg/hal/hal_if.h>
+#include <cyg/io/pci.h>
+
+#ifdef __WANT_CONFIG
+
+#define CYGHWR_NS_DP83902A_PLF_RESET(_dp_) \
+ CYG_MACRO_START \
+ cyg_uint8 _t; \
+ HAL_READ_UINT8(_dp_->reset, _t); \
+ CYGACC_CALL_IF_DELAY_US(10); \
+ HAL_WRITE_UINT8(_dp_->reset, _t); \
+ CYGACC_CALL_IF_DELAY_US(10000); \
+ CYG_MACRO_END
+
+#define DP_IN(_b_, _o_, _d_) \
+ CYG_MACRO_START \
+ _d_ = pci_io_read_8((cyg_addrword_t)(_b_)+(_o_)); \
+ CYG_MACRO_END
+
+#define DP_OUT(_b_, _o_, _d_) \
+ CYG_MACRO_START \
+ pci_io_write_8((cyg_addrword_t)(_b_)+(_o_), _d_); \
+ CYG_MACRO_END
+
+#define DP_IN_DATA(_b_, _d_) \
+ CYG_MACRO_START \
+ _d_ = pci_io_read_16((cyg_addrword_t)(_b_)); \
+ CYG_MACRO_END
+
+#define DP_OUT_DATA(_b_, _d_) \
+ CYG_MACRO_START \
+ pci_io_write_16((cyg_addrword_t)(_b_), _d_); \
+ CYG_MACRO_END
+
+//#define CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+//#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
+
+#endif // __WANT_CONFIG
+
+#ifdef __WANT_DEVS
+
+#if defined(CYGSEM_DEVS_ETH_UE250_ETH0_SET_ESA)
+#if defined(CYGPKG_REDBOOT)
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+RedBoot_config_option("Network hardware address [MAC]",
+ lan_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#endif // CYGPKG_REDBOOT
+#include <cyg/hal/hal_if.h>
+#ifndef CONFIG_ESA
+#define CONFIG_ESA 6
+#endif
+#endif
+
+static cyg_bool
+find_rtl8029_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+{
+ return ((v == 0x10EC) && (d == 0x8029));
+}
+
+static void
+_ue250_eth_init(dp83902a_priv_data_t *dp)
+{
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+#if defined(CYGSEM_DEVS_ETH_UE250_ETH0_SET_ESA)
+ cyg_bool esa_ok;
+ unsigned char _esa[6];
+#else
+ unsigned char prom[32];
+ int i;
+#endif
+
+ devid = CYG_PCI_NULL_DEVID;
+ if (cyg_pci_find_matching( &find_rtl8029_match_func, NULL, &devid )) {
+ cyg_pci_get_device_info(devid, &dev_info);
+ cyg_pci_translate_interrupt(&dev_info, &dp->interrupt);
+ dp->base = (cyg_uint8 *)(dev_info.base_map[0] & ~1);
+ dp->data = dp->base + 0x10;
+ dp->reset = dp->base + 0x1F;
+#if 0
+ diag_printf("RTL8029 at %p, interrupt: %x\n", dp->base, dp->interrupt);
+#endif
+#if defined(CYGSEM_DEVS_ETH_UE250_ETH0_SET_ESA)
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "lan_esa", _esa, CONFIG_ESA);
+ if (esa_ok) {
+ memcpy(dp->esa, _esa, sizeof(_esa));
+ }
+#else
+ // Read ESA from EEPROM
+ DP_OUT(dp->base, DP_DCR, 0x49); // Wordwide access
+ DP_OUT(dp->base, DP_RBCH, 0); // Remote byte count
+ DP_OUT(dp->base, DP_RBCL, 0);
+ DP_OUT(dp->base, DP_ISR, 0xFF); // Clear any pending interrupts
+ DP_OUT(dp->base, DP_IMR, 0x00); // Mask all interrupts
+ DP_OUT(dp->base, DP_RCR, 0x20); // Monitor
+ DP_OUT(dp->base, DP_TCR, 0x02); // loopback
+ DP_OUT(dp->base, DP_RBCH, 32); // Remote byte count
+ DP_OUT(dp->base, DP_RBCL, 0);
+ DP_OUT(dp->base, DP_RSAL, 0); // Remote address
+ DP_OUT(dp->base, DP_RSAH, 0);
+ DP_OUT(dp->base, DP_CR, DP_CR_START|DP_CR_RDMA); // Read data
+ for (i = 0; i < 32; i++) {
+ cyg_uint16 _val;
+ HAL_READ_UINT16(dp->data, _val);
+ prom[i] = _val;
+ }
+ // Set ESA into chip
+ DP_OUT(dp->base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); // Select page 1
+ for (i = 0; i < 6; i++) {
+ DP_OUT(dp->base, DP_P1_PAR0+i, prom[i]);
+ }
+ DP_OUT(dp->base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); // Select page 0
+#endif
+ }
+}
+
+#undef CYGHWR_NS_DP83902A_PLF_INIT
+#define CYGHWR_NS_DP83902A_PLF_INIT(dp) _ue250_eth_init(dp)
+
+#ifndef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static void
+_ue250_eth_int_clear(dp83902a_priv_data_t *dp)
+{
+ cyg_drv_interrupt_acknowledge(dp->interrupt);
+}
+
+#undef CYGHWR_NS_DP83902A_PLF_INT_CLEAR
+#define CYGHWR_NS_DP83902A_PLF_INT_CLEAR(dp) _ue250_eth_int_clear(dp)
+#endif
+
+#ifdef CYGPKG_DEVS_ETH_UE250_ETH0
+
+static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
+ base : (cyg_uint8*) 0, //
+ data : (cyg_uint8*) 0, // Filled in at runtime
+ reset: (cyg_uint8*) 0, //
+ interrupt: 0, //
+ tx_buf1: 0x40, //
+ tx_buf2: 0x48, // Buffer layout - change with care
+ rx_buf_start: 0x50, //
+ rx_buf_end: 0x80, //
+#ifdef CYGSEM_DEVS_ETH_UE250_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_UE250_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+};
+
+ETH_DRV_SC(dp83902a_sc,
+ &dp83902a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_UE250_ETH0_NAME,
+ dp83902a_start,
+ dp83902a_stop,
+ dp83902a_control,
+ dp83902a_can_send,
+ dp83902a_send,
+ dp83902a_recv,
+ dp83902a_deliver, // "pseudoDSR" called from fast net thread
+ dp83902a_poll, // poll function, encapsulates ISR and DSR
+ dp83902a_int_vector);
+
+NETDEVTAB_ENTRY(dp83902a_netdev,
+ "dp83902a_" CYGDAT_DEVS_ETH_UE250_ETH0_NAME,
+ dp83902a_init,
+ &dp83902a_sc);
+
+#endif // CYGPKG_DEVS_ETH_UE250_ETH0
+
+#endif // __WANT_DEVS
+
+// --------------------------------------------------------------
+
+// EOF devs_eth_ue250.inl
diff --git a/ecos/packages/devs/eth/arm/xsengine/current/ChangeLog b/ecos/packages/devs/eth/arm/xsengine/current/ChangeLog
new file mode 100644
index 0000000..a8c5987
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/xsengine/current/ChangeLog
@@ -0,0 +1,29 @@
+2005-02-23 Kurt Stremerch <kurt.stremerch@exys.be>
+
+ * include/devs_eth_xsengine.inl:
+ * cdl/xsengine_eth_drivers.cdl:
+ New package - support for Exys XSEngine (Xscale PXA255).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/arm/xsengine/current/cdl/xsengine_eth_drivers.cdl b/ecos/packages/devs/eth/arm/xsengine/current/cdl/xsengine_eth_drivers.cdl
new file mode 100644
index 0000000..36fa3d4
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/xsengine/current/cdl/xsengine_eth_drivers.cdl
@@ -0,0 +1,116 @@
+# ====================================================================
+#
+# xsengine_eth_drivers.cdl
+#
+# Ethernet drivers - support for LAN91C111 ethernet controller
+# on the Exys XSEngine board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Kurt Stremerch
+# Contributors: Jordi Colomer, nickg
+# Date: 2005-02-23
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_XSCALE_XSENGINE {
+ display "XSEngine SMC91C111 ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_ARM_XSCALE_XSENGINE
+
+ include_dir cyg/io
+
+ description "Ethernet driver for XSEngine boards."
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+
+ cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
+ display "SMSC LAN91CXX driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL <cyg/io/devs_eth_xsengine.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG <pkgconf/devs_eth_arm_xscale_xsengine.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_XSENGINE_ETH0 {
+ display "XSEngine ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ Microdev port."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_XSENGINE_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_XSENGINE_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_XSENGINE_ETH0_ESA {
+ display "The ethernet station address (MAC)"
+ flavor data
+ default_value {"{0x12, 0x13, 0x14, 0x15, 0x16, 0x17}"}
+ description "A static ethernet station address.
+ Caution: Booting two systems with the same MAC on the same
+ network, will cause severe conflicts."
+ }
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/arm/xsengine/current/include/devs_eth_xsengine.inl b/ecos/packages/devs/eth/arm/xsengine/current/include/devs_eth_xsengine.inl
new file mode 100644
index 0000000..2a16557
--- /dev/null
+++ b/ecos/packages/devs/eth/arm/xsengine/current/include/devs_eth_xsengine.inl
@@ -0,0 +1,141 @@
+//==========================================================================
+//
+//
+// XSEngine ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Kurt Stremerch
+// Contributors: Jordi Colomer, nickg
+// Date: 2005-02-23
+// Purpose: XSEngine ethernet definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_arm_xscale_xsengine.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+# endif
+#endif
+
+#define LAN91CXX_IS_LAN91C111
+#define CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR 1
+
+#ifdef CYGPKG_DEVS_ETH_XSENGINE_ETH0
+
+#if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_XSENGINE_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+);
+RedBoot_config_option(CYGDAT_DEVS_ETH_XSENGINE_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+);
+#endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+// Note that this section *is* active in an application, outside RedBoot,
+// where the above section is not included.
+
+# include <cyg/hal/hal_if.h>
+
+# ifndef CONFIG_ESA
+# define CONFIG_ESA (6)
+# endif
+# ifndef CONFIG_BOOL
+# define CONFIG_BOOL (1)
+# endif
+
+cyg_bool
+_xsengine_provide_eth0_esa(struct lan91cxx_priv_data* cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa", &set_esa, CONFIG_BOOL);
+ if (ok && set_esa) {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data", cpd->enaddr, CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
+ base : (unsigned short *) 0x60000000,
+#ifdef CYGSEM_DEVS_ETH_XSENGINE_ETH0_SET_ESA
+ enaddr : CYGDAT_DEVS_ETH_XSENGINE_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &_xsengine_provide_eth0_esa,
+#else
+ provide_esa : NULL,
+#endif
+};
+
+ETH_DRV_SC(lan91cxx_sc,
+ &lan91cxx_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_XSENGINE_ETH0_NAME, // Name for device
+ lan91cxx_start,
+ lan91cxx_stop,
+ lan91cxx_control,
+ lan91cxx_can_send,
+ lan91cxx_send,
+ lan91cxx_recv,
+ lan91cxx_deliver,
+ lan91cxx_poll,
+ lan91cxx_int_vector
+);
+
+NETDEVTAB_ENTRY(lan91cxx_netdev,
+ "lan91cxx_" CYGDAT_DEVS_ETH_XSENGINE_ETH0_NAME,
+ smsc_lan91cxx_init,
+ &lan91cxx_sc);
+
+#endif // CYGPKG_DEVS_ETH_XSENGINE_ETH0
diff --git a/ecos/packages/devs/eth/cf/current/ChangeLog b/ecos/packages/devs/eth/cf/current/ChangeLog
new file mode 100644
index 0000000..9bf061a
--- /dev/null
+++ b/ecos/packages/devs/eth/cf/current/ChangeLog
@@ -0,0 +1,157 @@
+2002-11-04 Gary Thomas <gthomas@ecoscentric.com>
+
+ * src/if_sc_lpe.c (do_delay): Fix problem with overloaded name 'ticks'.
+ n.b. the FreeBSD stack has this defined for it's own use.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_sc_lpe.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-05-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_sc_lpe.c: Conditionalize use of thread on CYGPKG_KERNEL
+ not CYGPKG_NET.
+
+2002-04-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c: Clean up warnings.
+
+2001-10-16 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_cf.inl: Added buffer parameters.
+
+2001-08-25 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c (sc_lpe_card_handler): Rework ESA discovery code.
+
+2001-08-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c:
+ printf() is no longer a part of RedBoot. Thus all programs
+ must use diag_printf() and related functions instead.
+
+2001-06-16 Jesper Skov <jskov@redhat.com>
+
+ * src/if_sc_lpe.c: Use generic DP83902A driver, only redefining
+ the init function to handle card details (which incidently do not
+ appear to be fully working).
+
+ * include/devs_eth_cf.inl: Device details moved here so the
+ generic driver can access them.
+
+ * cdl/cf_eth_drivers.cdl: Changes to use generic driver. Allow ESA
+ to be configured.
+ Require DP83902A package.
+
+ * src/dp8390.h: Deleted.
+
+2001-04-13 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c (sc_lpe_card_handler): Work around broken card(s)
+ which do not have valid ESA in config EPROM.
+
+2000-09-15 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c: Suppress noisy message which seems to sometimes
+ happen if the card is re-initialized from warm.
+
+2000-09-14 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c: Better recovery for bad devices [stand-alone].
+
+2000-09-13 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c: Fix handling of receive buffer overflow,
+ i.e. missed data. [quietly ignored]
+
+ * src/dp8390.h: Update layout of Tx/Rx buffers.
+
+2000-09-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c (sc_lpe_card_handler): Handle case when card
+ is warm (powered up from boot ROM).
+
+2000-09-01 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_sc_lpe.c (sc_lpe_init): Work with new fast net
+ thread to do all the copying work instead of loading up DSR time.
+ In detail:
+ o New "deliver" function in the interface record. It's the same
+ function as the poll entry; sc_lpe_int().
+ o In registering the interrupt handler, use eth_drv_dsr (from the
+ logical driver) instead of sc_lpe_int.
+
+2000-08-29 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c (sc_lpe_recv): Better handling if upper layer
+ had no buffers [this routine called anyway].
+
+2000-08-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c: Better handling of "hot" cards (i.e. one
+ initialized by a debug environment).
+
+2000-08-23 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c: Add new function to return interrupt vector
+ used by interface. Also, handle interrupts from interface even
+ if there is no kernel (CF callback).
+
+2000-08-03 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c: Ensure DSR locked while initializing hardware.
+
+ * cdl/cf_eth_drivers.cdl: Ethernet driver package hierarchy changed.
+
+2000-07-26 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c: Update for new eth_drv interfaces (via *sc).
+
+2000-07-18 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c (sc_lpe_RxEvent): Handle case where chip gets lost
+ and keeps returning the same input packet (hardware bug?).
+
+2000-07-16 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c (sc_lpe_card_handler): Add initialization message and
+ timeout when running stand-alone.
+
+2000-07-15 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_sc_lpe.c: CF interrupts are now handled by the slot handler,
+ not directly in this code.
+
+2000-07-14 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/cf_eth_drivers.cdl:
+ * src/if_sc_lpe.c: Support building in eCos and stand-alone modes.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/cf/current/cdl/cf_eth_drivers.cdl b/ecos/packages/devs/eth/cf/current/cdl/cf_eth_drivers.cdl
new file mode 100644
index 0000000..727f320
--- /dev/null
+++ b/ecos/packages/devs/eth/cf/current/cdl/cf_eth_drivers.cdl
@@ -0,0 +1,131 @@
+# ====================================================================
+#
+# cf_eth_drivers.cdl
+#
+# Ethernet drivers - device support for PCMCIA (Compact Flash)
+# Socket Communications: Low Power Compact Flash Ethernet board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov
+# Date: 2000-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_CF {
+ display "PCMCIA (Compact Flash) ethernet drivers"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_PCMCIA
+ requires CYGPKG_DEVS_ETH_NS_DP83902A
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ include_dir cyg/io
+ description "Ethernet driver for various PCMCIA (Compact Flash) boards."
+ compile -library=libextras.a if_sc_lpe.c
+
+ # FIXME: This really belongs in the NS DP83902A package
+ cdl_interface CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED {
+ display "NS DP83902A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_INL <cyg/io/devs_eth_cf.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_CFG <pkgconf/devs_eth_cf.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_CF_ETH0 {
+ display "CF ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for a
+ CF card."
+
+ implements CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_CF_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_CF_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_CF_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_CF_OPTIONS {
+ display "PCMCIA ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_CF_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the PCMCIA ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/cf/current/include/devs_eth_cf.inl b/ecos/packages/devs/eth/cf/current/include/devs_eth_cf.inl
new file mode 100644
index 0000000..24a1051
--- /dev/null
+++ b/ecos/packages/devs/eth/cf/current/include/devs_eth_cf.inl
@@ -0,0 +1,107 @@
+//==========================================================================
+//
+// devs_eth_cf.inl
+//
+// CF (PCMCIA) ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-06-15
+// Purpose: PCMCIA ethernet defintions
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+#include <cyg/hal/hal_if.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/io/pcmcia.h>
+
+#ifdef __WANT_CONFIG
+
+#undef CYGHWR_NS_DP83902A_PLF_INT_CLEAR
+#define CYGHWR_NS_DP83902A_PLF_INT_CLEAR(_dp_) \
+ CYG_MACRO_START \
+ struct cf_slot* slot = (struct cf_slot*) (_dp_)->plf_priv; \
+ cf_clear_interrupt(slot); \
+ CYG_MACRO_END
+
+#endif // __WANT_CONFIG
+
+#ifdef __WANT_DEVS
+
+externC int cyg_sc_lpe_int_vector(struct eth_drv_sc *sc);
+externC bool cyg_sc_lpe_init(struct cyg_netdevtab_entry *tab);
+
+#ifdef CYGPKG_DEVS_ETH_CF_ETH0
+
+static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
+ tx_buf1: 0x40,
+ tx_buf2: 0x48,
+ rx_buf_start: 0x50,
+ rx_buf_end: 0x80,
+#ifdef CYGSEM_DEVS_ETH_CF_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_CF_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+};
+
+ETH_DRV_SC(dp83902a_sc,
+ &dp83902a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_CF_ETH0_NAME,
+ dp83902a_start,
+ dp83902a_stop,
+ dp83902a_control,
+ dp83902a_can_send,
+ dp83902a_send,
+ dp83902a_recv,
+ dp83902a_deliver, // "pseudoDSR" called from fast net thread
+ dp83902a_poll, // poll function, encapsulates ISR and DSR
+ cyg_sc_lpe_int_vector);
+
+NETDEVTAB_ENTRY(dp83902a_netdev,
+ "dp83902a_" CYGDAT_DEVS_ETH_CF_ETH0_NAME,
+ cyg_sc_lpe_init,
+ &dp83902a_sc);
+#endif // CYGPKG_DEVS_ETH_CF_ETH0
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_cf.inl
diff --git a/ecos/packages/devs/eth/cf/current/src/if_sc_lpe.c b/ecos/packages/devs/eth/cf/current/src/if_sc_lpe.c
new file mode 100644
index 0000000..17e9140
--- /dev/null
+++ b/ecos/packages/devs/eth/cf/current/src/if_sc_lpe.c
@@ -0,0 +1,314 @@
+//==========================================================================
+//
+// dev/if_sc_lpe.c
+//
+// Ethernet device driver for Socket Communications Compact Flash card
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Date: 2000-07-07
+// Purpose:
+// Description: hardware driver for LPCF+ ethernet
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/pcmcia.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/netdev.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#else
+#include <cyg/hal/hal_if.h>
+#endif
+
+#include <cyg/io/dp83902a.h>
+
+#define DP_DATA 0x10
+#define DP_CARD_RESET 0x1f
+
+#define SC_LPE_MANUF 0x0104
+
+#ifdef CYGPKG_KERNEL
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+static char sc_lpe_card_handler_stack[STACK_SIZE];
+static cyg_thread sc_lpe_card_handler_thread_data;
+static cyg_handle_t sc_lpe_card_handler_thread_handle;
+#endif // CYGPKG_KERNEL
+
+__inline__ static void
+do_delay(int _ticks)
+{
+#ifdef CYGPKG_KERNEL
+ cyg_thread_delay(_ticks);
+#else
+ CYGACC_CALL_IF_DELAY_US(10000*_ticks);
+#endif
+}
+
+//
+// This runs as a separate thread to handle the card. In particular, insertions
+// and deletions need to be handled and they take time/coordination, thus the
+// separate thread.
+//
+#ifdef CYGPKG_KERNEL
+static void
+#else
+static int
+#endif
+sc_lpe_card_handler(cyg_addrword_t param)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)param;
+ dp83902a_priv_data_t *dp = (dp83902a_priv_data_t*)sc->driver_private;
+ struct cf_slot *slot;
+ struct cf_cftable cftable;
+ struct cf_config config;
+ int i, len, ptr, cor = 0;
+ unsigned char buf[256], *cp;
+ cyg_uint8* base;
+ unsigned char *vers_product, *vers_manuf, *vers_revision, *vers_date;
+#ifndef CYGPKG_KERNEL
+ int tries = 0;
+#endif
+ bool first = true;
+
+ slot = (struct cf_slot*)dp->plf_priv;
+ cyg_drv_dsr_lock();
+ while (true) {
+ cyg_drv_dsr_unlock(); // Give DSRs a chance to run (card insertion)
+ cyg_drv_dsr_lock();
+ if ((slot->state == CF_SLOT_STATE_Inserted) ||
+ ((slot->state == CF_SLOT_STATE_Ready) && first)) {
+ first = false;
+ if (slot->state != CF_SLOT_STATE_Ready) {
+ cf_change_state(slot, CF_SLOT_STATE_Ready);
+ }
+ if (slot->state != CF_SLOT_STATE_Ready) {
+ diag_printf("CF card won't go ready!\n");
+#ifndef CYGPKG_KERNEL
+ return false;
+#else
+ continue;
+#endif
+ }
+ len = sizeof(buf);
+ ptr = 0;
+ if (cf_get_CIS(slot, CF_CISTPL_MANFID, buf, &len, &ptr)) {
+ if (*(short *)&buf[2] != SC_LPE_MANUF) {
+ diag_printf("Not a SC LPE, sorry\n");
+ continue;
+ }
+ }
+ ptr = 0;
+ if (cf_get_CIS(slot, CF_CISTPL_VERS_1, buf, &len, &ptr)) {
+ // Find individual strings
+ cp = &buf[4];
+ vers_product = cp;
+ while (*cp++) ; // Skip to nul
+ vers_manuf = cp;
+ while (*cp++) ; // Skip to nul
+ vers_revision = cp;
+ while (*cp++) ; // Skip to nul
+ vers_date = cp;
+#ifndef CYGPKG_KERNEL
+ if (tries != 0) diag_printf("\n");
+ diag_printf("%s: %s %s %s\n", vers_manuf, vers_product, vers_revision, vers_date);
+#endif
+ }
+ ptr = 0;
+ if (cf_get_CIS(slot, CF_CISTPL_CONFIG, buf, &len, &ptr)) {
+ if (cf_parse_config(buf, len, &config)) {
+ cor = config.base;
+ }
+ }
+ if (!cor) {
+// diag_printf("Couldn't find COR pointer!\n");
+ continue;
+ }
+
+ ptr = 0;
+ if (cf_get_CIS(slot, CF_CISTPL_CFTABLE_ENTRY, buf, &len, &ptr)) {
+ if (cf_parse_cftable(buf, len, &cftable)) {
+ cyg_uint8 tmp;
+ // Initialize dp83902a IO details
+ dp->base = base = (cyg_uint8*)&slot->io[cftable.io_space.base[0]];
+ dp->data = base + DP_DATA;
+ dp->interrupt = slot->int_num;
+ cf_set_COR(slot, cor, cftable.cor);
+ // Reset card (read issues RESET, write clears it)
+ HAL_READ_UINT8(base+DP_CARD_RESET, tmp);
+ HAL_WRITE_UINT8(base+DP_CARD_RESET, tmp);
+ // Wait for card
+ do {
+ DP_IN(base, DP_ISR, tmp);
+ } while (0 == (tmp & DP_ISR_RESET));
+
+ // Fetch hardware address from card - terrible, but not well defined
+ // Patterned after what Linux drivers do
+ if (!dp->hardwired_esa) {
+ static unsigned char sc_lpe_addr[] = { 0x00, 0xC0, 0x1B, 0x00, 0x99, 0x9E};
+ if ((slot->attr[0x1C0] == sc_lpe_addr[0]) &&
+ (slot->attr[0x1C2] == sc_lpe_addr[1]) &&
+ (slot->attr[0x1C4] == sc_lpe_addr[2])) {
+ sc_lpe_addr[3] = slot->attr[0x1C6];
+ sc_lpe_addr[4] = slot->attr[0x1C8];
+ sc_lpe_addr[5] = slot->attr[0x1CA];
+ } else {
+ // Coudn't find it in the CIS (attribute) data
+ unsigned char prom[32];
+
+ // Tell device to give up ESA
+ DP_OUT(base, DP_DCR, 0x48); // Bytewide access
+ DP_OUT(base, DP_RBCH, 0); // Remote byte count
+ DP_OUT(base, DP_RBCL, 0);
+ DP_OUT(base, DP_ISR, 0xFF); // Clear any pending interrupts
+ DP_OUT(base, DP_IMR, 0x00); // Mask all interrupts
+ DP_OUT(base, DP_RCR, 0x20); // Monitor
+ DP_OUT(base, DP_TCR, 0x02); // loopback
+ DP_OUT(base, DP_RBCH, 32); // Remote byte count
+ DP_OUT(base, DP_RBCL, 0);
+ DP_OUT(base, DP_RSAL, 0); // Remote address
+ DP_OUT(base, DP_RSAH, 0);
+ DP_OUT(base, DP_CR, DP_CR_START|DP_CR_RDMA); // Read data
+ for (i = 0; i < 32; i++) {
+ HAL_READ_UINT8(base+DP_DATAPORT, prom[i]);
+ }
+ if ((prom[0] == sc_lpe_addr[0]) &&
+ (prom[2] == sc_lpe_addr[1]) &&
+ (prom[4] == sc_lpe_addr[2])) {
+ diag_printf("Getting address from port\n");
+ sc_lpe_addr[3] = prom[6];
+ sc_lpe_addr[4] = prom[8];
+ sc_lpe_addr[5] = prom[10];
+ } else {
+ diag_printf("No valid ESA found in CIS! Hardwiring to 00:C0:1B:00:99:9E\n");
+ }
+ }
+ for (i = 0; i < 6; i++) {
+ dp->esa[i] = sc_lpe_addr[i];
+ }
+ }
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, dp->esa);
+ // Tell system card is ready to talk
+ dp->tab->status = CYG_NETDEVTAB_STATUS_AVAIL;
+#ifndef CYGPKG_KERNEL
+ cyg_drv_dsr_unlock();
+ return true;
+#endif
+ } else {
+ diag_printf("Can't parse CIS\n");
+ continue;
+ }
+ } else {
+ diag_printf("Can't fetch config info\n");
+ continue;
+ }
+ } else if (slot->state == CF_SLOT_STATE_Removed) {
+ diag_printf("Compact Flash card removed!\n");
+ } else {
+ cyg_drv_dsr_unlock();
+ do_delay(50); // FIXME!
+#ifndef CYGPKG_KERNEL
+ if (tries == 0) diag_printf("... Waiting for network card: ");
+ diag_printf(".");
+ if (++tries == 10) {
+ // 5 seconds have elapsed - give up
+ return false;
+ }
+ cf_hwr_poll(slot); // Check to see if card has been inserted
+#endif
+ cyg_drv_dsr_lock();
+ }
+ }
+}
+
+bool
+cyg_sc_lpe_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *)sc->driver_private;
+ struct cf_slot* slot;
+
+ cf_init(); // Make sure Compact Flash subsystem is initialized
+ slot = dp->plf_priv = (void*)cf_get_slot(0);
+ dp->tab = tab;
+
+#ifdef CYGPKG_KERNEL
+ // Create card handling [background] thread
+ cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY-1, // Priority
+ sc_lpe_card_handler, // entry
+ (cyg_addrword_t)sc, // entry parameter
+ "SC LP-E card support", // Name
+ &sc_lpe_card_handler_stack[0], // Stack
+ STACK_SIZE, // Size
+ &sc_lpe_card_handler_thread_handle, // Handle
+ &sc_lpe_card_handler_thread_data // Thread data structure
+ );
+ cyg_thread_resume(sc_lpe_card_handler_thread_handle); // Start it
+
+ // Initialize environment, setup interrupt handler
+ // eth_drv_dsr is used to tell the fast net thread to run the deliver funcion.
+ cf_register_handler(slot, eth_drv_dsr, sc);
+
+ return false; // Device is not ready until inserted, powered up, etc.
+#else
+ // Initialize card
+ return sc_lpe_card_handler((cyg_addrword_t)sc);
+#endif
+}
+
+int
+cyg_sc_lpe_int_vector(struct eth_drv_sc *sc)
+{
+ dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *)sc->driver_private;
+ struct cf_slot* slot = (struct cf_slot*)dp->plf_priv;
+
+ return slot->int_num;
+}
diff --git a/ecos/packages/devs/eth/cl/cs8900a/current/ChangeLog b/ecos/packages/devs/eth/cl/cs8900a/current/ChangeLog
new file mode 100644
index 0000000..b030983
--- /dev/null
+++ b/ecos/packages/devs/eth/cl/cs8900a/current/ChangeLog
@@ -0,0 +1,194 @@
+ 2009-02-28 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * src/if_cs8900a.c: Fixed interrupt hooking block in cs8900a_init() to
+ prevent assertion fail on cyg_interrupt_attach() when interrupt is not
+ used.
+
+2008-11-07 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * cdl/cl_cs8900a_eth_drivers.cdl: Added
+ CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT option to manage chip in 8-bit
+ mode.
+ * include/cs8900.h
+ * src/if_cs8900a.c: Added a support for the 8-bit access for CS8900A.
+ All access to CS8900A registers wrapped via CS_IN, CS_OUT macros (the
+ macros were defined in past, but, still not used). In common way the
+ macros use the eCos macros: HAL_READ_UINT16, HAL_WRITE_UINT16 , but,
+ in other (rare) conditions they can use 8-bit access too.
+
+2007-09-04 Stephen Finney <shf@pfinc.com>
+
+ * add timeout to potential infinite loop in cs8900a_send per
+ bugzilla report 1000281
+
+2005-11-10 Laurent Gonzalez <laurent.gonzalez@trango-systems.com>
+
+ * include/cs8900a.h:
+ * src/if_cs8900a.c: Added a priority field in cpd
+ that makes interrupt priority configurable
+
+2005-05-04 Ian Campbell <icampbell@arcom.com>
+
+ * cdl/cl_cs8900a_eth_drivers.cdl: Added
+ CYGSEM_DEVS_ETH_CL_CS8900A_WRITE_EEPROM
+
+ * src/if_cs8900a.c: Added debug statements to print out where the
+ driver is obtaining its ESA from. Implement
+ ETH_DRV_SET_MAC_ADDRESS and ETH_DRV_GET_MAC_ADDRESS.
+
+2004-06-29 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/if_cs8900a.c: Added missing include of cyg_ass.h.
+
+2004-05-07 Bob Koninckx <bob.koninckx@o-3s.com>
+ * src/if_cs8900a.c: Drop "ghost" frames with zero length
+
+2004-04-19 Bob Koninckx <bob.koninckx@o-3s.com>
+ * src/if_cs8900a.c: function cs8900a_int_vector, return the vector
+ instead of a boolean.
+
+2004-04-08 Bob Koninckx <bob.koninckx@o-3s.com>
+ * cdl/cl_cs8900a_eth_drivers.cdl
+ * include/if_cs8900a.c
+ * src/if_cs8900a.c: Made hardware swapping or software swapping of
+ data bytes (mostly relevant to big endian machines) a configuration
+ option
+
+2003-11-05 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * src/if_cs8900a.c: Fix handling of odd bytes on big endian machines
+
+2003-04-12 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/if_cs8900a.c (cs8900a_send): Allow for data not being 16-bit
+ aligned. Thanks to Laurent Gonzalez <laurent.gonzalez@ri.silicomp.fr>
+ for reporting this and his initial patch.
+
+2003-03-03 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * src/if_cs8900a.c:
+ * include/cs8900a.h:
+ Changes to support both little and big endian targets
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_cs8900a.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-05-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/cs8900.h: Check for lost ints if we can - when kernel present.
+ * src/if_cs8900a.c: Use CYGINT_IO_ETH_INT_SUPPORT_REQUIRED where
+ appropriate.
+
+2002-03-20 Gary Thomas <gthomas@redhat.com>
+2002-03-06 Pieter Truter <ptruter@intrinsyc.com>
+
+ * src/if_cs8900a.c (cs8900a_isr): Need to acknowledge interrupt
+ here (in case DSR/poll causes a new one to occur).
+
+2002-02-18 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/cl_cs8900a_eth_drivers.cdl:
+ Add new interface CYGINT_IO_ETH_MULTICAST which is used to
+ insure that drivers support multicast addresses if IPv6 is used.
+
+2002-02-15 Gary Thomas <gthomas@redhat.com>
+
+ * include/cs8900.h:
+ * src/if_cs8900a.c (cs8900a_control): Support multicast addresses.
+
+2002-02-04 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_cs8900a.c:
+ * include/cs8900.h: Add CYGHWR_CL_CS8900A_PLF_POST_RESET() macro.
+
+2001-11-29 Jesper Skov <jskov@redhat.com>
+
+ * src/if_cs8900a.c (cs8900a_init): Changed order of ESA source
+ checking so user can always override at RedBoot runtime.
+
+2001-11-20 Jesper Skov <jskov@redhat.com>
+
+ * src/if_cs8900a.c: Added some more debug output. Set all 4 LAF
+ registers. Don't reset device to stop it - just disable TX & RX.
+
+2001-11-16 Jesper Skov <jskov@redhat.com>
+
+ * src/if_cs8900a.c (cs8900a_send): Wait for controller ready
+ signal before starting transmission.
+
+2001-11-14 Jesper Skov <jskov@redhat.com>
+
+ * src/if_cs8900a.c: Use platform init, reset and int_clear
+ macros.
+ * include/cs8900.h: Tidy up those (default) macros.
+
+2001-11-09 Jesper Skov <jskov@redhat.com>
+
+ * src/if_cs8900a.c (cs8900a_init): Rewrote ESA setup to be more
+ consistent.
+
+ * include/cs8900.h: Added provide_esa field to driver structure.
+
+2001-11-08 Jesper Skov <jskov@redhat.com>
+
+ * src/if_cs8900a.c: Made it build with faked interrupts.
+
+ * include/cs8900.h: Added debug output for put/get functions.
+
+ * src/if_cs8900a.c: Made it build when NET package enabled.
+
+ * include/cs8900.h: Added tab field.
+
+ * src/if_cs8900a.c: Renamed broken ints option, more diag_printf
+ #ifdefing and removed RedBoot ESA option code.
+
+2001-11-07 Jesper Skov <jskov@redhat.com>
+
+ * src/if_cs8900a.c: Interrupt stuff cleaned up. Fix device
+ probing. Make driver fail when no ESA available and none has been
+ configured. Compiler warning fixes and some printout cleanups.
+
+ * src/if_cs8900a.c: Platform driver provides device
+ information. Renamed functions and definitions. Init code changed
+ some.
+
+ * include/cs8900.h: Renaming some definitions.
+
+ * cdl/cl_cs8900a_eth_drivers.cdl: Platform driver provides
+ options.
+
+2001-11-06 Jesper Skov <jskov@redhat.com>
+
+ * src/if_cs8900a.c: Assorted hacking.
+ * include/cs8900.h: Same.
+
+2001-11-02 Jesper Skov <jskov@redhat.com>
+
+ * Cloned from edb7xxx driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl b/ecos/packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl
new file mode 100644
index 0000000..8fa6937
--- /dev/null
+++ b/ecos/packages/devs/eth/cl/cs8900a/current/cdl/cl_cs8900a_eth_drivers.cdl
@@ -0,0 +1,139 @@
+# ====================================================================
+#
+# cl_cs8900a_eth_drivers.cdl
+#
+# Ethernet driver for Cirrus Logic CS8900A controller
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov
+# Date: 2001-11-02
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_CL_CS8900A {
+ display "Driver for Cirrus Logic CS8900A ethernet controller."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGINT_IO_ETH_MULTICAST
+
+ active_if CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+
+ include_dir cyg/io
+ description "Driver for Cirrus Logic CS8900A ethernet controller."
+ compile -library=libextras.a if_cs8900a.c
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_CL_CS8900A_CFG";
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_CL_CS8900A_WRITE_EEPROM {
+ display "SIOCSIFHWADDR records ESA (MAC address) in EEPROM"
+ default_value 0
+ description "
+ The ioctl() socket call with operand SIOCSIFHWADDR sets the
+ interface hardware address - the MAC address or Ethernet Station
+ Address (ESA). This option causes the new MAC address to be written
+ into the EEPROM associated with the interface, so that the new
+ MAC address is permanently recorded. Doing this should be a
+ carefully chosen decision, hence this option."
+ }
+
+ cdl_option CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT {
+ display "8-bit data bus"
+ flavor bool
+ requires !CYGSEM_DEVS_ETH_CL_CS8900A_WRITE_EEPROM
+ requires CYGSEM_DEVS_ETH_CL_CS8900A_NOINTS
+ default_value 0
+ description "
+ The CS8900A can been use in 8-bit mode. From AN181 from
+ Cirrus Logic... Unsupported functions in 8-bit mode:
+ Interrupts are not supported. Polled mode must be used;
+ The DMA engine only uses 16 bit memory access and does not
+ support 8 bit transfers; The packet page pointer has an
+ auto increment feature that cannot be used in 8-bit mode;
+ An EEPROM is not supported."
+ }
+
+ cdl_option CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED {
+ display "Byte swapped data bus"
+ flavor bool
+ default_value 0
+ description "
+ From the application note AN205 from Cirrus Logic ...The CS8900a
+ assumes a litte-endian ISA type system. However, network byte order
+ is always big-endian.Therefore to minimize software manipulation of
+ frame data in ISA systems, the CS8900 byte-swaps frame data
+ internally. The control and status registers are not byte-swapped.
+ In a big-endian system you can either byte-swap the network data
+ (to reverse the byte swapping done internally to the CS8900) in
+ software or you can do it in hardware (byte swap the data lines to
+ the chip). Byte swapping the data lines is much more efficient; you
+ will only need to byte swap the control/status/counter values in
+ software and not the frame data. (Most of the read/writes to the chip
+ are frame data.) Since network byte order is always big endian, this
+ scheme works without special support on the other end of the network...
+ Normally, you won't need to check this option unless you are using a
+ CS8900a ethernet controller with a big endian machine and hardware
+ that has been designed with the cs8900a in mind."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_CL_CS8900A_OPTIONS {
+ display "Cirrus Logic ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_CL_CS8900A_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Cirrus Logic ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/cl/cs8900a/current/include/cs8900.h b/ecos/packages/devs/eth/cl/cs8900a/current/include/cs8900.h
new file mode 100644
index 0000000..2cf1c87
--- /dev/null
+++ b/ecos/packages/devs/eth/cl/cs8900a/current/include/cs8900.h
@@ -0,0 +1,452 @@
+#ifndef _CYGONCE_ETH_CL_CS8900_H_
+#define _CYGONCE_ETH_CL_CS8900_H_
+//==========================================================================
+//
+// dev/cs8900.h
+//
+// Cirrus Logic CS8900 Ethernet chip
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Date: 2001-11-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_io.h>
+#include <pkgconf/devs_eth_cl_cs8900a.h>
+
+#define __WANT_CONFIG
+#include CYGDAT_DEVS_ETH_CL_CS8900A_INL
+#undef __WANT_CONFIG
+
+// ------------------------------------------------------------------------
+// Debugging details
+
+// Set to perms of:
+// 0 disables all debug output
+// 1 for process debug output
+// 2 for added data IO output: get_reg, put_reg
+// 4 for packet allocation/free output
+// 8 for only startup status, so we can tell we're installed OK
+#ifndef DEBUG
+# define DEBUG 0x0
+#endif
+
+#if DEBUG & 1
+#define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0)
+#define DEBUG_LINE() do { diag_printf("%d\n", __LINE__); } while (0)
+#else
+#define DEBUG_FUNCTION() do {} while(0)
+#define DEBUG_LINE() do {} while(0)
+#endif
+
+// ------------------------------------------------------------------------
+// Macros for keeping track of statistics
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+#define KEEP_STATISTICS
+#endif
+
+#ifdef KEEP_STATISTICS
+#define INCR_STAT( _x_ ) (cpd->stats. _x_ ++)
+#else
+#define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
+#endif
+
+// ------------------------------------------------------------------------
+// Private driver structure
+struct cs8900a_priv_data;
+typedef cyg_bool (*provide_esa_t)(struct cs8900a_priv_data* cpd);
+
+typedef struct cs8900a_priv_data {
+ bool txbusy, hardwired_esa;
+ int rxmode;
+ cyg_uint8 esa[6];
+ provide_esa_t provide_esa;
+ cyg_vector_t interrupt; // Interrupt vector used by controller
+ int priority; // Priority level used by controller
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+ cyg_addrword_t base;
+ cyg_uint32 txkey; // Used to ack when packet sent
+ struct cyg_netdevtab_entry *tab;
+#ifdef CYGPKG_KERNEL
+ cyg_tick_count_t txstart;
+#endif
+} cs8900a_priv_data_t;
+
+// ------------------------------------------------------------------------
+// Macros for accessing CS registers
+// These can be overridden by the platform header
+
+#ifndef CS_IN
+# define CS_IN(_b_, _o_, _d_) HAL_READ_UINT16 ((cyg_addrword_t)(_b_)+(_o_), (_d_))
+# define CS_OUT(_b_, _o_, _d_) HAL_WRITE_UINT16((cyg_addrword_t)(_b_)+(_o_), (_d_))
+#endif
+
+// ------------------------------------------------------------------------
+// Macros allowing platform to customize some of the driver details
+
+#ifndef CYGHWR_CL_CS8900A_PLF_RESET
+# define CYGHWR_CL_CS8900A_PLF_RESET(_b_) do { } while (0)
+#endif
+
+#ifndef CYGHWR_CL_CS8900A_PLF_POST_RESET
+# define CYGHWR_CL_CS8900A_PLF_POST_RESET(_b_) do { } while (0)
+#endif
+
+#ifndef CYGHWR_CL_CS8900A_PLF_INT_CLEAR
+# define CYGHWR_CL_CS8900A_PLF_INT_CLEAR(_cdp_)
+#endif
+
+#ifndef CYGHWR_CL_CS8900A_PLF_INIT
+#define CYGHWR_CL_CS8900A_PLF_INIT(_cdp_) do { } while (0)
+#endif
+
+
+// ------------------------------------------------------------------------
+// Directly visible registers.
+// Platform can override stepping or layout if necessary.
+#ifndef CS8900A_step
+# define CS8900A_step 2
+#endif
+#ifndef CS8900A_RTDATA
+# define CS8900A_RTDATA (0*CS8900A_step)
+# define CS8900A_TxCMD (2*CS8900A_step)
+# define CS8900A_TxLEN (3*CS8900A_step)
+# define CS8900A_ISQ (4*CS8900A_step)
+# define CS8900A_PPTR (5*CS8900A_step)
+# define CS8900A_PDATA (6*CS8900A_step)
+#endif
+
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+#define ISQ_RxEvent 0x0004
+#define ISQ_TxEvent 0x0008
+#define ISQ_BufEvent 0x000C
+#define ISQ_RxMissEvent 0x0010
+#define ISQ_TxColEvent 0x0012
+#define ISQ_EventMask 0x003F
+#else
+#define ISQ_RxEvent 0x0400
+#define ISQ_TxEvent 0x0800
+#define ISQ_BufEvent 0x0C00
+#define ISQ_RxMissEvent 0x1000
+#define ISQ_TxColEvent 0x1200
+#define ISQ_EventMask 0x3F00
+#endif
+
+// ------------------------------------------------------------------------
+// Registers available via "page pointer" (indirect access)
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+
+#define PP_ChipID 0x0000 // Chip identifier - must be 0x630e
+#define PP_ChipRev 0x0002 // Chip revision, model codes
+#define PP_ChipID_CL 0x630e
+
+#define PP_IntReg 0x0022 // Interrupt configuration
+#define PP_IntReg_IRQ0 0x0000 // Use INTR0 pin
+#define PP_IntReg_IRQ1 0x0001 // Use INTR1 pin
+#define PP_IntReg_IRQ2 0x0002 // Use INTR2 pin
+#define PP_IntReg_IRQ3 0x0003 // Use INTR3 pin
+
+#define PP_RxCFG 0x0102 // Receiver configuration
+#define PP_RxCFG_Skip1 0x0040 // Skip (i.e. discard) current frame
+#define PP_RxCFG_Stream 0x0080 // Enable streaming mode
+#define PP_RxCFG_RxOK 0x0100 // RxOK interrupt enable
+#define PP_RxCFG_RxDMAonly 0x0200 // Use RxDMA for all frames
+#define PP_RxCFG_AutoRxDMA 0x0400 // Select RxDMA automatically
+#define PP_RxCFG_BufferCRC 0x0800 // Include CRC characters in frame
+#define PP_RxCFG_CRC 0x1000 // Enable interrupt on CRC error
+#define PP_RxCFG_RUNT 0x2000 // Enable interrupt on RUNT frames
+#define PP_RxCFG_EXTRA 0x4000 // Enable interrupt on frames with extra data
+
+#define PP_RxCTL 0x0104 // Receiver control
+#define PP_RxCTL_IAHash 0x0040 // Accept frames that match hash
+#define PP_RxCTL_Promiscuous 0x0080 // Accept any frame
+#define PP_RxCTL_RxOK 0x0100 // Accept well formed frames
+#define PP_RxCTL_Multicast 0x0200 // Accept multicast frames
+#define PP_RxCTL_IA 0x0400 // Accept frame that matches IA
+#define PP_RxCTL_Broadcast 0x0800 // Accept broadcast frames
+#define PP_RxCTL_CRC 0x1000 // Accept frames with bad CRC
+#define PP_RxCTL_RUNT 0x2000 // Accept runt frames
+#define PP_RxCTL_EXTRA 0x4000 // Accept frames that are too long
+
+#define PP_TxCFG 0x0106 // Transmit configuration
+#define PP_TxCFG_CRS 0x0040 // Enable interrupt on loss of carrier
+#define PP_TxCFG_SQE 0x0080 // Enable interrupt on Signal Quality Error
+#define PP_TxCFG_TxOK 0x0100 // Enable interrupt on successful xmits
+#define PP_TxCFG_Late 0x0200 // Enable interrupt on "out of window"
+#define PP_TxCFG_Jabber 0x0400 // Enable interrupt on jabber detect
+#define PP_TxCFG_Collision 0x0800 // Enable interrupt if collision
+#define PP_TxCFG_16Collisions 0x8000 // Enable interrupt if > 16 collisions
+
+#define PP_TxCmd 0x0108 // Transmit command status
+#define PP_TxCmd_TxStart_5 0x0000 // Start after 5 bytes in buffer
+#define PP_TxCmd_TxStart_381 0x0040 // Start after 381 bytes in buffer
+#define PP_TxCmd_TxStart_1021 0x0080 // Start after 1021 bytes in buffer
+#define PP_TxCmd_TxStart_Full 0x00C0 // Start after all bytes loaded
+#define PP_TxCmd_Force 0x0100 // Discard any pending packets
+#define PP_TxCmd_OneCollision 0x0200 // Abort after a single collision
+#define PP_TxCmd_NoCRC 0x1000 // Do not add CRC
+#define PP_TxCmd_NoPad 0x2000 // Do not pad short packets
+
+#define PP_BufCFG 0x010A // Buffer configuration
+#define PP_BufCFG_SWI 0x0040 // Force interrupt via software
+#define PP_BufCFG_RxDMA 0x0080 // Enable interrupt on Rx DMA
+#define PP_BufCFG_TxRDY 0x0100 // Enable interrupt when ready for Tx
+#define PP_BufCFG_TxUE 0x0200 // Enable interrupt in Tx underrun
+#define PP_BufCFG_RxMiss 0x0400 // Enable interrupt on missed Rx packets
+#define PP_BufCFG_Rx128 0x0800 // Enable Rx interrupt after 128 bytes
+#define PP_BufCFG_TxCol 0x1000 // Enable int on Tx collision ctr overflow
+#define PP_BufCFG_Miss 0x2000 // Enable int on Rx miss ctr overflow
+#define PP_BufCFG_RxDest 0x8000 // Enable int on Rx dest addr match
+
+#define PP_LineCTL 0x0112 // Line control
+#define PP_LineCTL_Rx 0x0040 // Enable receiver
+#define PP_LineCTL_Tx 0x0080 // Enable transmitter
+
+#define PP_RER 0x0124 // Receive event
+#define PP_RER_IAHash 0x0040 // Frame hash match
+#define PP_RER_Dribble 0x0080 // Frame had 1-7 extra bits after last byte
+#define PP_RER_RxOK 0x0100 // Frame received with no errors
+#define PP_RER_Hashed 0x0200 // Frame address hashed OK
+#define PP_RER_IA 0x0400 // Frame address matched IA
+#define PP_RER_Broadcast 0x0800 // Broadcast frame
+#define PP_RER_CRC 0x1000 // Frame had CRC error
+#define PP_RER_RUNT 0x2000 // Runt frame
+#define PP_RER_EXTRA 0x4000 // Frame was too long
+
+#define PP_TER 0x0128 // Transmit event
+#define PP_TER_CRS 0x0040 // Carrier lost
+#define PP_TER_SQE 0x0080 // Signal Quality Error
+#define PP_TER_TxOK 0x0100 // Packet sent without error
+#define PP_TER_Late 0x0200 // Out of window
+#define PP_TER_Jabber 0x0400 // Stuck transmit?
+#define PP_TER_NumCollisions 0x7800 // Number of collisions
+#define PP_TER_16Collisions 0x8000 // > 16 collisions
+
+#define PP_SelfCtl 0x0114 // Chip control
+#define PP_SelfCtl_Reset 0x0040 // Self-clearing reset
+
+#define PP_BusCtl 0x0116 // Bus control
+#define PP_BusCtl_ResetRxDMA 0x0040 // Reset receiver DMA engine
+#define PP_BusCtl_DMAextend 0x0100
+#define PP_BusCtl_UseSA 0x0200
+#define PP_BusCtl_MemoryE 0x0400 // Enable "memory mode"
+#define PP_BusCtl_DMAburst 0x0800
+#define PP_BusCtl_IOCH_RDYE 0x1000
+#define PP_BusCtl_RxDMAsize 0x2000
+#define PP_BusCtl_EnableIRQ 0x8000 // Enable interrupts
+
+#define PP_LineStat 0x0134 // Line status
+#define PP_LineStat_LinkOK 0x0080 // Line is connected and working
+#define PP_LineStat_AUI 0x0100 // Connected via AUI
+#define PP_LineStat_10BT 0x0200 // Connected via twisted pair
+#define PP_LineStat_Polarity 0x1000 // Line polarity OK (10BT only)
+#define PP_LineStat_CRS 0x4000 // Frame being received
+
+#define PP_SelfStat 0x0136 // Chip status
+#define PP_SelfStat_InitD 0x0080 // Chip initialization complete
+#define PP_SelfStat_SIBSY 0x0100 // EEPROM is busy
+#define PP_SelfStat_EEPROM 0x0200 // EEPROM present
+#define PP_SelfStat_EEPROM_OK 0x0400 // EEPROM checks out
+#define PP_SelfStat_ELPresent 0x0800 // External address latch logic available
+#define PP_SelfStat_EEsize 0x1000 // Size of EEPROM
+
+#define PP_BusStat 0x0138 // Bus status
+#define PP_BusStat_TxBid 0x0080 // Tx error
+#define PP_BusStat_TxRDY 0x0100 // Ready for Tx data
+
+#define PP_LAF 0x0150 // Logical address filter (6 bytes)
+#define PP_IA 0x0158 // Individual address (MAC)
+
+#else
+
+#define PP_ChipID 0x0000 // Chip identifier - must be 0x0e63
+#define PP_ChipRev 0x0200 // Chip revision, model codes
+#define PP_ChipID_CL 0x0e63
+
+#define PP_IntReg 0x2200 // Interrupt configuration
+#define PP_IntReg_IRQ0 0x0000 // Use INTR0 pin
+#define PP_IntReg_IRQ1 0x0100 // Use INTR1 pin
+#define PP_IntReg_IRQ2 0x0200 // Use INTR2 pin
+#define PP_IntReg_IRQ3 0x0300 // Use INTR3 pin
+
+#define PP_RxCFG 0x0201 // Receiver configuration
+#define PP_RxCFG_Skip1 0x4000 // Skip (i.e. discard) current frame
+#define PP_RxCFG_Stream 0x8000 // Enable streaming mode
+#define PP_RxCFG_RxOK 0x0001 // RxOK interrupt enable
+#define PP_RxCFG_RxDMAonly 0x0002 // Use RxDMA for all frames
+#define PP_RxCFG_AutoRxDMA 0x0004 // Select RxDMA automatically
+#define PP_RxCFG_BufferCRC 0x0008 // Include CRC characters in frame
+#define PP_RxCFG_CRC 0x0010 // Enable interrupt on CRC error
+#define PP_RxCFG_RUNT 0x0020 // Enable interrupt on RUNT frames
+#define PP_RxCFG_EXTRA 0x0040 // Enable interrupt on frames with extra data
+
+#define PP_RxCTL 0x0401 // Receiver control
+#define PP_RxCTL_IAHash 0x4000 // Accept frames that match hash
+#define PP_RxCTL_Promiscuous 0x8000 // Accept any frame
+#define PP_RxCTL_RxOK 0x0001 // Accept well formed frames
+#define PP_RxCTL_Multicast 0x0002 // Accept multicast frames
+#define PP_RxCTL_IA 0x0004 // Accept frame that matches IA
+#define PP_RxCTL_Broadcast 0x0008 // Accept broadcast frames
+#define PP_RxCTL_CRC 0x0010 // Accept frames with bad CRC
+#define PP_RxCTL_RUNT 0x0020 // Accept runt frames
+#define PP_RxCTL_EXTRA 0x0040 // Accept frames that are too long
+
+#define PP_TxCFG 0x0601 // Transmit configuration
+#define PP_TxCFG_CRS 0x4000 // Enable interrupt on loss of carrier
+#define PP_TxCFG_SQE 0x8000 // Enable interrupt on Signal Quality Error
+#define PP_TxCFG_TxOK 0x0001 // Enable interrupt on successful xmits
+#define PP_TxCFG_Late 0x0002 // Enable interrupt on "out of window"
+#define PP_TxCFG_Jabber 0x0004 // Enable interrupt on jabber detect
+#define PP_TxCFG_Collision 0x0008 // Enable interrupt if collision
+#define PP_TxCFG_16Collisions 0x0080 // Enable interrupt if > 16 collisions
+
+#define PP_TxCmd 0x0801 // Transmit command status
+#define PP_TxCmd_TxStart_5 0x0000 // Start after 5 bytes in buffer
+#define PP_TxCmd_TxStart_381 0x4000 // Start after 381 bytes in buffer
+#define PP_TxCmd_TxStart_1021 0x8000 // Start after 1021 bytes in buffer
+#define PP_TxCmd_TxStart_Full 0xC000 // Start after all bytes loaded
+#define PP_TxCmd_Force 0x0001 // Discard any pending packets
+#define PP_TxCmd_OneCollision 0x0002 // Abort after a single collision
+#define PP_TxCmd_NoCRC 0x0010 // Do not add CRC
+#define PP_TxCmd_NoPad 0x0020 // Do not pad short packets
+
+#define PP_BufCFG 0x0A01 // Buffer configuration
+#define PP_BufCFG_SWI 0x4000 // Force interrupt via software
+#define PP_BufCFG_RxDMA 0x8000 // Enable interrupt on Rx DMA
+#define PP_BufCFG_TxRDY 0x0001 // Enable interrupt when ready for Tx
+#define PP_BufCFG_TxUE 0x0002 // Enable interrupt in Tx underrun
+#define PP_BufCFG_RxMiss 0x0004 // Enable interrupt on missed Rx packets
+#define PP_BufCFG_Rx128 0x0008 // Enable Rx interrupt after 128 bytes
+#define PP_BufCFG_TxCol 0x0010 // Enable int on Tx collision ctr overflow
+#define PP_BufCFG_Miss 0x0020 // Enable int on Rx miss ctr overflow
+#define PP_BufCFG_RxDest 0x0080 // Enable int on Rx dest addr match
+
+#define PP_LineCTL 0x1201 // Line control
+#define PP_LineCTL_Rx 0x4000 // Enable receiver
+#define PP_LineCTL_Tx 0x8000 // Enable transmitter
+
+#define PP_RER 0x2401 // Receive event
+#define PP_RER_IAHash 0x4000 // Frame hash match
+#define PP_RER_Dribble 0x8000 // Frame had 1-7 extra bits after last byte
+#define PP_RER_RxOK 0x0001 // Frame received with no errors
+#define PP_RER_Hashed 0x0002 // Frame address hashed OK
+#define PP_RER_IA 0x0004 // Frame address matched IA
+#define PP_RER_Broadcast 0x0008 // Broadcast frame
+#define PP_RER_CRC 0x0010 // Frame had CRC error
+#define PP_RER_RUNT 0x0020 // Runt frame
+#define PP_RER_EXTRA 0x0040 // Frame was too long
+
+#define PP_TER 0x2801 // Transmit event
+#define PP_TER_CRS 0x4000 // Carrier lost
+#define PP_TER_SQE 0x8000 // Signal Quality Error
+#define PP_TER_TxOK 0x0001 // Packet sent without error
+#define PP_TER_Late 0x0002 // Out of window
+#define PP_TER_Jabber 0x0004 // Stuck transmit?
+#define PP_TER_NumCollisions 0x0078 // Number of collisions
+#define PP_TER_16Collisions 0x0080 // > 16 collisions
+
+#define PP_SelfCtl 0x1401 // Chip control
+#define PP_SelfCtl_Reset 0x4000 // Self-clearing reset
+
+#define PP_BusCtl 0x1601 // Bus control
+#define PP_BusCtl_ResetRxDMA 0x4000 // Reset receiver DMA engine
+#define PP_BusCtl_DMAextend 0x0001
+#define PP_BusCtl_UseSA 0x0002
+#define PP_BusCtl_MemoryE 0x0004 // Enable "memory mode"
+#define PP_BusCtl_DMAburst 0x0008
+#define PP_BusCtl_IOCH_RDYE 0x0010
+#define PP_BusCtl_RxDMAsize 0x0020
+#define PP_BusCtl_EnableIRQ 0x0080 // Enable interrupts
+
+#define PP_LineStat 0x3401 // Line status
+#define PP_LineStat_LinkOK 0x8000 // Line is connected and working
+#define PP_LineStat_AUI 0x0001 // Connected via AUI
+#define PP_LineStat_10BT 0x0002 // Connected via twisted pair
+#define PP_LineStat_Polarity 0x0010 // Line polarity OK (10BT only)
+#define PP_LineStat_CRS 0x0040 // Frame being received
+
+#define PP_SelfStat 0x3601 // Chip status
+#define PP_SelfStat_InitD 0x8000 // Chip initialization complete
+#define PP_SelfStat_SIBSY 0x0001 // EEPROM is busy
+#define PP_SelfStat_EEPROM 0x0002 // EEPROM present
+#define PP_SelfStat_EEPROM_OK 0x0004 // EEPROM checks out
+#define PP_SelfStat_ELPresent 0x0008 // External address latch logic available
+#define PP_SelfStat_EEsize 0x0010 // Size of EEPROM
+
+#define PP_BusStat 0x3801 // Bus status
+#define PP_BusStat_TxBid 0x8000 // Tx error
+#define PP_BusStat_TxRDY 0x0001 // Ready for Tx data
+
+#define PP_LAF 0x5001 // Logical address filter (6 bytes)
+#define PP_IA 0x5801 // Individual address (MAC)
+
+#endif
+
+// ------------------------------------------------------------------------
+// "page pointer" access functions
+static __inline__ cyg_uint16
+get_reg(cyg_addrword_t base, int regno)
+{
+ cyg_uint16 val;
+ CS_OUT(base, CS8900A_PPTR, regno);
+ CS_IN(base, CS8900A_PDATA, val);
+#if DEBUG & 2
+ diag_printf("get_reg(%p, %d) => 0x%04x\n", (void *)base, regno, val);
+#endif
+ return val;
+}
+
+static __inline__ void
+put_reg(cyg_addrword_t base, int regno, cyg_uint16 val)
+{
+#if DEBUG & 2
+ diag_printf("put_reg(%p, %d, 0x%04x)\n", (void *)base, regno, val);
+#endif
+ CS_OUT(base, CS8900A_PPTR, regno);
+ CS_OUT(base, CS8900A_PDATA, val);
+}
+
+#endif // _CYGONCE_ETH_CL_CS8900_H_
diff --git a/ecos/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c b/ecos/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c
new file mode 100644
index 0000000..9a095e4
--- /dev/null
+++ b/ecos/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c
@@ -0,0 +1,759 @@
+//==========================================================================
+//
+// dev/if_cs8900a.c
+//
+// Device driver for Cirrus Logic CS8900A ethernet controller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Date: 2001-11-02
+// Purpose:
+// Description: Driver for CS8900 ethernet controller
+//
+// Note: Platform can define CYGSEM_DEVS_ETH_CL_CS8900A_NOINTS
+// to get a timer thread polling instead of interupt based
+// operation.
+//
+// Note: Driver will need some changes to support multiple instances
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#ifdef CYGPKG_KERNEL
+#include <cyg/kernel/kapi.h>
+#endif
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_endian.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#undef __ECOS
+#define __ECOS
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/netdev.h>
+
+#include <cyg/io/cs8900.h>
+
+#define __WANT_DEVS
+#include CYGDAT_DEVS_ETH_CL_CS8900A_INL
+#undef __WANT_DEVS
+
+// NOINTS operation only relevant when the NET package is loaded
+#if !defined(CYGPKG_NET) || !defined(CYGPKG_KERNEL)
+# undef CYGSEM_DEVS_ETH_CL_CS8900A_NOINTS
+#endif
+
+#ifdef CYGSEM_DEVS_ETH_CL_CS8900A_NOINTS
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
+static char cs8900a_fake_int_stack[STACK_SIZE];
+static cyg_thread cs8900a_fake_int_thread_data;
+static cyg_handle_t cs8900a_fake_int_thread_handle;
+static void cs8900a_fake_int(cyg_addrword_t);
+#endif
+
+#ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
+extern int cyg_io_eth_net_debug;
+#endif
+
+static void cs8900a_poll(struct eth_drv_sc *sc);
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+// This ISR is called when the ethernet interrupt occurs
+static int
+cs8900a_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cs8900a_priv_data_t* cpd = (cs8900a_priv_data_t *)data;
+ cyg_drv_interrupt_mask(cpd->interrupt);
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+static void
+cs8900a_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ // This conditioning out is necessary because of explicit calls to this
+ // DSR - which would not ever be called in the case of a polled mode
+ // usage ie. in RedBoot.
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cs8900a_priv_data_t* cpd = (cs8900a_priv_data_t *)data;
+ struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->tab);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ DEBUG_FUNCTION();
+
+ // but here, it must be a *sc:
+ eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+#else
+# ifndef CYGPKG_REDBOOT
+# error Empty CS8900A ethernet DSR is compiled. Is this what you want?
+# endif
+#endif
+}
+#endif
+
+// The deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+cs8900a_deliver(struct eth_drv_sc *sc)
+{
+ cs8900a_poll(sc);
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ {
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+ }
+#endif
+}
+
+static int
+cs8900a_int_vector(struct eth_drv_sc *sc)
+{
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ return (cpd->interrupt);
+}
+
+static bool
+cs8900a_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ cyg_addrword_t base = cpd->base;
+ cyg_uint16 chip_type, chip_rev, chip_status;
+ cyg_uint16 i;
+ long timeout = 500000;
+ cyg_bool esa_configured = false;
+
+ cpd->tab = tab;
+
+ CYGHWR_CL_CS8900A_PLF_INIT(cpd);
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+# ifdef CYGSEM_DEVS_ETH_CL_CS8900A_NOINTS
+ // The olpce2994 target uses 8-bit, non-interrupt driven mode for CS8900A.
+ cyg_thread_create(1, // Priority
+ cs8900a_fake_int, // entry
+ (cyg_addrword_t)sc,// entry parameter
+ "CS8900 int", // Name
+ &cs8900a_fake_int_stack[0], // Stack
+ STACK_SIZE, // Size
+ &cs8900a_fake_int_thread_handle, // Handle
+ &cs8900a_fake_int_thread_data // Thread data structure
+ );
+ cyg_thread_resume(cs8900a_fake_int_thread_handle); // Start it
+# else
+ // Initialize environment, setup interrupt handler
+ cyg_drv_interrupt_create(cpd->interrupt,
+ cpd->priority,
+ (cyg_addrword_t)cpd, // Data item passed to interrupt handler
+ (cyg_ISR_t *)cs8900a_isr,
+ (cyg_DSR_t *)cs8900a_dsr,
+ &cpd->interrupt_handle,
+ &cpd->interrupt_object);
+ cyg_drv_interrupt_attach(cpd->interrupt_handle);
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+# endif // CYGSEM_DEVS_ETH_CL_CS8900A_NOINTS
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+ // Read controller ID - the first is a dummy read, since (on some
+ // platforms) the first access to the controller seems to skip the
+ // MSB 8 bits.
+ get_reg(base, PP_ChipID);
+ chip_type = get_reg(base, PP_ChipID);
+ chip_rev = get_reg(base, PP_ChipRev);
+#if DEBUG & 8
+ diag_printf("CS8900A[%p] - type: 0x%04x, rev: 0x%04x\n", (void *)base, chip_type, chip_rev);
+#endif
+ if (chip_type != PP_ChipID_CL) {
+#if DEBUG & 8
+ diag_printf("CS8900 - invalid type (0x%04x), must be 0x630e\n", chip_type);
+#endif
+ return false;
+ }
+
+ CYGHWR_CL_CS8900A_PLF_RESET(base);
+ put_reg(base, PP_SelfCtl, PP_SelfCtl_Reset); // Reset chip
+
+ CYGHWR_CL_CS8900A_PLF_POST_RESET(base);
+
+ while ((get_reg(base, PP_SelfStat) & PP_SelfStat_InitD) == 0) {
+ if (--timeout <= 0) {
+#if DEBUG & 8
+ diag_printf("CS8900 didn't reset - abort!\n");
+#endif
+ return false;
+ }
+ }
+
+ chip_status = get_reg(base, PP_SelfStat);
+#if DEBUG & 8
+ diag_printf("CS8900 - status: 0x%04x (%sEEPROM present)\n", chip_status,
+ chip_status & PP_SelfStat_EEPROM ? "" : "no ");
+#endif
+
+
+ // Disable reception whilst finding the ESA
+ put_reg(base, PP_LineCTL, 0 );
+ // Find ESA - check possible sources in sequence and stop when
+ // one provides the ESA:
+ // RedBoot option (via provide_esa)
+ // Compile-time configuration
+ // EEPROM
+ // <fail configuration of device>
+ if (NULL != cpd->provide_esa) {
+ esa_configured = cpd->provide_esa(cpd);
+# if DEBUG & 8
+ if (esa_configured)
+ diag_printf("Got ESA from RedBoot option\n");
+# endif
+ }
+ if (!esa_configured && cpd->hardwired_esa) {
+ // ESA is already set in cpd->esa[]
+#if DEBUG & 8
+ diag_printf("Got hardcoded ESA\n");
+#endif
+ esa_configured = true;
+ }
+ if (!esa_configured && (chip_status & PP_SelfStat_EEPROM)) {
+ // Get ESA from EEPROM - via the PP_IA registers
+ cyg_uint16 esa_word;
+ for (i = 0; i < sizeof(cpd->esa); i += 2) {
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ esa_word = get_reg(base, PP_IA+i);
+ cpd->esa[i] = (esa_word & 0xFF);
+ cpd->esa[i+1] = (esa_word >> 8) & 0xFF;
+#else
+ esa_word = get_reg(base, PP_IA+CYG_SWAP16(i));
+ cpd->esa[i+1] = (esa_word & 0xFF);
+ cpd->esa[i] = (esa_word >> 8) & 0xFF;
+#endif
+ }
+#if DEBUG & 8
+ diag_printf("Got EEPROM ESA\n");
+#endif
+ esa_configured = true;
+ }
+ if (!esa_configured) {
+# if DEBUG & 8
+ diag_printf("CS8900 - no EEPROM, static ESA or RedBoot config option.\n");
+# endif
+ return false;
+ }
+
+ // Tell the chip what ESA to use
+ for (i = 0; i < sizeof(cpd->esa); i += 2) {
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ put_reg(base, PP_IA+i, cpd->esa[i] | (cpd->esa[i+1] << 8));
+#else
+ put_reg(base, PP_IA+CYG_SWAP16(i), cpd->esa[i+1] | (cpd->esa[i] << 8));
+#endif
+ }
+ // Set logical address mask
+ for (i = 0; i < 8; i += 2) {
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ put_reg(base, PP_LAF+i, 0xFFFF);
+#else
+ put_reg(base, PP_LAF+CYG_SWAP16(i), 0xFFFF);
+#endif
+ }
+# if DEBUG & 8
+ diag_printf("ESA %02x:%02x:%02x:%02x:%02x:%02x\n",
+ cpd->esa[0], cpd->esa[1], cpd->esa[2],
+ cpd->esa[3], cpd->esa[4], cpd->esa[5]);
+# endif
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, cpd->esa);
+
+ return true;
+}
+
+static void
+cs8900a_stop(struct eth_drv_sc *sc)
+{
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ cyg_addrword_t base = cpd->base;
+
+ put_reg(base, PP_LineCTL, 0);
+}
+
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+static void
+cs8900a_start(struct eth_drv_sc *sc, cyg_uint8 *esa, int flags)
+{
+ cyg_uint16 stat;
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ cyg_addrword_t base = cpd->base;
+
+ put_reg(base, PP_BusCtl, PP_BusCtl_MemoryE); // Disable interrupts, memory mode
+ put_reg(base, PP_IntReg, PP_IntReg_IRQ0); // Only possibility
+ put_reg(base, PP_RxCFG, PP_RxCFG_RxOK | PP_RxCFG_CRC |
+ PP_RxCFG_RUNT | PP_RxCFG_EXTRA);
+ cpd->rxmode = PP_RxCTL_RxOK | PP_RxCTL_Broadcast | PP_RxCTL_IA;
+ put_reg(base, PP_RxCTL, cpd->rxmode);
+ put_reg(base, PP_TxCFG, PP_TxCFG_TxOK | PP_TxCFG_Collision |
+ PP_TxCFG_CRS | PP_TxCFG_SQE | PP_TxCFG_Late |
+ PP_TxCFG_Jabber | PP_TxCFG_16Collisions);
+ put_reg(base, PP_BufCFG, PP_BufCFG_TxRDY | PP_BufCFG_TxUE | PP_BufCFG_RxMiss |
+ PP_BufCFG_TxCol | PP_BufCFG_Miss | PP_BufCFG_SWI);
+ put_reg(base, PP_IntReg, PP_IntReg_IRQ0); // Only possibility
+ put_reg(base, PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
+ // Clear Interrupt Status Queue before enabling interrupts
+ do {
+ CS_IN(cpd->base, CS8900A_ISQ, stat);
+ } while (stat != 0) ;
+ cpd->txbusy = false;
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT
+ put_reg(base, PP_BusCtl, PP_BusCtl_EnableIRQ);
+#endif
+}
+
+// This routine is called to perform special "control" opertions
+static int
+cs8900a_control(struct eth_drv_sc *sc, unsigned long key, void *data, int data_length)
+{
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ cyg_addrword_t base = cpd->base;
+ struct eth_drv_mc_list *mc_list = data;
+ unsigned char *esa = (unsigned char *)data;
+ int i;
+
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+#if 9 & DEBUG
+ diag_printf("CS8900A - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ esa[0], esa[1], esa[2],
+ esa[3], esa[4], esa[5] );
+#if !defined(CYGSEM_DEVS_ETH_CL_CS8900A_WRITE_EEPROM) || !defined(CS8900A_PROGRAM_EEPROM)
+ diag_printf("*** PERMANENT EEPROM WRITE NOT ENABLED ***\n");
+#endif
+#endif // DEBUG
+
+ // We can write the MAC address into the interface info,
+ // and the chip registers no problem.
+ for ( i = 0; i < sizeof(cpd->esa); i++ )
+ cpd->esa[i] = esa[i];
+ for (i = 0; i < sizeof(cpd->esa); i += 2) {
+ cyg_uint16 reg = cpd->esa[i] | (cpd->esa[i+1] << 8);
+ put_reg(cpd->base, PP_IA+i, reg );
+ }
+#if defined(CYGSEM_DEVS_ETH_CL_CS8900A_WRITE_EEPROM) && defined(CS8900A_PROGRAM_EEPROM)
+ if (CS8900A_PROGRAM_EEPROM(cpd))
+ return 1;
+ else
+ return 0;
+#elif defined(CYGSEM_DEVS_ETH_CL_CS8900A_WRITE_EEPROM) && !defined(CS8900A_PROGRAM_EEPROM)
+ /* WRITE_EEPROM requested, but no PROGRAM_EEPROM provided */
+ return 1;
+#else /* !CYGSEM_DEVS_ETH_CL_CS8900A_WRITE_EEPROM - No need to write EEPROM */
+ return 0;
+#endif
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ // Extract the MAC address that is in the chip, and tell the
+ // system about it.
+ for (i = 0; i < sizeof(cpd->esa); i += 2) {
+ unsigned short z = get_reg(cpd->base, PP_IA+i/2 );
+ esa[i] = (unsigned char)(0xff & z);
+ esa[i+1] = (unsigned char)(0xff & (z >> 8));
+ }
+ return 0;
+#endif
+ case ETH_DRV_SET_MC_LIST:
+ case ETH_DRV_SET_MC_ALL:
+ // Note: this code always accepts all multicast addresses if any
+ // are desired. It would be possible to accept a subset by adjusting
+ // the Logical Address Filter (LAF), but that would require scanning
+ // this list and building a suitable mask.
+ if (mc_list->len) {
+ cpd->rxmode |= PP_RxCTL_Multicast;
+ } else {
+ cpd->rxmode &= ~PP_RxCTL_Multicast;
+ }
+ put_reg(base, PP_RxCTL, cpd->rxmode); // When is it safe to do this?
+ return 0;
+ default:
+ return 1;
+ break;
+ }
+}
+
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+static int
+cs8900a_can_send(struct eth_drv_sc *sc)
+{
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ cyg_addrword_t base = cpd->base;
+ cyg_uint16 stat;
+
+ stat = get_reg(base, PP_LineStat);
+ if ((stat & PP_LineStat_LinkOK) == 0) {
+ return false; // Link not connected
+ }
+#ifdef CYGPKG_KERNEL
+ // Horrible hack!
+ if (cpd->txbusy) {
+ cyg_tick_count_t now = cyg_current_time();
+ if ((now - cpd->txstart) > 25) {
+ // 250ms is more than enough to transmit one frame
+#if DEBUG & 1
+ diag_printf("CS8900: Tx interrupt lost\n");
+#endif
+ cpd->txbusy = false;
+ // Free up the buffer (with error indication)
+ (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 1);
+ }
+ }
+#endif
+ return (cpd->txbusy == false);
+}
+
+// This routine is called to send data to the hardware.
+static void
+cs8900a_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ cyg_addrword_t base = cpd->base;
+ int i;
+ int len;
+ cyg_uint8 *data;
+ cyg_uint16 saved_data = 0, *sdata;
+ cyg_uint16 stat;
+ bool force_coping_by_byte;
+ bool odd_byte = false;
+
+ // Mark xmitter busy
+ cpd->txbusy = true;
+ cpd->txkey = key;
+#ifdef CYGPKG_KERNEL
+ cpd->txstart = cyg_current_time();
+#endif
+
+ // Start the xmit sequence
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ total_len = CYG_SWAP16(total_len);
+#endif
+
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT
+ force_coping_by_byte = true;
+#else
+ force_coping_by_byte = false;
+#endif
+
+ // The hardware indicates that there are options as to when the actual
+ // packet transmission will start wrt moving of data into the transmit
+ // buffer. However, impirical results seem to indicate that if the
+ // packet is large and transmission is allowed to start before the
+ // entire packet has been pushed into the buffer, the hardware gets
+ // confused and the packet is lost, along with a "lost" Tx interrupt.
+ // This may be a case of the copy loop below being interrupted, e.g.
+ // a system timer interrupt, and the hardware getting unhappy that
+ // not all of the data was provided before the transmission should
+ // have completed (i.e. buffer underrun).
+ // For now, the solution is to not allow this overlap.
+ //CS_OUT(cpd->base, CS8900A_TxCMD, PP_TxCmd_TxStart_5)
+
+ // Start only when all data sent to chip
+ CS_OUT(cpd->base, CS8900A_TxCMD, PP_TxCmd_TxStart_Full);
+
+ CS_OUT(cpd->base, CS8900A_TxLEN, total_len);
+ // Wait for controller ready signal
+ {
+ // add timeout per cs8900a bugzilla report 1000281 */
+ int timeout = 1000;
+
+ do {
+ stat = get_reg(base, PP_BusStat);
+#if DEBUG & 1
+ if( stat & PP_BusStat_TxBid )
+ diag_printf( "cs8900a_send: Bid error!\n" );
+#endif
+ } while (!(stat & PP_BusStat_TxRDY) && --timeout);
+
+ if( !timeout ) {
+ // we might as well just return, since if we write the data it will
+ // just get thrown away
+ return;
+ }
+ }
+
+ // Put data into buffer
+ for (i = 0; i < sg_len; i++) {
+ data = (cyg_uint8 *)sg_list[i].buf;
+ len = sg_list[i].len;
+
+ if (len > 0) {
+ /* Finish the last word. */
+ if (odd_byte) {
+// This new byte must get on the bus _after_ the last saved odd byte, it therefore
+// belongs in the MSB of the CS8900a
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ saved_data |= *data++;
+#else
+ saved_data |= ((cyg_uint16)*data++) << 8;
+#endif
+ CS_OUT(cpd->base, CS8900A_RTDATA, saved_data);
+ len--;
+ odd_byte = false;
+ }
+ if (!force_coping_by_byte && ((CYG_ADDRESS)data & 0x1) == 0) {
+ /* Aligned on 16-bit boundary, so output contiguous words. */
+ sdata = (cyg_uint16 *)data;
+ while (len > 1) {
+ // Make sure data get on the bus in Big Endian format
+#if((CYG_BYTEORDER == CYG_MSBFIRST) && defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED) || \
+ (CYG_BYTEORDER == CYG_LSBFIRST) && !defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED ))
+ CS_OUT(cpd->base, CS8900A_RTDATA, *sdata++);
+#else
+ CS_OUT(cpd->base, CS8900A_RTDATA, CYG_SWAP16(*sdata++));
+#endif
+ len -= sizeof(cyg_uint16);
+ }
+ data = (cyg_uint8 *)sdata;
+ } else {
+ /* Not 16-bit aligned, so byte copy */
+ while (len > 1) {
+ saved_data = (cyg_uint16)*data++; // reuse saved_data
+ // Make sure data get on the bus in Big Endian format, the first byte belongs in the
+ // LSB of the CS8900A
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ saved_data = ((cyg_uint16)*data++) | (saved_data << 8);
+#else
+ saved_data |= ((cyg_uint16)*data++) << 8;
+#endif
+ CS_OUT(cpd->base, CS8900A_RTDATA, saved_data);
+ len -= sizeof(cyg_uint16);
+ }
+ }
+ /* Save last byte, if necessary. */
+ if (len == 1) {
+ saved_data = (cyg_uint16)*data;
+// This _last_ byte must get on the bus _first_, it therefore belongs in the LSB of
+// the CS8900a
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ saved_data = (saved_data << 8);
+#endif
+ odd_byte = true;
+ }
+ }
+ }
+ if (odd_byte) {
+ CS_OUT(cpd->base, CS8900A_RTDATA, saved_data);
+ }
+}
+
+// This function is called when a packet has been received. It's job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'cs8900a_recv' will be called to actually fetch it from the hardware.
+static void
+cs8900a_RxEvent(struct eth_drv_sc *sc, int stat)
+{
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ cyg_addrword_t base = cpd->base;
+ cyg_uint16 len;
+
+ if(stat & PP_RxCFG_RxOK) {
+ // Only start reading a message if one has been received
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_8BIT
+ CS_IN(base, CS8900A_RTDATA, stat);
+ CS_IN(base, CS8900A_RTDATA, len);
+#else
+ // From AN181 Using the Crystal CS8900A in 8-bit mode.
+ // Note: it is very important to read the RxStatus and RxLength high
+ // order byte first.
+ stat = *(volatile CYG_BYTE *)(base + CS8900A_RTDATA + 1) << 8;
+ stat |= *(volatile CYG_BYTE *)(base + CS8900A_RTDATA);
+ len = *(volatile CYG_BYTE *)(base + CS8900A_RTDATA + 1) << 8;
+ len |= *(volatile CYG_BYTE *)(base + CS8900A_RTDATA);
+#endif
+
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ len = CYG_SWAP16(len);
+#endif
+
+ CYG_ASSERT(len > 0, "Zero length ethernet frame received");
+
+#ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
+ if (cyg_io_eth_net_debug) {
+ diag_printf("RxEvent - stat: %x, len: %d\n", stat, len);
+ }
+#endif
+ (sc->funs->eth_drv->recv)(sc, len);
+ }
+}
+
+// This function is called as a result of the "eth_drv_recv()" call above.
+// It's job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+static void
+cs8900a_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ cyg_addrword_t base = cpd->base;
+ int i, mlen;
+ cyg_uint16 *data, val;
+ cyg_uint8 *cp, cval;
+
+ for (i = 0; i < sg_len; i++) {
+ data = (cyg_uint16 *)sg_list[i].buf;
+ mlen = sg_list[i].len;
+ while (mlen >= sizeof(*data)) {
+ CS_IN(base, CS8900A_RTDATA, val);
+ if (data) {
+#if((CYG_BYTEORDER == CYG_MSBFIRST) && defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED) || \
+ (CYG_BYTEORDER == CYG_LSBFIRST) && !defined(CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED ))
+ *data++ = val;
+#else
+ *data++ = CYG_SWAP16(val);
+#endif
+ }
+ mlen -= sizeof(*data);
+ }
+ if (mlen) {
+ CS_IN(base, CS8900A_RTDATA, val);
+#ifndef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ // last odd byte will be in the LSB
+ cval = (cyg_uint8)(val);
+#elif(CYG_BYTEORDER == CYG_MSBFIRST)
+ // last odd byte will be in the MSB
+ cval = (cyg_uint8)(val >> 8);
+#endif
+ cval &= 0xff;
+ if ((cp = (cyg_uint8 *)data) != 0) {
+ *cp = cval;
+ }
+ }
+ }
+}
+
+static void
+cs8900a_TxEvent(struct eth_drv_sc *sc, int stat)
+{
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ cyg_addrword_t base = cpd->base;
+
+ stat = get_reg(base, PP_TER);
+#ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
+ if (cyg_io_eth_net_debug) {
+ diag_printf("Tx event: %x\n", stat);
+ }
+#endif
+ cpd->txbusy = false;
+ (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
+}
+
+static void
+cs8900a_BufEvent(struct eth_drv_sc *sc, int stat)
+{
+ if (stat & PP_BufCFG_RxMiss) {
+ }
+ if (stat & PP_BufCFG_TxUE) {
+ }
+}
+
+static void
+cs8900a_poll(struct eth_drv_sc *sc)
+{
+ cyg_uint16 event;
+ cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private;
+ cyg_addrword_t base = cpd->base;
+
+ CS_IN(base, CS8900A_ISQ, event);
+ while (event != 0) {
+ switch (event & ISQ_EventMask) {
+ case ISQ_RxEvent:
+ cs8900a_RxEvent(sc, event);
+ break;
+ case ISQ_TxEvent:
+ cs8900a_TxEvent(sc, event);
+ break;
+ case ISQ_BufEvent:
+ cs8900a_BufEvent(sc, event);
+ break;
+ case ISQ_RxMissEvent:
+ // Receive miss counter has overflowed
+ break;
+ case ISQ_TxColEvent:
+ // Transmit collision counter has overflowed
+ break;
+ default:
+#if DEBUG & 1
+ diag_printf("%s: Unknown event: %x\n", __FUNCTION__, event);
+#endif
+ break;
+ }
+ CS_IN(base, CS8900A_ISQ, event);
+ }
+
+ CYGHWR_CL_CS8900A_PLF_INT_CLEAR(cpd);
+}
+
+#ifdef CYGSEM_DEVS_ETH_CL_CS8900A_NOINTS
+void
+cs8900a_fake_int(cyg_addrword_t param)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *) param;
+ int s;
+
+#if DEBUG & 1
+ diag_printf("cs8900a_fake_int()\n");
+#endif
+
+ while (true) {
+ cyg_thread_delay(5);
+ s = splnet();
+ cs8900a_poll(sc);
+ splx(s);
+ }
+}
+#endif
diff --git a/ecos/packages/devs/eth/cortexm/a2f200_eval/current/ChangeLog b/ecos/packages/devs/eth/cortexm/a2f200_eval/current/ChangeLog
new file mode 100644
index 0000000..ea9feba
--- /dev/null
+++ b/ecos/packages/devs/eth/cortexm/a2f200_eval/current/ChangeLog
@@ -0,0 +1,31 @@
+
+2011-05-07 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * include/a2fxxx_eval_eth.inl:
+ * cdl/a2fxxx_eval.cdl
+ New package --Ethernet driver for Actel Smartfusion Evaluation Board
+ [Bugzilla 1001291]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/cortexm/a2f200_eval/current/cdl/a2f200_eval.cdl b/ecos/packages/devs/eth/cortexm/a2f200_eval/current/cdl/a2f200_eval.cdl
new file mode 100644
index 0000000..577f9c9
--- /dev/null
+++ b/ecos/packages/devs/eth/cortexm/a2f200_eval/current/cdl/a2f200_eval.cdl
@@ -0,0 +1,121 @@
+# ==========================================================================
+#
+# a2f200_eval.cdl
+#
+# Ethernet driver specifics for Actel Smartfusion (A2F200) board
+#
+##==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+##==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ccoutand
+# Contributors:
+# Date: 2011-05-04
+# Purpose:
+# Description: Ethernet driver specifics for Actel Smartfusion (A2F200)
+# board
+#
+#####DESCRIPTIONEND####
+#
+# ==========================================================================
+
+
+cdl_package CYGPKG_DEVS_ETH_CORTEXM_A2F200_EVAL {
+ display "Actel Smartfusion (A2F200) kit Ethernet support"
+ description "
+ Ethernet driver specifics for Actel Smartfusion (A2F200) board"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_CORTEXM
+ active_if CYGPKG_HAL_CORTEXM_A2FXXX
+
+ requires CYGPKG_DEVS_ETH_CORTEXM_A2FXXX
+
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_CORTEXM_A2FXXX_ETH_CDL <pkgconf/devs_eth_cortexm_a2f200_eval.h>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_CORTEXM_A2FXXX_ETH_INL <cyg/io/a2f200_eval_eth.inl>"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0 {
+ display "Actel Smartfusion (A2F200) Ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the Ethernet device driver on the
+ Actel Smartfusion (A2F200) motherboard."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ cdl_option CYGDAT_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0_NAME {
+ display "Device name for the Ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the Ethernet device for the
+ Ethernet port 0."
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0_PHY_ADDRESS {
+ display "Ethernet PHY address of the Ethernet port 0 driver"
+ flavor data
+ default_value 0
+ description "
+ This option sets the Ethernet PHY address of the Ethernet device for the
+ Ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0_SET_ESA {
+ display "Set the Ethernet station address"
+ flavor bool
+ default_value !CYGPKG_DEVS_ETH_TSEC_ETH_REDBOOT_HOLDS_ESA
+ description "Enabling this option will allow the Ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA, and if RedBoot's
+ flash configuration support is not available."
+
+ cdl_option CYGDAT_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0_ESA {
+ display "The Ethernet station address"
+ flavor data
+ default_value {"{0x00, 0x20, 0x0E, 0x10, 0x39, 0x89}"}
+ description "The Ethernet station address"
+ }
+ }
+ }
+
+}
diff --git a/ecos/packages/devs/eth/cortexm/a2f200_eval/current/include/a2f200_eval_eth.inl b/ecos/packages/devs/eth/cortexm/a2f200_eval/current/include/a2f200_eval_eth.inl
new file mode 100644
index 0000000..f06d07b
--- /dev/null
+++ b/ecos/packages/devs/eth/cortexm/a2f200_eval/current/include/a2f200_eval_eth.inl
@@ -0,0 +1,129 @@
+//==========================================================================
+//
+// a2f200_eval.inl
+//
+// Ethernet driver specifics for Actel Smartfusion (A2F200) board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Contributors:
+// Date: 2011-05-04
+// Purpose:
+// Description: Ethernet driver specifics for Actel Smartfusion (A2F200) board
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#ifndef CYGONCE_DEVS_A2F200_EVAL_ETH_INL
+#define CYGONCE_DEVS_A2F200_EVAL_ETH_INL
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/var_io.h>
+
+// Make sure packet size is multiple of words
+#define CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ALIGN_BUFSIZE_RX \
+ ((CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_BUFSIZE_RX + 0x00000003) & (0xfffffffc))
+
+#define CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ALIGN_BUFSIZE_TX \
+ ((CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_BUFSIZE_TX + 0x00000003) & (0xfffffffc))
+
+#define RxBUFSIZE ( CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_RxNUM*CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ALIGN_BUFSIZE_RX )
+#define TxBUFSIZE ( CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_TxNUM*CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ALIGN_BUFSIZE_TX )
+
+#ifdef CYGPKG_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0
+
+#ifdef CYGPKG_DEVS_ETH_PHY
+ETH_PHY_REG_LEVEL_ACCESS_FUNS(eth0_phy,
+ a2fxxx_phy_init,
+ NULL,
+ a2fxxx_mdio_write,
+ a2fxxx_mdio_read);
+#endif
+
+// Declare TX / RX buffers
+static cyg_uint32 a2fxxx_eth0_rxbufs[ RxBUFSIZE / 4 ];
+static cyg_uint32 a2fxxx_eth0_txbufs[ TxBUFSIZE / 4 ];
+
+// Declare BDs
+static struct a2fxxx_bd
+ a2fxxx_eth0_rxring[CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_RxNUM];
+static struct a2fxxx_bd
+ a2fxxx_eth0_txring[CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_TxNUM];
+
+static struct a2fxxx_eth_info a2fxxx_eth0_info = {
+#ifdef CYGDAT_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0_ESA
+ .mac_address = CYGDAT_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0_ESA,
+#endif
+ .base = CYGHWR_HAL_A2FXXX_MAC,
+ .base_bb = CYGHWR_HAL_A2FXXX_MAC_BB,
+ .if_num = 0,
+ .init_rxbufs = (cyg_uint8 *) &a2fxxx_eth0_rxbufs[0],
+ .init_txbufs = (cyg_uint8 *) &a2fxxx_eth0_txbufs[0],
+ .init_rxring = &a2fxxx_eth0_rxring[0],
+ .init_txring = &a2fxxx_eth0_txring[0],
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ .vector = CYGNUM_HAL_INTERRUPT_MAC0,
+#endif
+#ifdef CYGPKG_DEVS_ETH_PHY
+ .phy = &eth0_phy,
+#endif
+};
+
+ETH_DRV_SC(a2fxxx_eth0_sc,
+ &a2fxxx_eth0_info,
+ CYGDAT_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0_NAME,
+ a2fxxx_eth_start,
+ a2fxxx_eth_stop,
+ a2fxxx_eth_control,
+ a2fxxx_eth_can_send,
+ a2fxxx_eth_send,
+ a2fxxx_eth_recv,
+ a2fxxx_eth_deliver,
+ a2fxxx_eth_poll,
+ a2fxxx_eth_int_vector);
+
+NETDEVTAB_ENTRY(a2fxxx_netdev0,
+ "a2fxxx_" CYGDAT_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0_NAME,
+ a2fxxx_eth_init,
+ &a2fxxx_eth0_sc);
+
+#endif// CYGPKG_DEVS_ETH_CORTEXM_A2F200_EVAL_ETH0
+
+#endif
diff --git a/ecos/packages/devs/eth/cortexm/a2fxxx/current/ChangeLog b/ecos/packages/devs/eth/cortexm/a2fxxx/current/ChangeLog
new file mode 100644
index 0000000..c85e177
--- /dev/null
+++ b/ecos/packages/devs/eth/cortexm/a2fxxx/current/ChangeLog
@@ -0,0 +1,31 @@
+
+2011-05-07 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * src/if_a2fxxx.c:
+ * cdl/a2fxxx_eth.cdl
+ New package -- Ethernet driver for Actel Smartfusion
+ [Bugzilla 1001291]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/cortexm/a2fxxx/current/cdl/a2fxxx_eth.cdl b/ecos/packages/devs/eth/cortexm/a2fxxx/current/cdl/a2fxxx_eth.cdl
new file mode 100644
index 0000000..70cb338
--- /dev/null
+++ b/ecos/packages/devs/eth/cortexm/a2fxxx/current/cdl/a2fxxx_eth.cdl
@@ -0,0 +1,152 @@
+#==========================================================================
+#
+# a2fxxx_eth.cdl
+#
+# Ethernet drivers for Actel AF2xxx Controller
+#
+#==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ccoutand
+# Contributors:
+# Date: 2011-05-04
+# Purpose:
+# Description:
+#
+#####DESCRIPTIONEND####
+#
+#========================================================================*/
+
+cdl_package CYGPKG_DEVS_ETH_CORTEXM_A2FXXX {
+ display "Actel Smartfusion Ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_CORTEXM_A2FXXX
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ include_dir net
+ description "
+ Ethernet drivers for Actel AF2xxx Controller."
+
+ compile -library=libextras.a if_a2fxxx.c
+
+ cdl_option CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_PROMISCUOUS {
+ display "Promiscuous Mode"
+ flavor bool
+ default_value 0
+ description "
+ Selecting this option will set the Ethernet MAC in promiscuous mode, all Ethernet
+ packets will be delivered to the application layer."
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_CHATTER {
+ display "Display status messages during Ethernet operations"
+ flavor bool
+ default_value 0
+ description "
+ Selecting this option will cause the Ethernet driver to print status
+ messages as various Ethernet operations are undertaken."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ISR_PRIORITY {
+ display "Ethernet interrupt ISR priority"
+ flavor data
+ default_value CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ISR_SP
+ description "
+ Set the Ethernet controller ISR priority."
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS {
+ display "Maintain statistics at the MAC layer"
+ flavor bool
+ default_value 0
+ description "
+ Selecting this option will cause the Ethernet driver to accumulate statistics
+ provided from the MAC layer."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_BUFSIZE_TX {
+ display "Buffer size"
+ flavor data
+ default_value 1536
+ description "
+ This option specifies the size of the internal transmit buffers used
+ for the Actel A2Fxxx/Ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_BUFSIZE_RX {
+ display "Buffer size"
+ flavor data
+ default_value 1536
+ description "
+ This option specifies the size of the internal receive buffers used
+ for the Actel A2Fxxx/Ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_TxNUM {
+ display "Number of output buffers"
+ flavor data
+ legal_values 2 to 8
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the Actel A2Fxxx/Ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_RxNUM {
+ display "Number of input buffers"
+ flavor data
+ legal_values 2 to 8
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the Actel A2Fxxx/Ethernet device."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_CORTEXM_A2FXXX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Actel A2Fxxx Ethernet driver package.
+ These flags are used in addition to the set of global flags."
+ }
+}
+
+# EOF a2fxxx_eth.cdl
diff --git a/ecos/packages/devs/eth/cortexm/a2fxxx/current/src/if_a2fxxx.c b/ecos/packages/devs/eth/cortexm/a2fxxx/current/src/if_a2fxxx.c
new file mode 100644
index 0000000..cb88a3c
--- /dev/null
+++ b/ecos/packages/devs/eth/cortexm/a2fxxx/current/src/if_a2fxxx.c
@@ -0,0 +1,1088 @@
+//==========================================================================
+//
+// if_a2fxxx.c
+//
+// Ethernet driver for Actel A2Fxxx device family
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Contributors:
+// Date: 2011-05-05
+// Purpose: Ethernet driver for Actel A2Fxxx device family
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_cortexm_a2fxxx.h>
+
+#ifdef CYGDAT_DEVS_CORTEXM_A2FXXX_ETH_CDL
+# include CYGDAT_DEVS_CORTEXM_A2FXXX_ETH_CDL
+#endif
+
+#include <pkgconf/io_eth_drivers.h>
+
+#ifdef CYGPKG_NET
+# include <pkgconf/net.h>
+#endif
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/var_io.h>
+
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#ifdef CYGPKG_DEVS_ETH_PHY
+# include <cyg/io/eth_phy.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+
+static unsigned char enaddr[6];
+
+// Buffer descriptor
+struct a2fxxx_bd {
+ cyg_uint32 des0;
+ cyg_uint32 des1;
+ cyg_uint32 des2;
+ cyg_uint32 des3;
+ cyg_uint32 private;
+};
+
+// Some statistics
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
+typedef struct {
+ cyg_uint32 rx_mcast;
+ cyg_uint32 rx_des_err;
+ cyg_uint32 rx_collision;
+ cyg_uint32 rx_crc_err;
+ cyg_uint32 rx_too_long;
+ cyg_uint32 tx_fifo_underflow;
+ cyg_uint32 tx_frame_deferred;
+ cyg_uint32 tx_late_collision;
+ cyg_uint32 tx_no_carrier;
+ cyg_uint32 tx_loss_carrier;
+} a2fxxx_eth_stats;
+#endif
+
+// Internal data structure
+struct a2fxxx_eth_info {
+ volatile struct a2fxxx_bd *txbd,
+ *rxbd; // Next Tx,Rx descriptor to use
+ volatile struct a2fxxx_bd *tbase,
+ *rbase; // First Tx,Rx descriptor
+ volatile struct a2fxxx_bd *tnext,
+ *rnext; // Next descriptor to check for interrupt
+ cyg_uint8 txactive; // Count of active Tx buffers
+ unsigned long txkey[CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_TxNUM];
+ cyg_uint8 mac_address[6]; // mac (hardware) address
+ cyg_uint8 *init_rxbufs; // Initial base pointer of RX buffers
+ cyg_uint8 *init_txbufs; // Initial base pointer of TX buffers
+ volatile struct a2fxxx_bd *init_rxring; // Initial base pointer of RX ring
+ volatile struct a2fxxx_bd *init_txring; // Initial base pointer of TX ring
+ cyg_uint32 rx_mac[48]; // Setup frame (192) bytes
+ cyg_uint32 valid_mac;
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
+ a2fxxx_eth_stats stats; // MAC statistics
+#endif
+ cyg_uint32 base; // MAC base address
+ cyg_uint32 base_bb; // MAC base address (bit-band)
+ cyg_uint8 if_num;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_uint8 vector;
+ cyg_interrupt interrupt;
+ cyg_handle_t interrupt_handle;
+#endif
+#ifdef CYGPKG_DEVS_ETH_PHY
+ eth_phy_access_t *phy;
+#endif
+};
+
+static void a2fxxx_phy_init(void);
+static bool a2fxxx_mdio_read(cyg_int32, cyg_int32, cyg_uint16 *);
+static void a2fxxx_mdio_write(cyg_int32, cyg_int32, cyg_uint16);
+
+static void a2fxxx_eth_int(struct eth_drv_sc *data);
+
+#ifdef CYGDAT_DEVS_CORTEXM_A2FXXX_ETH_INL
+# include CYGDAT_DEVS_CORTEXM_A2FXXX_ETH_INL
+#endif
+
+#include <cyg/infra/diag.h>
+
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_CHATTER
+# define a2fxxx_eth_printf(args...) diag_printf(args)
+#else
+# define a2fxxx_eth_printf(args...) /* NOOP */
+#endif
+
+// For fetching the ESA from RedBoot
+#include <cyg/hal/hal_if.h>
+#ifndef CONFIG_ESA
+# define CONFIG_ESA 6
+#endif
+
+// ----------------------------------------------------------------
+// Definition
+//
+//
+
+#define RESET_FULL_DUPLEX 0x00000001
+#define RESET_100MB 0x00000002
+
+#define MDIO_PREAMBLE_SEQ 0xffffffff
+#define MDIO_START_SEQ 0x01
+#define MDIO_WRITE_SEQ 0x01
+#define MDIO_READ_SEQ 0x02
+#define MDIO_STOP_WRITE_SEQ 0x02
+#define MDIO_STOP_READ_SEQ 0x00
+
+#define CYGHWR_HAL_A2FXXX_MAC_CSR5_TI_BB(_base_) \
+ ( _base_ + ( CYGHWR_HAL_A2FXXX_MAC_CSR5 << 5 ) + ( 0*sizeof(cyg_uint32) ) )
+#define CYGHWR_HAL_A2FXXX_MAC_CSR5_RI_BB(_base_) \
+ ( _base_ + ( CYGHWR_HAL_A2FXXX_MAC_CSR5 << 5 ) + ( 6*sizeof(cyg_uint32) ) )
+#define CYGHWR_HAL_A2FXXX_MAC_CSR5_NIS_BB(_base_) \
+ ( _base_ + ( CYGHWR_HAL_A2FXXX_MAC_CSR5 << 5 ) + ( 16*sizeof(cyg_uint32) ) )
+
+#define CYGHWR_HAL_A2FXXX_MAC_PRIVATE_SENT BIT_(0)
+
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
+# define A2FXXX_INC_STATS(_x_) (qi->stats._x_++)
+#endif
+
+// ----------------------------------------------------------------
+// MDIO API
+//
+//
+
+#define MDIO_XFER_BITS( reg, reg_val, sequence, length ) \
+{ \
+ cyg_uint32 i; \
+ for (i = (1 << (length-1)); i != 0; ) { \
+ reg_val &= ~CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC; \
+ HAL_WRITE_UINT32( reg, reg_val ); \
+ HAL_DELAY_US(1); \
+ if( i & sequence ) \
+ reg_val |= ( CYGHWR_HAL_A2FXXX_MAC_CSR9_MDO ); \
+ else \
+ reg_val &= ( ~CYGHWR_HAL_A2FXXX_MAC_CSR9_MDO ); \
+ HAL_WRITE_UINT32( reg, reg_val ); \
+ reg_val |= CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC; \
+ HAL_WRITE_UINT32( reg, reg_val ); \
+ HAL_DELAY_US(1); \
+ i = i >> 1; \
+ } \
+}
+
+//
+// Setup IOs
+//
+static void
+a2fxxx_phy_init(void)
+{
+ a2fxxx_eth_printf("ETH A2Fxxx - PHY Init\n");
+ CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_MDIO);
+ CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_MDC);
+}
+
+//
+// Start MDIO transfer -> 32 bits of preamble ('1'), start bits,
+// transfer type bits, phy address and register address bits
+//
+static void
+a2fxxx_mdio_xfer_start(cyg_bool rd, cyg_uint8 phy_addr, cyg_uint8 addr)
+{
+ cyg_uint32 csr9_reg =
+ (CYGHWR_HAL_A2FXXX_MAC + CYGHWR_HAL_A2FXXX_MAC_CSR9);
+ cyg_uint32 csr9_data,
+ bit_sequence;
+
+ // Enable MDIO write
+ HAL_READ_UINT32(csr9_reg, csr9_data);
+ csr9_data |=
+ (CYGHWR_HAL_A2FXXX_MAC_CSR9_MDEN | CYGHWR_HAL_A2FXXX_MAC_CSR9_MDO |
+ CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC);
+ HAL_WRITE_UINT32(csr9_reg, csr9_data);
+ HAL_DELAY_US(1);
+
+ // Send preamble bits
+ bit_sequence = MDIO_PREAMBLE_SEQ;
+ MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 32);
+
+ // Send 2 start bits
+ bit_sequence = MDIO_START_SEQ;
+ MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 2);
+
+ // Send transfer type bits
+ bit_sequence = (rd == true) ? MDIO_READ_SEQ : MDIO_WRITE_SEQ;
+ MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 2);
+
+ // Send PHY address
+ bit_sequence = (cyg_uint32)phy_addr;
+ MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 5);
+
+ // Send register address
+ bit_sequence = (cyg_uint32)addr;
+ MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 5);
+
+ // Send TA sequence
+ if (rd == true) {
+ bit_sequence = MDIO_STOP_READ_SEQ;
+ csr9_data &= ~(CYGHWR_HAL_A2FXXX_MAC_CSR9_MDEN);
+ HAL_WRITE_UINT32(csr9_reg, csr9_data);
+ } else {
+ bit_sequence = MDIO_STOP_WRITE_SEQ;
+ }
+ MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 2);
+
+ // now we can read or write the 16 bits data ...
+}
+
+//
+// Read 16 bits data from MDIO interface
+//
+static cyg_bool
+a2fxxx_mdio_xfer_read(cyg_uint16 *data)
+{
+ cyg_uint32 csr9_reg =
+ (CYGHWR_HAL_A2FXXX_MAC + CYGHWR_HAL_A2FXXX_MAC_CSR9);
+ cyg_uint32 csr9_data;
+ *data = 0;
+ int i;
+
+ // Read MDIO register
+ HAL_READ_UINT32(csr9_reg, csr9_data);
+
+ // Clock in the RX data
+ for (i = (1 << 15); i != 0;) {
+ csr9_data &= ~CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC;
+ HAL_WRITE_UINT32(csr9_reg, csr9_data);
+ HAL_DELAY_US(1);
+ HAL_READ_UINT32(csr9_reg, csr9_data);
+ if (csr9_data & CYGHWR_HAL_A2FXXX_MAC_CSR9_MDI)
+ *data |= i;
+ csr9_data |= CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC;
+ HAL_WRITE_UINT32(csr9_reg, csr9_data);
+ HAL_DELAY_US(1);
+ i = i >> 1;
+ }
+
+ return true;
+}
+
+//
+// Write 16 bits data to MDIO interface
+//
+static bool
+a2fxxx_mdio_xfer_write(cyg_uint16 data)
+{
+ cyg_uint32 csr9_reg =
+ (CYGHWR_HAL_A2FXXX_MAC + CYGHWR_HAL_A2FXXX_MAC_CSR9);
+ cyg_uint32 csr9_data,
+ bit_sequence;
+
+ // Read MDIO register
+ HAL_READ_UINT32(csr9_reg, csr9_data);
+
+ // Write data
+ bit_sequence = (cyg_uint32)data;
+ MDIO_XFER_BITS(csr9_reg, csr9_data, bit_sequence, 16);
+
+ // Set back clock to low
+ csr9_data &= ~CYGHWR_HAL_A2FXXX_MAC_CSR9_MDC;
+ HAL_WRITE_UINT32(csr9_reg, csr9_data);
+
+ return true;
+}
+
+//
+// MDIO read register
+//
+static bool
+a2fxxx_mdio_read(cyg_int32 addr, cyg_int32 phy_addr, cyg_uint16 *data)
+{
+ bool res;
+ a2fxxx_mdio_xfer_start(true, phy_addr, addr);
+ res = a2fxxx_mdio_xfer_read(data);
+ a2fxxx_eth_printf("ETH A2Fxxx - PHY %x(%x) - RX data %x\n", phy_addr, addr,
+ *data);
+ return res;
+}
+
+//
+// MDIO write register
+//
+static void
+a2fxxx_mdio_write(cyg_int32 addr, cyg_int32 phy_addr, cyg_uint16 data)
+{
+ a2fxxx_mdio_xfer_start(false, phy_addr, addr);
+ a2fxxx_eth_printf("ETH A2Fxxx - PHY %x(%x) - TX data %x\n", phy_addr, addr,
+ data);
+ a2fxxx_mdio_xfer_write(data);
+}
+
+
+// ----------------------------------------------------------------
+// Ethernet driver
+//
+//
+#define A2FXXX_RESET_MAC( qi ) \
+{ \
+ cyg_uint32 swr_addr = \
+ qi->base_bb + (CYGHWR_HAL_A2FXXX_MAC_CSR0 << 5); \
+ cyg_uint32 swr_data = 0x1; \
+ HAL_WRITE_UINT32(swr_addr, swr_data); \
+ do { \
+ HAL_READ_UINT32(swr_addr, swr_data); \
+ } while (swr_data); \
+}
+
+//
+// Deliver function (ex-DSR) handles the Ethernet [logical] processing
+//
+static void
+a2fxxx_eth_deliver(struct eth_drv_sc *sc)
+{
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *)sc->driver_private;
+#endif
+ a2fxxx_eth_int(sc);
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(qi->vector);
+#endif
+}
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+//
+// This ISR is called when the Ethernet interrupt occurs
+//
+static int
+a2fxxx_eth_isr(cyg_vector_t vector, cyg_addrword_t data,
+ HAL_SavedRegisters * regs)
+{
+ a2fxxx_eth_printf("ETH A2Fxxx - ISR\n");
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+
+ return (CYG_ISR_HANDLED | CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+void
+a2fxxx_eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ a2fxxx_eth_deliver((struct eth_drv_sc *)data);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(vector);
+}
+#endif
+
+//
+// This function add MAC address to the list of allowed MAC address
+// that the MAC layer can deliver to the application layer
+//
+static bool
+a2fxxx_eth_add_mac ( struct eth_drv_sc *sc, cyg_uint8 *mac )
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *)sc->driver_private;
+ cyg_uint8 idx = 12;
+ struct a2fxxx_bd setup_bd;
+ cyg_uint32 i, csr4, csr5, csr6, csr7;
+
+ // If no MAC to be added, just re-send the setup frame
+ if( mac != NULL )
+ {
+ // no more room
+ if( qi->valid_mac == (cyg_uint32) -1 )
+ return false;
+
+ // Search empty spot
+ while( qi->valid_mac & i ){
+ i = i << 1;
+ idx += 12;
+ }
+
+ qi->rx_mac[idx+0] = mac[0];
+ qi->rx_mac[idx+1] = mac[1];
+ qi->rx_mac[idx+4] = mac[2];
+ qi->rx_mac[idx+5] = mac[3];
+ qi->rx_mac[idx+8] = mac[4];
+ qi->rx_mac[idx+9] = mac[6];
+ }
+
+ a2fxxx_eth_printf("ETH A2Fxxx - Send setup frame for %s\n", sc->dev_name);
+
+ // Stop TX
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
+ csr6 &= ~( CYGHWR_HAL_A2FXXX_MAC_CSR6_ST );
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
+
+ // Wait until controller is halted
+ do {
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR5), csr5);
+ } while( ((csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_MASK)
+ != CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_STOP) );
+
+ // Backup the current BD / interrupt mask
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR4), csr4);
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR7), csr7);
+
+ // Disable interrupt
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR7), 0);
+
+ // Setup descriptor for setup frame
+ setup_bd.des0 = CYGHWR_HAL_A2FXXX_MAC_TDES0_OWN;
+ setup_bd.des1 = CYGHWR_HAL_A2FXXX_MAC_TDES1_TER |
+ CYGHWR_HAL_A2FXXX_MAC_TDES1_SET |
+ CYGHWR_HAL_A2FXXX_MAC_TDES1_TBS1(192);
+ setup_bd.des2 = (cyg_uint32) &qi->rx_mac[0];
+ setup_bd.des3 = (cyg_uint32) NULL;
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR4),
+ (cyg_uint32) &setup_bd);
+
+ // Start transmission
+ csr6 |= ( CYGHWR_HAL_A2FXXX_MAC_CSR6_ST );
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
+
+ // Poll for transmission completed
+ do {
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR5), csr5);
+ } while( ((csr5 & A2FXXX_MAC_TX_STATE_MASK) != A2FXXX_MAC_TX_STATE(SUSPEND)) );
+
+ // Stop transmission
+ csr6 &= ~( CYGHWR_HAL_A2FXXX_MAC_CSR6_ST );
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
+
+ // Wait until controller is halted
+ do {
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR5), csr5);
+ } while( ((csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_MASK)
+ != CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_STOP) );
+
+ // Restore BD
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR4), csr4);
+
+ HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_TI_BB(qi->base_bb), 1);
+
+ // Restore interrupt mask
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR7), csr7);
+
+ return true;
+}
+
+//
+// [re]Initialize the Ethernet controller
+// Done separately since shutting down the device requires a
+// full reconfiguration when re-enabling.
+// when
+static bool
+a2fxxx_eth_setup(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
+ volatile struct a2fxxx_bd *rxbd, *txbd;
+ cyg_uint8 *RxBUF, *TxBUF;
+ cyg_uint32 csr0, csr6 = 0, csr11;
+ int i = 0;
+
+ qi->valid_mac = 0;
+ qi->rx_mac[5] = enaddr[0];
+ qi->rx_mac[4] = enaddr[1];
+ qi->rx_mac[3] = enaddr[2];
+ qi->rx_mac[2] = enaddr[3];
+ qi->rx_mac[1] = enaddr[4];
+ qi->rx_mac[0] = enaddr[5];
+
+ txbd = qi->init_txring;
+ rxbd = qi->init_rxring;
+
+ /* Init Rx / Tx ring base */
+ qi->tbase = qi->txbd = qi->tnext = txbd;
+ qi->rbase = qi->rxbd = qi->rnext = rxbd;
+ qi->txactive = 0;
+
+ RxBUF = qi->init_rxbufs;
+ TxBUF = qi->init_txbufs;
+
+ /* Initialize Rx BDs */
+ for (i = 0; i < CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_RxNUM; i++)
+ {
+ rxbd->des0 = CYGHWR_HAL_A2FXXX_MAC_RDES0_OWN;
+ rxbd->des1 =
+ CYGHWR_HAL_A2FXXX_MAC_RDES1_RBS1(CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ALIGN_BUFSIZE_RX);
+ rxbd->des2 = (cyg_uint32) RxBUF;
+ rxbd->des3 = (cyg_uint32) NULL;
+ RxBUF += CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ALIGN_BUFSIZE_RX;
+ rxbd++;
+ }
+ rxbd--;
+ rxbd->des1 |= CYGHWR_HAL_A2FXXX_MAC_RDES1_RER; // Last buffer
+
+ /* Initialize Tx BDs */
+ for (i = 0; i < CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_TxNUM; i++)
+ {
+ txbd->des1 = 0;
+ txbd->des2 = (cyg_uint32) TxBUF;
+ rxbd->des3 = (cyg_uint32) NULL;
+ txbd->private = 0;
+ TxBUF += CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ALIGN_BUFSIZE_TX;
+ txbd++;
+ }
+ txbd--;
+ txbd->des1 |= CYGHWR_HAL_A2FXXX_MAC_TDES1_TER; // Last buffer
+
+ // Setup automatic polling
+ csr0 = CYGHWR_HAL_A2FXXX_MAC_CSR0_CLEAR | CYGHWR_HAL_A2FXXX_MAC_CSR0_TAP(3) |
+ CYGHWR_HAL_A2FXXX_MAC_CSR0_DSL(1);
+
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR0),
+ (cyg_uint32) csr0);
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR3),
+ (cyg_uint32) (qi->rbase));
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR4),
+ (cyg_uint32) (qi->tbase));
+
+ csr11 = CYGHWR_HAL_A2FXXX_MAC_CSR11_TT(7) |
+ CYGHWR_HAL_A2FXXX_MAC_CSR11_NTP(1) |
+ CYGHWR_HAL_A2FXXX_MAC_CSR11_RT(7) |
+ CYGHWR_HAL_A2FXXX_MAC_CSR11_NRP(1);
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR11), (cyg_uint32) csr11);
+
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
+ csr6 |= CYGHWR_HAL_A2FXXX_MAC_CSR6_CLEAR;
+
+ csr6 |= ((flags & RESET_100MB) ? CYGHWR_HAL_A2FXXX_MAC_CSR6_TTM : 0x0) |
+ ((flags & RESET_FULL_DUPLEX) ? CYGHWR_HAL_A2FXXX_MAC_CSR6_FD : 0x0);
+
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_PROMISCUOUS
+ csr6 |= CYGHWR_HAL_A2FXXX_MAC_CSR6_PR;
+#endif
+
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
+
+ return true;
+}
+
+//
+// This function is called to shut down the interface.
+//
+static void
+a2fxxx_eth_stop(struct eth_drv_sc *sc)
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *)sc->driver_private;
+ cyg_uint32 csr6, csr5;
+
+ a2fxxx_eth_printf("ETH A2Fxxx - Stop\n");
+
+ // Stop RX / TX
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
+ csr6 &= ~( CYGHWR_HAL_A2FXXX_MAC_CSR6_SR | CYGHWR_HAL_A2FXXX_MAC_CSR6_ST );
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
+
+ // Stall until controller is halted
+ do {
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR5), csr5);
+ } while( ((csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_MASK) != CYGHWR_HAL_A2FXXX_MAC_CSR5_TS_STOP) &&
+ ((csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_RS_MASK) != CYGHWR_HAL_A2FXXX_MAC_CSR5_RS_STOP));
+
+}
+
+//
+// Setup Ethernet IOs.
+//
+static void
+a2fxxx_eth_io(void)
+{
+ CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_TXD0);
+ CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_TXD1);
+ CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_RXD0);
+ CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_RXD1);
+ CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_TXEN);
+ CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_CRSDV);
+ CYGHWR_HAL_A2FXXX_GPIO_SET(CYGHWR_HAL_A2FXXX_MAC0_RXER);
+}
+
+//
+// Initialize the interface - performed at system startup
+// This function must set up the interface, including arranging to
+// handle interrupts, etc, so that it may be "started" cheaply later.
+//
+static bool
+a2fxxx_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *)sc->driver_private;
+ cyg_uint32 speed100 = 0, full_duplex = 0;
+ bool esa_ok;
+ cyg_uint16 phy_state = 0;
+ cyg_uint32 istate, csr7;
+ bool ret = true;
+
+ a2fxxx_eth_printf("ETH A2Fxxx - Initialization for %s\n", sc->dev_name);
+
+ // Release MAC controller
+ CYGHWR_HAL_A2FXXX_PERIPH_RELEASE(CYGHWR_HAL_A2FXXX_PERIPH_SOFTRST(MAC));
+
+ // Setup IOs
+ a2fxxx_eth_io();
+
+ // Reset MAC
+ A2FXXX_RESET_MAC( qi );
+
+ HAL_DISABLE_INTERRUPTS(istate);
+
+ a2fxxx_eth_stop(sc);
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_create(qi->vector,
+ CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_ISR_PRIORITY,
+ (cyg_addrword_t)sc, // Data item passed to interrupt handler
+ (cyg_ISR_t *)a2fxxx_eth_isr,
+ (cyg_DSR_t *)eth_drv_dsr,
+ &qi->interrupt_handle, &qi->interrupt);
+ cyg_drv_interrupt_attach(qi->interrupt_handle);
+ cyg_drv_interrupt_unmask(qi->vector);
+#endif
+
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "a2fxxx_esa", enaddr, CONFIG_ESA);
+
+ if (!esa_ok) {
+ a2fxxx_eth_printf("ETH A2Fxxx - Warning! ESA unknown for %s\n", sc->dev_name);
+ memcpy(&enaddr, &qi->mac_address, sizeof(enaddr));
+ }
+
+#ifdef CYGPKG_DEVS_ETH_PHY
+ if (!_eth_phy_init(qi->phy)) {
+ a2fxxx_eth_printf("ETH A2Fxxx - Failed to initialize PHY of %s\n",
+ sc->dev_name);
+ ret = false;
+ goto exit;
+ }
+ phy_state = _eth_phy_state(qi->phy);
+
+ if (phy_state & ETH_PHY_STAT_100MB)
+ speed100 = 1;
+ if (phy_state & ETH_PHY_STAT_FDX)
+ full_duplex = 1;
+ if (phy_state & ETH_PHY_STAT_LINK) {
+ a2fxxx_eth_printf("Ethernet Mode (%s): %sMbps/%s\n",
+ sc->dev_name,
+ (speed100 ? "100" : "10"),
+ (full_duplex ? "Full" : "Half"));
+ } else {
+ a2fxxx_eth_printf("ETH A2Fxxx - NO LINK on %s\n", sc->dev_name);
+ }
+#else
+ a2fxxx_eth_printf("ETH A2Fxxx - No PHY interface specified for %s\n",
+ sc->dev_name);
+ ret = false;
+ goto exit;
+#endif
+
+ if (!a2fxxx_eth_setup(sc, enaddr, (full_duplex ? RESET_FULL_DUPLEX
+ : 0x00000000) | (speed100 ? RESET_100MB : 0x00000000)))
+ {
+ ret = false;
+ goto exit;
+ }
+
+ a2fxxx_eth_add_mac( sc, NULL );
+
+ HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_RI_BB(qi->base_bb), 1);
+ HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_TI_BB(qi->base_bb), 1);
+
+ csr7 = ( CYGHWR_HAL_A2FXXX_MAC_CSR7_TIE | CYGHWR_HAL_A2FXXX_MAC_CSR7_RIE |
+ CYGHWR_HAL_A2FXXX_MAC_CSR7_NIE);
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR7), csr7);
+
+ HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_NIS_BB(qi->base_bb),
+ (cyg_uint32) 0x1);
+
+ // Call upper layer initialization
+ (sc->funs->eth_drv->init)(sc, (unsigned char *) &enaddr);
+
+exit:
+ HAL_RESTORE_INTERRUPTS(istate);
+ return ret;
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+a2fxxx_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *)sc->driver_private;
+ cyg_uint32 csr6;
+
+ a2fxxx_eth_printf("ETH A2Fxxx - Start\n");
+
+ // Stop RX / TX
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
+ csr6 |= ( CYGHWR_HAL_A2FXXX_MAC_CSR6_SR | CYGHWR_HAL_A2FXXX_MAC_CSR6_ST );
+ HAL_WRITE_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR6), csr6);
+}
+
+//
+// This function is called for low level "control" operations
+//
+static int
+a2fxxx_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int length)
+{
+ switch (key)
+ {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ return 0;
+ break;
+#ifdef ETH_DRV_SET_MC_ALL
+ case ETH_DRV_SET_MC_ALL:
+ case ETH_DRV_SET_MC_LIST:
+ // TODO
+ return 0;
+ break;
+#endif
+ default:
+ return 1;
+ break;
+ }
+}
+
+//
+// This function is called to see if another packet can be sent.
+// It should return the number of packets which can be handled.
+// Zero should be returned if the interface is busy and can not send any more.
+//
+static int
+a2fxxx_eth_can_send(struct eth_drv_sc *sc)
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
+
+ return (qi->txactive < CYGNUM_DEVS_ETH_CORTEXM_A2FXXX_TxNUM);
+}
+
+//
+// This routine is called to send data to the hardware.
+static void
+a2fxxx_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
+ int sg_len, int total_len, unsigned long key)
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
+ volatile struct a2fxxx_bd *txbd, *txfirst;
+ cyg_uint32 des1 = CYGHWR_HAL_A2FXXX_MAC_TDES1_TBS1(total_len);
+ volatile cyg_uint8 *bp;
+ cyg_int32 i, txindex, istate;
+
+ a2fxxx_eth_printf("ETH A2Fxxx - transmit pkt, length %d\n", total_len);
+
+ // Continue from current descriptor
+ txbd = txfirst = qi->txbd;
+
+ if ( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_OWN) == CYGHWR_HAL_A2FXXX_MAC_TDES0_OWN ) {
+ a2fxxx_eth_printf("ETH A2Fxxx - Fatal error, no free BD for %s\n",
+ sc->dev_name);
+ a2fxxx_eth_printf("ETH A2Fxxx - Cannot transmit packet, active pkt in queue:%d\n",
+ qi->txactive);
+ return;
+ }
+
+ // Set up buffer
+ bp = (cyg_uint8 *) txbd->des2;
+ for (i = 0; i < sg_len; i++) {
+ memcpy((void *) bp, (void *) sg_list[i].buf, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+
+ if (txbd->des1 & CYGHWR_HAL_A2FXXX_MAC_TDES1_TER) {
+ des1 |= CYGHWR_HAL_A2FXXX_MAC_TDES1_TER;
+ }
+ txbd->des1 =
+ ( des1 | CYGHWR_HAL_A2FXXX_MAC_TDES1_LS | CYGHWR_HAL_A2FXXX_MAC_TDES1_FS |
+ CYGHWR_HAL_A2FXXX_MAC_TDES1_IC );
+ txindex = ((unsigned long) txbd - (unsigned long) qi->tbase)
+ / sizeof(*txbd);
+ qi->txkey[txindex] = key;
+
+ qi->txactive++;
+
+ HAL_DISABLE_INTERRUPTS(istate);
+ // Give ownership to the MAC
+ txbd->des0 = CYGHWR_HAL_A2FXXX_MAC_TDES0_OWN;
+ txbd->private = CYGHWR_HAL_A2FXXX_MAC_PRIVATE_SENT;
+
+ // Remember the next buffer to try
+ if (qi->txbd->des1 & CYGHWR_HAL_A2FXXX_MAC_TDES1_TER){
+ qi->txbd = qi->tbase;
+ }
+ else {
+ qi->txbd++;
+ }
+ HAL_RESTORE_INTERRUPTS(istate);
+}
+
+//
+// This function is called for low level "control" operations
+//
+static void
+a2fxxx_eth_TxEvent(struct eth_drv_sc *sc)
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
+ volatile struct a2fxxx_bd *txbd;
+ int key, txindex;
+
+ txbd = qi->tnext;
+
+ while ( ( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_OWN ) == 0) &&
+ (txbd->private & CYGHWR_HAL_A2FXXX_MAC_PRIVATE_SENT) )
+ {
+ txindex = ((unsigned long) txbd - (unsigned long) qi->tbase)
+ / sizeof(*txbd);
+ if ((key = qi->txkey[txindex]) != 0)
+ {
+ qi->txkey[txindex] = 0;
+ (sc->funs->eth_drv->tx_done)(sc, key, 0);
+ }
+ qi->txactive--;
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
+ if( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_LC) ) {
+ A2FXXX_INC_STATS(tx_late_collision);
+ }
+ if( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_NC) ) {
+ A2FXXX_INC_STATS(tx_no_carrier);
+ }
+ if( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_LO) ) {
+ A2FXXX_INC_STATS(tx_loss_carrier);
+ }
+ if( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_DE) ) {
+ A2FXXX_INC_STATS(tx_frame_deferred);
+ }
+ if( (txbd->des0 & CYGHWR_HAL_A2FXXX_MAC_TDES0_UF) ) {
+ A2FXXX_INC_STATS(tx_fifo_underflow);
+ }
+#endif
+ txbd->private &= ~CYGHWR_HAL_A2FXXX_MAC_PRIVATE_SENT;
+ if (txbd->des1 & CYGHWR_HAL_A2FXXX_MAC_TDES1_TER){
+ txbd = qi->tbase;
+ } else {
+ txbd++;
+ }
+ }
+ // Remember where we left off
+ qi->tnext = (struct a2fxxx_bd *) txbd;
+}
+
+//
+// Interrupt vector
+//
+static int
+a2fxxx_eth_int_vector(struct eth_drv_sc *sc)
+{
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
+ return (qi->vector);
+#else
+ return 0;
+#endif
+}
+
+//
+// This function is called when a packet has been received. It's job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'fec_eth_recv' will be called to actually fetch it from the hardware.
+//
+static void
+a2fxxx_eth_RxEvent(struct eth_drv_sc *sc)
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
+ volatile struct a2fxxx_bd *rxbd, *rxfirst;
+ int cnt_bd = 0;
+ cyg_int32 len;
+
+ rxbd = rxfirst = qi->rnext;
+ while ((rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_OWN) == 0)
+ {
+ cnt_bd++;
+ qi->rxbd = rxbd; // Save for callback
+
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
+ if( (rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_CE) ) {
+ A2FXXX_INC_STATS(rx_crc_err);
+ }
+ if( (rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_CS) ) {
+ A2FXXX_INC_STATS(rx_collision);
+ }
+ if( (rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_TL) ) {
+ A2FXXX_INC_STATS(rx_too_long);
+ }
+ if( (rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_MF) ) {
+ A2FXXX_INC_STATS(rx_mcast);
+ }
+ if( (rxbd->des0 & CYGHWR_HAL_A2FXXX_MAC_RDES0_DE) ) {
+ A2FXXX_INC_STATS(rx_des_err);
+ }
+#endif
+
+ len = (rxbd->des0 >> 16) & 0x3fff;
+ a2fxxx_eth_printf("ETH A2Fxxx - Receive pkt, length %d\n", len);
+
+ (sc->funs->eth_drv->recv)(sc, len - 4);
+ if (rxbd->des1 & CYGHWR_HAL_A2FXXX_MAC_RDES1_RER){
+ rxbd = qi->rbase;
+ } else {
+ rxbd++;
+ }
+ }
+ // Remember where we left off
+ qi->rnext = (struct a2fxxx_bd *) rxbd;
+}
+
+//
+// Interrupt processing
+//
+static void
+a2fxxx_eth_int(struct eth_drv_sc *sc)
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
+ cyg_uint32 csr5;
+
+ // Check interrupt status
+ HAL_READ_UINT32( (qi->base + CYGHWR_HAL_A2FXXX_MAC_CSR5), csr5);
+
+ if (( csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_TI ) != 0)
+ {
+ a2fxxx_eth_printf("%s - Transmit packet irq\n", sc->dev_name);
+ a2fxxx_eth_TxEvent(sc);
+ HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_TI_BB(qi->base_bb), 1);
+ }
+
+ if (( csr5 & CYGHWR_HAL_A2FXXX_MAC_CSR5_RI ) != 0)
+ {
+ a2fxxx_eth_printf("%s - Receive packet irq\n", sc->dev_name);
+ a2fxxx_eth_RxEvent(sc);
+ HAL_WRITE_UINT32( CYGHWR_HAL_A2FXXX_MAC_CSR5_RI_BB(qi->base_bb), 1);
+ }
+}
+
+//
+// Polling function
+//
+static void
+a2fxxx_eth_poll(struct eth_drv_sc *sc)
+{
+ a2fxxx_eth_int(sc);
+ CYGACC_CALL_IF_DELAY_US(500);
+}
+
+static void
+a2fxxx_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
+ cyg_uint8 *bp;
+ int i;
+
+ bp = (cyg_uint8 *) qi->rxbd->des2;
+ for (i = 0; i < sg_len; i++)
+ {
+ if (sg_list[i].buf != 0)
+ {
+ memcpy((void *) sg_list[i].buf, bp, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+ }
+ qi->rxbd->des0 |= CYGHWR_HAL_A2FXXX_MAC_RDES0_OWN;
+}
+
+
+//
+// Display ETH statistics
+//
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_A2FXXX_STATS
+externC void
+a2fxxx_disp_stats(struct eth_drv_sc *sc , char flag )
+{
+ struct a2fxxx_eth_info *qi = (struct a2fxxx_eth_info *) sc->driver_private;
+
+ diag_printf("Ethernet Statistics\n");
+
+ diag_printf("%17s %10d\n",
+ "RX MCAST",
+ qi->stats.rx_mcast);
+ diag_printf("%17s %10d\n",
+ "RX DESC ERR",
+ qi->stats.rx_des_err);
+ diag_printf("%17s %10d\n",
+ "RX COLLISION",
+ qi->stats.rx_collision);
+ diag_printf("%17s %10d\n",
+ "RX CRC ERR",
+ qi->stats.rx_crc_err);
+ diag_printf("%17s %10d\n",
+ "RX TOO LONG",
+ qi->stats.rx_too_long);
+ diag_printf("%17s %10d\n",
+ "TX FIFO UNDERFLOW",
+ qi->stats.tx_fifo_underflow);
+ diag_printf("%17s %10d\n",
+ "TX FRAME DEFERRED",
+ qi->stats.tx_frame_deferred);
+ diag_printf("%17s %10d\n",
+ "TX LATE COLLISION",
+ qi->stats.tx_late_collision);
+ diag_printf("%17s %10d\n",
+ "TX NO CARRIER",
+ qi->stats.tx_no_carrier);
+ diag_printf("%17s %10d\n",
+ "TX LOSS CARRIER",
+ qi->stats.tx_loss_carrier);
+}
+#endif
+
+// EOF if_a2fxxx.c
diff --git a/ecos/packages/devs/eth/cortexm/stm32/current/ChangeLog b/ecos/packages/devs/eth/cortexm/stm32/current/ChangeLog
new file mode 100644
index 0000000..6ac2bb1
--- /dev/null
+++ b/ecos/packages/devs/eth/cortexm/stm32/current/ChangeLog
@@ -0,0 +1,29 @@
+2010-11-04 Jerzy Dyrda <jerzdy@gmail.com>
+
+ * cdl/stm32_eth.cdl:
+ * src/if_stm32.c:
+ STM32 ETH driver package created. [ Bugzilla 1001219 ]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/cortexm/stm32/current/cdl/stm32_eth.cdl b/ecos/packages/devs/eth/cortexm/stm32/current/cdl/stm32_eth.cdl
new file mode 100644
index 0000000..ca74e7b
--- /dev/null
+++ b/ecos/packages/devs/eth/cortexm/stm32/current/cdl/stm32_eth.cdl
@@ -0,0 +1,241 @@
+#==========================================================================
+#
+# stm32_eth.cdl
+#
+# Ethernet drivers for ST STM32 Cores
+#
+#==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Jerzy Dyrda (jerzdy@gmail.com)
+# Contributors:
+# Date: 2010-11-04
+# Purpose:
+# Description:
+#
+#####DESCRIPTIONEND####
+#
+#========================================================================*/
+
+cdl_package CYGPKG_DEVS_ETH_CORTEXM_STM32 {
+ display "ST STM32 ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_CORTEXM_STM32
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ include_dir net
+ description "
+ Ethernet driver for ST STM32 controler."
+
+ compile -library=libextras.a if_stm32.c
+
+ cdl_option CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL {
+ display "Driver debug output level"
+ flavor data
+ legal_values {0 1 2 3}
+ default_value 0
+ description "
+ This option specifies the level of debug data output by
+ the STM32 ethernet device driver. A value of 0 signifies
+ no debug data output; 1 signifies normal debug data
+ output; 2 signifies extended debug data output;
+ and 3 signifies maximum debug data output (not
+ suitable when GDB and application are sharing an ethernet
+ port)."
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_CORTEXM_STM32_INTF {
+ display "Type of interface to PHY"
+ flavor data
+ default_value {"RMII"}
+ legal_values {"MII" "RMII"}
+ description "
+ Type of interface used to connect with PHY : MII or RMII"
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_CORTEXM_STM32_REMAP_PINS {
+ display "MII/RMII pins remapped"
+ flavor bool
+ default_value 0
+ description "
+ MII/RMII interface signals are remapped"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_CORTEXM_STM32_PHY_CLK_MCO {
+ display "Configure MCO as PHY clock"
+ default_value 0
+ description "
+ Enable the MCO clock signals as clock for PHY."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_CORTEXM_STM32_RX_BUFS {
+ display "Number of RX buffers"
+ flavor data
+ default_value 6
+ legal_values 2 to 16
+ description "
+ Number of receive buffers. Each buffer is 1520 bytes in size"
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_CORTEXM_STM32_CHECKSUM {
+ display "TCP/IP checksums"
+ flavor none
+ no_define
+ active_if { is_active (CYGPKG_LWIP_CHECKSUMS) }
+ description "
+ STM32 Ethernet controller provides for hardware TCP/IP
+ header checksum generation and check."
+
+ active_if CYGPKG_NET_LWIP
+ requires CYGPKG_LWIP_CHECKSUMS
+
+
+ cdl_option CYGSEM_DEVS_ETH_CORTEXM_STM32_TX_CHECKSUM_GEN {
+ display "Generating the checksum for transmitting packets"
+ flavor bool
+ default_value 1
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ 0 == CYGIMP_LWIP_CHECKSUM_GEN_IP }
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ 0 == CYGIMP_LWIP_CHECKSUM_GEN_UDP }
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ 0 == CYGIMP_LWIP_CHECKSUM_GEN_TCP }
+ description "
+ Generating and inserting the checksum of the IP, UDP, TCP
+ and ICMP protocols by hardware for transmitting packets."
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_CORTEXM_STM32_RX_CHECKSUM_VER {
+ display "Verifying the checksum for receiving packets"
+ flavor bool
+ default_value 1
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ 0 == CYGIMP_LWIP_CHECKSUM_CHECK_IP }
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ 0 == CYGIMP_LWIP_CHECKSUM_CHECK_UDP }
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ 0 == CYGIMP_LWIP_CHECKSUM_CHECK_TCP }
+ description "
+ Verifying the checksum of the IP, UDP, TCP and ICMP
+ protocols by hardware for receiving packets."
+ }
+
+ cdl_option CYGSEM_ETH_LWIP_CHECKSUMS {
+ display "lwIP Checksum calculation"
+ flavor none
+ no_define
+ description "
+ Re-enable lwIP software checksum generation/check if
+ hardware generation/check is disabled."
+
+ requires { !CYGSEM_DEVS_ETH_CORTEXM_STM32_TX_CHECKSUM_GEN implies
+ CYGIMP_LWIP_CHECKSUM_GEN_IP == 1 }
+ requires { !CYGSEM_DEVS_ETH_CORTEXM_STM32_TX_CHECKSUM_GEN implies
+ CYGIMP_LWIP_CHECKSUM_GEN_TCP == 1 }
+ requires { !CYGSEM_DEVS_ETH_CORTEXM_STM32_TX_CHECKSUM_GEN implies
+ CYGIMP_LWIP_CHECKSUM_GEN_UDP == 1 }
+
+ requires { !CYGSEM_DEVS_ETH_CORTEXM_STM32_RX_CHECKSUM_VER implies
+ CYGIMP_LWIP_CHECKSUM_CHECK_IP == 1 }
+ requires { !CYGSEM_DEVS_ETH_CORTEXM_STM32_RX_CHECKSUM_VER implies
+ CYGIMP_LWIP_CHECKSUM_CHECK_TCP == 1 }
+ requires { !CYGSEM_DEVS_ETH_CORTEXM_STM32_RX_CHECKSUM_VER implies
+ CYGIMP_LWIP_CHECKSUM_CHECK_UDP == 1 }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_CORTEXM_STM32_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 0
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ active_if (CYGPKG_REDBOOT || CYGSEM_HAL_USE_ROM_MONITOR)
+
+ description "
+ Enabling this option will allow the ethernet station
+ address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually
+ by the 'Set the ethernet station address' option for each
+ interface."
+
+
+ cdl_component CYGPKG_DEVS_ETH_CORTEXM_STM32_REDBOOT_HOLDS_ESA_VARS {
+ display "Export RedBoot command to set ESA in FLASH config"
+ flavor none
+ no_define
+ description "
+ This component contains options which, when enabled, allow
+ RedBoot to support the setting of the ESA in the FLASH
+ configuration. This can then subsequently be accessed by
+ applications using virtual vector calls if those applications
+ are also built with
+ CYGPKG_DEVS_ETH_CORTEXM_STM32_REDBOOT_HOLDS_ESA enabled."
+
+ cdl_option CYGSEM_DEVS_ETH_CORTEXM_STM32_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 1
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+ }
+ }
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_CORTEXM_STM32_MACADDR {
+ display "Ethernet station (MAC) address for eth0"
+ flavor data
+ default_value {"0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC"}
+ description "The default ethernet station address. This is the
+ MAC address used when no value is found in the
+ RedBoot FLASH configuration field."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_CORTEXM_STM32_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the ST STM32 ethernet driver package.
+ These flags are used in addition to the set of global flags."
+ }
+}
+
+# EOF stm32_eth.cdl
diff --git a/ecos/packages/devs/eth/cortexm/stm32/current/src/if_stm32.c b/ecos/packages/devs/eth/cortexm/stm32/current/src/if_stm32.c
new file mode 100644
index 0000000..930e7fa
--- /dev/null
+++ b/ecos/packages/devs/eth/cortexm/stm32/current/src/if_stm32.c
@@ -0,0 +1,1030 @@
+//==========================================================================
+//
+// if_stm32.c
+//
+// Fast ethernet device driver for ST STM32 controller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Jerzy Dyrda <jerzdy@gmail.com>
+// Contributors:
+// Date: 2010-10-05
+// Purpose:
+// Description: hardware driver for STM32 ETH
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_eth_cortexm_stm32.h>
+#include <pkgconf/io_eth_drivers.h>
+#if defined(CYGPKG_REDBOOT)
+ #include <pkgconf/redboot.h>
+#endif
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/plf_io.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/eth_drv_stats.h>
+#include <cyg/io/eth_phy.h>
+#include <errno.h>
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// Maintenance and debug macros.
+
+// Set up the level of debug output
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+#define DIAG_PRINTF(__fmt, ... ) \
+ diag_printf("if_stm32:%s[%d]:" \
+ _fmt, __FUNCTION__, __LINE__, ## __VA_ARGS__ );
+#else
+#define DIAG_PRINTF( __fmt, ... ) \
+ while(0){}
+#endif
+
+#define IF_STM32_INC_DESC(_curr_desc_, _max_desc_) \
+ _curr_desc_++; \
+ if (_curr_desc_ >= _max_desc_) { \
+ _curr_desc_ = 0; \
+ }
+
+//---------------------------------------------------------------------
+// Shorthand for some of the configuration options.
+#define ETH_BASE CYGHWR_HAL_STM32_ETH
+#define TDES_NUM (CYGNUM_IO_ETH_DRIVERS_SG_LIST_SIZE >> 1)
+#define RDES_NUM CYGNUM_DEVS_ETH_CORTEXM_STM32_RX_BUFS
+#define ETH_MAX_PACKET_SIZE 1520
+
+// Bits in status register of tx descriptor which are set up during
+// initialization and remain unchanged while sending process
+#define ETH_DMA_TDES_INIT_MASK \
+ (CYGHWR_HAL_STM32_ETH_TDES0_TER | CYGHWR_HAL_STM32_ETH_TDES0_CIC_HPP)
+
+//Driver interface callbacks
+#define _eth_drv_init(sc,mac) \
+ (sc->funs->eth_drv->init)(sc,(unsigned char *)mac)
+#define _eth_drv_tx_done(sc,key,status) \
+ (sc->funs->eth_drv->tx_done)(sc,key,status)
+#define _eth_drv_recv(sc,len) \
+ (sc->funs->eth_drv->recv)(sc,len)
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32 stm32_eth_isr (cyg_vector_t vector, cyg_addrword_t data);
+#endif
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// Decide whether to have redboot config vars for it
+#if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGPKG_REDBOOT_NETWORKING)
+ #include <redboot.h>
+ #include <flash_config.h>
+
+ #ifdef CYGSEM_DEVS_ETH_CORTEXM_STM32_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa_data,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0);
+ #endif
+
+#endif // CYGPKG_REDBOOT_NETWORKING && CYGSEM_REDBOOT_FLASH_CONFIG
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_CORTEXM_STM32_REDBOOT_HOLDS_ESA
+
+ #include <cyg/hal/hal_if.h>
+
+ #ifndef CONFIG_ESA
+ #define CONFIG_ESA (6)
+ #endif
+
+ #define CYGHWR_DEVS_ETH_CORTEXM_STM32_GET_ESA( mac_address, ok ) \
+ CYG_MACRO_START \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa_data", \
+ mac_address, \
+ CONFIG_ESA); \
+ CYG_MACRO_END
+
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_REDBOOT_HOLDS_ESA
+
+//============================================================================
+
+// Private Data
+typedef struct stm32_eth_dma_des_s {
+ cyg_uint32 status; // DES0 : Own and Status
+ cyg_uint32 ctrl_len; // DES1 : Ctrl/Buffer1 and Buffer2 length
+ cyg_uint32 buff1_addr; // DES2 : Buffer1 address
+ cyg_uint32 buff2_addr; // DES3 : Buffer2 address
+} stm32_eth_dma_des_t;
+
+static cyg_uint8 __attribute__ ((aligned (4)))
+ rx_buff[RDES_NUM][ETH_MAX_PACKET_SIZE];
+static stm32_eth_dma_des_t __attribute__ ((aligned (4))) rdes[RDES_NUM];
+
+static stm32_eth_dma_des_t __attribute__ ((aligned (4))) tdes[TDES_NUM];
+
+// STM32 Ethernet private data
+typedef struct stm32_eth_priv_s
+{
+ cyg_uint32 intr_vector;
+ char * esa_key; // RedBoot 'key' for device ESA
+ eth_phy_access_t *phy;
+ unsigned long tx_key[TDES_NUM];
+ cyg_uint32 curr_tdes_idx;
+ cyg_uint32 prev_tdes_idx;
+ cyg_uint32 curr_rdes_idx;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_interrupt intr;
+ cyg_handle_t intr_handle;
+#endif
+} stm32_eth_priv_t;
+
+__externC cyg_uint32 hal_stm32_hclk;
+static cyg_uint32 mdc_clock_div;
+
+//============================================================================
+// PHY access bits and pieces
+
+static void stm32_init_phy(void)
+{
+ int stm32_hclk_mhz = hal_stm32_hclk / 1000000;
+ mdc_clock_div = 0;
+
+ CYG_ASSERTC(CYGHWR_HAL_STM32_ETH_MACMIIAR_CR_MHZ_CHECK(stm32_hclk_mhz));
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("init phy: hclk %d MHz\n", stm32_hclk_mhz);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+
+ if (CYGHWR_HAL_STM32_ETH_MACMIIAR_CR_MHZ_CHECK(stm32_hclk_mhz))
+ mdc_clock_div = CYGHWR_HAL_STM32_ETH_MACMIIAR_CR_MHZ(stm32_hclk_mhz);
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ else
+ DIAG_PRINTF("init phy : clk for ETH module out of supported range\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+}
+
+// Write one of the PHY registers via the MII bus
+
+static void stm32_write_phy(int reg_addr, int phy_addr, unsigned short data)
+{
+ cyg_uint32 addr = 0;
+ volatile cyg_uint32 reg_val;
+
+ CYG_ASSERTC(reg_addr >= 0 && reg_addr < 32);
+ CYG_ASSERTC(phy_addr >= 0 && phy_addr < 32);
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("write phy: addr %d, reg %d, data 0x%x\n",
+ phy_addr, reg_addr, data);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+
+ /* Prepare the ENET MIIA address */
+ addr |= CYGHWR_HAL_STM32_ETH_MACMIIAR_PA(phy_addr);
+ addr |= CYGHWR_HAL_STM32_ETH_MACMIIAR_MR(reg_addr);
+ addr |= mdc_clock_div;
+ addr |= CYGHWR_HAL_STM32_ETH_MACMIIAR_MW;
+ addr |= CYGHWR_HAL_STM32_ETH_MACMIIAR_MB;
+
+ do
+ {
+ HAL_READ_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_MACMIIAR, reg_val);
+ } while (reg_val & CYGHWR_HAL_STM32_ETH_MACMIIAR_MB);
+
+ // Lauch MDIO transaction
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_MACMIIDR, data);
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_MACMIIAR, addr);
+}
+
+// Read one of the PHY registers via the MII bus
+
+static bool stm32_read_phy(int reg_addr, int phy_addr, unsigned short *data)
+{
+ cyg_uint32 addr = 0;
+ volatile cyg_uint32 reg_val;
+
+ CYG_ASSERTC(reg_addr >= 0 && reg_addr < 32);
+ CYG_ASSERTC(phy_addr >= 0 && phy_addr < 32);
+
+ /* Prepare the ENET MIIA address */
+ addr |= CYGHWR_HAL_STM32_ETH_MACMIIAR_PA(phy_addr);
+ addr |= CYGHWR_HAL_STM32_ETH_MACMIIAR_MR(reg_addr);
+ addr |= mdc_clock_div;
+ addr |= CYGHWR_HAL_STM32_ETH_MACMIIAR_MB;
+
+ do
+ {
+ HAL_READ_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_MACMIIAR, reg_val);
+ } while (reg_val & CYGHWR_HAL_STM32_ETH_MACMIIAR_MB);
+
+ // Lauch MDIO transaction
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_MACMIIAR, addr);
+
+ do
+ {
+ HAL_READ_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_MACMIIAR, reg_val);
+ } while (reg_val & CYGHWR_HAL_STM32_ETH_MACMIIAR_MB);
+
+ HAL_READ_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_MACMIIDR, *data);
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("read phy: addr %d, reg %d, data 0x%x\n",
+ phy_addr, reg_addr, *data);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+
+ return (true);
+}
+
+ETH_PHY_REG_LEVEL_ACCESS_FUNS(stm32_phy,
+ stm32_init_phy,
+ NULL,
+ stm32_write_phy,
+ stm32_read_phy);
+
+//======================================================================
+// Receiver buffer handling
+
+// Initialize the receiver buffers and descriptors in ring mode
+
+static void stm32_rdes_init(void)
+{
+ int ii;
+
+ for (ii = 0; ii < RDES_NUM; ii++) {
+ rdes[ii].status = (cyg_uint32) CYGHWR_HAL_STM32_ETH_RDES0_OWN;
+ rdes[ii].ctrl_len = (cyg_uint32) ETH_MAX_PACKET_SIZE;
+ rdes[ii].buff1_addr = (cyg_uint32) &rx_buff[ii][0];
+ }
+
+ // End of ring
+ rdes[RDES_NUM - 1].ctrl_len |=
+ (cyg_uint32) CYGHWR_HAL_STM32_ETH_RDES1_RER;
+
+ /* Set Receive Desciptor List Address Register */
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMARDLAR,
+ ((cyg_uint32) &rdes[0]));
+}
+
+//======================================================================
+// Transmit buffer handling
+
+// Initialize the transmit buffer descriptors in ring mode
+
+static void stm32_tdes_init(void)
+{
+
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_STM32_TX_CHECKSUM_GEN
+ int ii;
+
+ for (ii = 0; ii < TDES_NUM; ii++) {
+ tdes[ii].status = (cyg_uint32) CYGHWR_HAL_STM32_ETH_TDES0_CIC_HPP;
+ }
+#endif
+
+ // End of ring
+ tdes[TDES_NUM - 1].status |= (cyg_uint32) CYGHWR_HAL_STM32_ETH_TDES0_TER;
+
+ /* Set Receive Desciptor List Address Register */
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMATDLAR,
+ ((cyg_uint32) &tdes[0]));
+}
+
+//======================================================================
+// Initialization code
+
+// Set a specific address match to a given address. Packets received which
+// match this address will be passed on.
+
+static void stm32_set_mac(cyg_uint8 * enaddr)
+{
+ cyg_uint32 hi, lo;
+
+ lo = ((enaddr[3] << 24) | (enaddr[2] << 16) |
+ (enaddr[1] << 8) | (enaddr[0]));
+
+ hi = ((enaddr[5] << 8) | (enaddr[4]));
+
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_MACA0LR, lo);
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_MACA0HR, hi);
+}
+
+// Enable and Disable of the receiver and transmitter.
+// Initialize the interface. This configures the interface ready for use.
+// Interrupts are grabbed etc. This means the start function has
+// little to do except enable the receiver
+
+static bool stm32_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ stm32_eth_priv_t *priv = (stm32_eth_priv_t *)sc->driver_private;
+#ifdef CYGHWR_DEVS_ETH_ARM_STM32_GET_ESA
+ bool esa_ok = false;
+#endif
+ unsigned char enaddr[6] = { CYGPKG_DEVS_ETH_CORTEXM_STM32_MACADDR};
+ volatile cyg_uint32 reg_val;
+ unsigned short phy_state = 0;
+
+#ifdef CYGHWR_DEVS_ETH_CORTEXM_STM32_PHY_CLK_MCO
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MCO);
+#endif
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ DIAG_PRINTF("Initialising ETH module\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+
+ // Enable clock for ETH module
+ HAL_READ_UINT32(CYGHWR_HAL_STM32_RCC + CYGHWR_HAL_STM32_RCC_AHB1ENR, reg_val);
+ reg_val |= BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_ETHMAC) |
+ BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_ETHMACTX) |
+ BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_ETHMACRX) |
+ BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_ETHMACPTP);
+ HAL_WRITE_UINT32(CYGHWR_HAL_STM32_RCC + CYGHWR_HAL_STM32_RCC_AHB1ENR, reg_val);
+
+#if defined (CYGHWR_HAL_CORTEXM_STM32_FAMILY_HIPERFORMANCE)
+ HAL_READ_UINT32(CYGHWR_HAL_STM32_RCC + CYGHWR_HAL_STM32_RCC_APB2ENR, reg_val);
+ reg_val |= BIT_(CYGHWR_HAL_STM32_RCC_APB2ENR_SYSCFG);
+ HAL_WRITE_UINT32(CYGHWR_HAL_STM32_RCC + CYGHWR_HAL_STM32_RCC_APB2ENR, reg_val);
+#endif
+ hal_delay_us(100);
+
+ // Configure the GPIO ports
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_STM32_INTF_MII
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ DIAG_PRINTF("Initialise MII interface\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+
+ // Configure MAC interface in MII mode
+#ifdef CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1
+ HAL_READ_UINT32(CYGHWR_HAL_STM32_AFIO + CYGHWR_HAL_STM32_AFIO_MAPR, reg_val);
+ reg_val &= ~CYGHWR_HAL_STM32_AFIO_MAPR_ETH_RMII;
+ HAL_WRITE_UINT32(CYGHWR_HAL_STM32_AFIO + CYGHWR_HAL_STM32_AFIO_MAPR, reg_val);
+#else
+ HAL_WRITE_UINT32(CYGHWR_HAL_STM32_SYSCFG + CYGHWR_HAL_STM32_SYSCFG_PMC,
+ CYGHWR_HAL_STM32_SYSCFG_PMC_MII);
+#endif // CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1
+
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_TX_CLK);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_RX_CLK);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_MDIO);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_MDC);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_COL);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_TX_CRS);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_TX_EN);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_TXD0);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_TXD1);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_TXD2);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_TXD3);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_RX_ER);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_RX_DV);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_RXD0);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_RXD1);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_RXD2);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_MII_RXD3);
+#elif defined(CYGSEM_DEVS_ETH_CORTEXM_STM32_INTF_RMII)
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ DIAG_PRINTF("Initialise RMII interface\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+
+ // Configure MAC interface in RMII mode
+#ifdef CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1
+ HAL_READ_UINT32(CYGHWR_HAL_STM32_AFIO + CYGHWR_HAL_STM32_AFIO_MAPR, reg_val);
+ reg_val |= CYGHWR_HAL_STM32_AFIO_MAPR_ETH_RMII;
+ HAL_WRITE_UINT32(CYGHWR_HAL_STM32_AFIO + CYGHWR_HAL_STM32_AFIO_MAPR, reg_val);
+#else
+ HAL_WRITE_UINT32(CYGHWR_HAL_STM32_SYSCFG + CYGHWR_HAL_STM32_SYSCFG_PMC,
+ CYGHWR_HAL_STM32_SYSCFG_PMC_RMII);
+#endif // CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1
+
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_RMII_REF_CLK);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_RMII_MDIO);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_RMII_MDC);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_RMII_TX_EN);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_RMII_TXD0);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_RMII_TXD1);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_RMII_CRS_DV);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_RMII_RXD0);
+ CYGHWR_HAL_STM32_GPIO_SET(CYGHWR_HAL_STM32_ETH_RMII_RXD1);
+#else
+#error "Neither MII nor RMII interface defined"
+#endif // CYGSEM_DEVS_ETH_CORTEXM_STM32_INTF_MII
+
+#ifdef CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1
+ HAL_WRITE_UINT32 (CYGHWR_HAL_STM32_AFIO + CYGHWR_HAL_STM32_RCC_AHBRSTR,
+ CYGHWR_HAL_STM32_RCC_AHBRSTR_ETHMACRST);
+ hal_delay_us(1000);
+ HAL_WRITE_UINT32 (CYGHWR_HAL_STM32_AFIO + CYGHWR_HAL_STM32_RCC_AHBRSTR, 0);
+#else
+ HAL_WRITE_UINT32 (CYGHWR_HAL_STM32_RCC + CYGHWR_HAL_STM32_RCC_AHB1RSTR,
+ CYGHWR_HAL_STM32_RCC_AHB1RSTR_ETHMACRST);
+ hal_delay_us(1000);
+ HAL_WRITE_UINT32 (CYGHWR_HAL_STM32_RCC + CYGHWR_HAL_STM32_RCC_AHB1RSTR, 0);
+#endif // CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ DIAG_PRINTF("Reset ETH DMA module\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+
+ // Software reset of ETH module and wait until it will be done
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMABMR,
+ CYGHWR_HAL_STM32_ETH_DMABMR_SR);
+
+ do {
+ hal_delay_us(100);
+ HAL_READ_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMABMR, reg_val);
+ } while (reg_val & CYGHWR_HAL_STM32_ETH_DMABMR_SR);
+
+ // Setup the PHY
+ CYG_ASSERTC(priv->phy);
+
+ if (!_eth_phy_init(priv->phy))
+ {
+ return (false);
+ }
+
+ reg_val = 0;
+
+ // Get the current mode and print it
+ phy_state = _eth_phy_state(priv->phy);
+
+ if ((phy_state & ETH_PHY_STAT_LINK) != 0) {
+ //Connection mode
+ if((phy_state & ETH_PHY_STAT_FDX)) {
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ DIAG_PRINTF("Link type : Full Duplex\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ reg_val |= CYGHWR_HAL_STM32_ETH_MACCR_DM;
+ } else {
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ DIAG_PRINTF("Link type : Half Duplex\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ reg_val &= ~(CYGHWR_HAL_STM32_ETH_MACCR_DM);
+ }
+ //Connection speed
+ if((phy_state & ETH_PHY_STAT_100MB)) {
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ DIAG_PRINTF("Link speed : 100Mbits/s\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ reg_val |= CYGHWR_HAL_STM32_ETH_MACCR_FES;
+ } else {
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ DIAG_PRINTF("Link speed : 10Mbits/s\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ reg_val &= ~(CYGHWR_HAL_STM32_ETH_MACCR_FES);
+ }
+ } else {
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ DIAG_PRINTF("No Link\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ }
+ // ------------------- Configure MAC module -------------------
+
+ reg_val |= CYGHWR_HAL_STM32_ETH_MACCR_RD;
+
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_STM32_RX_CHECKSUM_VER
+ reg_val |= CYGHWR_HAL_STM32_ETH_MACCR_IPCO;
+#endif
+
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_MACCR, reg_val);
+
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_MACFFR,
+ (CYGHWR_HAL_STM32_ETH_MACFFR_HU |
+ CYGHWR_HAL_STM32_ETH_MACFFR_HM |
+ CYGHWR_HAL_STM32_ETH_MACFFR_HPF));
+
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_MACHTHR, 0);
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_MACHTLR, 0);
+
+ // Give the MAC its ethernet address
+ stm32_set_mac(enaddr);
+
+ // ------------------- Configure DMA module -------------------
+
+#ifdef CYGSEM_DEVS_ETH_CORTEXM_STM32_TX_CHECKSUM_GEN
+ // The checksum generation is enabled only if the
+ // Transmit FIFO is configured for Store-and-forward mode
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAOMR,
+ CYGHWR_HAL_STM32_ETH_DMAOMR_TSF);
+#else
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAOMR,
+ CYGHWR_HAL_STM32_ETH_DMAOMR_TTC(3) /* TTC = 256 */);
+#endif
+
+ // Clear any pending interrupt and disable it
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMASR, 0x1FFFF);
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAIER, 0x0);
+
+ // If we are building an interrupt enabled version, install the
+ // interrupt handler
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ DIAG_PRINTF("Installing Interrupts on IRQ %d\n", priv->intr_vector);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+
+ cyg_drv_interrupt_create(priv->intr_vector,
+ 4,
+ (cyg_addrword_t)sc,
+ stm32_eth_isr,
+ eth_drv_dsr,
+ &priv->intr_handle,
+ &priv->intr);
+
+ cyg_drv_interrupt_attach(priv->intr_handle);
+ cyg_drv_interrupt_unmask(priv->intr_vector);
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+#ifdef CYGHWR_DEVS_ETH_ARM_STM32_GET_ESA
+ // Get MAC address from RedBoot configuration variables
+ CYGHWR_DEVS_ETH_ARM_STM32_GET_ESA(&enaddr[0], esa_ok);
+ // If this call fails myMacAddr is unchanged and MAC address from
+ // CDL is used
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ if (!esa_ok)
+ {
+ // Can't figure out ESA
+ DIAG_PRINTF("Warning! ESA unknown\n");
+ }
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+#endif // CYGHWR_DEVS_ETH_ARM_STM32_GET_ESA
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ DIAG_PRINTF("MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ enaddr[0],enaddr[1],enaddr[2],
+ enaddr[3],enaddr[4],enaddr[5]);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+
+ // Initialize Rx/Tx Descriptors list
+ stm32_tdes_init();
+ stm32_rdes_init();
+
+ // Enable transmit and receive state machine of the MAC
+ HAL_READ_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_MACCR, reg_val);
+ reg_val |= CYGHWR_HAL_STM32_ETH_MACCR_TE |
+ CYGHWR_HAL_STM32_ETH_MACCR_RE;
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_MACCR, reg_val);
+
+ // Flush Transmit FIFO
+ HAL_READ_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAOMR, reg_val);
+ reg_val |= CYGHWR_HAL_STM32_ETH_DMAOMR_FTF;
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAOMR, reg_val);
+
+ do {
+ HAL_READ_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAOMR, reg_val);
+ } while (reg_val & CYGHWR_HAL_STM32_ETH_DMAOMR_FTF);
+
+ // Initialize the upper layer driver
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ DIAG_PRINTF("Initialize the upper layer driver\n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ _eth_drv_init(sc,enaddr);
+
+ return (true);
+}
+
+// This function is called to stop the interface.
+
+static void stm32_eth_stop(struct eth_drv_sc *sc)
+{
+ volatile cyg_uint32 reg_val;
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ DIAG_PRINTF("Stoping \n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMASR, 0x1FFFF);
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAIER, 0x0);
+
+ HAL_READ_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAOMR, reg_val);
+ reg_val &= ~(CYGHWR_HAL_STM32_ETH_DMAOMR_SR |
+ CYGHWR_HAL_STM32_ETH_DMAOMR_ST);
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAOMR, reg_val);
+}
+
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running.
+
+static void stm32_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr,
+ int flags)
+{
+ volatile cyg_uint32 reg_val;
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ DIAG_PRINTF("Starting \n");
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+
+ // Enable the interrupts we are interested in
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAIER,
+ (CYGHWR_HAL_STM32_ETH_DMAIER_RIE |
+ CYGHWR_HAL_STM32_ETH_DMAIER_TIE |
+ CYGHWR_HAL_STM32_ETH_DMAIER_NISE));
+
+ // Start DMA transmission and reception
+ HAL_READ_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAOMR, reg_val);
+ reg_val |= CYGHWR_HAL_STM32_ETH_DMAOMR_SR |
+ CYGHWR_HAL_STM32_ETH_DMAOMR_ST;
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMAOMR, reg_val);
+}
+
+// This function is called for low level "control" operations
+
+static int stm32_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int length)
+{
+ switch (key)
+ {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ if(length >= ETHER_ADDR_LEN) {
+ stm32_eth_stop(sc);
+ cyg_uint8 * enaddr = (cyg_uint8 *)data;
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("Change MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ enaddr[0],enaddr[1],enaddr[2],
+ enaddr[3],enaddr[4],enaddr[5]);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ stm32_set_mac(enaddr);
+ stm32_eth_start(sc,enaddr,0);
+ return 0;
+ }
+ return 1;
+
+#ifdef CYGPKG_NET
+ case ETH_DRV_GET_IF_STATS:
+ {
+ // todo
+ return 1;
+ }
+#endif
+
+ default:
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ DIAG_PRINTF("Unsupported key %lx\n", key);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ return 1;
+ }
+}
+
+// This routine is called to receive data from the hardware
+
+static void stm32_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
+ int sg_len)
+{
+ stm32_eth_priv_t *priv = (stm32_eth_priv_t *)sc->driver_private;
+ int ii, rx_frame_length;
+ cyg_uint32 rx_buffer_pos = 0, data_to_copy;
+ cyg_uint8 * psg_buf, * prx_buff;
+
+ prx_buff = (cyg_uint8 *) rx_buff[priv->curr_rdes_idx];
+ rx_frame_length =
+ CYGHWR_HAL_STM32_ETH_RDES0_FL(rdes[priv->curr_rdes_idx].status) - 4;
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("current rx desc %d, sg_len %d, total_len %d\n",
+ priv->curr_rdes_idx, sg_len, rx_frame_length);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+
+ for(ii = 0; (ii < sg_len) && (rx_frame_length > 0); ii++) {
+ psg_buf = (cyg_uint8 *)(sg_list[ii].buf);
+ data_to_copy = rx_frame_length > sg_list[ii].len ?
+ sg_list[ii].len : rx_frame_length;
+ memcpy(psg_buf, &prx_buff[rx_buffer_pos], data_to_copy);
+ // frame copied
+ rx_buffer_pos += data_to_copy;
+ rx_frame_length -= data_to_copy;
+ }
+}
+
+// This function is called to see if another packet can be sent.
+
+static int stm32_eth_can_send(struct eth_drv_sc *sc)
+{
+ stm32_eth_priv_t *priv = (stm32_eth_priv_t *)sc->driver_private;
+
+ return ((tdes[priv->curr_tdes_idx].status &
+ CYGHWR_HAL_STM32_ETH_TDES0_OWN) ? 0 : 1);
+}
+
+// This routine is called to send data to the hardware - zero copying version
+
+static void stm32_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
+ int sg_len, int total_len, unsigned long key)
+{
+ stm32_eth_priv_t *priv = (stm32_eth_priv_t *) sc->driver_private;
+ cyg_uint8 sg_item = 0, sg_len_even, sg_len_rest;
+ volatile cyg_uint32 reg_val;
+
+ CYG_ASSERT(total_len <= ETH_MAX_PACKET_SIZE, "packet too long");
+
+ sg_len_even = sg_len / 2;
+ sg_len_rest = sg_len % 2;
+
+ // Look if it's enough numer of free descriptors
+ CYG_ASSERT((sg_len_even + sg_len_rest) <
+ ((priv->curr_tdes_idx >= priv->prev_tdes_idx) ?
+ (TDES_NUM - (priv->curr_tdes_idx - priv->prev_tdes_idx)) :
+ (priv->prev_tdes_idx - priv->curr_tdes_idx)),
+ "not enough number of descriptors");
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("current tx desc %d, sg_len %d, total_len %d\n",
+ priv->curr_tdes_idx, sg_len, total_len);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+
+ for(sg_item = 0; sg_item < 2 * sg_len_even; sg_item += 2) {
+ tdes[priv->curr_tdes_idx].status &= ETH_DMA_TDES_INIT_MASK;
+ tdes[priv->curr_tdes_idx].buff1_addr = sg_list[sg_item].buf;
+ tdes[priv->curr_tdes_idx].ctrl_len =
+ CYGHWR_HAL_STM32_ETH_TDES1_TBS1(sg_list[sg_item].len);
+ tdes[priv->curr_tdes_idx].buff2_addr = sg_list[sg_item + 1].buf;
+ tdes[priv->curr_tdes_idx].ctrl_len |=
+ CYGHWR_HAL_STM32_ETH_TDES1_TBS2(sg_list[sg_item + 1].len);
+
+ if (sg_item == 0)
+ tdes[priv->curr_tdes_idx].status |=
+ CYGHWR_HAL_STM32_ETH_TDES0_FS;
+
+ if ((sg_item == sg_len - 2) && !sg_len_rest) {
+ tdes[priv->curr_tdes_idx].status |=
+ CYGHWR_HAL_STM32_ETH_TDES0_IC |
+ CYGHWR_HAL_STM32_ETH_TDES0_LS;
+ }
+ // All flags set thus gives the buffer back to DMA
+ tdes[priv->curr_tdes_idx].status |=
+ CYGHWR_HAL_STM32_ETH_TDES0_OWN;
+ priv->tx_key[priv->curr_tdes_idx] = key;
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("tx desc %d : status %x, len1 %d, len2 %d\n",
+ priv->curr_tdes_idx, tdes[priv->curr_tdes_idx].status,
+ sg_list[sg_item].len, sg_list[sg_item + 1].len);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+
+ IF_STM32_INC_DESC(priv->curr_tdes_idx, TDES_NUM);
+ }
+
+ if (sg_len_rest) {
+ tdes[priv->curr_tdes_idx].status &= ETH_DMA_TDES_INIT_MASK;
+ tdes[priv->curr_tdes_idx].buff1_addr = sg_list[sg_item].buf;
+ tdes[priv->curr_tdes_idx].ctrl_len =
+ CYGHWR_HAL_STM32_ETH_TDES1_TBS1(sg_list[sg_item].len);
+ tdes[priv->curr_tdes_idx].buff2_addr = 0;
+ if (sg_item == 0) // Only one sg element to send
+ tdes[priv->curr_tdes_idx].status |=
+ CYGHWR_HAL_STM32_ETH_TDES0_FS;
+
+ // All flags set thus gives the buffer back to DMA
+ tdes[priv->curr_tdes_idx].status |=
+ CYGHWR_HAL_STM32_ETH_TDES0_OWN |
+ CYGHWR_HAL_STM32_ETH_TDES0_IC |
+ CYGHWR_HAL_STM32_ETH_TDES0_LS;
+ priv->tx_key[priv->curr_tdes_idx] = key;
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("tx desc %d : status %x, len1 %d\n",
+ priv->curr_tdes_idx, tdes[priv->curr_tdes_idx].status,
+ sg_list[sg_item].len);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+
+ IF_STM32_INC_DESC(priv->curr_tdes_idx, TDES_NUM);
+ }
+
+ // Starts desc refetch by DMA
+ HAL_READ_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMASR, reg_val);
+ if (reg_val & CYGHWR_HAL_STM32_ETH_DMASR_TBUS) {
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMASR,
+ CYGHWR_HAL_STM32_ETH_DMASR_TBUS);
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMATPDR, 0);
+ }
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("packets put into dma - number of used desc %d\n",
+ sg_len_even + sg_len_rest);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+}
+
+//======================================================================
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32 stm32_eth_isr (cyg_vector_t vector, cyg_addrword_t data)
+{
+ volatile cyg_uint32 status_reg;
+ cyg_uint32 status = CYG_ISR_HANDLED;
+
+ HAL_READ_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMASR, status_reg);
+ if (status_reg & CYGHWR_HAL_STM32_ETH_DMASR_NIS) {
+ cyg_interrupt_mask(vector);
+ status |= CYG_ISR_CALL_DSR;
+ }
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ // It seems that comes other eth int even it's nothing more
+ // enabled than Trans/Recv interrupt
+ else {
+ DIAG_PRINTF("unexpected eth int - reason 0x%x\n",
+ status_reg);
+ }
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+
+ cyg_interrupt_acknowledge(vector);
+
+ return(status);
+}
+#endif
+
+static void stm32_eth_deliver(struct eth_drv_sc *sc)
+{
+ stm32_eth_priv_t *priv = (stm32_eth_priv_t *) sc->driver_private;
+ volatile cyg_uint32 status_reg;
+ cyg_uint32 rx_frame_length;
+
+ // Get the interrupt status
+ HAL_READ_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMASR, status_reg);
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+ DIAG_PRINTF("DMA status 0x%x\n", status_reg);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 1
+
+ if (status_reg & CYGHWR_HAL_STM32_ETH_DMASR_RS) {
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMASR,
+ CYGHWR_HAL_STM32_ETH_DMASR_NIS |
+ CYGHWR_HAL_STM32_ETH_DMASR_RS);
+
+ // check if desc is ready to service - just in case
+ while (!(rdes[priv->curr_rdes_idx].status &
+ CYGHWR_HAL_STM32_ETH_RDES0_OWN)) {
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("New packet in rx desc %d\n",
+ priv->curr_rdes_idx);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+
+ // and eth frame is ok
+ if (((rdes[priv->curr_rdes_idx].status &
+ CYGHWR_HAL_STM32_ETH_RDES0_ES) == 0) &&
+ ((rdes[priv->curr_rdes_idx].status &
+ CYGHWR_HAL_STM32_ETH_RDES0_FS) != 0) &&
+ ((rdes[priv->curr_rdes_idx].status &
+ CYGHWR_HAL_STM32_ETH_RDES0_LS) != 0) &&
+ (CYGHWR_HAL_STM32_ETH_RDES0_FL(
+ rdes[priv->curr_rdes_idx].status) != 0)) {
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("Rcv packet status 0x%x\n",
+ rdes[priv->curr_rdes_idx].status);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ rx_frame_length =
+ CYGHWR_HAL_STM32_ETH_RDES0_FL(
+ rdes[priv->curr_rdes_idx].status) - 4;
+ _eth_drv_recv(sc, rx_frame_length);
+ }
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ else {
+ DIAG_PRINTF("Error in rcv frame - reason 0x%x\n",
+ rdes[priv->curr_rdes_idx].status);
+ }
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+
+ // Starts desc refetch by DMA
+ if (status_reg & CYGHWR_HAL_STM32_ETH_DMASR_RBUS) {
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMASR,
+ CYGHWR_HAL_STM32_ETH_DMASR_RBUS);
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMARPDR, 0);
+ }
+
+ // Desc handeled
+ rdes[priv->curr_rdes_idx].status = CYGHWR_HAL_STM32_ETH_RDES0_OWN;
+ IF_STM32_INC_DESC(priv->curr_rdes_idx, RDES_NUM);
+ }
+ }
+
+ if (status_reg & CYGHWR_HAL_STM32_ETH_DMASR_TS) {
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMASR,
+ CYGHWR_HAL_STM32_ETH_DMASR_NIS | CYGHWR_HAL_STM32_ETH_DMASR_TS);
+
+ // Walk throug descriptor list until find serviced last segment
+ while ((priv->prev_tdes_idx != priv->curr_tdes_idx) &&
+ !(tdes[priv->prev_tdes_idx].status &
+ CYGHWR_HAL_STM32_ETH_TDES0_OWN)) {
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+ DIAG_PRINTF("Sent packet (key 0x%x) from desc %d with status 0x%x\n",
+ (cyg_uint32) priv->tx_key[priv->prev_tdes_idx],
+ priv->prev_tdes_idx, tdes[priv->prev_tdes_idx].status);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 2
+
+ // Starts desc refetch by DMA if it happens error during transmit
+ if (tdes[priv->prev_tdes_idx].status &
+ CYGHWR_HAL_STM32_ETH_TDES0_ES) {
+ HAL_WRITE_UINT32(ETH_BASE + CYGHWR_HAL_STM32_ETH_DMASR,
+ CYGHWR_HAL_STM32_ETH_DMASR_TUS);
+ HAL_WRITE_UINT32 (ETH_BASE + CYGHWR_HAL_STM32_ETH_DMATPDR, 0);
+
+#if CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ DIAG_PRINTF("Error in sending - reason 0x%x\n",
+ tdes[priv->prev_tdes_idx].status);
+#endif // CYGPKG_DEVS_ETH_CORTEXM_STM32_DEBUG_LEVEL > 0
+ }
+
+ if (tdes[priv->prev_tdes_idx].status &
+ CYGHWR_HAL_STM32_ETH_TDES0_LS) {
+ if (!(tdes[priv->prev_tdes_idx].status &
+ CYGHWR_HAL_STM32_ETH_TDES0_ES))
+ _eth_drv_tx_done(sc,
+ priv->tx_key[priv->prev_tdes_idx], 0);
+ else
+ _eth_drv_tx_done(sc,
+ priv->tx_key[priv->prev_tdes_idx], -1);
+ }
+ IF_STM32_INC_DESC(priv->prev_tdes_idx, TDES_NUM);
+ }
+ }
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_interrupt_unmask(priv->intr_vector);
+#endif
+}
+
+// routine called to handle ethernet controller in polled mode
+static void stm32_eth_poll(struct eth_drv_sc *sc)
+{
+ /* Service the buffers */
+ stm32_eth_deliver(sc);
+}
+
+static int stm32_eth_int_vector(struct eth_drv_sc *sc)
+{
+ return(CYGNUM_HAL_INTERRUPT_ETH);
+}
+
+stm32_eth_priv_t stm32_priv_data =
+{
+ .intr_vector = CYGNUM_HAL_INTERRUPT_ETH,
+ .phy = &stm32_phy
+};
+
+ETH_DRV_SC(stm32_sc,
+ &stm32_priv_data, // Driver specific data
+ "eth0", // Name for this interface
+ stm32_eth_start,
+ stm32_eth_stop,
+ stm32_eth_control,
+ stm32_eth_can_send,
+ stm32_eth_send,
+ stm32_eth_recv,
+ stm32_eth_deliver,
+ stm32_eth_poll,
+ stm32_eth_int_vector);
+
+NETDEVTAB_ENTRY(stm32_netdev,
+ "stm32",
+ stm32_eth_init,
+ &stm32_sc);
+
+// EOF if_stm32.c
diff --git a/ecos/packages/devs/eth/davicom/dm9000/current/ChangeLog b/ecos/packages/devs/eth/davicom/dm9000/current/ChangeLog
new file mode 100644
index 0000000..2c41505
--- /dev/null
+++ b/ecos/packages/devs/eth/davicom/dm9000/current/ChangeLog
@@ -0,0 +1,51 @@
+2005-11-07 David Vrabel <dvrabel@arcom.com>
+
+ * src/if_dm9000.c, include/dm9000_info.h: Support interrupts.
+ * cdl/davicom_dm9000_eth_drivers.cdl
+ (CYGPKG_DEVS_ETH_DAVICOM_DM9000_CFLAGS_ADD): Need _KERNEL and
+ __ECOS defined for non-stand-alone builds.
+
+2005-10-25 David Vrabel <dvrabel@arcom.com>
+
+ * src/if_dm9000.c (eeprom_read, eeprom_write, eeprom_reload):
+ Delay more when writing/reading eeprom (200 us isn't enough).
+ (phy_init): Turn on PHY before writing PHY registers. Wait for
+ auto negotiation to be complete.
+ (dm9000_send): Correctly write last words to Tx SRAM when using a
+ 8/16 bit device. Clarify and comment code.
+ (dm9000_poll): Parse Rx packet header correctly on 8/16 bit
+ devices.
+ (dm9000_ioctl): Handle ETH_DRV_GET_MAC_ADDRESS and
+ ETH_DRV_SET_MAC_ADDRESS.
+
+ * cdl/davicom_dm9000_eth_drivers.cdl: New option
+ CYGSEM_DEVS_ETH_DAVICOM_DM9000_WRITE_EEPROM to enable/disable
+ writing to EEPROM.
+
+2004-09-05 Mark Salter <msalter@redhat.com>
+
+ Initial Checkin of DM9000 Ethernet driver (RedBoot only for now).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/davicom/dm9000/current/cdl/davicom_dm9000_eth_drivers.cdl b/ecos/packages/devs/eth/davicom/dm9000/current/cdl/davicom_dm9000_eth_drivers.cdl
new file mode 100644
index 0000000..d3b3ffa
--- /dev/null
+++ b/ecos/packages/devs/eth/davicom/dm9000/current/cdl/davicom_dm9000_eth_drivers.cdl
@@ -0,0 +1,105 @@
+# ====================================================================
+#
+# davicom_dm9000_eth_drivers.cdl
+#
+# Davicom dm9000 ethernet driver
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data:
+# Contributors:
+# Date: 2004-3-18
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_DAVICOM_DM9000 {
+ display "Davicom DM9000 ethernet driver"
+ description "Ethernet driver for Davicom DM9000 NIC."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ active_if CYGINT_DEVS_ETH_DAVICOM_DM9000_REQUIRED
+
+ define_proc {
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_DAVICOM_DM9000_CFG";
+ }
+
+ compile -library=libextras.a if_dm9000.c
+
+ cdl_option CYGSEM_DEVS_ETH_DAVICOM_DM9000_WRITE_EEPROM {
+ display "SIOCSIFHWADDR records ESA (MAC address) in EEPROM"
+ default_value 0
+ description "
+ The ioctl() socket call with operand SIOCSIFHWADDR sets the
+ interface hardware address - the MAC address or Ethernet Station
+ Address (ESA). This option causes the new MAC address to be
+ written into the EEPROM associated with the interface, so that the
+ new MAC address is permanently recorded. Doing this should be a
+ carefully chosen decision, hence this option."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_DAVICOM_DM9000_DEV_COUNT {
+ display "Number of supported interfaces."
+ calculated { CYGINT_DEVS_ETH_DAVICOM_DM9000_REQUIRED }
+ flavor data
+ description "
+ This option selects the number of PCMCIA cards to
+ be supported by the driver."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_DAVICOM_DM9000_OPTIONS {
+ display "Davicom dm9000 ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_DAVICOM_DM9000_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Davicom DM9000 ethernet driver package.
+ These flags are used in addition to the set of
+ global flags."
+ }
+ }
+}
+# EOF davicom_dm9000_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/davicom/dm9000/current/include/dm9000_info.h b/ecos/packages/devs/eth/davicom/dm9000/current/include/dm9000_info.h
new file mode 100644
index 0000000..3b8b479
--- /dev/null
+++ b/ecos/packages/devs/eth/davicom/dm9000/current/include/dm9000_info.h
@@ -0,0 +1,77 @@
+#ifndef CYGONCE_DEVS_ETH_DAVICOM_DM9000_INFO_H
+#define CYGONCE_DEVS_ETH_DAVICOM_DM9000_INFO_H
+/*==========================================================================
+//
+// dm9000_info.h
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors:
+// Date: 2004-03-18
+// Description:
+//
+//####DESCRIPTIONEND####
+*/
+
+#include <pkgconf/devs_eth_davicom_dm9000.h>
+
+struct dm9000 {
+ struct eth_drv_sc *sc;
+ cyg_uint8 active; // interface is active
+ cyg_uint8 reset_pending;
+ cyg_uint8 txbusy;
+ cyg_uint8 mac_address[6];
+ cyg_uint16 rxlen;
+ unsigned long txkey;
+ volatile unsigned char *io_addr; // addr register
+ volatile unsigned char *io_data; // data register
+ cyg_vector_t interrupt; // Interrupt vector used by controller
+ int (*read_data)(struct dm9000 *p, cyg_uint8 *dest);
+ int (*write_data)(struct dm9000 *p, cyg_uint8 *src);
+ int buswidth;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+#endif
+};
+
+#define CYGDAT_DEVS_ETH_DESCRIPTION "Davicom DM9000 Ethernet"
+
+#endif
+
+/* EOF dm9000_info.h */
diff --git a/ecos/packages/devs/eth/davicom/dm9000/current/src/if_dm9000.c b/ecos/packages/devs/eth/davicom/dm9000/current/src/if_dm9000.c
new file mode 100644
index 0000000..b735da7
--- /dev/null
+++ b/ecos/packages/devs/eth/davicom/dm9000/current/src/if_dm9000.c
@@ -0,0 +1,950 @@
+//==========================================================================
+//
+// if_dm9000.c
+//
+// Davicom DM9000 ethernet driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: msalter
+// Date: 2004-03-18
+// Purpose:
+// Description: hardware driver for Davicom DM9000 NIC
+// Notes:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_eth_drivers.h>
+#include <pkgconf/devs_eth_davicom_dm9000.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_endian.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#include <dm9000_info.h>
+
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#include <redboot.h>
+#include <flash_config.h>
+#endif
+
+#include CYGDAT_DEVS_ETH_DAVICOM_DM9000_INL
+
+#define DM9000_PKT_MAX 1536
+
+//#define DEBUG
+//#define DEBUG_DUMP
+
+//
+// Control and Status register offsets
+//
+#define DM_NCR 0x00
+#define DM_NSR 0x01
+#define DM_TCR 0x02
+#define DM_TSRI 0x03
+#define DM_TSRII 0x04
+#define DM_RCR 0x05
+#define DM_RSR 0x06
+#define DM_ROCR 0x07
+#define DM_BPTR 0x08
+#define DM_FCTR 0x09
+#define DM_FCR 0x0a
+#define DM_EPCR 0x0b
+#define DM_EPAR 0x0c
+#define DM_EPDRL 0x0d
+#define DM_EPDRH 0x0e
+#define DM_WCR 0x0f
+#define DM_PAR 0x10
+#define DM_MAR 0x16
+#define DM_GPCR 0x1e
+#define DM_GPR 0x1f
+#define DM_TRPAL 0x22
+#define DM_TRPAH 0x23
+#define DM_RWPAL 0x24
+#define DM_RWPAH 0x25
+#define DM_VIDL 0x28
+#define DM_VIDH 0x29
+#define DM_PIDL 0x2a
+#define DM_PIDH 0x2b
+#define DM_CHIPR 0x2c
+#define DM_SMCR 0x2f
+#define DM_MRCMDX 0xf0
+#define DM_MRCMD 0xf2
+#define DM_MDRAL 0xf4
+#define DM_MDRAH 0xf5
+#define DM_MWCMDX 0xf6
+#define DM_MWCMD 0xf8
+#define DM_MDWAL 0xfa
+#define DM_MDWAH 0xfb
+#define DM_TXPLL 0xfc
+#define DM_TXPLH 0xfd
+#define DM_ISR 0xfe
+#define DM_IMR 0xff
+
+// NCR (Network Control Register)
+#define NCR_EXT_PHY (1 << 7) // 1 ==> external PHY, 0 ==> internal
+#define NCR_WAKEEN (1 << 6) // enable wakeup events
+#define NCR_FCOL (1 << 4) // force collision mode (test)
+#define NCR_FDX (1 << 3) // full duplex (read-only for internal phy)
+#define NCR_LBK_NOR (0 << 1) // loopback off
+#define NCR_LBK_MAC (1 << 1) // MAC loopback
+#define NCR_LBK_PHY (2 << 1) // PHY loopback
+#define NCR_RST (1 << 0) // Reset (auto-clears after 10us)
+
+// NSR (Network Status Register)
+#define NSR_SPEED (1 << 7) // 0 = 100Mbps, 1 = 10Mbps
+#define NSR_LINKST (1 << 6) // link status (1 = okay)
+#define NSR_WAKEST (1 << 5) // wake status (clear by read)
+#define NSR_TX2END (1 << 3) // TX packet 2 complete
+#define NSR_TX1END (1 << 2) // TX packet 1 complete
+#define NSR_RXOV (1 << 1) // RX overflow
+
+// TCR (TX Control Register)
+#define TCR_TJDIS (1 << 6) // TX jabber disable
+#define TCR_EXCECM (1 << 5) // 0 = abort after 15 collisions
+#define TCR_PAD_DIS2 (1 << 4)
+#define TCR_CRC_DIS2 (1 << 3)
+#define TCR_PAD_DIS1 (1 << 2)
+#define TCR_CRC_DIS1 (1 << 1)
+#define TCR_TXREQ (1 << 0)
+
+// TSR (TX Status Register)
+#define TSR_TJTO (1 << 7)
+#define TSR_LC (1 << 6)
+#define TSR_NC (1 << 5)
+#define TSR_LCOL (1 << 4)
+#define TSR_COL (1 << 3)
+#define TSR_EC (1 << 2)
+
+// RCR (RX Control Register)
+#define RCR_WTDIS (1 << 6)
+#define RCR_DIS_LONG (1 << 5)
+#define RCR_DIS_CRC (1 << 4)
+#define RCR_ALL (1 << 3)
+#define RCR_RUNT (1 << 2)
+#define RCR_PRMSC (1 << 1)
+#define RCR_RXEN (1 << 0)
+
+// RSR (RX Status Register)
+#define RSR_RF (1 << 7)
+#define RSR_MF (1 << 6)
+#define RSR_LCS (1 << 5)
+#define RSR_RWTO (1 << 4)
+#define RSR_PLE (1 << 3)
+#define RSR_AE (1 << 2)
+#define RSR_CE (1 << 1)
+#define RSR_FOE (1 << 0)
+
+// FCR (Flow Control Register)
+#define FCR_TXPO (1 << 7)
+#define FCR_TXPF (1 << 6)
+#define FCR_TXPEN (1 << 5)
+#define FCR_BKPA (1 << 4)
+#define FCR_BKPM (1 << 3)
+#define FCR_RXPS (1 << 2)
+#define FCR_RXPCS (1 << 1)
+#define FCR_FLCE (1 << 0)
+
+// EPCR (EEPROM & PHY Control Register)
+#define EPCR_REEP (1 << 5)
+#define EPCR_WEP (1 << 4)
+#define EPCR_EPOS (1 << 3)
+#define EPCR_ERPRR (1 << 2)
+#define EPCR_ERPRW (1 << 1)
+#define EPCR_ERRE (1 << 0)
+
+// WCR (Wakeup Control Register)
+#define WCR_LINKEN (1 << 5)
+#define WCR_SAMPLEEN (1 << 4)
+#define WCR_MAGICEN (1 << 3)
+#define WCR_LINKST (1 << 2)
+#define WCR_SAMPLEST (1 << 1)
+#define WCR_MAGIGST (1 << 0)
+
+// SMCR (Special Mode Control Register)
+#define SMCR_SM_EN (1 << 7)
+#define SMCR_FLC (1 << 2)
+#define SMCR_FB1 (1 << 1)
+#define SMCR_FB0 (1 << 0)
+
+// ISR (Interrupt Status Register)
+#define ISR_IOMODE_16 (0 << 6)
+#define ISR_IOMODE_32 (1 << 6)
+#define ISR_IOMODE_8 (2 << 6)
+#define ISR_ROOS (1 << 3)
+#define ISR_ROS (1 << 2)
+#define ISR_PTS (1 << 1)
+#define ISR_PRS (1 << 0)
+
+// IMR (Interrupt Mask Register)
+#define IMR_PAR (1 << 7)
+#define IMR_ROOM (1 << 3)
+#define IMR_ROM (1 << 2)
+#define IMR_PTM (1 << 1)
+#define IMR_PRM (1 << 0)
+
+/* PHY registers */
+#define PHY_BMCR 0x00
+#define PHY_BMSR 0x01
+#define PHY_ANAR 0x04
+
+/* PHY BMCR (Basic Mode Control Register) */
+#define PHY_BMCR_AUTO_NEG_EN (1 << 12)
+#define PHY_BMCR_AUTO_NEG_START (1 << 12)
+
+/* PHY BMSR (Basic Mode Status Register) */
+#define PHY_BMSR_AUTO_NEG_COMPLETE (1 << 5)
+
+// Read one datum from 8-bit bus
+static int read_data_8(struct dm9000 *p, cyg_uint8 *dest)
+{
+ HAL_READ_UINT8(p->io_data, *dest);
+ return 1;
+}
+
+// Read one datum from 16-bit bus
+static int read_data_16(struct dm9000 *p, cyg_uint8 *dest)
+{
+ cyg_uint16 val;
+
+ HAL_READ_UINT16(p->io_data, val);
+ memcpy(dest, &val, 2);
+ return 2;
+}
+
+// Read one datum from 32-bit bus
+static int read_data_32(struct dm9000 *p, cyg_uint8 *dest)
+{
+ cyg_uint32 val;
+
+ HAL_READ_UINT32(p->io_data, val);
+ memcpy(dest, &val, 4);
+ return 4;
+}
+
+
+// Write one datum to 8-bit bus
+static int write_data_8(struct dm9000 *p, cyg_uint8 *src)
+{
+ HAL_WRITE_UINT8(p->io_data, *src);
+ return 1;
+}
+
+// Write one datum to 16-bit bus
+static int write_data_16(struct dm9000 *p, cyg_uint8 *src)
+{
+ cyg_uint16 val;
+
+ memcpy(&val, src, 2);
+ HAL_WRITE_UINT16(p->io_data, val);
+ return 2;
+}
+
+// Write one datum to 32-bit bus
+static int write_data_32(struct dm9000 *p, cyg_uint8 *src)
+{
+ cyg_uint32 val;
+
+ memcpy(&val, src, 4);
+ HAL_WRITE_UINT32(p->io_data, val);
+ return 4;
+}
+
+
+
+// Return one byte from DM9000 register
+static cyg_uint8 getreg(struct dm9000 *p, cyg_uint8 reg)
+{
+ cyg_uint8 val;
+ HAL_WRITE_UINT8(p->io_addr, reg);
+ HAL_READ_UINT8(p->io_data, val);
+ return val;
+}
+
+// Write one byte to DM9000 register
+static void putreg(struct dm9000 *p, cyg_uint8 reg, cyg_uint8 val)
+{
+ HAL_WRITE_UINT8(p->io_addr, reg);
+ HAL_WRITE_UINT8(p->io_data, val);
+}
+
+// Read a word from EEPROM
+static cyg_uint16 eeprom_read(struct dm9000 *p, int offset)
+{
+ putreg(p, DM_EPAR, offset);
+ putreg(p, DM_EPCR, EPCR_ERPRR);
+ while (getreg(p, DM_EPCR) & EPCR_ERRE)
+ ;
+ CYGACC_CALL_IF_DELAY_US(8000);
+ putreg(p, DM_EPCR, 0);
+ return getreg(p, DM_EPDRL) | (getreg(p, DM_EPDRH) << 8);
+}
+
+// Write a word to EEPROM
+static void eeprom_write(struct dm9000 *p, int offset, cyg_uint16 val)
+{
+ putreg(p, DM_EPAR, offset);
+ putreg(p, DM_EPDRH, val >> 8);
+ putreg(p, DM_EPDRL, val);
+ putreg(p, DM_EPCR, EPCR_WEP | EPCR_ERPRW);
+ while (getreg(p, DM_EPCR) & EPCR_ERRE)
+ ;
+ CYGACC_CALL_IF_DELAY_US(8000);
+ putreg(p, DM_EPCR, 0);
+}
+
+// Reload info from EEPROM
+static void eeprom_reload(struct dm9000 *p)
+{
+ putreg(p, DM_EPCR, EPCR_REEP);
+ while (getreg(p, DM_EPCR) & EPCR_ERRE)
+ ;
+ CYGACC_CALL_IF_DELAY_US(8000);
+ putreg(p, DM_EPCR, 0);
+}
+
+
+// Read a word from PHY
+static cyg_uint16 phy_read(struct dm9000 *p, int offset)
+{
+ putreg(p, DM_EPAR, 0x40 + offset);
+ putreg(p, DM_EPCR, EPCR_EPOS | EPCR_ERPRR);
+ CYGACC_CALL_IF_DELAY_US(200);
+ putreg(p, DM_EPCR, 0);
+ return getreg(p, DM_EPDRL) | (getreg(p, DM_EPDRH) << 8);
+}
+
+// Write a word to PHY
+static void phy_write(struct dm9000 *p, int offset, cyg_uint16 val)
+{
+ putreg(p, DM_EPAR, 0x40 + offset);
+ putreg(p, DM_EPDRL, val);
+ putreg(p, DM_EPDRH, val >> 8);
+ putreg(p, DM_EPCR, EPCR_EPOS | EPCR_ERPRW);
+ CYGACC_CALL_IF_DELAY_US(500);
+ putreg(p, DM_EPCR, 0);
+}
+
+
+static void init_phy(struct dm9000 *p)
+{
+ int t = 0;
+ cyg_uint16 r;
+
+ /* power on PHY */
+ putreg(p, DM_GPCR, 0x01);
+ putreg(p, DM_GPR, 0x00);
+
+ phy_write(p, PHY_ANAR, 0x1e1); // Advertise 10/100 half/full duplex w/CSMA
+ phy_write(p, PHY_BMCR, PHY_BMCR_AUTO_NEG_EN | PHY_BMCR_AUTO_NEG_START);
+
+ /* wait for autonegotiation to complete */
+ do {
+ CYGACC_CALL_IF_DELAY_US(1000);
+ r = phy_read(p, PHY_BMSR);
+ } while (!(r & PHY_BMSR_AUTO_NEG_COMPLETE) && t++ < 2000);
+}
+
+
+static inline void dm9000_reset(struct dm9000 *p)
+{
+ putreg(p, DM_NCR, NCR_RST);
+ CYGACC_CALL_IF_DELAY_US(100);
+}
+
+static int initialize_nic(struct dm9000 *priv)
+{
+ int i;
+
+ dm9000_reset(priv);
+
+ switch (getreg(priv, DM_ISR) >> 6) {
+ case 0:
+ priv->read_data = read_data_16;
+ priv->write_data = write_data_16;
+ priv->buswidth = 2;
+ break;
+ case 1:
+ priv->read_data = read_data_32;
+ priv->write_data = write_data_32;
+ priv->buswidth = 4;
+ break;
+ case 2:
+ priv->read_data = read_data_8;
+ priv->write_data = write_data_8;
+ priv->buswidth = 1;
+ break;
+ default:
+ diag_printf("Unknown DM9000 bus i/f.\n");
+ return 0;
+ }
+
+ init_phy(priv);
+
+ putreg(priv, DM_TCR, 0);
+ putreg(priv, DM_BPTR, 0x3f);
+ putreg(priv, DM_FCTR, 0x38);
+ putreg(priv, DM_FCR, 0xff);
+ putreg(priv, DM_SMCR, 0);
+ putreg(priv, DM_NSR, NSR_WAKEST | NSR_TX1END | NSR_TX2END);
+ putreg(priv, DM_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);
+
+ // set MAC address
+ for (i = 0; i < 6; i++)
+ putreg(priv, DM_PAR + i, priv->mac_address[i]);
+
+ // clear multicast table except for broadcast address
+ for (i = 0; i < 6; i++)
+ putreg(priv, DM_MAR + i, 0x00);
+ putreg(priv, DM_MAR + 6, 0x00);
+ putreg(priv, DM_MAR + 7, 0x80);
+
+ return 1;
+}
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32 dm9000_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+
+ cyg_drv_interrupt_mask(priv->interrupt);
+ cyg_drv_interrupt_acknowledge(priv->interrupt);
+
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+#endif
+
+
+// ------------------------------------------------------------------------
+//
+// API Function : dm9000_init
+//
+// ------------------------------------------------------------------------
+static bool
+dm9000_init(struct cyg_netdevtab_entry * ndp)
+{
+ struct eth_drv_sc *sc;
+ struct dm9000 *priv;
+ int i;
+ unsigned id;
+ unsigned short u16tab[64];
+
+ sc = (struct eth_drv_sc *)ndp->device_instance;
+ priv = (struct dm9000 *)sc->driver_private;
+
+ priv->sc = sc;
+
+#ifdef CYG_HAL_DM9000_PRESENT
+ if (!CYG_HAL_DM9000_PRESENT())
+ return 0;
+#endif
+
+ id = getreg(priv, DM_VIDL);
+ id |= getreg(priv, DM_VIDH) << 8;
+ id |= getreg(priv, DM_PIDL) << 16;
+ id |= getreg(priv, DM_PIDH) << 24;
+
+ if (id != 0x90000A46)
+ return 0;
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_create(priv->interrupt,
+ 0,
+ (cyg_addrword_t)sc,
+ dm9000_isr,
+ eth_drv_dsr,
+ &priv->interrupt_handle,
+ &priv->interrupt_object);
+ cyg_drv_interrupt_attach(priv->interrupt_handle);
+ cyg_drv_interrupt_acknowledge(priv->interrupt);
+ cyg_drv_interrupt_unmask(priv->interrupt);
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+
+ for (i = 0; i < 64; i++)
+ u16tab[i] = eeprom_read(priv, i);
+
+ u16tab[3] &= ~0xc;
+ u16tab[3] |= 4;
+ u16tab[6] &= 0xfe00;
+ u16tab[6] |= 6;
+
+#if 0
+ eeprom_write(priv, 6, u16tab[6]);
+ eeprom_write(priv, 3, u16tab[3]);
+#endif
+
+ eeprom_reload(priv);
+
+ do {
+ for (i = 0; i < 64; i++)
+ u16tab[i] = eeprom_read(priv, i);
+ } while ((u16tab[0] | u16tab[1] | u16tab[2]) == 0);
+
+ priv->mac_address[0] = u16tab[0];
+ priv->mac_address[1] = u16tab[0] >> 8;
+ priv->mac_address[2] = u16tab[1];
+ priv->mac_address[3] = u16tab[1] >> 8;
+ priv->mac_address[4] = u16tab[2];
+ priv->mac_address[5] = u16tab[2] >> 8;
+
+ if (!initialize_nic(priv))
+ return 0;
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, &(priv->mac_address[0]) );
+ return 1;
+}
+
+// ------------------------------------------------------------------------
+//
+// API Function : dm9000_start
+//
+// ------------------------------------------------------------------------
+static void
+dm9000_start( struct eth_drv_sc *sc, unsigned char *enaddr, int flags )
+{
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+
+ // turn on receiver
+ putreg(priv, DM_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
+
+ // unmask interrupt
+ putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
+
+ priv->active = 1;
+}
+
+// ------------------------------------------------------------------------
+//
+// API Function : dm9000_stop
+//
+// ------------------------------------------------------------------------
+static void
+dm9000_stop( struct eth_drv_sc *sc )
+{
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+
+ // turn on receiver
+ putreg(priv, DM_RCR, 0);
+
+ // mask interrupts
+ putreg(priv, DM_IMR, IMR_PAR);
+
+ priv->active = 0;
+}
+
+
+// ------------------------------------------------------------------------
+//
+// API Function : dm9000_recv
+//
+// ------------------------------------------------------------------------
+static void
+dm9000_recv( struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len )
+{
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+ struct eth_drv_sg *sg = sg_list;
+ cyg_uint8 tmpbuf[4];
+ char *p;
+ int len, total_len, nread, n, leftover;
+
+ total_len = priv->rxlen;
+ nread = leftover = 0;
+
+// diag_printf("dm9000_recv: total_len=%d\n", total_len);
+
+ do {
+ p = (char *)sg->buf;
+ len = sg->len;
+
+// diag_printf("recv: buf=%p len=%d to_read=%d, leftover=%d\n", p, len, total_len - nread, leftover);
+
+ if ((nread + len) > total_len)
+ len = total_len - nread;
+
+ if (leftover) {
+ if (leftover <= len) {
+ memcpy(p, tmpbuf + (sizeof(tmpbuf) - leftover), leftover);
+ p += leftover;
+ len -= leftover;
+ nread += leftover;
+ leftover = 0;
+ } else {
+ memcpy(p, tmpbuf + (sizeof(tmpbuf) - leftover), len);
+ leftover -= len;
+ p += len;
+ nread += len;
+ len = 0;
+ }
+ }
+
+ while (len >= sizeof(tmpbuf)) {
+ n = priv->read_data(priv, p);
+ nread += n;
+ len -= n;
+ p += n;
+ }
+
+ while (len > 0) {
+ n = priv->read_data(priv, tmpbuf);
+ if (n <= len) {
+ memcpy(p, tmpbuf, n);
+ len -= n;
+ nread += n;
+ p += n;
+ } else {
+ memcpy(p, tmpbuf, len);
+ nread += len;
+ leftover = n - len;
+ len = 0;
+ }
+ }
+
+ ++sg;
+ } while (nread < total_len);
+
+#ifdef DEBUG_DUMP
+ for (sg = sg_list; sg < (sg_list + sg_len); sg++) {
+ diag_printf("\n");
+ diag_dump_buf(sg->buf, sg->len);
+ }
+#endif
+}
+
+// ------------------------------------------------------------------------
+//
+// API Function : dm9000_can_send
+//
+// ------------------------------------------------------------------------
+static int
+dm9000_can_send(struct eth_drv_sc *sc)
+{
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+
+ if (!priv->active || priv->txbusy || priv->reset_pending)
+ return 0;
+
+ return 1;
+}
+
+
+// ------------------------------------------------------------------------
+//
+// API Function : dm9000_send
+//
+// ------------------------------------------------------------------------
+static void
+dm9000_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+ struct eth_drv_sg *sg;
+ cyg_uint8 tmpbuf[4];
+ int i, len, n, save_len, tail_extra;
+ char *p;
+
+#ifdef DEBUG
+ diag_printf("dm9000_send: NCR[%02x] NSR[%02x] TRPA[%04x]\n",
+ getreg(priv, DM_NCR), getreg(priv, DM_NSR),
+ getreg(priv, DM_TRPAL) | (getreg(priv, DM_TRPAH) << 8)
+ );
+#endif
+#ifdef DEBUG_DUMP
+ for (sg = sg_list; sg < (sg_list + sg_len); sg++) {
+ diag_printf("\n");
+ diag_dump_buf(sg->buf, sg->len);
+ }
+#endif
+
+ priv->txbusy = 1;
+
+ sg = sg_list;
+ save_len = total_len;
+ tail_extra = 0;
+
+ /* Disable all interrupts */
+ putreg(priv, DM_IMR, IMR_PAR);
+
+ HAL_WRITE_UINT8(priv->io_addr, DM_MWCMD);
+
+ while (total_len > 0) {
+ len = sg->len;
+ if (len > total_len)
+ len = total_len;
+ p = (char *)sg->buf;
+
+ /* write any left over partial words by combining them with the start
+ * of this sg block */
+ if (tail_extra) {
+ int head_extra = sizeof(tmpbuf) - tail_extra;
+ memcpy(tmpbuf + tail_extra, p, head_extra);
+ p += head_extra;
+ len -= head_extra;
+ for (i = 0; i < sizeof(tmpbuf) && total_len > 0; i += n) {
+ n = priv->write_data(priv, tmpbuf + i);
+ total_len -= n;
+ }
+ tail_extra = 0;
+ }
+
+ /* write out whole words */
+ while (len >= priv->buswidth) {
+ n = priv->write_data(priv, p);
+ len -= n;
+ total_len -= n;
+ p += n;
+ }
+
+ /* if we have some left over partial words... */
+ if (len > 0) {
+ /* combine them with the next sg block if available */
+ if (total_len > len ) {
+ tail_extra = len;
+ memcpy(tmpbuf, p, tail_extra);
+ } else {
+ /* otherwise just write this last partial word */
+ n = priv->write_data(priv, p);
+ total_len -= n;
+ }
+ }
+ sg++;
+ }
+
+ priv->txkey = key;
+
+ putreg(priv, DM_TXPLL, save_len);
+ putreg(priv, DM_TXPLH, save_len >> 8);
+
+ putreg(priv, DM_TCR, TCR_TXREQ);
+
+ /* Re-enable interrupt */
+ putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
+}
+
+// ------------------------------------------------------------------------
+//
+// API Function : dm9000_poll
+//
+// ------------------------------------------------------------------------
+static void
+dm9000_poll(struct eth_drv_sc *sc)
+{
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+ cyg_uint8 status, rxstat;
+ cyg_uint16 pkt_stat, pkt_len;
+ int i;
+
+ // mask interrupts
+ putreg(priv, DM_IMR, IMR_PAR);
+
+ // get and clear staus
+ status = getreg(priv, DM_ISR);
+ putreg(priv, DM_ISR, status);
+
+ // check for rx done
+ if (1 /*status & ISR_PRS*/) {
+ cyg_uint8 hdr[4]; /* 4 byte Rx pkt hdr */
+
+ getreg(priv, DM_MRCMDX); /* dummy read */
+
+ HAL_READ_UINT8(priv->io_data, rxstat);
+
+ // check for packet ready
+ if (rxstat == 1) {
+ HAL_WRITE_UINT8(priv->io_addr, DM_MRCMD);
+ for (i = 0; i < 4;)
+ i += priv->read_data(priv, hdr + i);
+
+ pkt_stat = hdr[0] | (hdr[1] << 8);
+ pkt_len = hdr[2] | (hdr[3] << 8);
+
+#ifdef DEBUG
+ diag_printf("pkt_stat=%04x pkt_len=%04x\n", pkt_stat, pkt_len);
+#endif
+
+ if (pkt_len < 0x40) {
+ diag_printf("packet too short: %d (0x%04x)\n", pkt_len, pkt_len);
+ i = 0;
+ while (i < pkt_len)
+ i += priv->read_data(priv, hdr);
+ } else if (pkt_len > 1536) {
+ priv->reset_pending = 1;
+ diag_printf("packet too long: %d (0x%04x)\n", pkt_len, pkt_len);
+ } else if (pkt_stat & 0xbf00) {
+ diag_printf("bad packet status: 0x%04x\n", pkt_stat);
+ i = 0;
+ while (i < pkt_len)
+ i += priv->read_data(priv, hdr);
+ } else {
+ // receive packet
+ priv->rxlen = pkt_len;
+ (sc->funs->eth_drv->recv)(sc, pkt_len);
+ }
+
+ } else if (rxstat > 1) {
+ // this should never happen.
+ diag_printf("unknown rxstat byte: %d\n", rxstat);
+ priv->reset_pending = 1;
+ }
+ }
+
+
+ // check transmit status
+ if (status & ISR_PTS) {
+ cyg_uint8 txstat;
+
+ txstat = getreg(priv, DM_NSR);
+
+ if (txstat & (NSR_TX1END | NSR_TX2END)) {
+ if (txstat & NSR_TX1END)
+ txstat = getreg(priv, DM_TSRI);
+ else
+ txstat = getreg(priv, DM_TSRII);
+
+ if (txstat & TSR_COL) {
+ // collision
+ }
+
+ if (getreg(priv, DM_TRPAL) & 3) {
+ // NIC bug detected. Need to reset.
+ priv->reset_pending = 1;
+ diag_printf("NIC collision bug detected!\n");
+ }
+
+ (sc->funs->eth_drv->tx_done)(sc, priv->txkey, 0);
+ priv->txbusy = 0;
+ }
+ }
+
+ if (priv->reset_pending && !priv->txbusy) {
+ initialize_nic(priv);
+
+ // turn on receiver
+ putreg(priv, DM_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
+
+ priv->reset_pending = 0;
+ }
+
+ // unmask interrupts
+ putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
+}
+
+
+// ------------------------------------------------------------------------
+//
+// API Function : dm9000_deliver
+//
+// ------------------------------------------------------------------------
+static void
+dm9000_deliver(struct eth_drv_sc *sc)
+{
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+
+ dm9000_poll(sc);
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_unmask(priv->interrupt);
+#endif
+}
+
+// ------------------------------------------------------------------------
+//
+// API Function : dm9000_int_vector
+//
+// ------------------------------------------------------------------------
+static int
+dm9000_int_vector(struct eth_drv_sc *sc)
+{
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+
+ return priv->interrupt;
+}
+
+
+// ------------------------------------------------------------------------
+//
+// API Function : dm9000_ioctl
+//
+// ------------------------------------------------------------------------
+static int
+dm9000_ioctl(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+ cyg_uint8 *esa = (cyg_uint8 *)data;
+ int i;
+
+ switch (key) {
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ memcpy(esa, priv->mac_address, sizeof(priv->mac_address));
+ return 0;
+#endif
+#ifdef ETH_DRV_SET_MAC_ADDRESS
+ case ETH_DRV_SET_MAC_ADDRESS:
+ for (i = 0; i < sizeof(priv->mac_address); i++) {
+ priv->mac_address[i] = esa[i];
+ putreg(priv, DM_PAR + i, priv->mac_address[i]);
+ }
+#if defined(CYGSEM_DEVS_ETH_DAVICOM_DM9000_WRITE_EEPROM)
+ for (i = 0; i < sizeof(priv->mac_address) / 2; i++)
+ eeprom_write(priv, i, priv->mac_address[2*i] | (priv->mac_address[2*i+1] << 8));
+#else
+ diag_printf("dm9000: eeprom write disabled\n");
+#endif
+ return 0;
+#endif
+ }
+
+ return -1;
+}
+
+// ------------------------------------------------------------------------
+// EOF if_dm9000.c
diff --git a/ecos/packages/devs/eth/freescale/enet/current/ChangeLog b/ecos/packages/devs/eth/freescale/enet/current/ChangeLog
new file mode 100644
index 0000000..b174c02
--- /dev/null
+++ b/ecos/packages/devs/eth/freescale/enet/current/ChangeLog
@@ -0,0 +1,47 @@
+2013-04-01 Ilija Kocho <ilijak@siva.com.mk>
+
+ * src/if_freescale_enet.c: Add clock gating enable. [ Bugzilla 1001814 ]
+
+2012-05-04 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/eth_freescale_enet.cdl:
+ * src/if_freescale_enet.c:
+ Add optional non-cached regions for TCD and buffers [Bugzilla 1001579]
+
+2012-01-06 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/eth_freescale_enet.cdl:
+ * src/if_freescale_enet.c:
+ Add Redboot ESA support [Bugzilla 1001450]
+
+2011-08-26 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/eth_freescale_enet.cdl:
+ * include/if_freescale_enet_bd.h:
+ * include/if_freescale_enet_io.h:
+ * src/if_freescale_enet.c:
+ New package -- Freescale ENET Ethernet driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/freescale/enet/current/cdl/eth_freescale_enet.cdl b/ecos/packages/devs/eth/freescale/enet/current/cdl/eth_freescale_enet.cdl
new file mode 100644
index 0000000..844b167
--- /dev/null
+++ b/ecos/packages/devs/eth/freescale/enet/current/cdl/eth_freescale_enet.cdl
@@ -0,0 +1,453 @@
+#==========================================================================
+#
+# eth_freescale_enet.cdl
+#
+# Ethernet driver for Freescale ENET controller
+#
+#==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Kocho <ilijak@siva.com.mk>
+# Contributors:
+# Date: 2011-06-14
+#
+#####DESCRIPTIONEND####
+#
+#========================================================================
+
+
+cdl_package CYGPKG_DEVS_ETH_FREESCALE_ENET {
+ display "Freescale ENET ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ requires CYGHWR_FREESCALE_ENET_MII_MDC_HAL_CLOCK
+
+ include_dir cyg/io/eth
+ description "
+ Ethernet driver for Freescale ENET controller. Freescale ENET
+ Ethernet controller is found on some Freescale families of
+ controllers such as Kinetis and ColdFire+."
+
+ compile -library=libextras.a if_freescale_enet.c
+
+ # ENET0 Configuration options --------------------------------------------
+ cdl_option CYGDAT_IO_ETH_IF_FREESCALE_ENET0_NAME {
+ display "Device name for Freescale ENET0 interface"
+ flavor data
+ default_value { "\"eth0\"" }
+ description "
+ This option specifies the device name for Freescale ENET0
+ interface."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_FREESCALE_ENET0_MACADDR {
+ display "Ethernet station (MAC) address for eth0"
+ flavor data
+ default_value {"0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC"}
+ description "
+ The default ethernet station address."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_FREESCALE_ENET0_INTPRIO {
+ display "Interrupt priority"
+ flavor data
+ default_value CYGNUM_DEVS_ETH_FREESCALE_ENET0_INTPRIO_SP
+ description "
+ This option selects the interrupt priority for the EMAC
+ interrupts."
+ }
+
+ cdl_component CYGHWR_DEVS_ETH_FREESCALE_ENET0_FLOW_CONTROL {
+ display "Congestion control"
+ flavor none
+ no_define
+
+ cdl_option CYGSEM_ETH_FREESCALE_ENET0_RCR_FCE {
+ display "Rx Flow control enable"
+ flavor data
+ legal_values { 0 1 }
+ default_value 0
+ description "
+ If enabled ENET shall regard pause frames requests from peer."
+ }
+
+ cdl_option CYGNUM_ETH_FREESCALE_ENET0_OPD_PAUSE_DUR {
+ display "Tx flow control pause duration"
+ flavor data
+ legal_values 0 to 255
+ default_value 0
+ description "
+ Flow control pause legth in pause quanta asked from peer.
+ 1 pause quant equals to 512 bit time increments."
+ }
+ }
+
+ cdl_component CYGHWR_DEVS_ETH_FREESCALE_ENET0_BUFFS {
+ display "Buffers"
+ flavor none
+ no_define
+ description "Rx and Tx buffers"
+
+ cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET0_MAX_FRAME_LEN {
+ display "Maximal frame length"
+ flavor data
+ default_value 1518
+ legal_values 64 to 1522
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET0_RX_BUFS {
+ display "Number of RX buffers"
+ flavor data
+ default_value 8
+ legal_values 2 to 64
+ description "
+ Number of buffers for receiving. The number of receive
+ buffers also defines the number of descriptors in the
+ descriptor array."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET0_RXBUF_SIZE {
+ display "Rx buffer size"
+ flavor data
+ requires { (CYGNUM_DEVS_ETH_FREESCALE_ENET0_RXBUF_SIZE %
+ CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN) == 0
+ }
+ legal_values 16 to 1536
+ default_value {
+ ((CYGNUM_DEVS_ETH_FREESCALE_ENET0_MAX_FRAME_LEN +
+ CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN-1)/
+ (CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN ?
+ CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN : 1)) *
+ CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN
+ }
+ description "Rx buffer size must be evenly divisible by 16."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS {
+ display "Number of TX descriptors (buffers)"
+ flavor data
+ default_value ( CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY ? 8 : \
+ CYGPKG_IO_ETH_DRIVERS_NET ? 8 : 2 )
+ legal_values 2 to 64
+ description "
+ Number of transmit buffers or descriptors. We need one
+ descriptor/buffer for each element in the scatter/gather list.
+ If NoCopy is selected then only buffer descriptors are allocated.
+ If Copying is selected (NoCopy == 0) then a buffer is allocated
+ for every buffer descriptor."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET0_TXBUF_SIZE {
+ display "Tx buffer size"
+ flavor data
+ active_if { !CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY }
+ requires { (CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_SIZE %
+ CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN) == 0
+ }
+
+ legal_values { 16 to 1536 }
+ default_value {
+ ((CYGNUM_DEVS_ETH_FREESCALE_ENET0_MAX_FRAME_LEN +
+ CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN-1)/
+ (CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN ?
+ CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN : 1)) *
+ CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN
+ }
+ }
+ }
+
+ # END of ENET0 specific configuration options. ---------------------------
+
+ # Common ENET options. ---------------------------------------------------
+ # Following configuration options are common to all ENET instances
+
+ cdl_option CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED {
+ display "Enhanced buffer descriptors"
+ flavor bool
+ default_value 0
+ }
+
+ cdl_component CYGHWR_DEVS_ETH_FREESCALE_ENET_ALIGN {
+ display "Buffer/descriptor memory alignment"
+ flavor none
+ no_define
+ description "
+ ENET conatins internal DMA controller that
+ requires certain memory alighment"
+
+ cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBD_ALIGN {
+ display "Rx buffer descriptor alignment"
+ flavor data
+ default_value 8
+ legal_values { 8 16 }
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN {
+ display "Rx buffer alignment"
+ flavor data
+ default_value 16
+ legal_values { 16 }
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBD_ALIGN {
+ display "Tx buffer descriptor alignment"
+ flavor data
+ default_value 8
+ legal_values { 8 16 }
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN {
+ display "Tx buffer alignment"
+ flavor data
+ default_value 8
+ legal_values { 8 16 }
+ }
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_FREESCALE_ENET_PHY {
+ display "RMII or MII Phy"
+ flavor data
+ default_value { "RMII" }
+ legal_values { "RMII" "MII" }
+
+ cdl_option CYGOPT_DEVS_ETH_FREESCALE_ENET_PHY_RXER_USE {
+ display "Enable PHY Rx Error signal"
+ flavor bool
+ default_value 1
+ }
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL {
+ display "TCP/IP acceleration"
+ flavor none
+ no_define
+ description "
+ Freescale ENET provides for hardware TCP/IP header checksum
+ generation and check."
+
+ active_if CYGPKG_NET_LWIP
+ requires CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ requires CYGPKG_LWIP_CHECKSUMS
+
+ cdl_component CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_IP {
+ display "IP Checksum generation"
+ flavor bool
+ default_value 1
+
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ (CYGIMP_LWIP_CHECKSUM_GEN_IP == 0) }
+
+ cdl_option CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_PROT {
+ display "TCP and UDP Checksum generation"
+ flavor bool
+ default_value 1
+
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ (CYGIMP_LWIP_CHECKSUM_GEN_TCP == 0) }
+
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ (CYGIMP_LWIP_CHECKSUM_GEN_UDP == 0) }
+ }
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_IP {
+ display "IP Checksum check"
+ flavor bool
+ default_value 1
+
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ (CYGIMP_LWIP_CHECKSUM_CHECK_IP == 0) }
+
+ cdl_option CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_PROT {
+ display "TCP and UDP checksum check"
+ flavor bool
+ default_value 1
+
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ (CYGIMP_LWIP_CHECKSUM_CHECK_TCP == 0) }
+
+ requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies
+ (CYGIMP_LWIP_CHECKSUM_CHECK_UDP == 0) }
+ }
+ }
+
+ cdl_option CYGSEM_ENET_LWIP_CHECKSUMS {
+ display "lwIP Checksum calculation"
+ flavor none
+ no_define
+ description "
+ Re-enable lwIP software checksum generation/check if
+ hardware generation/check is disabled."
+
+ requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_IP implies
+ CYGIMP_LWIP_CHECKSUM_GEN_IP == 1 }
+ requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_PROT implies
+ CYGIMP_LWIP_CHECKSUM_GEN_TCP == 1 }
+ requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_PROT implies
+ CYGIMP_LWIP_CHECKSUM_GEN_UDP == 1 }
+
+ requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_IP implies
+ CYGIMP_LWIP_CHECKSUM_CHECK_IP == 1 }
+ requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_PROT implies
+ CYGIMP_LWIP_CHECKSUM_CHECK_TCP == 1 }
+ requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_PROT implies
+ CYGIMP_LWIP_CHECKSUM_CHECK_UDP == 1 }
+ }
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_FREESCALE_ENET_1588 {
+ display "IEEE 1588 timers"
+ requires CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ flavor bool
+ default_value 0
+ }
+
+ cdl_component CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS {
+ display "ENET Error statistics"
+ flavor bool
+ default_value 0
+
+ cdl_option CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS_DEBUG {
+ display "Debug print ENET error statistics"
+ flavor bool
+ default_value 0
+ }
+ }
+
+ cdl_option CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY {
+ display "NullCopy send"
+ flavor bool
+ default_value 0
+ active_if (CYGPKG_NET_LWIP)
+
+ requires { is_active(CYGPKG_NET_LWIP) implies
+ (CYGNUM_LWIP_MEM_ALIGNMENT >=
+ CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN) }
+
+ description "
+ ENET driver can send buffers 'out of place'
+ (wihout making a private copy), offloading CPU from
+ copying data and saving space for Tx buffers . This is
+ 'NullCopy' option, opposite to 'Copying' option where ENET
+ driver has private Tx buffers and requires additional copying
+ operation (by CPU).
+ On the pther hand, 'Copying' option needs no Tx IRQ which may
+ make it better choice than NullCopy if system dominantly sends
+ short messages. Also, ENET has some requiresments for buffer
+ alignment, therefore if upper layer networking stack /
+ application can not guarantee for boundary alignment then
+ 'Copying' should be used."
+ }
+
+ cdl_option CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK {
+ display "Fast IRQ masking"
+ flavor bool
+ default_value 1
+
+ description "
+ Fast (un)masking operates on bits in ENET's EIR
+ register instead of calling cyg_drv_interrupt_(un)mask.
+ This allows sumultaneous (un)masking of both Tx and Rx
+ interrupts and is prefered mode, but case of compatibility
+ problems disable fast IRQ mask."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_FREESCALE_ENET_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 0
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ active_if (CYGPKG_REDBOOT || CYGSEM_HAL_USE_ROM_MONITOR)
+
+ description "
+ Enabling this option will allow the ethernet station
+ address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually
+ by the 'Set the ethernet station address' option for each
+ interface."
+
+
+ cdl_component CYGPKG_DEVS_ETH_FREESCALE_ENET_REDBOOT_HOLDS_ESA_VARS {
+ display "Export RedBoot command to set ESA in FLASH config"
+ flavor none
+ no_define
+ description "
+ This component contains options which, when enabled, allow
+ RedBoot to support the setting of the ESA in the FLASH
+ configuration. This can then subsequently be accessed by
+ applications using virtual vector calls if those applications
+ are also built with
+ CYGPKG_DEVS_ETH_FREESCALE_ENET_REDBOOT_HOLDS_ESA enabled."
+
+ cdl_option CYGSEM_DEVS_ETH_FREESCALE_ENET_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 1
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+ }
+ }
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_FREESCALE_ENET_DEBUG_LEVEL {
+ display "Driver debug output level"
+ flavor data
+ legal_values { 0 1 2 3 }
+ default_value 0
+ description "
+ This option specifies the level of debug data output by
+ the Freescale ENET ethernet device driver. A value of 0 signifies
+ no debug data output; 1 signifies normal debug data
+ output; and 2 signifies maximum debug data output."
+ }
+
+ cdl_option CYGPKG_DEVS_ETH_FREESCALE_ENET_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Freescale ENET ethernet driver package.
+ These flags are used in addition to the set of global flags."
+ }
+}
+
+# EOF eth_freescale_enet.cdl
diff --git a/ecos/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_bd.h b/ecos/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_bd.h
new file mode 100644
index 0000000..139a073
--- /dev/null
+++ b/ecos/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_bd.h
@@ -0,0 +1,209 @@
+#ifndef CYGONCE_FREESCALE_ENET_BD_H
+#define CYGONCE_FREESCALE_ENET_BD_H
+//=============================================================================
+//
+// freescale_enet_bd.h
+//
+// Variant specific registers
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Kocho <ilijak@siva.com.mk>
+// Date: 2011-06-05
+// Purpose: Freescale ENET buffer descriptors
+// Description:
+// Usage: #include <cyg/io/freescale_enet_bd.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//---------------------------------------------------------------------------
+// ENET Buffer Descriptors
+// All mrmbers except key must be big endian
+typedef volatile struct enet_bd_s {
+ cyg_uint16 ctrl; // 00
+ cyg_uint16 len; // 02
+ cyg_uint8 *buffer_p; // 04
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ cyg_uint32 ebd_ctrl; // 08
+ cyg_uint16 hlen_proto; // 0c
+ cyg_uint16 payload_csum; // 0e
+ cyg_uint32 bdu; // 10
+ cyg_uint32 timestamp_1588; // 14
+ cyg_uint32 reserved[2]; // 18
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+} enet_bd_t;
+
+
+#if (CYG_BYTEORDER == CYG_LSBFIRST)
+//======================================================================
+// Little Endian
+//----------------------------------------------------------------------
+
+// ----------------------------------------------------------------------
+// TX Buffer Descriptor Bit Definitions
+
+# define ENET_TXBD_R 0x0080
+# define ENET_TXBD_TO1 0x0040
+# define ENET_TXBD_W 0x0020
+# define ENET_TXBD_TO2 0x0010
+# define ENET_TXBD_L 0x0008
+# define ENET_TXBD_TC 0x0004
+# define ENET_TXBD_ABC 0x0002
+
+// ----------------------------------------------------------------------
+// TX Enhanced BD Bit Definitions
+
+# define ENET_TXBD_INT 0x00000040
+# define ENET_TXBD_TS 0x00000020
+# define ENET_TXBD_PINS 0x00000010
+# define ENET_TXBD_IINS 0x00000008
+# define ENET_TXBD_TXE 0x00800000
+# define ENET_TXBD_UE 0x00200000
+# define ENET_TXBD_EE 0x00100000
+# define ENET_TXBD_FE 0x00080000
+# define ENET_TXBD_LCE 0x00040000
+# define ENET_TXBD_OE 0x00020000
+# define ENET_TXBD_TSE 0x00010000
+
+# define ENET_TXBD_BDU 0x00000080
+
+// ----------------------------------------------------------------------
+// RX Buffer Descriptor Bit Definitions
+// Offset 0 flags - ctrl
+# define ENET_RXBD_E 0x0080
+# define ENET_RXBD_R01 0x0040
+# define ENET_RXBD_W 0x0020
+# define ENET_RXBD_R02 0x0010
+# define ENET_RXBD_L 0x0008
+# define ENET_RXBD_M 0x0001
+# define ENET_RXBD_BC 0x8000
+# define ENET_RXBD_MC 0x4000
+# define ENET_RXBD_LG 0x2000
+# define ENET_RXBD_NO 0x1000
+# define ENET_RXBD_CR 0x0400
+# define ENET_RXBD_OV 0x0200
+# define ENET_RXBD_TR 0x0100
+
+// ----------------------------------------------------------------------
+// RX Enhanced BD Bit Definitions
+
+# define ENET_RXBD_ME 0x00000080
+# define ENET_RXBD_PE 0x00000004
+# define ENET_RXBD_CE 0x00000002
+# define ENET_RXBD_UC 0x00000001
+
+# define ENET_RXBD_INT 0x00008000
+
+# define ENET_RXBD_ICE 0x20000000
+# define ENET_RXBD_PCR 0x10000000
+# define ENET_RXBD_VLAN 0x04000000
+# define ENET_RXBD_IPV6 0x02000000
+# define ENET_RXBD_FRAG 0x01000000
+
+# define ENET_RXBD_BDU 0x00000080
+
+#else //(CYG_BYTEORDER == CYG_LSBFIRST)
+//======================================================================
+// Big Endian
+//----------------------------------------------------------------------
+
+// ----------------------------------------------------------------------
+// TX Buffer Descriptor Bit Definitions
+
+# define ENET_TXBD_R 0x8000
+# define ENET_TXBD_TO1 0x4000
+# define ENET_TXBD_W 0x2000
+# define ENET_TXBD_TO2 0x1000
+# define ENET_TXBD_L 0x0800
+# define ENET_TXBD_TC 0x0400
+# define ENET_TXBD_ABC 0x0200
+
+// ----------------------------------------------------------------------
+// TX Enhanced BD Bit Definitions
+
+# define ENET_TXBD_INT 0x40000000
+# define ENET_TXBD_TS 0x20000000
+# define ENET_TXBD_PINS 0x10000000
+# define ENET_TXBD_IINS 0x08000000
+# define ENET_TXBD_TXE 0x00008000
+# define ENET_TXBD_UE 0x00002000
+# define ENET_TXBD_EE 0x00001000
+# define ENET_TXBD_FE 0x00000800
+# define ENET_TXBD_LCE 0x00000400
+# define ENET_TXBD_OE 0x00000200
+# define ENET_TXBD_TSE 0x00000100
+
+# define ENET_TXBD_BDU 0x80000000
+
+// ----------------------------------------------------------------------
+// RX Buffer Descriptor Bit Definitions
+// Offset 0 flags - ctrl
+# define ENET_RXBD_E 0x8000
+# define ENET_RXBD_R01 0x4000
+# define ENET_RXBD_W 0x2000
+# define ENET_RXBD_R02 0x1000
+# define ENET_RXBD_L 0x0800
+# define ENET_RXBD_M 0x0100
+# define ENET_RXBD_BC 0x0080
+# define ENET_RXBD_MC 0x0040
+# define ENET_RXBD_LG 0x0020
+# define ENET_RXBD_NO 0x0010
+# define ENET_RXBD_CR 0x0004
+# define ENET_RXBD_OV 0x0002
+# define ENET_RXBD_TR 0x0001
+
+// ----------------------------------------------------------------------
+// RX Enhanced BD Bit Definitions
+
+# define ENET_RXBD_ME 0x80000000
+# define ENET_RXBD_PE 0x04000000
+# define ENET_RXBD_CE 0x02000000
+# define ENET_RXBD_UC 0x01000000
+# define ENET_RXBD_INT 0x00800000
+# define ENET_RXBD_ICE 0x00000020
+# define ENET_RXBD_PCR 0x00000010
+# define ENET_RXBD_VLAN 0x00000004
+# define ENET_RXBD_IPV6 0x00000002
+# define ENET_RXBD_FRAG 0x00000001
+
+# define ENET_RXBD_BDU 0x80000000
+
+#endif // (CYG_BYTEORDER == CYG_LSBFIRST)
+
+// EOF freescale_enet_bd.h
+#endif // CYGONCE_FREESCALE_ENET_BD_H
diff --git a/ecos/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_io.h b/ecos/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_io.h
new file mode 100644
index 0000000..196b2ee
--- /dev/null
+++ b/ecos/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_io.h
@@ -0,0 +1,685 @@
+#ifndef CYGONCE_IF_FREESCALE_ENET_IO_H
+#define CYGONCE_IF_FREESCALE_ENET_IO_H
+//=============================================================================
+//
+// if_freescale_enet_io.h
+//
+// Variant specific registers
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Kocho <ilijak@siva.com.mk>
+// Date: 2011-06-05
+// Purpose: Freescale ENET specific registers
+// Description:
+// Usage: #include <cyg/io/if_freescale_enet_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+
+//=============================================================================
+// Freescale ENET Ethernet controller
+
+// ENET Register offsets relative to CYGADDR_IO_ETH_FREESCALE_ENET_BASE
+// Note: CYGADDR_IO_ETH_FREESCALE_ENET_BASE is provided by HAL.
+// Typically you can find CYGADDR_IO_ETH_FREESCALE_ENET_BASE in var_io.h
+//-----------------------------------------------------------------------------
+// Interrupt Event Register
+#define FREESCALE_ENET_REG_EIR 0x004
+// Interrupt Mask Register
+#define FREESCALE_ENET_REG_EIMR 0x008
+// Receive Descriptor Active Register
+#define FREESCALE_ENET_REG_RDAR 0x010
+// Transmit Descriptor Active Register
+#define FREESCALE_ENET_REG_TDAR 0x014
+// Ethernet Control Register
+#define FREESCALE_ENET_REG_ECR 0x024
+// MII Management Frame Register
+#define FREESCALE_ENET_REG_MMFR 0x040
+// MII Speed Control Register
+#define FREESCALE_ENET_REG_MSCR 0x044
+// MIB Control Register
+#define FREESCALE_ENET_REG_MIBC 0x064
+// Receive Control Register
+#define FREESCALE_ENET_REG_RCR 0x084
+// Transmit Control Register
+#define FREESCALE_ENET_REG_TCR 0x0C4
+// Physical Address Lower Register
+#define FREESCALE_ENET_REG_PALR 0x0E4
+// Physical Address Upper Register
+#define FREESCALE_ENET_REG_PAUR 0x0E8
+// Opcode/Pause Duration Register
+#define FREESCALE_ENET_REG_OPD 0x0EC
+// Descriptor Individual Upper Address Register
+#define FREESCALE_ENET_REG_IAUR 0x118
+// Descriptor Individual Lower Address Register
+#define FREESCALE_ENET_REG_IALR 0x11C
+// Descriptor Group Upper Address Register
+#define FREESCALE_ENET_REG_GAUR 0x120
+// Descriptor Group Lower Address Register
+#define FREESCALE_ENET_REG_GALR 0x124
+// Transmit FIFO Watermark Register
+#define FREESCALE_ENET_REG_TFWR 0x144
+// Receive Descriptor Ring Start Register
+#define FREESCALE_ENET_REG_RDSR 0x180
+// Transmit Buffer Descriptor Ring Start Register
+#define FREESCALE_ENET_REG_TDSR 0x184
+// Maximum Receive Buffer Size Register
+#define FREESCALE_ENET_REG_MRBR 0x188
+// Receive FIFO Section Full Threshold
+#define FREESCALE_ENET_REG_RSFL 0x190
+// Receive FIFO Section Empty Threshold
+#define FREESCALE_ENET_REG_RSEM 0x194
+// Receive FIFO Almost Empty Threshold
+#define FREESCALE_ENET_REG_RAEM 0x198
+// Receive FIFO Almost Full Threshold
+#define FREESCALE_ENET_REG_RAFL 0x19C
+// Transmit FIFO Section Empty Threshold
+#define FREESCALE_ENET_REG_TSEM 0x1A0
+// Transmit FIFO Almost Empty Threshold
+#define FREESCALE_ENET_REG_TAEM 0x1A4
+// Transmit FIFO Almost Full Threshold
+#define FREESCALE_ENET_REG_TAFL 0x1A8
+// Transmit Inter-Packet Gap
+#define FREESCALE_ENET_REG_TIPG 0x1AC
+// Frame Truncation Length
+#define FREESCALE_ENET_REG_FTRL 0x1B0
+// Transmit Accelerator Function Configuration
+#define FREESCALE_ENET_REG_TACC 0x1C0
+// Receive Accelerator Function Configuration
+#define FREESCALE_ENET_REG_RACC 0x1C4
+// Count of frames not counted correctly (RMON_T_DROP).
+// NOTE: Counter not implemented (read 0 always) as not applicable.
+#define FREESCALE_ENET_REG_RMON_T_DROP 0x200
+// RMON Tx packet count (RMON_T_PACKETS)
+#define FREESCALE_ENET_REG_RMON_T_PACKETS 0x204
+// RMON Tx Broadcast Packets (RMON_T_BC_PKT)
+#define FREESCALE_ENET_REG_RMON_T_BC_PKT 0x208
+// RMON Tx Multicast Packets (RMON_T_MC_PKT)
+#define FREESCALE_ENET_REG_RMON_T_MC_PKT 0x20C
+// RMON Tx Packets w CRC/Align error (RMON_T_CRC_ALIGN)
+#define FREESCALE_ENET_REG_RMON_T_CRC_ALIGN 0x210
+// RMON Tx Packets < 64 bytes
+#define FREESCALE_ENET_REG_RMON_T_UNDERSIZE 0x214
+// RMON Tx Packets > MAX_FL bytes
+#define FREESCALE_ENET_REG_RMON_T_OVERSIZE 0x218
+// RMON Tx Packets < 64 bytes
+#define FREESCALE_ENET_REG_RMON_T_FRAG 0x21C
+// RMON Tx Packets > MAX_FL bytes
+#define FREESCALE_ENET_REG_RMON_T_JAB 0x220
+// RMON Tx collision count (RMON_T_COL)
+#define FREESCALE_ENET_REG_RMON_T_COL 0x224
+// RMON Tx 64 byte packets (RMON_T_P64)
+#define FREESCALE_ENET_REG_RMON_T_P64 0x228
+// RMON Tx 65 to 127 byte packets (RMON_T_P65TO127)
+#define FREESCALE_ENET_REG_RMON_T_P65TO127 0x22C
+// RMON Tx 128 to 255 byte packets (RMON_T_P128TO255)
+#define FREESCALE_ENET_REG_RMON_T_P128TO255 0x230
+// RMON Tx 256 to 511 byte packets (RMON_T_P256TO511)
+#define FREESCALE_ENET_REG_RMON_T_P256TO511 0x234
+// RMON Tx 512 to 1023 byte packets (RMON_T_P512TO1023)
+#define FREESCALE_ENET_REG_RMON_T_P512TO1023 0x238
+// RMON Tx 1024 to 2047 byte packets (RMON_T_P1024TO2047)
+#define FREESCALE_ENET_REG_RMON_T_P1024TO2047 0x23C
+// RMON Tx packets w > 2048 bytes (RMON_T_P_GTE2048)
+#define FREESCALE_ENET_REG_RMON_T_P_GTE2048 0x240
+// RMON Tx Octets (RMON_T_OCTETS)
+#define FREESCALE_ENET_REG_RMON_T_OCTETS 0x244
+// Count of frames not counted correctly (IEEE_T_DROP).
+// NOTE: Counter not implemented (read 0 always) as not applicable.
+#define FREESCALE_ENET_REG_IEEE_T_DROP 0x248
+// Frames Transmitted OK (IEEE_T_FRAME_OK)
+#define FREESCALE_ENET_REG_IEEE_T_FRAME_OK 0x24C
+// Frames Transmitted with Single Collision (IEEE_T_1COL)
+#define FREESCALE_ENET_REG_IEEE_T_1COL 0x250
+// Frames Transmitted with Multiple Collisions (IEEE_T_MCOL)
+#define FREESCALE_ENET_REG_IEEE_T_MCOL 0x254
+// Frames Transmitted after Deferral Delay (IEEE_T_DEF)
+#define FREESCALE_ENET_REG_IEEE_T_DEF 0x258
+// Frames Transmitted with Late Collision (IEEE_T_LCOL)
+#define FREESCALE_ENET_REG_IEEE_T_LCOL 0x25C
+// Frames Transmitted with Excessive Collisions (IEEE_T_EXCOL)
+#define FREESCALE_ENET_REG_IEEE_T_EXCOL 0x260
+// Frames Transmitted with Tx FIFO Underrun (IEEE_T_MACERR)
+#define FREESCALE_ENET_REG_IEEE_T_MACERR 0x264
+// Frames Transmitted with Carrier Sense Error (IEEE_T_CSERR)
+#define FREESCALE_ENET_REG_IEEE_T_CSERR 0x268
+// Frames Transmitted with SQE Error (IEEE_T_SQE).
+// NOTE: Counter not implemented (read 0 always)
+// as no SQE information is available.
+#define FREESCALE_ENET_REG_IEEE_T_SQE 0x26C
+// Flow Control Pause frames transmitted (IEEE_T_FDXFC)
+#define FREESCALE_ENET_REG_IEEE_T_FDXFC 0x270
+// Octet count for Frames Transmitted w/o Error (IEEE_T_OCTETS_OK).
+// NOTE: Counts total octets (includes header and FCS fields).
+#define FREESCALE_ENET_REG_IEEE_T_OCTETS_OK 0x274
+// RMON Rx packet count (RMON_R_PACKETS)
+#define FREESCALE_ENET_REG_RMON_R_PACKETS 0x284
+// RMON Rx Broadcast Packets (RMON_R_BC_PKT)
+#define FREESCALE_ENET_REG_RMON_R_BC_PKT 0x288
+// RMON Rx Multicast Packets (RMON_R_MC_PKT)
+#define FREESCALE_ENET_REG_RMON_R_MC_PKT 0x28C
+// RMON Rx Packets w CRC/Align error (RMON_R_CRC_ALIGN)
+#define FREESCALE_ENET_REG_RMON_R_CRC_ALIGN 0x290
+// RMON Rx Packets < 64 bytes
+#define FREESCALE_ENET_REG_RMON_R_UNDERSIZE 0x294
+// RMON Rx Packets > MAX_FL bytes
+#define FREESCALE_ENET_REG_RMON_R_OVERSIZE 0x298
+// RMON Rx Packets < 64 bytes
+#define FREESCALE_ENET_REG_RMON_R_FRAG 0x29C
+// RMON Rx Packets > MAX_FL bytes
+#define FREESCALE_ENET_REG_RMON_R_JAB 0x2A0
+// Reserved (RMON_R_RESVD_0)
+#define FREESCALE_ENET_REG_RMON_R_RESVD_0 0x2A4
+// RMON Rx 64 byte packets (RMON_R_P64)
+#define FREESCALE_ENET_REG_RMON_R_P64 0x2A8
+// RMON Rx 65 to 127 byte packets (RMON_R_P65TO127)
+#define FREESCALE_ENET_REG_RMON_R_P65TO127 0x2AC
+// RMON Rx 128 to 255 byte packets (RMON_R_P128TO255)
+#define FREESCALE_ENET_REG_RMON_R_P128TO255 0x2B0
+// RMON Rx 256 to 511 byte packets (RMON_R_P256TO511)
+#define FREESCALE_ENET_REG_RMON_R_P256TO511 0x2B4
+// RMON Rx 512 to 1023 byte packets (RMON_R_P512TO1023)
+#define FREESCALE_ENET_REG_RMON_R_P512TO1023 0x2B8
+// RMON Rx 1024 to 2047 byte packets (RMON_R_P1024TO2047)
+#define FREESCALE_ENET_REG_RMON_R_P1024TO2047 0x2BC
+// RMON Rx packets w > 2048 bytes (RMON_R_P_GTE2048)
+#define FREESCALE_ENET_REG_RMON_R_P_GTE2048 0x2C0
+// RMON Rx Octets (RMON_R_OCTETS)
+#define FREESCALE_ENET_REG_RMON_R_OCTETS 0x2C4
+// Count of frames not counted correctly (IEEE_R_DROP).
+// NOTE: Counter increments if a frame with valid/
+// missing SFD character is detected and has been dropped.
+// None of the other counters increments if
+// this counter increments.
+#define FREESCALE_ENET_REG_RMON_R_DROP 0x2C8
+// Frames Received OK (IEEE_R_FRAME_OK)
+#define FREESCALE_ENET_REG_RMON_R_FRAME_OK 0x2CC
+// Frames Received with CRC Error (IEEE_R_CRC)
+#define FREESCALE_ENET_REG_IEEE_R_CRC 0x2D0
+// Frames Received with Alignment Error (IEEE_R_ALIGN)
+#define FREESCALE_ENET_REG_IEEE_R_ALIGN 0x2D4
+// Receive Fifo Overflow count (IEEE_R_MACERR)
+#define FREESCALE_ENET_REG_IEEE_R_MACERR 0x2D8
+// Flow Control Pause frames received (IEEE_R_FDXFC)
+#define FREESCALE_ENET_REG_IEEE_R_FDXFC 0x2DC
+// Octet count for Frames Rcvd w/o Error (IEEE_R_OCTETS_OK).
+// Counts total octets (includes header and FCS fields).
+#define FREESCALE_ENET_REG_IEEE_R_OCTETS_OK 0x2E0
+// Timer Control Register
+#define FREESCALE_ENET_REG_ATCR 0x400
+// Timer Value Register
+#define FREESCALE_ENET_REG_ATVR 0x404
+// Timer Offset Register
+#define FREESCALE_ENET_REG_ATOFF 0x408
+// Timer Period Register
+#define FREESCALE_ENET_REG_ATPER 0x40C
+// Timer Correction Register
+#define FREESCALE_ENET_REG_ATCOR 0x410
+// Time-Stamping Clock Period Register
+#define FREESCALE_ENET_REG_ATINC 0x414
+// Timestamp of Last Transmitted Frame
+#define FREESCALE_ENET_REG_ATSTMP 0x418
+// Timer Global Status Register
+#define FREESCALE_ENET_REG_TGSR 0x604
+
+// IEEE 1588 Timers
+// Timer 0 Control Status Register
+#define FREESCALE_ENET_REG_TCSR0 0x608
+// Timer 0Control Capture Register
+#define FREESCALE_ENET_REG_TCCR0 0x60c
+// Timer 1 Control Status Register
+#define FREESCALE_ENET_REG_TCSR1 0x610
+// Timer 1 Control Capture Register
+#define FREESCALE_ENET_REG_TCCR1 0x614
+// Timer 2 Control Status Register
+#define FREESCALE_ENET_REG_TCSR2 0x618
+// Timer 2 Control Capture Register
+#define FREESCALE_ENET_REG_TCCR2 0x61C
+// Timer 3 Control Status Register
+#define FREESCALE_ENET_REG_TCSR3 0x620
+// Timer 3 Control Capture Register
+#define FREESCALE_ENET_REG_TCCR3 0x624
+
+
+
+// ----------------------------------------------------------------------------
+// ENET Register Masks
+
+// EIR Bit Fields
+#define FREESCALE_ENET_EIR_TS_TIMER_M 0x8000
+#define FREESCALE_ENET_EIR_TS_TIMER_S 15
+#define FREESCALE_ENET_EIR_TS_AVAIL_M 0x10000
+#define FREESCALE_ENET_EIR_TS_AVAIL_S 16
+#define FREESCALE_ENET_EIR_WAKEUP_M 0x20000
+#define FREESCALE_ENET_EIR_WAKEUP_S 17
+#define FREESCALE_ENET_EIR_PLR_M 0x40000
+#define FREESCALE_ENET_EIR_PLR_S 18
+#define FREESCALE_ENET_EIR_UN_M 0x80000
+#define FREESCALE_ENET_EIR_UN_S 19
+#define FREESCALE_ENET_EIR_RL_M 0x100000
+#define FREESCALE_ENET_EIR_RL_S 20
+#define FREESCALE_ENET_EIR_LC_M 0x200000
+#define FREESCALE_ENET_EIR_LC_S 21
+#define FREESCALE_ENET_EIR_EBERR_M 0x400000
+#define FREESCALE_ENET_EIR_EBERR_S 22
+#define FREESCALE_ENET_EIR_MII_M 0x800000
+#define FREESCALE_ENET_EIR_MII_S 23
+#define FREESCALE_ENET_EIR_RXB_M 0x1000000
+#define FREESCALE_ENET_EIR_RXB_S 24
+#define FREESCALE_ENET_EIR_RXF_M 0x2000000
+#define FREESCALE_ENET_EIR_RXF_S 25
+#define FREESCALE_ENET_EIR_TXB_M 0x4000000
+#define FREESCALE_ENET_EIR_TXB_S 26
+#define FREESCALE_ENET_EIR_TXF_M 0x8000000
+#define FREESCALE_ENET_EIR_TXF_S 27
+#define FREESCALE_ENET_EIR_GRA_M 0x10000000
+#define FREESCALE_ENET_EIR_GRA_S 28
+#define FREESCALE_ENET_EIR_BABT_M 0x20000000
+#define FREESCALE_ENET_EIR_BABT_S 29
+#define FREESCALE_ENET_EIR_BABR_M 0x40000000
+#define FREESCALE_ENET_EIR_BABR_S 30
+// EIMR Bit Fields
+#define FREESCALE_ENET_EIMR_TS_TIMER_M 0x8000
+#define FREESCALE_ENET_EIMR_TS_TIMER_S 15
+#define FREESCALE_ENET_EIMR_TS_AVAIL_M 0x10000
+#define FREESCALE_ENET_EIMR_TS_AVAIL_S 16
+#define FREESCALE_ENET_EIMR_WAKEUP_M 0x20000
+#define FREESCALE_ENET_EIMR_WAKEUP_S 17
+#define FREESCALE_ENET_EIMR_PLR_M 0x40000
+#define FREESCALE_ENET_EIMR_PLR_S 18
+#define FREESCALE_ENET_EIMR_UN_M 0x80000
+#define FREESCALE_ENET_EIMR_UN_S 19
+#define FREESCALE_ENET_EIMR_RL_M 0x100000
+#define FREESCALE_ENET_EIMR_RL_S 20
+#define FREESCALE_ENET_EIMR_LC_M 0x200000
+#define FREESCALE_ENET_EIMR_LC_S 21
+#define FREESCALE_ENET_EIMR_EBERR_M 0x400000
+#define FREESCALE_ENET_EIMR_EBERR_S 22
+#define FREESCALE_ENET_EIMR_MII_M 0x800000
+#define FREESCALE_ENET_EIMR_MII_S 23
+#define FREESCALE_ENET_EIMR_RXB_M 0x1000000
+#define FREESCALE_ENET_EIMR_RXB_S 24
+#define FREESCALE_ENET_EIMR_RXF_M 0x2000000
+#define FREESCALE_ENET_EIMR_RXF_S 25
+#define FREESCALE_ENET_EIMR_TXB_M 0x4000000
+#define FREESCALE_ENET_EIMR_TXB_S 26
+#define FREESCALE_ENET_EIMR_TXF_M 0x8000000
+#define FREESCALE_ENET_EIMR_TXF_S 27
+#define FREESCALE_ENET_EIMR_GRA_M 0x10000000
+#define FREESCALE_ENET_EIMR_GRA_S 28
+#define FREESCALE_ENET_EIMR_BABT_M 0x20000000
+#define FREESCALE_ENET_EIMR_BABT_S 29
+#define FREESCALE_ENET_EIMR_BABR_M 0x40000000
+#define FREESCALE_ENET_EIMR_BABR_S 30
+// RDAR Bit Fields
+#define FREESCALE_ENET_RDAR_RDAR_M 0x1000000
+#define FREESCALE_ENET_RDAR_RDAR_S 24
+// TDAR Bit Fields
+#define FREESCALE_ENET_TDAR_TDAR_M 0x1000000
+#define FREESCALE_ENET_TDAR_TDAR_S 24
+// ECR Bit Fields
+#define FREESCALE_ENET_ECR_RESET_M 0x1
+#define FREESCALE_ENET_ECR_RESET_S 0
+#define FREESCALE_ENET_ECR_ETHEREN_M 0x2
+#define FREESCALE_ENET_ECR_ETHEREN_S 1
+#define FREESCALE_ENET_ECR_MAGICEN_M 0x4
+#define FREESCALE_ENET_ECR_MAGICEN_S 2
+#define FREESCALE_ENET_ECR_SLEEP_M 0x8
+#define FREESCALE_ENET_ECR_SLEEP_S 3
+#define FREESCALE_ENET_ECR_EN1588_M 0x10
+#define FREESCALE_ENET_ECR_EN1588_S 4
+#define FREESCALE_ENET_ECR_DBGEN_M 0x40
+#define FREESCALE_ENET_ECR_DBGEN_S 6
+#define FREESCALE_ENET_ECR_STOPEN_M 0x80
+#define FREESCALE_ENET_ECR_STOPEN_S 7
+// MMFR Bit Fields
+#define FREESCALE_ENET_MMFR_DATA_M 0xFFFF
+#define FREESCALE_ENET_MMFR_DATA_S 0
+#define FREESCALE_ENET_MMFR_DATA(__val) \
+ VALUE_(FREESCALE_ENET_MMFR_DATA_S, __val)
+#define FREESCALE_ENET_MMFR_TA_M 0x30000
+#define FREESCALE_ENET_MMFR_TA_S 16
+#define FREESCALE_ENET_MMFR_TA(__val) \
+ VALUE_(FREESCALE_ENET_MMFR_TA_S, __val)
+#define FREESCALE_ENET_MMFR_RA_M 0x7C0000
+#define FREESCALE_ENET_MMFR_RA_S 18
+#define FREESCALE_ENET_MMFR_RA(__val) \
+ VALUE_(FREESCALE_ENET_MMFR_RA_S, __val)
+#define FREESCALE_ENET_MMFR_PA_M 0xF800000
+#define FREESCALE_ENET_MMFR_PA_S 23
+#define FREESCALE_ENET_MMFR_PA(__val) \
+ VALUE_(FREESCALE_ENET_MMFR_PA_S, __val)
+#define FREESCALE_ENET_MMFR_OP_M 0x30000000
+#define FREESCALE_ENET_MMFR_OP_S 28
+#define FREESCALE_ENET_MMFR_OP(__val) \
+ VALUE_(FREESCALE_ENET_MMFR_OP_S, __val)
+#define FREESCALE_ENET_MMFR_ST_M 0xC0000000
+#define FREESCALE_ENET_MMFR_ST_S 30
+#define FREESCALE_ENET_MMFR_ST(__val) \
+ VALUE_(FREESCALE_ENET_MMFR_ST_S, __val)
+// MSCR Bit Fields
+#define FREESCALE_ENET_MSCR_MII_SPEED_M 0x7E
+#define FREESCALE_ENET_MSCR_MII_SPEED_S 1
+#define FREESCALE_ENET_MSCR_MII_SPEED(__val) \
+ VALUE_(FREESCALE_ENET_MSCR_MII_SPEED_S, __val)
+#define FREESCALE_ENET_MSCR_DIS_PRE_M 0x80
+#define FREESCALE_ENET_MSCR_DIS_PRE_S 7
+#define FREESCALE_ENET_MSCR_HOLDTIME_M 0x700
+#define FREESCALE_ENET_MSCR_HOLDTIME_S 8
+#define FREESCALE_ENET_MSCR_HOLDTIME(__val) \
+ VALUE_(FREESCALE_ENET_MSCR_HOLDTIME_S, __val)
+// MIBC Bit Fields
+#define FREESCALE_ENET_MIBC_MIB_CLEAR_M 0x20000000
+#define FREESCALE_ENET_MIBC_MIB_CLEAR_S 29
+#define FREESCALE_ENET_MIBC_MIB_IDLE_M 0x40000000
+#define FREESCALE_ENET_MIBC_MIB_IDLE_S 30
+#define FREESCALE_ENET_MIBC_MIB_DIS_M 0x80000000
+#define FREESCALE_ENET_MIBC_MIB_DIS_S 31
+// RCR Bit Fields
+#define FREESCALE_ENET_RCR_LOOP_M 0x1
+#define FREESCALE_ENET_RCR_LOOP_S 0
+#define FREESCALE_ENET_RCR_DRT_M 0x2
+#define FREESCALE_ENET_RCR_DRT_S 1
+#define FREESCALE_ENET_RCR_MII_MODE_M 0x4
+#define FREESCALE_ENET_RCR_MII_MODE_S 2
+#define FREESCALE_ENET_RCR_PROM_M 0x8
+#define FREESCALE_ENET_RCR_PROM_S 3
+#define FREESCALE_ENET_RCR_BC_REJ_M 0x10
+#define FREESCALE_ENET_RCR_BC_REJ_S 4
+#define FREESCALE_ENET_RCR_FCE_M 0x20
+#define FREESCALE_ENET_RCR_FCE_S 5
+#define FREESCALE_ENET_RCR_RMII_MODE_M 0x100
+#define FREESCALE_ENET_RCR_RMII_MODE_S 8
+#define FREESCALE_ENET_RCR_RMII_10T_M 0x200
+#define FREESCALE_ENET_RCR_RMII_10T_S 9
+#define FREESCALE_ENET_RCR_PADEN_M 0x1000
+#define FREESCALE_ENET_RCR_PADEN_S 12
+#define FREESCALE_ENET_RCR_PAUFWD_M 0x2000
+#define FREESCALE_ENET_RCR_PAUFWD_S 13
+#define FREESCALE_ENET_RCR_CRCFWD_M 0x4000
+#define FREESCALE_ENET_RCR_CRCFWD_S 14
+#define FREESCALE_ENET_RCR_CFEN_M 0x8000
+#define FREESCALE_ENET_RCR_CFEN_S 15
+#define FREESCALE_ENET_RCR_MAX_FL_M 0x3FFF0000
+#define FREESCALE_ENET_RCR_MAX_FL_S 16
+#define FREESCALE_ENET_RCR_MAX_FL(__val) \
+ VALUE_(FREESCALE_ENET_RCR_MAX_FL_S, __val)
+#define FREESCALE_ENET_RCR_NLC_M 0x40000000
+#define FREESCALE_ENET_RCR_NLC_S 30
+#define FREESCALE_ENET_RCR_GRS_M 0x80000000
+#define FREESCALE_ENET_RCR_GRS_S 31
+// TCR Bit Fields
+#define FREESCALE_ENET_TCR_GTS_M 0x1
+#define FREESCALE_ENET_TCR_GTS_S 0
+#define FREESCALE_ENET_TCR_FDEN_M 0x4
+#define FREESCALE_ENET_TCR_FDEN_S 2
+#define FREESCALE_ENET_TCR_TFC_PAUSE_M 0x8
+#define FREESCALE_ENET_TCR_TFC_PAUSE_S 3
+#define FREESCALE_ENET_TCR_RFC_PAUSE_M 0x10
+#define FREESCALE_ENET_TCR_RFC_PAUSE_S 4
+#define FREESCALE_ENET_TCR_ADDSEL_M 0xE0
+#define FREESCALE_ENET_TCR_ADDSEL_S 5
+#define FREESCALE_ENET_TCR_ADDSEL(__val) \
+ VALUE_(FREESCALE_ENET_TCR_ADDSEL_S, __val)
+#define FREESCALE_ENET_TCR_ADDINS_M 0x100
+#define FREESCALE_ENET_TCR_ADDINS_S 8
+#define FREESCALE_ENET_TCR_CRCFWD_M 0x200
+#define FREESCALE_ENET_TCR_CRCFWD_S 9
+// PALR Bit Fields
+#define FREESCALE_ENET_PALR_PADDR1_M 0xFFFFFFFF
+#define FREESCALE_ENET_PALR_PADDR1_S 0
+#define FREESCALE_ENET_PALR_PADDR1(__val) \
+ VALUE_(FREESCALE_ENET_PALR_PADDR1_S, __val)
+// PAUR Bit Fields
+#define FREESCALE_ENET_PAUR_TYPE_M 0xFFFF
+#define FREESCALE_ENET_PAUR_TYPE_S 0
+#define FREESCALE_ENET_PAUR_TYPE(__val) \
+ VALUE_(FREESCALE_ENET_PAUR_TYPE_S, __val)
+#define FREESCALE_ENET_PAUR_PADDR2_M 0xFFFF0000
+#define FREESCALE_ENET_PAUR_PADDR2_S 16
+#define FREESCALE_ENET_PAUR_PADDR2(__val) \
+ VALUE_(FREESCALE_ENET_PAUR_PADDR2_S, __val)
+// OPD Bit Fields
+#define FREESCALE_ENET_OPD_PAUSE_DUR_M 0xFFFF
+#define FREESCALE_ENET_OPD_PAUSE_DUR_S 0
+#define FREESCALE_ENET_OPD_PAUSE_DUR(__val) \
+ VALUE_(FREESCALE_ENET_OPD_PAUSE_DUR_S, __val)
+#define FREESCALE_ENET_OPD_OPCODE_M 0xFFFF0000
+#define FREESCALE_ENET_OPD_OPCODE_S 16
+#define FREESCALE_ENET_OPD_OPCODE(__val) \
+ VALUE_(FREESCALE_ENET_OPD_OPCODE_S, __val)
+// IAUR Bit Fields
+#define FREESCALE_ENET_IAUR_IADDR1_M 0xFFFFFFFF
+#define FREESCALE_ENET_IAUR_IADDR1_S 0
+#define FREESCALE_ENET_IAUR_IADDR1(__val) \
+ VALUE_(FREESCALE_ENET_IAUR_IADDR1_S, __val)
+// IALR Bit Fields
+#define FREESCALE_ENET_IALR_IADDR2_M 0xFFFFFFFF
+#define FREESCALE_ENET_IALR_IADDR2_S 0
+#define FREESCALE_ENET_IALR_IADDR2(__val) \
+ VALUE_(FREESCALE_ENET_IALR_IADDR2_S, __val)
+// GAUR Bit Fields
+#define FREESCALE_ENET_GAUR_GADDR1_M 0xFFFFFFFF
+#define FREESCALE_ENET_GAUR_GADDR1_S 0
+#define FREESCALE_ENET_GAUR_GADDR1(__val) \
+ VALUE_(FREESCALE_ENET_GAUR_GADDR1_S, __val)
+// GALR Bit Fields
+#define FREESCALE_ENET_GALR_GADDR2_M 0xFFFFFFFF
+#define FREESCALE_ENET_GALR_GADDR2_S 0
+#define FREESCALE_ENET_GALR_GADDR2(__val) \
+ VALUE_(FREESCALE_ENET_GALR_GADDR2_S, __val)
+// TFWR Bit Fields
+#define FREESCALE_ENET_TFWR_TFWR_M 0x3F
+#define FREESCALE_ENET_TFWR_TFWR_S 0
+#define FREESCALE_ENET_TFWR_TFWR(__val) \
+ VALUE_(FREESCALE_ENET_TFWR_TFWR_S, __val)
+#define FREESCALE_ENET_TFWR_STRFWD_M 0x100
+#define FREESCALE_ENET_TFWR_STRFWD_S 8
+
+#define FREESCALE_ENET_TFWR_TFWR_64 0x0
+#define FREESCALE_ENET_TFWR_TFWR_64A 0x1
+#define FREESCALE_ENET_TFWR_TFWR_128 0x2
+#define FREESCALE_ENET_TFWR_TFWR_192 0x3
+#define FREESCALE_ENET_TFWR_TFWR_4032 0x3F
+// RDSR Bit Fields
+#define FREESCALE_ENET_RDSR_R_DES_START_M 0xFFFFFFF8
+#define FREESCALE_ENET_RDSR_R_DES_START_S 3
+#define FREESCALE_ENET_RDSR_R_DES_START(__val) \
+ VALUE_(FREESCALE_ENET_RDSR_R_DES_S, __val)
+// TDSR Bit Fields
+#define FREESCALE_ENET_TDSR_X_DES_START_M 0xFFFFFFF8
+#define FREESCALE_ENET_TDSR_X_DES_START_S 3
+#define FREESCALE_ENET_TDSR_X_DES_START(__val) \
+ VALUE_(FREESCALE_ENET_TDSR_X_DES_S, __val)
+// MRBR Bit Fields
+#define FREESCALE_ENET_MRBR_R_BUF_SIZE_M 0x3FF0
+#define FREESCALE_ENET_MRBR_R_BUF_SIZE_S 4
+#define FREESCALE_ENET_MRBR_R_BUF_SIZE(__val) \
+ VALUE_(FREESCALE_ENET_MRBR_R_BUF_S, __val)
+// RSFL Bit Fields
+#define FREESCALE_ENET_RSFL_RX_SECTION_FULL_M 0xFF
+#define FREESCALE_ENET_RSFL_RX_SECTION_FULL_S 0
+#define FREESCALE_ENET_RSFL_RX_SECTION_FULL(__val) \
+ VALUE_(FREESCALE_ENET_RSFL_RX_S, __val)
+// RSEM Bit Fields
+#define FREESCALE_ENET_RSEM_RX_SECTION_EMPTY_M 0xFF
+#define FREESCALE_ENET_RSEM_RX_SECTION_EMPTY_S 0
+#define FREESCALE_ENET_RSEM_RX_SECTION_EMPTY(__val) \
+ VALUE_(FREESCALE_ENET_RSEM_RX_S, __val)
+// RAEM Bit Fields
+#define FREESCALE_ENET_RAEM_RX_ALMOST_EMPTY_M 0xFF
+#define FREESCALE_ENET_RAEM_RX_ALMOST_EMPTY_S 0
+#define FREESCALE_ENET_RAEM_RX_ALMOST_EMPTY(__val) \
+ VALUE_(FREESCALE_ENET_RAEM_RX_ALMOST_EMPTY_S, __val)
+// RAFL Bit Fields
+#define FREESCALE_ENET_RAFL_RX_ALMOST_FULL_M 0xFF
+#define FREESCALE_ENET_RAFL_RX_ALMOST_FULL_S 0
+#define FREESCALE_ENET_RAFL_RX_ALMOST_FULL(__val) \
+ VALUE_(FREESCALE_ENET_RAFL_RX_ALMOST_FULL_S, __val)
+// TSEM Bit Fields
+#define FREESCALE_ENET_TSEM_TX_SECTION_EMPTY_M 0xFF
+#define FREESCALE_ENET_TSEM_TX_SECTION_EMPTY_S 0
+#define FREESCALE_ENET_TSEM_TX_SECTION_EMPTY(__val) \
+ VALUE_(FREESCALE_ENET_TSEM_TX_S, __val)
+// TAEM Bit Fields
+#define FREESCALE_ENET_TAEM_TX_ALMOST_EMPTY_M 0xFF
+#define FREESCALE_ENET_TAEM_TX_ALMOST_EMPTY_S 0
+#define FREESCALE_ENET_TAEM_TX_ALMOST_EMPTY(__val) \
+ VALUE_(FREESCALE_ENET_TAEM_TX_ALMOST_EMPTY_S, __val)
+// TAFL Bit Fields
+#define FREESCALE_ENET_TAFL_TX_ALMOST_FULL_M 0xFF
+#define FREESCALE_ENET_TAFL_TX_ALMOST_FULL_S 0
+#define FREESCALE_ENET_TAFL_TX_ALMOST_FULL(__val) \
+ VALUE_(FREESCALE_ENET_TAFL_TX_ALMOST_FULL_S, __val)
+// TIPG Bit Fields
+#define FREESCALE_ENET_TIPG_IPG_M 0x1F
+#define FREESCALE_ENET_TIPG_IPG_S 0
+#define FREESCALE_ENET_TIPG_IPG(__val) \
+ VALUE_(FREESCALE_ENET_TIPG_IPG_S, __val)
+// FTRL Bit Fields
+#define FREESCALE_ENET_FTRL_TRUNC_FL_M 0x3FFF
+#define FREESCALE_ENET_FTRL_TRUNC_FL_S 0
+#define FREESCALE_ENET_FTRL_TRUNC_FL(__val) \
+ VALUE_(FREESCALE_ENET_FTRL_TRUNC_FL_S, __val)
+// TACC Bit Fields
+#define FREESCALE_ENET_TACC_S16_M 0x1
+#define FREESCALE_ENET_TACC_S16_S 0
+#define FREESCALE_ENET_TACC_IPCHK_M 0x8
+#define FREESCALE_ENET_TACC_IPCHK_S 3
+#define FREESCALE_ENET_TACC_PROCHK_M 0x10
+#define FREESCALE_ENET_TACC_PROCHK_S 4
+// RACC Bit Fields
+#define FREESCALE_ENET_RACC_PADREM_M 0x1
+#define FREESCALE_ENET_RACC_PADREM_S 0
+#define FREESCALE_ENET_RACC_IPDIS_M 0x2
+#define FREESCALE_ENET_RACC_IPDIS_S 1
+#define FREESCALE_ENET_RACC_PRODIS_M 0x4
+#define FREESCALE_ENET_RACC_PRODIS_S 2
+#define FREESCALE_ENET_RACC_LINEDIS_M 0x40
+#define FREESCALE_ENET_RACC_LINEDIS_S 6
+#define FREESCALE_ENET_RACC_S16_M 0x80
+#define FREESCALE_ENET_RACC_S16_S 7
+// ATCR Bit Fields
+#define FREESCALE_ENET_ATCR_EN_M 0x1
+#define FREESCALE_ENET_ATCR_EN_S 0
+#define FREESCALE_ENET_ATCR_OFFEN_M 0x4
+#define FREESCALE_ENET_ATCR_OFFEN_S 2
+#define FREESCALE_ENET_ATCR_OFFRST_M 0x8
+#define FREESCALE_ENET_ATCR_OFFRST_S 3
+#define FREESCALE_ENET_ATCR_PEREN_M 0x10
+#define FREESCALE_ENET_ATCR_PEREN_S 4
+#define FREESCALE_ENET_ATCR_PINPER_M 0x80
+#define FREESCALE_ENET_ATCR_PINPER_S 7
+#define FREESCALE_ENET_ATCR_RESTART_M 0x200
+#define FREESCALE_ENET_ATCR_RESTART_S 9
+#define FREESCALE_ENET_ATCR_CAPTURE_M 0x800
+#define FREESCALE_ENET_ATCR_CAPTURE_S 11
+#define FREESCALE_ENET_ATCR_SLAVE_M 0x2000
+#define FREESCALE_ENET_ATCR_SLAVE_S 13
+// ATVR Bit Fields
+#define FREESCALE_ENET_ATVR_ATIME_M 0xFFFFFFFF
+#define FREESCALE_ENET_ATVR_ATIME_S 0
+#define FREESCALE_ENET_ATVR_ATIME(__val) \
+ VALUE_(FREESCALE_ENET_ATVR_ATIME_S, __val)
+// ATOFF Bit Fields
+#define FREESCALE_ENET_ATOFF_OFFSET_M 0xFFFFFFFF
+#define FREESCALE_ENET_ATOFF_OFFSET_S 0
+#define FREESCALE_ENET_ATOFF_OFFSET(__val) \
+ VALUE_(FREESCALE_ENET_ATOFF_OFFSET_S, __val)
+// ATPER Bit Fields
+#define FREESCALE_ENET_ATPER_PERIOD_M 0xFFFFFFFF
+#define FREESCALE_ENET_ATPER_PERIOD_S 0
+#define FREESCALE_ENET_ATPER_PERIOD(__val) \
+ VALUE_(FREESCALE_ENET_ATPER_PERIOD_S, __val)
+// ATCOR Bit Fields
+#define FREESCALE_ENET_ATCOR_COR_M 0x7FFFFFFF
+#define FREESCALE_ENET_ATCOR_COR_S 0
+#define FREESCALE_ENET_ATCOR_COR(__val) \
+ VALUE_(FREESCALE_ENET_ATCOR_COR_S, __val)
+// ATINC Bit Fields
+#define FREESCALE_ENET_ATINC_INC_M 0x7F
+#define FREESCALE_ENET_ATINC_INC_S 0
+#define FREESCALE_ENET_ATINC_INC(__val) \
+ VALUE_(FREESCALE_ENET_ATINC_INC_S, __val)
+#define FREESCALE_ENET_ATINC_INC_CORR_M 0x7F00
+#define FREESCALE_ENET_ATINC_INC_CORR_S 8
+#define FREESCALE_ENET_ATINC_INC_CORR(__val) \
+ VALUE_(FREESCALE_ENET_ATINC_INC_CORR_S, __val)
+// ATSTMP Bit Fields
+#define FREESCALE_ENET_ATSTMP_TIMESTAMP_M 0xFFFFFFFF
+#define FREESCALE_ENET_ATSTMP_TIMESTAMP_S 0
+#define FREESCALE_ENET_ATSTMP_TIMESTAMP(__val) \
+ VALUE_(FREESCALE_ENET_ATSTMP_TIMESTAMP_S, __val)
+// TGSR Bit Fields
+#define FREESCALE_ENET_TGSR_TF0_M 0x1
+#define FREESCALE_ENET_TGSR_TF0_S 0
+#define FREESCALE_ENET_TGSR_TF1_M 0x2
+#define FREESCALE_ENET_TGSR_TF1_S 1
+#define FREESCALE_ENET_TGSR_TF2_M 0x4
+#define FREESCALE_ENET_TGSR_TF2_S 2
+#define FREESCALE_ENET_TGSR_TF3_M 0x8
+#define FREESCALE_ENET_TGSR_TF3_S 3
+// TCSR Bit Fields
+#define FREESCALE_ENET_TCSR_TDRE_M 0x1
+#define FREESCALE_ENET_TCSR_TDRE_S 0
+#define FREESCALE_ENET_TCSR_TMODE_M 0x3C
+#define FREESCALE_ENET_TCSR_TMODE_S 2
+#define FREESCALE_ENET_TCSR_TMODE(__val) \
+ VALUE_(FREESCALE_ENET_TCSR_TMODE_S, __val)
+#define FREESCALE_ENET_TCSR_TIE_M 0x40
+#define FREESCALE_ENET_TCSR_TIE_S 6
+#define FREESCALE_ENET_TCSR_TF_M 0x80
+#define FREESCALE_ENET_TCSR_TF_S 7
+// TCCR Bit Fields
+#define FREESCALE_ENET_TCCR_TCC_M 0xFFFFFFFF
+#define FREESCALE_ENET_TCCR_TCC_S 0
+#define FREESCALE_ENET_TCCR_TCC(__val) \
+ VALUE_(FREESCALE_ENET_TCCR_TCC_S, __val)
+
+#define FREESCALE_ENET_EIR_ERROR \
+ (FREESCALE_ENET_EIR_PLR_M | \
+ FREESCALE_ENET_EIR_UN_M | \
+ FREESCALE_ENET_EIR_RL_M | \
+ FREESCALE_ENET_EIR_LC_M | \
+ FREESCALE_ENET_EIR_EBERR_M | \
+ FREESCALE_ENET_EIR_BABT_M | \
+ FREESCALE_ENET_EIR_BABR_M)
+
+// EOF if_freescale_enet_io.h
+#endif // CYGONCE_IF_FREESCALE_ENET_IO_H
diff --git a/ecos/packages/devs/eth/freescale/enet/current/src/if_freescale_enet.c b/ecos/packages/devs/eth/freescale/enet/current/src/if_freescale_enet.c
new file mode 100644
index 0000000..ac11678
--- /dev/null
+++ b/ecos/packages/devs/eth/freescale/enet/current/src/if_freescale_enet.c
@@ -0,0 +1,1616 @@
+//==========================================================================
+//
+// if_freescale_enet.c
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Kocho <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2011-06-04
+// Description: Hardware driver for Freescale ENET peripheral
+//
+// This driver was originally written for Kinetis and may
+// require some modifications to work on other Freescale
+// families such as ColdFire+.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_eth_freescale_enet.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#if defined(CYGPKG_REDBOOT)
+# include <pkgconf/redboot.h>
+#endif
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/eth_drv_stats.h>
+#include <cyg/io/eth_phy.h>
+#include <errno.h>
+#include <string.h>
+
+#ifdef CYGPKG_NET
+# include <pkgconf/net.h>
+# include <net/if.h> //Needed for struct ifnet
+#endif
+
+#include <cyg/hal/hal_endian.h>
+#include <cyg/io/eth/if_freescale_enet_bd.h>
+#include <cyg/io/eth/if_freescale_enet_io.h>
+
+#if defined CYGHWR_HAL_ENET_TCD_SECTION || defined CYGHWR_HAL_ENET_BUF_SECTION
+# include <cyg/infra/cyg_type.h>
+#endif
+// Some debugging helpers ---------------------------------------------------
+
+#define DEBUG_ENET CYGPKG_DEVS_ETH_FREESCALE_ENET_DEBUG_LEVEL
+
+#if DEBUG_ENET >= 3
+# define debug3_printf(args...) diag_printf(args)
+#else
+# define debug3_printf(args...)
+#endif
+
+#if DEBUG_ENET >= 2
+# define debug2_printf(args...) diag_printf(args)
+#else
+# define debug2_printf(args...)
+#endif
+
+#if DEBUG_ENET >= 1
+# define debug1_printf(args...) diag_printf(args)
+#else
+# define debug1_printf(args...)
+#endif
+
+
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+#define enet_eth_send enet_eth_send_nocopy
+#define enet_eth_deliver enet_eth_deliver_nocopy
+#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+#define enet_eth_send enet_eth_send_copying
+#define enet_eth_deliver enet_eth_deliver_copying
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+
+// Some delay macros ------------------------------------------------------
+// Busy waiting delay
+#define ENET_WAIT_US(__us) HAL_DELAY_US(__us)
+// Delays / Timeouts
+#define FREESCALE_ENET_RESET_DELAY 1 // Enet reset [us]
+#define FREESCALE_ENET_ENABLE_DELAY 1 // Enet eneble [us]
+
+#define FREESCALE_ENET_PHY_INIT_TOUT 100 // Phy start up [ms]
+#define FREESCALE_ENET_MII_WRITE_TOUT 2000 // Phy write timeout [us]
+#define FREESCALE_ENET_MII_READ_TOUT 2000 // Phy read timeout [us]
+
+#ifndef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+// If kernel is available ENET_ETH_WAIT should be a normal,
+// not a busy-waiting delay.
+# ifdef CYGFUN_KERNEL_API_C
+# define ENET_ETH_WAIT(__tick) cyg_thread_delay(__tick)
+# elif !defined(CYGPKG_KERNEL)
+# define ENET_ETH_WAIT(__ms) HAL_DELAY_US(__ms * 1000)
+# else
+# error Can not define ENET_ETH_WAIT().
+# endif
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+// Resources provided by HAL ==============================================
+// Ethernet RAM and DMA configuration --------------------------------------
+
+// Buffer descriptor memory section
+#ifdef CYGHWR_HAL_ENET_TCD_SECTION
+# define ENET_RAM_TCD_SECTION CYGBLD_ATTRIB_SECTION(CYGHWR_HAL_ENET_TCD_SECTION)
+#else
+# define ENET_RAM_TCD_SECTION
+#endif // CYGHWR_HAL_ENET_TCD_SECTION
+
+// Buffer memory section
+#ifdef CYGHWR_HAL_ENET_BUF_SECTION
+# define ENET_RAM_BUF_SECTION CYGBLD_ATTRIB_SECTION(CYGHWR_HAL_ENET_BUF_SECTION)
+#else
+# define ENET_RAM_BUF_SECTION
+#endif // CYGHWR_HAL_ENET_BUF_SECTION
+
+// IRQ masking --------------------------------------------------------------
+//
+
+#define FREESCALE_ENET_EIR_MASK_M (FREESCALE_ENET_EIR_TXF_M | \
+ FREESCALE_ENET_EIR_TXB_M | FREESCALE_ENET_EIR_RXF_M | \
+ FREESCALE_ENET_EIR_RXB_M)
+
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+# define FREESCALE_ENET_EIMR_MASK_M (FREESCALE_ENET_EIMR_RXF_M | \
+ FREESCALE_ENET_EIMR_TXF_M)
+#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+# define FREESCALE_ENET_EIMR_MASK_M FREESCALE_ENET_EIMR_RXF_M
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+
+// Buffer configuration macros ----------------------------------------------------
+//
+
+#define ENET_RXBD_ALIGN \
+ CYGBLD_ATTRIB_ALIGN(CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBD_ALIGN)
+#define ENET_TXBD_ALIGN \
+ CYGBLD_ATTRIB_ALIGN(CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBD_ALIGN)
+#define ENET_RXBUF_ALIGN \
+ CYGBLD_ATTRIB_ALIGN(CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN)
+#define ENET_TXBUF_ALIGN \
+ CYGBLD_ATTRIB_ALIGN(CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN)
+
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+# define ENET_TXKEY_FLAG ENET_TXBD_TO2
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+
+// ENET statistics ----------------------------------------------------
+//
+
+#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS_DEBUG
+# define ENET_STAT_PRINTF(args...) diag_printf(args)
+#else //CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS_DEBUG
+# define ENET_STAT_PRINTF(args...)
+#endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS_DEBUG
+
+#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS
+typedef struct freescale_enet_stats_s {
+ cyg_uint32 TR; // Truncated
+ cyg_uint32 CR; // CRC or frame error
+ cyg_uint32 OV; // Overrun
+ cyg_uint32 LG; // Frame length violation
+ cyg_uint32 NO; // Non octet aligned frame
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ cyg_uint32 ME; // MAC error
+ cyg_uint32 CE; // Receive CRC error
+ cyg_uint32 PE; // PHY error
+ cyg_uint32 FRAG; // IPv4 Fragment
+ cyg_uint32 ICE; // IP header chechsum error
+ cyg_uint32 PCR; // Protocol checksum error
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+} freescale_enet_stats_t;
+
+void freescale_enet_stats_init(freescale_enet_stats_t *stats_p) {
+ stats_p->TR = 0;
+ stats_p->CR = 0;
+ stats_p->OV = 0;
+ stats_p->LG = 0;
+ stats_p->NO = 0;
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ stats_p->ME = 0;
+ stats_p->CE = 0;
+ stats_p->PE = 0;
+ stats_p->FRAG = 0;
+ stats_p->ICE = 0;
+ stats_p->PCR = 0;
+#endif //CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+}
+
+# define FREESCALE_ENET_STATS_INIT(__poin) freescale_enet_stats_init(__poin)
+# define FREESCALE_ENET_STAT_COUNT(__poin,__val) (__poin->enet_stats.__val++)
+
+# define FREESCALE_ENET_STAT_DO(__ctrl,__poin,__val) \
+CYG_MACRO_START \
+ if(__ctrl & ENET_RXBD_##__val){ \
+ FREESCALE_ENET_STAT_COUNT(__poin,__val); \
+ ENET_STAT_PRINTF(#__val "(%d) ", __poin->enet_stats.__val); \
+ } \
+CYG_MACRO_END
+
+#else
+
+# define FREESCALE_ENET_STATS_INIT(__poin)
+# define FREESCALE_ENET_STAT_COUNT(_poin,_val)
+# define FREESCALE_ENET_STAT_DO(__ctrl,__poin,__val)
+
+#endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// Decide whether to have redboot config vars for it...
+#if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGPKG_REDBOOT_NETWORKING)
+#include <redboot.h>
+#include <flash_config.h>
+
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa_data,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0);
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_REDBOOT_HOLDS_ESA_ETH0
+#endif // CYGPKG_REDBOOT_NETWORKING && CYGSEM_REDBOOT_FLASH_CONFIG
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_FREESCALE_ENET_REDBOOT_HOLDS_ESA
+#include <cyg/hal/hal_if.h>
+#ifndef CONFIG_ESA
+ #define CONFIG_ESA (6)
+#endif
+
+#define CYGHWR_DEVS_ETH_FREESCALE_ENET_GET_ESA( mac_address, ok ) \
+ CYG_MACRO_START \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa_data", \
+ mac_address, \
+ CONFIG_ESA); \
+ CYG_MACRO_END
+#endif // CYGPKG_DEVS_ETH_FREESCALE_ENET_REDBOOT_HOLDS_ESA
+
+
+// ENET device ===============================================================
+// Freescale ENET driver private data ----------------------------------------
+
+typedef struct freescale_enet_priv_t {
+ CYG_ADDRWORD enet_base; // ENET base address
+ eth_phy_access_t *phy_p; // PHY access
+ cyg_uint16 max_frame_len; // Maximal frame length
+ cyg_uint8 rxbd_num; // Number of Rx buffer descriptors
+ cyg_uint8 txbd_num; // Number of Tx buffer descriptors
+ cyg_uint8 pins_n; // Number of (R)MII pins
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ cyg_uint8 txbd_avail; // Avalable Tx buffer descriptors
+ cyg_uint8 txkey_num; // Number of Tx key entries
+ cyg_uint8 txbd_can_send_min; // Minimal number of avail
+#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ cyg_uint8 res0; // Reserved
+ cyg_uint16 txbuf_size; // Tx buffer size
+ cyg_uint8 *txbuf_p; // Tx buffer pool
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ cyg_uint16 rxbuf_size; // Rx buffer size
+ cyg_uint8 fc_pause; // Flow control pause length
+ cyg_uint8 flags; // Various flags
+ cyg_uint8 *rxbuf_p; // Rx buffer pool
+ enet_bd_t *rxbd_pool_p; // Rx buffer descriptor pool
+ enet_bd_t *txbd_pool_p; // TX buffer descriptor poll
+ enet_bd_t *rxbd_p; // Current Rx BD
+ enet_bd_t *txbd_head_p; // Current Tx BD head
+ enet_bd_t *txbd_tail_p; // Current Tx BD tail
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ cyg_uint32 *txkey_pool_p; // Tx key queue pool
+ cyg_uint32 *txkey_head_p; // Last Txkey entry
+ cyg_uint32 *txkey_tail_p; // Last Txkey released
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ cyg_uint32 clock; // Clock gating
+ const cyg_uint32 *pins_p; // (R)MII pin configuration data
+ cyg_uint8 *enaddr; // Default ethernet (MAC) address
+ cyg_uint32 rx_intr_vector;
+ cyg_uint32 rx_intr_prio;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_interrupt rx_interrupt;
+ cyg_handle_t rx_interrupt_handle;
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ cyg_uint32 tx_intr_vector;
+ cyg_uint32 tx_intr_prio;
+# ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_interrupt tx_interrupt;
+ cyg_handle_t tx_interrupt_handle;
+# endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS
+ freescale_enet_stats_t enet_stats;
+#endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS
+} freescale_enet_priv_t;
+
+// Forward declarations ======================================================
+
+static void enet_write_phy(int reg_addr, int phy_addr, unsigned short data);
+static bool enet_read_phy(int reg_addr, int phy_addr, unsigned short *data_p);
+static void enet_init_phy(void);
+static void enet_eth_phy_set(freescale_enet_priv_t *enet_priv_p);
+static bool eth_phy_init_wait(eth_phy_access_t *phy_p, cyg_uint32 ms);
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32 enet_eth_isr(cyg_vector_t vector, cyg_addrword_t data);
+#endif
+
+// Device instances ===========================================================
+//
+
+// ENET0 ======================================================================
+// (R)MII pins - Provided by HAL ----------------------------------------------
+
+static const cyg_uint32 const enet0_pins[] = {
+ // Both RMII and MII interface
+ CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_MDIO,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_MDC,
+#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_PHY_RXER_USE
+ CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_RXER,
+#endif
+ CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_RXD1,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_RXD0,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_TXEN,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_TXD0,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_TXD1,
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_PHY_RMII
+ // RMII interface only
+ CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_CRS_DV
+#else
+ // MII interface only
+ CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_RXD3,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_RXD2,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_RXCLK,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_TXD2,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_TXCLK,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_TXD3,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_CRS,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_MIIO_TXER,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_COL
+#endif
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_1588
+ ,
+ // IEEE 1588 timers
+ CYGHWR_IO_FREESCALE_ENET0_PIN_1588_CLKIN,
+
+ CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR0,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR1,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR2,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR3,
+
+ CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR0,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR1,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR2,
+ CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR3
+#endif
+};
+
+// Buffer and buffer descriptor memory --------------------------------------
+
+// Buffer descriptors
+enet_bd_t enet0_rxbd_pool[CYGNUM_DEVS_ETH_FREESCALE_ENET0_RX_BUFS]
+ENET_RAM_TCD_SECTION ENET_RXBD_ALIGN;
+enet_bd_t enet0_txbd_pool[CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS]
+ ENET_RAM_TCD_SECTION ENET_TXBD_ALIGN;
+
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+// Tx key queue
+cyg_uint32 enet0_txkey_pool[CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS]
+ ENET_RAM_TCD_SECTION;
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+// Buffers
+cyg_uint8 enet0_rxbuf[CYGNUM_DEVS_ETH_FREESCALE_ENET0_RX_BUFS *
+ CYGNUM_DEVS_ETH_FREESCALE_ENET0_RXBUF_SIZE]
+ ENET_RXBUF_ALIGN ENET_RAM_BUF_SECTION;
+#ifndef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+cyg_uint8 enet0_txbuf[CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS *
+ CYGNUM_DEVS_ETH_FREESCALE_ENET0_TXBUF_SIZE]
+ ENET_TXBUF_ALIGN ENET_RAM_BUF_SECTION;
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+# if CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS >= 8
+# define ENET0_TXBD_CAN_SEND_MIN 3
+# elif CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS >= 6
+# define ENET0_TXBD_CAN_SEND_MIN 2
+# else
+# define ENET0_TXBD_CAN_SEND_MIN 1
+# endif
+#endif
+
+// PHY interface entry -----------------------------------------------------
+static cyg_uint8 enet0_macaddr[16] =
+ {CYGPKG_DEVS_ETH_FREESCALE_ENET0_MACADDR};
+
+//
+
+ETH_PHY_REG_LEVEL_ACCESS_FUNS(freescale_enet0_phy,
+ enet_init_phy,
+ NULL,
+ enet_write_phy,
+ enet_read_phy);
+
+// ENET0 device private data -------------------------------------------------
+freescale_enet_priv_t enet0_eth0_priv = {
+ .enet_base = CYGADDR_IO_ETH_FREESCALE_ENET0_BASE,
+ .phy_p = &freescale_enet0_phy,
+ .max_frame_len = CYGNUM_DEVS_ETH_FREESCALE_ENET0_MAX_FRAME_LEN,
+ .rxbd_num = CYGNUM_DEVS_ETH_FREESCALE_ENET0_RX_BUFS,
+ .rxbuf_size = CYGNUM_DEVS_ETH_FREESCALE_ENET0_RXBUF_SIZE,
+ .rxbuf_p = enet0_rxbuf,
+ .txbd_num = CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS,
+ .rxbd_pool_p = enet0_rxbd_pool,
+ .txbd_pool_p = enet0_txbd_pool,
+ .rxbd_p = NULL,
+ .txbd_head_p = NULL,
+ .txbd_tail_p = NULL,
+ .fc_pause = CYGNUM_ETH_FREESCALE_ENET0_OPD_PAUSE_DUR,
+ .flags = CYGSEM_ETH_FREESCALE_ENET0_RCR_FCE,
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ .txbd_avail = CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS,
+ .txkey_pool_p = enet0_txkey_pool,
+ .txkey_num = CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS,
+ .txbd_can_send_min = ENET0_TXBD_CAN_SEND_MIN,
+ .txkey_head_p = NULL,
+ .txkey_tail_p = NULL,
+#else
+ .txbuf_size = CYGNUM_DEVS_ETH_FREESCALE_ENET0_TXBUF_SIZE,
+ .txbuf_p = enet0_txbuf,
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ .clock = CYGHWR_IO_FREESCALE_ENET0_CLOCK,
+ .pins_p = enet0_pins,
+ .pins_n = sizeof(enet0_pins)/sizeof(enet0_pins[0]),
+ .enaddr = enet0_macaddr,
+ .rx_intr_vector = CYGNUM_FREESCALE_ENET0_RECEIVE_INT_VECTOR,
+ .rx_intr_prio = CYGPKG_DEVS_ETH_FREESCALE_ENET0_INTPRIO
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ , .tx_intr_vector = CYGNUM_FREESCALE_ENET0_TRANSMIT_INT_VECTOR,
+ .tx_intr_prio = CYGPKG_DEVS_ETH_FREESCALE_ENET0_INTPRIO
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+};
+
+// Ethernet interface entry -------------------------------------------------
+ETH_DRV_SC(enet0_eth0_sc,
+ &enet0_eth0_priv, // Driver specific data
+ CYGDAT_IO_ETH_IF_FREESCALE_ENET0_NAME, // Name for this interface
+ enet_eth_start,
+ enet_eth_stop,
+ enet_eth_control,
+ enet_eth_can_send,
+ enet_eth_send,
+ enet_eth_recv,
+ enet_eth_deliver,
+ enet_eth_poll,
+ enet_eth_int_vector);
+
+NETDEVTAB_ENTRY(enet0_netdev,
+ "enet0_eth",
+ enet_eth_init,
+ &enet0_eth0_sc);
+
+// End ENET0 =================================================================
+
+
+// Driver code ===============================================================
+//
+
+// Buffer and buffer descriptor (BD) macros ==================================
+// BD Iterators --------------------------------------------------------------
+
+// Generic BD iterator template used by Rx and Tx iterators
+#define ENET_NEXT_BD(__bd_p,__priv_p,__wrap,__pool) \
+CYG_MACRO_START \
+ __bd_p = __bd_p->ctrl & __wrap ? \
+ __priv_p->__pool##_pool_p : __bd_p + 1; \
+CYG_MACRO_END
+
+// Rx BD Iterator ------------------------------------------
+#define ENET_RXBD_NEXT(__bd_p,__priv_p) \
+ ENET_NEXT_BD(__bd_p, __priv_p, ENET_RXBD_W, rxbd)
+
+// Tx BD Iterator
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+// Tx BD Iterator - NoCopy option --------------------------
+# define ENET_BD_AVAIL_INC(__priv_p) (__priv_p->txbd_avail++)
+# define ENET_BD_AVAIL_DEC(__priv_p) (__priv_p->txbd_avail--)
+
+# define ENET_TXBD_ALLOC(__bd_p,__priv_p) \
+CYG_MACRO_START \
+ ENET_NEXT_BD(__bd_p, __priv_p, ENET_TXBD_W, txbd); \
+ ENET_BD_AVAIL_DEC(__priv_p); \
+CYG_MACRO_END
+
+# define ENET_TXBD_FREE(__bd_p,__priv_p) \
+CYG_MACRO_START \
+ ENET_NEXT_BD(__bd_p, __priv_p, ENET_TXBD_W, txbd); \
+ ENET_BD_AVAIL_INC(__priv_p); \
+CYG_MACRO_END
+
+# define ENET_TXBD_TRYFREE(__bd_p,__priv_p) \
+CYG_MACRO_START \
+ ENET_NEXT_BD(__bd_p, __priv_p, ENET_TXBD_W, txbd); \
+CYG_MACRO_END
+
+// Tx key iterator -----------------------------------------
+# define ENET_TXKEY_NEXT(__bd_p,__priv_p) \
+CYG_MACRO_START \
+ __bd_p = (__bd_p == (__priv_p->txkey_pool_p + __priv_p->txkey_num-1)) ? \
+ __priv_p->txkey_pool_p : __bd_p + 1; \
+CYG_MACRO_END
+
+#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+// Tx BD Iterator - Copying option -------------------------
+# define ENET_TXBD_NEXT(__bd_p,__priv_p) \
+ ENET_NEXT_BD(__bd_p, __priv_p, ENET_TXBD_W, txbd)
+
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+// Buffer descriptor initialization functions ================================
+//
+
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+# define ENET_RESET_BD_TX(__priv_p) \
+CYG_MACRO_START \
+ __priv_p->txbd_head_p = __priv_p->txbd_pool_p + __priv_p->txbd_num - 1; \
+ __priv_p->txbd_tail_p = __priv_p->txbd_head_p; \
+ __priv_p->txbd_avail = __priv_p->txbd_num; \
+ __priv_p->txkey_head_p = __priv_p->txkey_pool_p + __priv_p->txkey_num - 1; \
+ __priv_p->txkey_tail_p = __priv_p->txkey_head_p; \
+CYG_MACRO_END
+#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+# define ENET_RESET_BD_TX(__priv_p) \
+CYG_MACRO_START \
+ __priv_p->txbd_head_p = __priv_p->txbd_pool_p + __priv_p->txbd_num - 1; \
+ __priv_p->txbd_tail_p = __priv_p->txbd_head_p; \
+CYG_MACRO_END
+#endif //
+
+#define ENET_INIT_BD_TX(__priv_p) ENET_RESET_BD_TX(__priv_p)
+
+
+// Initialize a buffer descriptor --------------------------------------------
+// Generic function for initialization of a buffer descriptor
+
+static void
+enet_init_bd(enet_bd_t *bd_p, cyg_uint32 bd_size, cyg_uint16 cntrl_init,
+ cyg_uint16 cntrl_wrap, cyg_uint8 *buff_p, cyg_uint32 buf_size
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ , cyg_uint32 *key_p
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ , cyg_uint32 ebd_ctrl
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ )
+{
+ enet_bd_t *bd_end;
+ debug1_printf("ENET: Inint_bd:\n");
+ for(bd_end = bd_p + bd_size; bd_p < bd_end; bd_p++){
+ debug1_printf("ENET: %p -> ", bd_p);
+ bd_p->ctrl = cntrl_init;
+ bd_p->len = 0;
+ bd_p->buffer_p = (cyg_uint8 *)CYG_CPU_TO_BE32((cyg_uint32)buff_p);
+ debug1_printf("cntrl=0x%04x len=%d buffer=%p[%p]",
+ bd_p->ctrl, bd_p->len, bd_p->buffer_p, buff_p);
+ buff_p += (buf_size);
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ bd_p->ebd_ctrl = ebd_ctrl;
+ bd_p->hlen_proto = 0;
+ bd_p->payload_csum = 0;
+ bd_p->bdu = ENET_TXBD_BDU;
+ bd_p->timestamp_1588 = 0;
+ bd_p->reserved[0] = 0;
+ bd_p->reserved[1] = 0;
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ if(key_p) {
+ *key_p = 0;
+ debug1_printf(" tx_key[%p]=%x", key_p, *key_p);
+ key_p++;
+ }
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ debug1_printf("\n");
+ }
+ debug1_printf("ENET: end, bd_p=%p\n", bd_p);
+ bd_p--;
+ bd_p->ctrl |= cntrl_wrap;
+ debug1_printf("ENET: %p -> ", bd_p);
+ debug1_printf("cntrl=0x%04x len=%d buffer=%p\n",
+ bd_p->ctrl, bd_p->len, bd_p->buffer_p);
+}
+
+
+// Initialize buffer descriptors and buffers --------------------------------
+//
+
+static void
+enet_init_buffers(freescale_enet_priv_t *enet_priv_p)
+{
+ CYG_ADDRWORD enet_base = enet_priv_p->enet_base;
+
+ // Initialize receive descriptor ring
+ enet_priv_p->rxbd_p = enet_priv_p->rxbd_pool_p;
+ enet_init_bd(enet_priv_p->rxbd_pool_p, enet_priv_p->rxbd_num,
+ ENET_RXBD_E, ENET_RXBD_W, enet_priv_p->rxbuf_p, enet_priv_p->rxbuf_size
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ , NULL
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ , ENET_RXBD_INT
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ );
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RDSR,
+ (cyg_uint32)enet_priv_p->rxbd_pool_p);
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_MRBR, enet_priv_p->rxbuf_size);
+
+ // Initialize transmit descriptor ring
+ ENET_INIT_BD_TX(enet_priv_p);
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ enet_init_bd(enet_priv_p->txbd_pool_p, enet_priv_p->txbd_num, 0, ENET_TXBD_W,
+ NULL, 0, enet_priv_p->txkey_pool_p
+#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ enet_init_bd(enet_priv_p->txbd_pool_p, enet_priv_p->txbd_num, 0, ENET_TXBD_W,
+ enet_priv_p->txbuf_p, enet_priv_p->txbuf_size
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ , ENET_TXBD_INT
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_IP
+ | ENET_TXBD_IINS
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_IP
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_PROT
+ | ENET_TXBD_PINS
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_PROT
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_1588
+ | ENET_TXBD_TS
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_1588
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ );
+
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_TDSR,
+ (cyg_uint32)enet_priv_p->txbd_pool_p);
+ enet_priv_p->txbd_tail_p = enet_priv_p->txbd_head_p;
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_TFWR,
+ FREESCALE_ENET_TFWR_STRFWD_M);
+#else //CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_TFWR,
+ FREESCALE_ENET_TFWR_TFWR(FREESCALE_ENET_TFWR_TFWR_192));
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+
+}
+
+// Hardware initialization functions =========================================
+
+// Configure ENET (R)MII pins ------------------------------------------------
+// Note: pin acces uses services from HAL.
+
+static void
+enet_cfg_pins(freescale_enet_priv_t *enet_priv_p)
+{
+ const cyg_uint32 *pin_p;
+
+ if((pin_p = enet_priv_p->pins_p)) {
+ for(;
+ pin_p < enet_priv_p->pins_p + enet_priv_p->pins_n;
+ CYGHWR_IO_FREESCALE_ENET_PIN(*pin_p++));
+ }
+}
+
+// Set a MAC address match. -------------------------------------------------
+// Packets received which match this address will be passed on.
+
+void
+enet_set_mac_addr (CYG_ADDRWORD enet_base, const cyg_uint8 *addr_p)
+{
+ cyg_uint32 regval;
+
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_PALR,
+ (cyg_uint32)((addr_p[0]<<24) + (addr_p[1]<<16) +
+ (addr_p[2]<<8) + addr_p[3]));
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_PAUR, regval);
+ regval &= 0x0000ffff;
+ regval |= (cyg_uint32)((addr_p[4]<<24) + (addr_p[5]<<16));
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_PAUR, regval);
+}
+
+
+// Initialize ENET device ----------------------------------------------------
+//
+
+static bool
+enet_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *) sc->driver_private;
+ CYG_ADDRWORD enet_base = enet_priv_p->enet_base;
+#ifdef CYGHWR_DEVS_ETH_FREESCALE_ENET_GET_ESA
+ bool esa_ok = false;
+#endif
+ // Bring clock to the sevice
+ CYGHWR_IO_CLOCK_ENABLE(enet_priv_p->clock);
+ // Assign pins
+ enet_cfg_pins(enet_priv_p);
+
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR, 0);
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, 0xFFFFFFFF);
+
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_ECR,
+ FREESCALE_ENET_ECR_RESET_M);
+ ENET_WAIT_US(FREESCALE_ENET_RESET_DELAY);
+
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_ECR,
+ FREESCALE_ENET_ECR_EN1588_M);
+#else // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_ECR, 0);
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_create(enet_priv_p->rx_intr_vector,
+ enet_priv_p->rx_intr_prio,
+ (cyg_addrword_t)sc,
+ (cyg_ISR_t *)enet_eth_isr,
+ (cyg_DSR_t *)eth_drv_dsr,
+ &enet_priv_p->rx_interrupt_handle,
+ &enet_priv_p->rx_interrupt);
+ cyg_drv_interrupt_attach(enet_priv_p->rx_interrupt_handle);
+# ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ cyg_drv_interrupt_create(enet_priv_p->tx_intr_vector,
+ enet_priv_p->tx_intr_prio,
+ (cyg_addrword_t)sc,
+ (cyg_ISR_t *)enet_eth_isr,
+ (cyg_DSR_t *)eth_drv_dsr,
+ &enet_priv_p->tx_interrupt_handle,
+ &enet_priv_p->tx_interrupt);
+ cyg_drv_interrupt_attach(enet_priv_p->tx_interrupt_handle);
+# endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+#ifdef CYGHWR_DEVS_ETH_FREESCALE_ENET_GET_ESA
+ // Get MAC address from RedBoot configuration variables
+ CYGHWR_DEVS_ETH_FREESCALE_ENET_GET_ESA(&enet_priv_p->enaddr[0], esa_ok);
+ // If this call fails myMacAddr is unchanged and MAC address from
+ // CDL is used
+ if (!esa_ok) {
+ // Can't figure out ESA
+ debug1_printf("Freescale ENET - Warning! ESA unknown\n");
+ }
+#endif
+ // Set the source address for the controller
+ enet_set_mac_addr (enet_base, enet_priv_p->enaddr);
+
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_IALR, 0x00000000);
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_IAUR, 0x00000000);
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_GALR, 0x00000000);
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_GAUR, 0x00000000);
+
+ if(eth_phy_init_wait(enet_priv_p->phy_p, FREESCALE_ENET_PHY_INIT_TOUT)) {
+ // Initialize upper level driver.
+ (sc->funs->eth_drv->init)(sc, (cyg_uint8 *)enet_priv_p->enaddr);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// Start ENET ----------------------------------------------------------------
+
+static void
+enet_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr_p, int flags)
+{
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *)sc->driver_private;
+ CYG_ADDRWORD enet_base = enet_priv_p->enet_base;
+ cyg_uint32 enet_reg;
+
+
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_ECR, enet_reg);
+ if(!(enet_reg & FREESCALE_ENET_ECR_ETHEREN_M)) {
+ // Set Speed, duplex, etc.
+ enet_eth_phy_set(enet_priv_p);
+
+ // Init Buffers
+ enet_init_buffers(enet_priv_p);
+
+ // Enable the device!
+
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR,
+ FREESCALE_ENET_EIR_MASK_M);
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_unmask(enet_priv_p->rx_intr_vector);
+# ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ cyg_drv_interrupt_unmask(enet_priv_p->tx_intr_vector);
+# endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR,
+ FREESCALE_ENET_EIMR_MASK_M);
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+ // Flow controll
+ if(enet_priv_p->flags & CYGSEM_ETH_FREESCALE_ENET0_RCR_FCE) {
+ debug1_printf("ENET: Flow control: RCR enabled.\n");
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_RCR, enet_reg);
+ enet_reg |= FREESCALE_ENET_RCR_FCE_M;
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RCR, enet_reg);
+ } else {
+ debug1_printf("ENET: Flow control: RCR disabled.\n");
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_RCR, enet_reg);
+ enet_reg &= ~FREESCALE_ENET_RCR_FCE_M;
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RCR, enet_reg);
+ }
+ debug1_printf("ENET: Flow control: RCR 0x%08x.\n", enet_reg);
+
+ // Flow controll pause duration
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_OPD, enet_reg);
+ enet_reg &= 0xffff000;
+ enet_reg |= enet_priv_p->fc_pause;
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_OPD, enet_reg);
+ debug1_printf("ENET: Flow control: pause %08x\n", enet_reg);
+
+ // Enable ENET...
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_ECR, enet_reg);
+ enet_reg |= FREESCALE_ENET_ECR_ETHEREN_M;
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_ECR, enet_reg);
+ // ...and wait a bit to settle
+ ENET_WAIT_US(FREESCALE_ENET_ENABLE_DELAY);
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RDAR,
+ FREESCALE_ENET_RDAR_RDAR_M);
+#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS
+ FREESCALE_ENET_STATS_INIT(&enet_priv_p->enet_stats);
+#endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS
+ }
+}
+
+// Stop ENET ----------------------------------------------------------------
+
+static void
+enet_eth_stop(struct eth_drv_sc *sc)
+{
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *)sc->driver_private;
+ CYG_ADDRWORD enet_base = enet_priv_p->enet_base;
+ cyg_uint32 ecr;
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ enet_bd_t *tx_bd_head_p, *tx_bd_tail_p;
+ cyg_uint32 *tx_key_tail_p;
+ void (*tx_done)(struct eth_drv_sc *sc, CYG_ADDRESS key, int status);
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_mask(enet_priv_p->rx_intr_vector);
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ cyg_drv_interrupt_mask(enet_priv_p->tx_intr_vector);
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR, 0x00000000);
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR,
+ FREESCALE_ENET_EIR_MASK_M);
+
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_ECR, ecr);
+ ecr &= ~FREESCALE_ENET_ECR_ETHEREN_M;
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_ECR, ecr);
+
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ // Free eventual unsent buffers.
+ tx_bd_head_p = enet_priv_p->txbd_head_p;
+ tx_bd_tail_p = enet_priv_p->txbd_tail_p;
+ tx_key_tail_p = enet_priv_p->txkey_tail_p;
+ tx_done = sc->funs->eth_drv->tx_done;
+ while(tx_bd_tail_p != tx_bd_head_p) {
+ ENET_TXBD_FREE(tx_bd_tail_p, enet_priv_p);
+ if(tx_bd_tail_p->ctrl & ENET_TXKEY_FLAG) {
+ tx_bd_tail_p->ctrl &= ~ENET_TXKEY_FLAG;
+ (tx_done)(sc, *tx_key_tail_p, 0);
+ *tx_key_tail_p = 0;
+ ENET_TXKEY_NEXT(tx_key_tail_p, enet_priv_p);
+ }
+ }
+ enet_priv_p->txbd_tail_p = tx_bd_tail_p;
+ enet_priv_p->txkey_tail_p = tx_key_tail_p;
+#endif //CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+}
+
+// ENET processing functions =================================================
+// ENET control function -----------------------------------------------------
+
+static int
+enet_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data_p, int length)
+{
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *)sc->driver_private;
+ CYG_ADDRWORD enet_base = enet_priv_p->enet_base;
+ int retcode = 1;
+
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ if(length >= ETHER_ADDR_LEN) {
+ enet_eth_stop(sc);
+ enet_set_mac_addr(enet_base, (cyg_uint8 *)data_p);
+ enet_eth_start(sc, (cyg_uint8 *)data_p, 0);
+ retcode = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ return retcode;
+}
+
+// Can send ------------------------------------------------------------------
+// NoCopy: returns number of free Tx buffer descriprors
+// Copying: returns 1 if there is at least 1 free Tx buffer descriotor
+
+static int
+enet_eth_can_send(struct eth_drv_sc *sc)
+{
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *)sc->driver_private;
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ cyg_int32 avail = enet_priv_p->txbd_avail;
+# if DEBUG_ENET >= 2
+ if(avail < enet_priv_p->txbd_can_send_min)
+ diag_printf("ENET can_send: available = %d buffer descriptors.\n",
+ avail);
+# endif // DEBUG_ENET
+ return (int) avail < enet_priv_p->txbd_can_send_min ? 0 : avail;
+#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+ enet_bd_t *tx_bd_p = enet_priv_p->txbd_head_p;
+
+ ENET_TXBD_NEXT(tx_bd_p, enet_priv_p);
+ debug2_printf("ENET: can send: %d\n", !(tx_bd_p->ctrl & ENET_TXBD_R));
+ if(!(tx_bd_p->ctrl & ENET_TXBD_R))
+ return 1;
+ else
+ return 0;
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+}
+
+// Send ----------------------------------------------------------------------
+//
+// Trigger ENET for sending --------------------------------------------------
+
+static void inline
+enet_eth_send_trigger(freescale_enet_priv_t *enet_priv_p)
+{
+ cyg_uint32 tdar;
+
+ do {
+ HAL_READ_UINT32(enet_priv_p->enet_base + FREESCALE_ENET_REG_TDAR, tdar);
+ } while(tdar & FREESCALE_ENET_TDAR_TDAR_M);
+ tdar = FREESCALE_ENET_TDAR_TDAR_M;
+ HAL_WRITE_UINT32(enet_priv_p->enet_base + FREESCALE_ENET_REG_TDAR, tdar);
+}
+
+#define ENET_ETH_SEND_RDY(__bd_p,_ad_flag) \
+CYG_MACRO_START \
+ cyg_uint16 ctrl; \
+ ctrl = __bd_p->ctrl & ENET_TXBD_W; \
+ ctrl |= ENET_TXBD_R | ENET_TXBD_TC | (_ad_flag); \
+ __bd_p->ctrl = ctrl; \
+CYG_MACRO_END
+
+// There different send functios for NoCopy and Copying driver options.
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+// Send - NoCopy version.
+// This version does not copy SG buffer but writes SG buf pointer
+// in ENET BD.
+// Note: ENET requires that buf pointer is evenly divisible by 8.
+
+static void
+enet_eth_send_nocopy(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
+ int sg_len, int total_len, unsigned long key)
+{
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *)sc->driver_private;
+ enet_bd_t *tx_bd_p;
+ enet_bd_t *tx_bd0_p=NULL;
+ cyg_uint32 *tx_key_p;
+ struct eth_drv_sg *sg_list_z;
+
+ if(enet_priv_p->txbd_avail < sg_len) {
+ debug1_printf("ENET Send: Error! sg_len %d avail %d\n", sg_len, enet_priv_p->txbd_avail);
+ (sc->funs->eth_drv->tx_done)(sc, key, 0);
+ return;
+ }
+ debug3_printf("ENET Send: sg_len %d avail %d\n", sg_len, enet_priv_p->txbd_avail);
+ tx_bd_p=enet_priv_p->txbd_head_p;
+ for(sg_list_z=sg_list+sg_len; sg_list<sg_list_z; sg_list++) {
+ ENET_TXBD_ALLOC(tx_bd_p, enet_priv_p);
+ tx_bd_p->buffer_p=(cyg_uint8 *)CYG_CPU_TO_BE32(sg_list->buf);
+ tx_bd_p->len=CYG_CPU_TO_BE16(sg_list->len);
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ tx_bd_p->bdu = 0;
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ if(tx_bd0_p) {
+ ENET_ETH_SEND_RDY(tx_bd_p, 0);
+ } else {
+ tx_bd0_p=tx_bd_p;
+ }
+ }
+ tx_key_p=enet_priv_p->txkey_head_p;
+ *tx_key_p = key;
+ ENET_TXKEY_NEXT(tx_key_p, enet_priv_p);
+ if(tx_bd_p != tx_bd0_p) {
+ debug3_printf("ENET Send2: Key[%p] = 0x%x\n", tx_key_p, key);
+ tx_bd_p->ctrl |= (ENET_TXBD_L | ENET_TXKEY_FLAG); // is last and has key
+ ENET_ETH_SEND_RDY(tx_bd0_p, 0);
+ } else {
+ debug3_printf("ENET Send1: Key[%p] = 0x%x\n", tx_key_p, key);
+ ENET_ETH_SEND_RDY(tx_bd0_p, ENET_TXBD_L | ENET_TXKEY_FLAG);
+ }
+ enet_priv_p->txkey_head_p = tx_key_p;
+ enet_priv_p->txbd_head_p = tx_bd_p;
+ enet_eth_send_trigger(enet_priv_p);
+}
+
+#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+// Send - Copying version.
+// This version physically copies SG buf(s) in private ENET buffer(s).
+// This version is usefull if upper layer stack does not guarantee
+// buffers aligned to 8 byte boundary.
+// Also requires no Tx interrupts.
+
+static void
+enet_eth_send_copying(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
+ int sg_len, int total_len, unsigned long key)
+{
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *)sc->driver_private;
+ enet_bd_t *tx_bd_p;
+ struct eth_drv_sg *sg_list_z;
+ cyg_uint16 ctrl;
+ cyg_uint8* txbuf_p;
+ cyg_uint32 txbuf_k;
+ enet_bd_t *tx_bd_save_p;
+
+ tx_bd_p=enet_priv_p->txbd_head_p;
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ while(!(tx_bd_p->bdu & ENET_TXBD_BDU)){
+ debug1_printf("ENET Send: Waiting for BDU %p\n", tx_bd_p);
+ }
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ debug2_printf("ENET Send: sg_len %d total_len %d\n", sg_len, total_len);
+ tx_bd_save_p=tx_bd_p;
+ ENET_TXBD_NEXT(tx_bd_p, enet_priv_p);
+ txbuf_p = (cyg_uint8 *)CYG_CPU_TO_BE32((cyg_uint32)tx_bd_p->buffer_p);
+ txbuf_k = 0;
+ for(sg_list_z=sg_list+sg_len; sg_list<sg_list_z; sg_list++) {
+ if((txbuf_k += sg_list->len) > enet_priv_p->txbuf_size) {
+ debug1_printf("ENET Send: Buffer overflow: %d (max = %d)\n", txbuf_k,
+ enet_priv_p->txbuf_size);
+ enet_priv_p->txbd_head_p = tx_bd_save_p;
+ (sc->funs->eth_drv->tx_done)(sc, key, 0);
+ return;
+ }
+ memcpy(txbuf_p, (cyg_uint8 *)sg_list->buf, sg_list->len);
+ txbuf_p += sg_list->len;
+ }
+ tx_bd_p->len=CYG_CPU_TO_BE16(total_len);
+ ctrl = tx_bd_p->ctrl & ENET_TXBD_W;
+ ctrl |= ENET_TXBD_R | ENET_TXBD_TC | ENET_TXBD_L;
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ tx_bd_p->bdu = 0;
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ tx_bd_p->ctrl = ctrl;
+ enet_priv_p->txbd_head_p = tx_bd_p;
+ debug2_printf("ENET Send: trigger, done.\n");
+ enet_eth_send_trigger(enet_priv_p);
+ (sc->funs->eth_drv->tx_done)(sc, key, 0);
+}
+
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+// Receive ------------------------------------------------------------------
+
+static void
+enet_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *)sc->driver_private;
+ cyg_uint8 *rxbuffer_p;
+ struct eth_drv_sg *sg_list_z;
+ enet_bd_t *rx_bd_p;
+
+ debug3_printf("ENET recv: sg_len=%d first len=%d\n", sg_len, sg_list->len);
+ rx_bd_p=enet_priv_p->rxbd_p;
+ rxbuffer_p=(cyg_uint8 *)CYG_CPU_TO_BE32((cyg_uint32)rx_bd_p->buffer_p);
+ for(sg_list_z=sg_list+sg_len; sg_list<sg_list_z; sg_list++) {
+ if(sg_list->buf) {
+ memcpy((cyg_uint8 *)sg_list->buf, rxbuffer_p, sg_list->len);
+ rxbuffer_p+=sg_list->len;
+ }
+ }
+}
+
+// Reception error check -----------------------------------------------------
+
+static inline bool
+enet_eth_recv_error(enet_bd_t *rx_bd_p, freescale_enet_priv_t *enet_priv_p)
+{
+ bool errcod=false;
+ cyg_uint32 ctrl = rx_bd_p->ctrl;
+
+ if(ctrl & ENET_RXBD_TR) {
+ ENET_STAT_PRINTF("ENET: Ethernet trunc error ctrl = 0x%04x\n",
+ rx_bd_p->ctrl);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, TR);
+ errcod = true;
+ } else if(ctrl & ENET_RXBD_L) {
+ if(ctrl & (ENET_RXBD_CR | ENET_RXBD_OV | ENET_RXBD_LG | ENET_RXBD_NO))
+ {
+ // Ethernet fault processing
+ ENET_STAT_PRINTF("ENET: Ethernet error ctrl = 0x%04x => ",
+ rx_bd_p->ctrl);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, CR);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, OV);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, LG);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, NO);
+ ENET_STAT_PRINTF("\n");
+ errcod = true;
+ }
+
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ ctrl = rx_bd_p->ebd_ctrl;
+ if(ctrl & (ENET_RXBD_ME | ENET_RXBD_PE | ENET_RXBD_CE | ENET_RXBD_FRAG
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_IP
+ | ENET_RXBD_ICE
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_PROT
+ | ENET_RXBD_PCR
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_PROT
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_IP
+ ))
+ {
+ cyg_uint32 head_len = (rx_bd_p->hlen_proto >> 11) & 0x1f;
+ if(head_len || (ctrl & (ENET_RXBD_ME | ENET_RXBD_PE |
+ ENET_RXBD_CE | ENET_RXBD_FRAG )))
+ {
+ // Enhanced bd fault processing
+ ENET_STAT_PRINTF("ENET: Enhanced bd error ctrl = 0x%08x => ",
+ rx_bd_p->ebd_ctrl);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, ME);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, PE);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, CE);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, FRAG);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, ICE);
+ FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, PCR);
+ ENET_STAT_PRINTF("\n");
+ ENET_STAT_PRINTF("ENET: HeadLen=%d[0x%x] Proto=%d[0x%x]\n",
+ head_len, head_len,
+ rx_bd_p->hlen_proto & 0xff,
+ rx_bd_p->hlen_proto & 0xff);
+ errcod = true;
+ }
+ }
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ }
+ if(errcod) {
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ debug2_printf("ENET: Bad msg ctrl = 0x%04x ebd_ctrl = 0x%08x\n",
+ rx_bd_p->ctrl, rx_bd_p->ebd_ctrl);
+#else // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ debug2_printf("ENET: Bad msg ctrl = 0x%04x\n", rx_bd_p->ctrl);
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ }
+ return errcod;
+}
+
+// Deliver -------------------------------------------------------------------
+#define ENET_DELIVER_NEED_SERVICE_RX FREESCALE_ENET_EIMR_RXF_M
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+# define ENET_DELIVER_NEED_SERVICE_TX FREESCALE_ENET_EIMR_TXF_M
+# define ENET_DELIVER_NEED_SERVICE (ENET_DELIVER_NEED_SERVICE_RX | \
+ ENET_DELIVER_NEED_SERVICE_TX)
+#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+# define ENET_DELIVER_NEED_SERVICE (ENET_DELIVER_NEED_SERVICE_RX)
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+#define ENET_DELIVER_NEED_SERVICE_SET(__var,__rt) \
+CYG_MACRO_START \
+ __var |= ENET_DELIVER_NEED_SERVICE_##__rt; \
+CYG_MACRO_END
+
+#define ENET_DELIVER_NEED_SERVICE_CLEAR(__var,__rt) \
+CYG_MACRO_START \
+ __var &= ~ENET_DELIVER_NEED_SERVICE_##__rt; \
+CYG_MACRO_END
+
+// There different deliver functios for NoCopy and Copying driver options.
+
+#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+// Deliver - NoCopy varsion
+// This deliver vresion is compatible with NoCopy send version.
+
+static void
+enet_eth_deliver_nocopy(struct eth_drv_sc * sc)
+{
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *)sc->driver_private;
+ CYG_ADDRWORD enet_base = enet_priv_p->enet_base;
+ enet_bd_t *tx_bd_tail_p, *tx_bd_tail_save_p;
+ cyg_uint32 *tx_key_tail_p;
+ enet_bd_t *rx_bd_p;
+ cyg_uint16 ctrl;
+ cyg_uint32 eir;
+ cyg_uint32 need_service;
+ void (*recv)(struct eth_drv_sc *sc, int total_len);
+ void (*tx_done)(struct eth_drv_sc *sc, CYG_ADDRESS key, int status);
+
+ recv = sc->funs->eth_drv->recv;
+ tx_done = sc->funs->eth_drv->tx_done;
+
+ tx_bd_tail_p = enet_priv_p->txbd_tail_p;
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir);
+ need_service = eir & ENET_DELIVER_NEED_SERVICE;
+ do {
+ //Clear all ENET Interrupt events
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR,
+ FREESCALE_ENET_EIR_MASK_M);
+ if(eir & FREESCALE_ENET_EIR_ERROR) {
+ debug2_printf("ENET: EIR Error 0x%08x\n",
+ eir & FREESCALE_ENET_EIR_ERROR);
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR,
+ FREESCALE_ENET_EIR_ERROR);
+ }
+
+ // RX Event processing
+ if(need_service & ENET_DELIVER_NEED_SERVICE_RX) {
+ rx_bd_p=enet_priv_p->rxbd_p;
+ ctrl=rx_bd_p->ctrl;
+ if(ctrl & ENET_RXBD_E) {
+ ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, RX);
+ } else {
+ if(!enet_eth_recv_error(rx_bd_p, enet_priv_p)) {
+ (recv)(sc, CYG_CPU_TO_BE16(rx_bd_p->len));
+ }
+ ctrl &= ENET_RXBD_W;
+ ctrl |= ENET_RXBD_E;
+ rx_bd_p->ctrl = ctrl;
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ rx_bd_p->bdu = 0;
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ // Inform ENET that free Rx buffers have beeen freed.
+ HAL_WRITE_UINT32(enet_priv_p->enet_base +
+ FREESCALE_ENET_REG_RDAR,
+ FREESCALE_ENET_RDAR_RDAR_M);
+
+ ENET_RXBD_NEXT(rx_bd_p, enet_priv_p);
+ enet_priv_p->rxbd_p=rx_bd_p;
+
+ if(rx_bd_p->ctrl & ENET_RXBD_E) {
+ ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, RX);
+ }
+ }
+ }
+
+ // TX Event processing
+ if(need_service & ENET_DELIVER_NEED_SERVICE_TX) {
+ if(enet_priv_p->txbd_num == enet_priv_p->txbd_avail) {
+ debug2_printf("ENET: Tx nothing to send\n");
+ ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, TX);
+ } else {
+ tx_bd_tail_save_p=tx_bd_tail_p;
+ ENET_TXBD_TRYFREE(tx_bd_tail_p, enet_priv_p);
+ ctrl = tx_bd_tail_p->ctrl;
+ if(ctrl & ENET_TXBD_R){
+ tx_bd_tail_p=tx_bd_tail_save_p;
+ ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, TX);
+ } else {
+ ENET_BD_AVAIL_INC(enet_priv_p);
+ if(ctrl & ENET_TXKEY_FLAG){
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ while(!(tx_bd_tail_p->bdu & ENET_TXBD_BDU)){
+ debug1_printf("ENET Send: Waiting for BDU %p\n", tx_bd_tail_p);
+ }
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ tx_key_tail_p = enet_priv_p->txkey_tail_p;
+ debug3_printf("ENET Deliver: Key[%p] = 0x%x\n",
+ tx_key_tail_p, *tx_key_tail_p);
+ ENET_TXKEY_NEXT(tx_key_tail_p, enet_priv_p);
+ enet_priv_p->txkey_tail_p = tx_key_tail_p;
+ ctrl &= ~ENET_TXKEY_FLAG;
+ tx_bd_tail_p->ctrl = ctrl;
+ (tx_done)(sc, *tx_key_tail_p, 0);
+ }
+ if(enet_priv_p->txbd_avail == enet_priv_p->txbd_num) {
+ debug3_printf("ENET: Tx All sent.\n");
+ ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, TX);
+ }
+ }
+ }
+ }
+
+ // Check if Interrupt had arrived in meantime
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir);
+ need_service |= eir & ENET_DELIVER_NEED_SERVICE;
+ } while(need_service);
+ debug3_printf("ENET: Delivered.\n");
+ enet_priv_p->txbd_tail_p = tx_bd_tail_p;
+# ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+# ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK
+ //Unmask all ENET interrupts
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR,
+ FREESCALE_ENET_EIMR_MASK_M);
+# else // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK
+ cyg_drv_interrupt_unmask(enet_priv_p->tx_intr_vector);
+ cyg_drv_interrupt_unmask(enet_priv_p->rx_intr_vector);
+# endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK
+# endif //CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+}
+
+#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+// Deliver - Copying varsion
+// This deliver vresion is compatible with Copying send version.
+
+static void
+enet_eth_deliver_copying(struct eth_drv_sc * sc)
+{
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *)sc->driver_private;
+ CYG_ADDRWORD enet_base = enet_priv_p->enet_base;
+ enet_bd_t *rx_bd_p;
+ cyg_uint16 ctrl;
+ cyg_uint32 eir;
+ cyg_uint32 need_service;
+ void (*recv)(struct eth_drv_sc *sc, int total_len);
+
+ recv = sc->funs->eth_drv->recv;
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir);
+ need_service = eir & ENET_DELIVER_NEED_SERVICE;
+ do {
+ //Clear all ENET Interrupt events
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR,
+ FREESCALE_ENET_EIR_MASK_M);
+ if(eir & FREESCALE_ENET_EIR_ERROR) {
+ debug2_printf("ENET: EIR Error 0x%08x\n",
+ eir & FREESCALE_ENET_EIR_ERROR);
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR,
+ FREESCALE_ENET_EIR_ERROR);
+ }
+
+ // RX Event processing
+ if(need_service & ENET_DELIVER_NEED_SERVICE_RX) {
+ rx_bd_p=enet_priv_p->rxbd_p;
+ ctrl=rx_bd_p->ctrl;
+ if(ctrl & ENET_RXBD_E) {
+ ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, RX);
+ } else {
+ if(!enet_eth_recv_error(rx_bd_p, enet_priv_p)) {
+ (recv)(sc, CYG_CPU_TO_BE16(rx_bd_p->len));
+ }
+ ctrl &= ENET_RXBD_W;
+ ctrl |= ENET_RXBD_E;
+ rx_bd_p->ctrl = ctrl;
+# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ rx_bd_p->bdu = 0;
+# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED
+ // Inform ENET that Rx buffers have been freed.
+ HAL_WRITE_UINT32(enet_priv_p->enet_base +
+ FREESCALE_ENET_REG_RDAR,
+ FREESCALE_ENET_RDAR_RDAR_M);
+
+ ENET_RXBD_NEXT(rx_bd_p, enet_priv_p);
+ enet_priv_p->rxbd_p=rx_bd_p;
+
+ if(rx_bd_p->ctrl & ENET_RXBD_E) {
+ ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, RX);
+ }
+ }
+ }
+
+ // Check if Interrupt had arrived in meantime
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir);
+ need_service |= eir & ENET_DELIVER_NEED_SERVICE;
+ } while(need_service);
+
+# ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+# ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK
+ //Unmask all ENET interrupts
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR,
+ FREESCALE_ENET_EIMR_MASK_M);
+# else // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK
+// cyg_drv_interrupt_unmask(enet_priv_p->tx_intr_vector);
+ cyg_drv_interrupt_unmask(enet_priv_p->rx_intr_vector);
+# endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK
+# endif //CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+}
+
+#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY
+
+// Poll ---------------------------------------------------------------------
+static void
+enet_eth_poll(struct eth_drv_sc *sc)
+{
+ enet_eth_deliver(sc);
+}
+
+// ISR ----------------------------------------------------------------------
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32
+enet_eth_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
+ freescale_enet_priv_t *enet_priv_p =
+ (freescale_enet_priv_t *)sc->driver_private;
+ CYG_ADDRWORD enet_base = enet_priv_p->enet_base;
+
+ //Mask ENET Interrupts
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR, 0x00000000);
+#else // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK
+ cyg_drv_interrupt_mask(vector);
+#endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK
+ cyg_drv_interrupt_acknowledge(vector);
+
+ return CYG_ISR_CALL_DSR;
+}
+
+#endif //CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+static int
+enet_eth_int_vector(struct eth_drv_sc *sc)
+{
+ return CYGNUM_FREESCALE_ENET0_RECEIVE_INT_VECTOR;
+}
+
+// PHY related stuff =========================================================
+// MDIO interface
+
+// Polling based waiting function for MDIO transactions
+static bool
+freescale_enet_busywait_mii(CYG_ADDRWORD enet_base, cyg_uint32 counter)
+{
+ cyg_uint32 eir;
+ bool done=0;
+
+ for(; counter; counter--) {
+ ENET_WAIT_US(2);
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir);
+ if(eir & FREESCALE_ENET_EIR_MII_M) {
+ eir |= FREESCALE_ENET_EIR_MII_M;
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir);
+ done=1;
+ break;
+ }
+ }
+ return done;
+}
+
+// Write a PHY register via the MDIO interface -------------------------------
+
+static void
+enet_write_phy(int reg_addr, int phy_addr, unsigned short data)
+{
+ CYG_ADDRWORD enet_base = enet0_eth0_priv.enet_base;
+ cyg_uint32 eir;
+
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir);
+ eir |= FREESCALE_ENET_EIR_MII_M;
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir);
+
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_MMFR,
+ FREESCALE_ENET_MMFR_ST(01) |
+ FREESCALE_ENET_MMFR_OP(01) |
+ FREESCALE_ENET_MMFR_PA(phy_addr) |
+ FREESCALE_ENET_MMFR_RA(reg_addr) |
+ FREESCALE_ENET_MMFR_TA(02) |
+ FREESCALE_ENET_MMFR_DATA(data));
+ freescale_enet_busywait_mii(enet_base, FREESCALE_ENET_MII_WRITE_TOUT);
+}
+
+// Read a PHY register via the MDIO interface --------------------------------
+
+static bool
+enet_read_phy(int reg_addr, int phy_addr, unsigned short *data_p)
+{
+ bool done = 0;
+ volatile cyg_uint32 mmfr;
+ CYG_ADDRWORD enet_base = enet0_eth0_priv.enet_base;
+ cyg_uint32 eir;
+
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir);
+ eir |= FREESCALE_ENET_EIR_MII_M;
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir);
+
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_MMFR,
+ FREESCALE_ENET_MMFR_ST(01) |
+ FREESCALE_ENET_MMFR_OP(02) |
+ FREESCALE_ENET_MMFR_PA(phy_addr) |
+ FREESCALE_ENET_MMFR_RA(reg_addr) |
+ FREESCALE_ENET_MMFR_TA(02));
+ if((done = freescale_enet_busywait_mii(enet_base,
+ FREESCALE_ENET_MII_READ_TOUT))) {
+ HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_MMFR, mmfr);
+ *data_p = (unsigned short)(mmfr & FREESCALE_ENET_MMFR_DATA_M);
+ }
+ return done;
+}
+
+
+// PHY initialization functions ----------------------------------------------
+// Init ENET device for phy access -------------------------------------------
+//
+static void
+enet_init_phy(void)
+{
+ CYG_ADDRWORD enet_base = enet0_eth0_priv.enet_base;
+ cyg_uint32 mii_speed;
+
+ mii_speed = (2 * CYGHWR_FREESCALE_ENET_MII_MDC_HAL_CLOCK / 5000000 + 1);
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_MSCR,
+ FREESCALE_ENET_MSCR_MII_SPEED(mii_speed) |
+ FREESCALE_ENET_MSCR_HOLDTIME(0)
+ );
+}
+
+// Set ENET device according to PHY stat -------------------------------------
+//
+static void
+enet_eth_phy_set(freescale_enet_priv_t *enet_priv_p)
+{
+ CYG_ADDRWORD enet_base = enet_priv_p->enet_base;
+ unsigned short phy_state = 0;
+ cyg_uint32 regval;
+
+ phy_state=_eth_phy_state(enet_priv_p->phy_p);
+#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_PHY_RMII
+ regval = FREESCALE_ENET_RCR_MAX_FL(enet_priv_p->max_frame_len)
+ | FREESCALE_ENET_RCR_RMII_MODE_M | FREESCALE_ENET_RCR_MII_MODE_M;
+ if((phy_state & ETH_PHY_STAT_LINK) && !(phy_state & ETH_PHY_STAT_100MB)) {
+ // Operate in 10MB mode
+ regval |= FREESCALE_ENET_RCR_RMII_10T_M;
+ }
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RCR, regval);
+#else // CYGSEM_DEVS_ETH_FREESCALE_ENET_PHY_RMII
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RCR,
+ FREESCALE_ENET_RCR_MAX_FL(enet_priv_p->max_frame_len) |
+ FREESCALE_ENET_RCR_MII_MODE_M);
+#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_PHY_RMII
+ if(phy_state & ETH_PHY_STAT_FDX) { // Operate in full-duplex mode
+ HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_TCR,
+ FREESCALE_ENET_TCR_FDEN_M);
+ }
+}
+
+
+// PHY may need some start-up time -------------------------------------------
+//
+
+static bool
+eth_phy_init_wait(eth_phy_access_t *phy_p, cyg_uint32 ms)
+{
+ cyg_uint32 cnt;
+
+ for(cnt=0; cnt<ms; cnt++) {
+ if(_eth_phy_init(phy_p))
+ return true;
+ ENET_WAIT_US(1000);
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+// EOF if_freescale_enet.c
diff --git a/ecos/packages/devs/eth/frv/cb70/current/ChangeLog b/ecos/packages/devs/eth/frv/cb70/current/ChangeLog
new file mode 100644
index 0000000..420305a
--- /dev/null
+++ b/ecos/packages/devs/eth/frv/cb70/current/ChangeLog
@@ -0,0 +1,27 @@
+2004-09-05 Mark Salter <msalter@redhat.com>
+
+ * Initial checkin.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/frv/cb70/current/cdl/cb70_eth_driver.cdl b/ecos/packages/devs/eth/frv/cb70/current/cdl/cb70_eth_driver.cdl
new file mode 100755
index 0000000..8988919
--- /dev/null
+++ b/ecos/packages/devs/eth/frv/cb70/current/cdl/cb70_eth_driver.cdl
@@ -0,0 +1,147 @@
+# ====================================================================
+#
+# cb70_eth_driver.cdl
+#
+# Ethernet driver
+# CB70 w/DM9000 platform specific support
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):
+# Original data: msalter
+# Contributors:
+# Date: 2004-03-22
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_FRV_CB70 {
+ display "cb70 CPU board with Davicom DM9000 ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_FRV_MB93091
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the DM9000 package
+ cdl_interface CYGINT_DEVS_ETH_DAVICOM_DM9000_REQUIRED {
+ display "Davicom DM9000 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_DAVICOM_DM9000_INL <cyg/io/cb70_eth_driver.inl>"
+
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_DAVICOM_DM9000_CFG <pkgconf/devs_eth_frv_cb70.h>"
+
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+
+ cdl_component CYGPKG_DEVS_ETH_FRV_CB70_ETH0 {
+ display "cb70 ethernet port driver for builtin Davicom DM9000"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the Davicom DM9000 ethernet device driver for a
+ CB70 CPU board."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_DAVICOM_DM9000_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_FRV_CB70_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for a
+ DM9000-based CB70 CPU card."
+ }
+ }
+
+
+ cdl_component CYGPKG_DEVS_ETH_DM9000_ETH_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 0
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+ description "Enabling this option will allow the ethernet
+ station address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually by the
+ 'Set the ethernet station address' option for each interface."
+
+ cdl_component CYGPKG_DEVS_ETH_DM9000_ETH_REDBOOT_HOLDS_ESA_VARS {
+ display "Build-in flash config fields for ESAs"
+ flavor bool
+ default_value 0
+
+ active_if CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT_FLASH
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+
+ description "
+ This option controls the presence of RedBoot flash
+ configuration fields for the ESAs of the interfaces when you
+ are building RedBoot. It is independent of whether RedBoot
+ itself uses the network or any particular interface; this
+ support is more for the application to use than for RedBoot
+ itself, though the application gets at the data by vector
+ calls; this option cannot be enabled outside of building
+ RedBoot."
+
+ cdl_option CYGVAR_ETH_DM9000_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 0
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_FRV_CB70_ETH0_DEFAULT_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0x03, 0x47, 0xdf, 0x32, 0xa8}"}
+ description "The default ethernet station address. This is the
+ address used as the default value in the RedBoot
+ flash configuration field."
+ }
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/frv/cb70/current/include/cb70_eth_driver.inl b/ecos/packages/devs/eth/frv/cb70/current/include/cb70_eth_driver.inl
new file mode 100644
index 0000000..6c50ab2
--- /dev/null
+++ b/ecos/packages/devs/eth/frv/cb70/current/include/cb70_eth_driver.inl
@@ -0,0 +1,157 @@
+//==========================================================================
+//
+// cb70_eth_drivers.inl
+//
+// cb70's DM9000 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):
+// Contributors:msalter
+// Date: 2004-03-22
+// Purpose: dm9000 ethernet definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHERNET
+#include <cyg/hal/hal_cache.h> // HAL_DCACHE_LINE_SIZE
+#include <cyg/hal/plf_io.h> // CYGARC_UNCACHED_ADDRESS
+
+extern int cyg_hal_dm9000_present(void);
+
+#define CYG_HAL_DM9000_PRESENT() cyg_hal_dm9000_present()
+
+#ifdef CYGPKG_DEVS_ETH_FRV_CB70_ETH0
+
+static struct dm9000 dm9000_eth0_priv_data = {
+#if defined(CYGPKG_REDBOOT) && defined(CYGVAR_ETH_DM9000_REDBOOT_HOLDS_ESA_ETH0)
+ mac_address: CYGDAT_DEVS_ETH_FRV_CB70_ETH0_DEFAULT_ESA,
+#endif
+ io_addr: (volatile unsigned char *)0xf0600300,
+ io_data: (volatile unsigned char *)0xf0600304
+};
+
+ETH_DRV_SC(dm9000_sc0,
+ &dm9000_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_FRV_CB70_ETH0_NAME, // Name for device
+ dm9000_start,
+ dm9000_stop,
+ dm9000_ioctl,
+ dm9000_can_send,
+ dm9000_send,
+ dm9000_recv,
+ dm9000_deliver,
+ dm9000_poll,
+ dm9000_int_vector
+ );
+
+NETDEVTAB_ENTRY(dm9000_netdev0,
+ "dm9000_" CYGDAT_DEVS_ETH_FRV_CB70_ETH0_NAME,
+ dm9000_init,
+ &dm9000_sc0);
+#endif // CYGPKG_DEVS_ETH_FRV_CB70_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+struct dm9000 *
+dm9000_priv_array[CYGNUM_DEVS_ETH_DAVICOM_DM9000_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_FRV_CB70_ETH0
+ &dm9000_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+dm9000_netdev_array[CYGNUM_DEVS_ETH_DAVICOM_DM9000_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_FRV_CB70_ETH0
+ &dm9000_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+dm9000_sc_array[CYGNUM_DEVS_ETH_DAVICOM_DM9000_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_FRV_CB70_ETH0
+ &dm9000_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// Decide whether to have redboot config vars for it...
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#ifdef CYGPKG_REDBOOT_NETWORKING
+#include <redboot.h>
+#include <flash_config.h>
+
+#ifdef CYGVAR_DEVS_ETH_DM9000_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, dm9000_eth0_priv_data.mac_address
+ );
+#endif
+
+#endif // CYGPKG_REDBOOT_NETWORKING
+#endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#endif // CYGPKG_REDBOOT
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_DM9000_ETH_REDBOOT_HOLDS_ESA
+
+#include <cyg/hal/hal_if.h>
+
+#ifndef CONFIG_ESA
+#define CONFIG_ESA (6)
+#endif
+
+#define CYGHWR_DEVS_ETH_DAVICOM_DM9000_GET_ESA( p_dm9000, mac_address, ok ) \
+CYG_MACRO_START \
+ ok = false; \
+ if ( 0 == p_dm9000->index ) \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa", mac_address, CONFIG_ESA); \
+ else if ( 1 == p_dm9000->index ) \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth1_esa", mac_address, CONFIG_ESA); \
+CYG_MACRO_END
+
+#endif // CYGPKG_DEVS_ETH_DM9000_ETH_REDBOOT_HOLDS_ESA
diff --git a/ecos/packages/devs/eth/frv/frv400/current/ChangeLog b/ecos/packages/devs/eth/frv/frv400/current/ChangeLog
new file mode 100644
index 0000000..5c21517
--- /dev/null
+++ b/ecos/packages/devs/eth/frv/frv400/current/ChangeLog
@@ -0,0 +1,68 @@
+2004-09-05 Mark Salter <msalter@redhat.com>
+ David Woodhouse <dwmw2@redhat.com>
+
+ * include/devs_eth_frv400.inl: Use unsigned char for printing. Check
+ for no MAC address being given.
+ * include/devs_eth_frv400.inl: Read MAC address from ID PROM bytewise.
+ Add 'setmac' RedBoot command for setting the MAC address in the EEPROM.
+
+2002-05-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/devs_eth_frv400.inl: Use CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ instead of CYGPKG_NET where required.
+
+2002-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/frv400_eth_drivers.cdl: Don't define CYGHWR_NET_DRIVERS as this
+ is done in the generic driver.
+
+2001-12-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * include/devs_eth_frv400.inl (_frv400_eth_int_clear): Don't
+ unmask the interrupt after clearing it.
+
+2001-10-16 Gary Thomas <gthomas@redhat.com>
+
+ * include/devs_eth_frv400.inl: Specify buffer layout (change in
+ generic driver requires this).
+
+2001-10-15 Gary Thomas <gthomas@redhat.com>
+
+ * include/devs_eth_frv400.inl: Allow configuration to force ESA
+ (in case EEPROM is bad), otherwise make sure EEPROM is used to
+ set chip address (ESA) before use.
+
+2001-10-12 Gary Thomas <gthomas@redhat.com>
+
+ * include/devs_eth_frv400.inl: Add PCI scanning for device.
+ (_frv400_eth_int_clear): Need explicit interrupt acknowledge.
+
+2001-10-10 Gary Thomas <gthomas@redhat.com>
+
+ * include/devs_eth_frv400.inl:
+ * cdl/frv400_eth_drivers.cdl: New device driver for onboard LAN,
+ based on RTL8029s which is the same as DP8390 (NE2000).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/frv/frv400/current/cdl/frv400_eth_drivers.cdl b/ecos/packages/devs/eth/frv/frv400/current/cdl/frv400_eth_drivers.cdl
new file mode 100644
index 0000000..1b7efb3
--- /dev/null
+++ b/ecos/packages/devs/eth/frv/frv400/current/cdl/frv400_eth_drivers.cdl
@@ -0,0 +1,133 @@
+# ====================================================================
+#
+# frv400_eth_drivers.cdl
+#
+# Ethernet drivers - support for i82559 ethernet controller
+# on the Fujitsu FR-V400
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov, hmt, gthomas
+# Date: 2001-02-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_FRV_FRV400 {
+ display "FRV400 ethernet driver"
+ description "
+ Ethernet drivers for Fujitsu FR-V400 board."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_PCI
+ requires CYGPKG_DEVS_ETH_NS_DP83902A
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ include_dir cyg/io
+
+# compile -library=libextras.a if_frv400.c
+
+ # FIXME: This really belongs in the NS DP83902A package
+ cdl_interface CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED {
+ display "NS DP83902A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_INL <cyg/io/devs_eth_frv400.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_CFG <pkgconf/devs_eth_frv_frv400.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_FRV400_ETH0 {
+ display "CF ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for a
+ CF card."
+
+ implements CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_FRV400_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_FRV400_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_FRV400_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_FRV400_OPTIONS {
+ display "PCMCIA ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_FRV400_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the PCMCIA ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
+
+# EOF frv400_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/frv/frv400/current/include/devs_eth_frv400.inl b/ecos/packages/devs/eth/frv/frv400/current/include/devs_eth_frv400.inl
new file mode 100644
index 0000000..c4ca167
--- /dev/null
+++ b/ecos/packages/devs/eth/frv/frv400/current/include/devs_eth_frv400.inl
@@ -0,0 +1,391 @@
+//==========================================================================
+//
+// devs/eth/frv/frv400/..../include/devs_eth_frv400.inl
+//
+// FRV400 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, hmt, gthomas
+// Contributors: jskov
+// Date: 2001-02-28
+// Purpose: FRV400 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+#include <cyg/hal/hal_if.h>
+#include <cyg/io/pci.h>
+
+#ifdef __WANT_CONFIG
+
+#define CYGHWR_NS_DP83902A_PLF_RESET(_dp_) \
+ CYG_MACRO_START \
+ cyg_uint8 _t; \
+ HAL_READ_UINT8(_dp_->reset, _t); \
+ CYGACC_CALL_IF_DELAY_US(10); \
+ HAL_WRITE_UINT8(_dp_->reset, _t); \
+ CYGACC_CALL_IF_DELAY_US(10000); \
+ CYG_MACRO_END
+
+#define DP_IN(_b_, _o_, _d_) \
+ CYG_MACRO_START \
+ HAL_READ_UINT8(((cyg_addrword_t)(_b_)+(_o_))^0x03, (_d_)); \
+ CYG_MACRO_END
+
+#define DP_OUT(_b_, _o_, _d_) \
+ CYG_MACRO_START \
+ HAL_WRITE_UINT8(((cyg_addrword_t)(_b_)+(_o_))^0x03, (_d_)); \
+ CYG_MACRO_END
+
+#define DP_IN_DATA(_b_, _d_) \
+ CYG_MACRO_START \
+ HAL_READ_UINT16((cyg_addrword_t)(_b_)^0x02, (_d_)); \
+ CYG_MACRO_END
+
+#define DP_OUT_DATA(_b_, _d_) \
+ CYG_MACRO_START \
+ HAL_WRITE_UINT16((cyg_addrword_t)(_b_)^0x02, (_d_)); \
+ CYG_MACRO_END
+
+//#define CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+//#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
+
+#endif // __WANT_CONFIG
+
+#ifdef __WANT_DEVS
+
+#if defined(CYGSEM_DEVS_ETH_FRV400_ETH0_SET_ESA)
+#if defined(CYGPKG_REDBOOT)
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+RedBoot_config_option("Network hardware address [MAC]",
+ lan_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#endif // CYGPKG_REDBOOT
+#include <cyg/hal/hal_if.h>
+#ifndef CONFIG_ESA
+#define CONFIG_ESA 6
+#endif
+#endif
+
+static cyg_bool
+find_rtl8029_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+{
+ return ((v == 0x10EC) && (d == 0x8029));
+}
+
+static void
+_frv400_eth_init(dp83902a_priv_data_t *dp)
+{
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+#if defined(CYGSEM_DEVS_ETH_FRV400_ETH0_SET_ESA)
+ cyg_bool esa_ok;
+ unsigned char _esa[6];
+#else
+ unsigned char prom[32];
+ int i;
+#endif
+
+ devid = CYG_PCI_NULL_DEVID;
+ if (cyg_pci_find_matching( &find_rtl8029_match_func, NULL, &devid )) {
+ cyg_pci_get_device_info(devid, &dev_info);
+ cyg_pci_translate_interrupt(&dev_info, &dp->interrupt);
+ dp->base = (cyg_uint8 *)(dev_info.base_map[0] & ~1);
+ dp->data = dp->base + 0x10;
+ dp->reset = dp->base + 0x1F;
+ diag_printf("RTL8029 at %p, interrupt: %x\n", dp->base, dp->interrupt);
+#if defined(CYGSEM_DEVS_ETH_FRV400_ETH0_SET_ESA)
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "lan_esa", _esa, CONFIG_ESA);
+ if (esa_ok) {
+ memcpy(dp->esa, _esa, sizeof(_esa));
+ }
+#else
+ // Read ESA from EEPROM
+ DP_OUT(dp->base, DP_DCR, 0x48); // Bytewide access
+ DP_OUT(dp->base, DP_RBCH, 0); // Remote byte count
+ DP_OUT(dp->base, DP_RBCL, 0);
+ DP_OUT(dp->base, DP_ISR, 0xFF); // Clear any pending interrupts
+ DP_OUT(dp->base, DP_IMR, 0x00); // Mask all interrupts
+ DP_OUT(dp->base, DP_RCR, 0x20); // Monitor
+ DP_OUT(dp->base, DP_TCR, 0x02); // loopback
+ DP_OUT(dp->base, DP_RBCH, 32); // Remote byte count
+ DP_OUT(dp->base, DP_RBCL, 0);
+ DP_OUT(dp->base, DP_RSAL, 0); // Remote address
+ DP_OUT(dp->base, DP_RSAH, 0);
+ DP_OUT(dp->base, DP_CR, DP_CR_START|DP_CR_RDMA); // Read data
+ for (i = 0; i < 32; i++) {
+ cyg_uint16 _val;
+ HAL_READ_UINT16(dp->data, _val);
+ prom[i] = _val;
+ }
+ // Set ESA into chip
+ DP_OUT(dp->base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); // Select page 1
+ for (i = 0; i < 6; i++) {
+ DP_OUT(dp->base, DP_P1_PAR0+i, prom[i]);
+ }
+ DP_OUT(dp->base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); // Select page 0
+#endif
+ }
+}
+
+#define CYGHWR_NS_DP83902A_PLF_INIT(dp) _frv400_eth_init(dp)
+
+#ifndef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static void
+_frv400_eth_int_clear(dp83902a_priv_data_t *dp)
+{
+ cyg_drv_interrupt_acknowledge(dp->interrupt);
+}
+
+#define CYGHWR_NS_DP83902A_PLF_INT_CLEAR(dp) _frv400_eth_int_clear(dp)
+#endif
+
+#ifdef CYGPKG_DEVS_ETH_FRV400_ETH0
+
+static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
+ base : (cyg_uint8*) 0, //
+ data : (cyg_uint8*) 0, // Filled in at runtime
+ reset: (cyg_uint8*) 0, //
+ interrupt: 0, //
+ tx_buf1: 0x40, //
+ tx_buf2: 0x48, // Buffer layout - change with care
+ rx_buf_start: 0x50, //
+ rx_buf_end: 0x80, //
+#ifdef CYGSEM_DEVS_ETH_FRV400_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_FRV400_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+};
+
+ETH_DRV_SC(dp83902a_sc,
+ &dp83902a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_FRV400_ETH0_NAME,
+ dp83902a_start,
+ dp83902a_stop,
+ dp83902a_control,
+ dp83902a_can_send,
+ dp83902a_send,
+ dp83902a_recv,
+ dp83902a_deliver, // "pseudoDSR" called from fast net thread
+ dp83902a_poll, // poll function, encapsulates ISR and DSR
+ dp83902a_int_vector);
+
+NETDEVTAB_ENTRY(dp83902a_netdev,
+ "dp83902a_" CYGDAT_DEVS_ETH_FRV400_ETH0_NAME,
+ dp83902a_init,
+ &dp83902a_sc);
+
+
+#ifdef CYGPKG_REDBOOT
+
+
+#define EECS (0x80|(1<<3))
+#define EESK (1<<2)
+#define EEDI (1<<1)
+#define EEDO (1<<0)
+#define dprintf(x...) do { } while(0)
+
+
+static int eeprom_cmd(dp83902a_priv_data_t *dp, int cmd, int cmd_len)
+{
+ unsigned retval = 0;
+
+ DP_OUT(dp->base, 1, EECS);
+ CYGACC_CALL_IF_DELAY_US(2000);
+
+ dprintf("Enabled for %08x (%d bits)\n", cmd, cmd_len);
+
+ DP_OUT(dp->base, 1, EECS | EESK);
+ CYGACC_CALL_IF_DELAY_US(2000);
+
+ dprintf("Clock\n");
+
+ /* Shift the command bits out. */
+ do {
+ short databit = (cmd & (1 << cmd_len)) ? EEDI : 0;
+ unsigned char tmp, tmp2;
+ DP_OUT(dp->base, 1, EECS | databit);
+ CYGACC_CALL_IF_DELAY_US(2000);
+ dprintf("Bit %d ... ", !!(cmd&(1<<cmd_len)));
+ DP_OUT(dp->base, 1, EECS | databit | EESK);
+ CYGACC_CALL_IF_DELAY_US(2000);
+ dprintf(" \b");
+ DP_IN(dp->base, 0, tmp2);
+ DP_IN(dp->base, 1, tmp);
+ CYGACC_CALL_IF_DELAY_US(2000);
+ retval = (retval << 1) | !!(tmp & EEDO);
+ dprintf(" \b");
+ dprintf("Got bit %d (%02x %02x)\n", retval & 1, tmp2, tmp);
+ } while (--cmd_len >= 0);
+ DP_OUT(dp->base, 1, EECS);
+ CYGACC_CALL_IF_DELAY_US(2000);
+ dprintf("Last enb...\n");
+
+ /* Terminate the EEPROM access. */
+ DP_OUT(dp->base, 1, 0x80);
+ CYGACC_CALL_IF_DELAY_US(2000);
+ dprintf("Bye. retval %x\n", retval);
+ return retval;
+}
+
+static void setmac(dp83902a_priv_data_t *dp, unsigned short *newmac)
+{
+ unsigned char old_cr, old_ee;
+ int i;
+
+ DP_IN(dp->base, DP_CR, old_cr);
+ DP_OUT(dp->base, DP_CR, old_cr | 0xc0); // Select page 3.
+ CYGACC_CALL_IF_DELAY_US(2000);
+
+ DP_IN(dp->base, 1, old_ee);
+ DP_OUT(dp->base, 1, 0x80);
+ CYGACC_CALL_IF_DELAY_US(2000);
+
+ /* Write enable */
+ eeprom_cmd(dp, (4<<6) + (0x30), 8);
+
+ for (i=0; i<3; i++) {
+ unsigned adr = i+1;
+ /* Erase word */
+// eeprom_cmd(dp, (7<<6) + (adr), 8);
+ /* Write word */
+ eeprom_cmd(dp, (5<<22) + (adr<<16) + newmac[i], 24);
+ }
+
+ /* Write disable */
+ eeprom_cmd(dp, (4<<6), 8);
+
+#if 0
+ unsigned long words[16];
+ for (i=0; i<15; i++) {
+ unsigned long cmd = (6<<22) + (i<<16);
+ words[i] = eeprom_cmd(dp, cmd /*6<<23 + (i<<16)*/, 24);
+ }
+
+ for (i=0; i<15; i++) {
+ diag_printf("Words[%d] %08x\n", i, words[i]);
+ }
+#endif
+ DP_OUT(dp->base, 1, old_ee);
+ CYGACC_CALL_IF_DELAY_US(2000);
+ DP_OUT(dp->base, DP_CR, old_cr);
+ CYGACC_CALL_IF_DELAY_US(2000);
+}
+
+
+#include <redboot.h>
+static void do_setmac(int argc, char *argv[]);
+RedBoot_cmd("setmac",
+ "Set Ethernet MAC address",
+ "<xx:xx:xx:xx:xx:xx>",
+ do_setmac
+ );
+
+static void
+do_setmac(int argc, char *argv[])
+{
+ unsigned char *mac = NULL;
+ unsigned char mac_nybble[12];
+ unsigned short mac_word[3];
+ int c, n;
+
+ if (!scan_opts(argc, argv, 1, NULL, 0, (void *)&mac,
+ OPTION_ARG_TYPE_STR, "<MAC address>"))
+ return;
+
+ if (!mac) {
+ diag_printf("Must supply MAC address\n");
+ return;
+ }
+ for (c=n=0; n<12; c++) {
+ if (mac[c] == ':' && !((c+1) % 3))
+ /* Colon in an allowed place */
+ continue;
+
+ if (mac[c] >= '0' && mac[c] <= '9')
+ mac_nybble[n] = mac[c] - '0';
+ else if (mac[c] >= 'A' && mac[c] <= 'F')
+ mac_nybble[n] = mac[c] - 'A' + 10;
+ else if (mac[c] >= 'a' && mac[c] <= 'f')
+ mac_nybble[n] = mac[c] - 'a' + 10;
+ else {
+ diag_printf("Invalid MAC address bad char %x\n", mac[c]);
+ return;
+ }
+
+ n++;
+ }
+ if (mac[c] || n!=12 || (mac_nybble[1]&1)) {
+ diag_printf("Invalid MAC address\n");
+ return;
+ }
+ mac_word[0] = (mac_nybble[2] << 12) |
+ (mac_nybble[3] << 8) |
+ (mac_nybble[0] << 4) |
+ (mac_nybble[1]);
+ mac_word[1] = (mac_nybble[6] << 12) |
+ (mac_nybble[7] << 8) |
+ (mac_nybble[4] << 4) |
+ (mac_nybble[5]);
+ mac_word[2] = (mac_nybble[10] << 12) |
+ (mac_nybble[11] << 8) |
+ (mac_nybble[8] << 4) |
+ (mac_nybble[9]);
+
+ diag_printf("Setting MAC address...");
+
+ setmac(&dp83902a_eth0_priv_data, mac_word);
+ diag_printf("... done. Reset to take effect.\n");
+ return;
+}
+#endif /* CYGPKG_REDBOOT */
+#endif // CYGPKG_DEVS_ETH_FRV400_ETH0
+
+#endif // __WANT_DEVS
+
+// --------------------------------------------------------------
+
+// EOF devs_eth_frv400.inl
diff --git a/ecos/packages/devs/eth/frv/pdk403/current/ChangeLog b/ecos/packages/devs/eth/frv/pdk403/current/ChangeLog
new file mode 100644
index 0000000..f6801c5
--- /dev/null
+++ b/ecos/packages/devs/eth/frv/pdk403/current/ChangeLog
@@ -0,0 +1,29 @@
+2004-09-09 David Woodhouse <dwmw2@redhat.com>
+
+ * include/devs_eth_pdk403.inl, src/pdk403_eth_init.c,
+ cdl/pdk403_eth_drivers.cdl: New device driver for onboard LAN,
+ based on AX88796 which is (almost) the same as DP8390 (NE2000).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/frv/pdk403/current/cdl/pdk403_eth_drivers.cdl b/ecos/packages/devs/eth/frv/pdk403/current/cdl/pdk403_eth_drivers.cdl
new file mode 100644
index 0000000..1cb0832
--- /dev/null
+++ b/ecos/packages/devs/eth/frv/pdk403/current/cdl/pdk403_eth_drivers.cdl
@@ -0,0 +1,132 @@
+# ====================================================================
+#
+# pdk403_eth_drivers.cdl
+#
+# Ethernet drivers - support for AXL88796 Ethernet controller
+# on the Fujitsu MB93093-PD01 Portable Demonstration Kit.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov, hmt, gthomas
+# Date: 2001-02-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_FRV_PDK403 {
+ display "PDK403 ethernet driver"
+ description "
+ Ethernet drivers for Fujitsu MB93093-PD01 PDK."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ requires CYGPKG_DEVS_ETH_NS_DP83902A
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ include_dir cyg/io
+
+ compile -library=libextras.a pdk403_eth_init.c
+
+ # FIXME: This really belongs in the NS DP83902A package
+ cdl_interface CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED {
+ display "NS DP83902A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_INL <cyg/io/devs_eth_pdk403.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_CFG <pkgconf/devs_eth_frv_pdk403.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_PDK403_ETH0 {
+ display "AXL88796 ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ AXL88796 Ethernet port on the PDK403 board."
+
+ implements CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_PDK403_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_PDK403_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_PDK403_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_PDK403_OPTIONS {
+ display "PCMCIA ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_PDK403_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the PCMCIA ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
+
+# EOF pdk403_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/frv/pdk403/current/include/devs_eth_pdk403.inl b/ecos/packages/devs/eth/frv/pdk403/current/include/devs_eth_pdk403.inl
new file mode 100644
index 0000000..52e66c4
--- /dev/null
+++ b/ecos/packages/devs/eth/frv/pdk403/current/include/devs_eth_pdk403.inl
@@ -0,0 +1,134 @@
+//==========================================================================
+//
+// devs/eth/frv/pdk403/..../include/devs_eth_pdk403.inl
+//
+// PDK403 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, hmt, gthomas
+// Contributors: jskov
+// Date: 2001-02-28
+// Purpose: PDK403 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+#include <cyg/hal/hal_if.h>
+
+#ifdef __WANT_CONFIG
+
+#define CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+#define CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
+
+#define CYGHWR_NS_DP83902A_PLF_INIT(dp) cyg_ax88796_eth_init(dp)
+
+#ifndef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+#define CYGHWR_NS_DP83902A_PLF_INT_CLEAR(dp) \
+ cyg_drv_interrupt_acknowledge((dp)->interrupt)
+#endif
+
+#endif // __WANT_CONFIG
+
+#ifdef __WANT_DEVS
+
+#if defined(CYGSEM_DEVS_ETH_PDK403_ETH0_SET_ESA)
+#if defined(CYGPKG_REDBOOT)
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+RedBoot_config_option("Network hardware address [MAC]",
+ lan_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#endif // CYGPKG_REDBOOT
+#include <cyg/hal/hal_if.h>
+#ifndef CONFIG_ESA
+#define CONFIG_ESA 6
+#endif
+#endif
+
+extern void cyg_ax88796_eth_init(dp83902a_priv_data_t *dp);
+
+
+#ifdef CYGPKG_DEVS_ETH_PDK403_ETH0
+
+static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
+ base : (cyg_uint8*) 0x10000200, //
+ data : (cyg_uint8*) 0x10000210, // Filled in at runtime
+ reset: (cyg_uint8*) 0x1000021f, //
+ interrupt: CYGNUM_HAL_INTERRUPT_LAN, //
+ tx_buf1: 0x40, //
+ tx_buf2: 0x48, // Buffer layout - change with care
+ rx_buf_start: 0x50, //
+ rx_buf_end: 0x80, //
+#ifdef CYGSEM_DEVS_ETH_PDK403_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_PDK403_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+};
+
+ETH_DRV_SC(dp83902a_sc,
+ &dp83902a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_PDK403_ETH0_NAME,
+ dp83902a_start,
+ dp83902a_stop,
+ dp83902a_control,
+ dp83902a_can_send,
+ dp83902a_send,
+ dp83902a_recv,
+ dp83902a_deliver, // "pseudoDSR" called from fast net thread
+ dp83902a_poll, // poll function, encapsulates ISR and DSR
+ dp83902a_int_vector);
+
+NETDEVTAB_ENTRY(dp83902a_netdev,
+ "dp83902a_" CYGDAT_DEVS_ETH_PDK403_ETH0_NAME,
+ dp83902a_init,
+ &dp83902a_sc);
+
+#endif // CYGPKG_DEVS_ETH_PDK403_ETH0
+
+#endif // __WANT_DEVS
+
+// --------------------------------------------------------------
+
+// EOF devs_eth_pdk403.inl
diff --git a/ecos/packages/devs/eth/frv/pdk403/current/src/pdk403_eth_init.c b/ecos/packages/devs/eth/frv/pdk403/current/src/pdk403_eth_init.c
new file mode 100644
index 0000000..ffd53f1
--- /dev/null
+++ b/ecos/packages/devs/eth/frv/pdk403/current/src/pdk403_eth_init.c
@@ -0,0 +1,178 @@
+//==========================================================================
+//
+// pdk403_eth_init.c
+//
+// Ethernet device driver for NS DP83902a ethernet controller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dwmw2
+// Contributors:
+// Date: 2003-11-17
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/netdev.h>
+
+#include <cyg/io/dp83902a.h>
+
+#define _EECLK 0x80
+#define _EEO 0x40
+#define _EEI 0x20
+#define _EECS 0x10
+
+void cyg_ax88796_eth_init(dp83902a_priv_data_t *dp)
+{
+ int i;
+ unsigned char x;
+#if defined(CYGSEM_DEVS_ETH_PDK403_ETH0_SET_ESA)
+ cyg_bool esa_ok;
+ unsigned char _esa[6];
+#endif
+
+ /* Reset */
+ DP_IN(dp->base, 0x1f, x);
+
+ /* Wait (but not indefinitely) for RST bit in ISR */
+ for (i=0; i < 10000; i++) {
+ DP_IN(dp->base, DP_ISR, x);
+ if (x & DP_ISR_RESET)
+ goto ready;
+ CYGACC_CALL_IF_DELAY_US(1);
+ }
+ diag_printf("AX88796 at %p not ready after 10ms. Giving up\n",
+ dp->base);
+ dp->base = 0;
+ return;
+
+ ready:
+ diag_printf("AX88796 at %p, interrupt: %x\n", dp->base, dp->interrupt);
+
+ /* Wait for 2s for link, else power cycle the PHY */
+ for (i=0; i<2000; i++) {
+ DP_IN(dp->base, 0x17, x);
+ if (x&1) {
+ diag_printf("Link OK: %dMbps %s duplex (after %d ms)\n",
+ x&4?100:10, x&2?"full":"half", i);
+ goto link_ok;
+ }
+ CYGACC_CALL_IF_DELAY_US(1000);
+ }
+ diag_printf("No Ethernet link after 2s, power cycle PHY...");
+
+ // Assert PPDSET to turn off internal PHY, wait 2s, turn it back on again.
+ DP_OUT(dp->base, 0x17, 0x40);
+ CYGACC_CALL_IF_DELAY_US(2000000);
+ DP_OUT(dp->base, 0x17, 0x00);
+ diag_printf("done.\n");
+
+ // Maybe we're not actually connected. Don't wait.
+ link_ok:
+
+#if defined(CYGSEM_DEVS_ETH_PDK403_ETH0_SET_ESA)
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "lan_esa", _esa, CONFIG_ESA);
+ if (esa_ok) {
+ memcpy(dp->esa, _esa, sizeof(_esa));
+ }
+#else
+ // Send 13 bits of EEPROM read command 0.0110.0000.0000.
+ for (i=0; i < 13; i++) {
+ x = _EECS;
+ if (i == 2 || i == 3)
+ x |= _EEI;
+
+ DP_OUT(dp->base, 0x14, x);
+ CYGACC_CALL_IF_DELAY_US(10);
+
+ DP_OUT(dp->base, 0x14, x | _EECLK);
+ CYGACC_CALL_IF_DELAY_US(10);
+ }
+
+ // Read MAC address
+ for (i=0; i<6; i++) {
+ int j;
+
+ dp->esa[i] = 0;
+ for (j=0; j<8; j++) {
+ DP_OUT(dp->base, 0x14, _EECS);
+ CYGACC_CALL_IF_DELAY_US(10);
+
+ DP_OUT(dp->base, 0x14, _EECS | _EECLK);
+ CYGACC_CALL_IF_DELAY_US(10);
+
+ DP_IN(dp->base, 0x14, x);
+
+ dp->esa[i] <<= 1;
+ dp->esa[i] |= !!(x & _EEO);
+ }
+ }
+ DP_OUT(dp->base, 0x14, _EECS);
+ CYGACC_CALL_IF_DELAY_US(20);
+ DP_OUT(dp->base, 0x14, 0);
+ CYGACC_CALL_IF_DELAY_US(20);
+ if (dp->esa[0] != 0 || dp->esa[1] != 0x0e ||
+ dp->esa[2] != 0 || dp->esa[3] != 0x50) {
+ /* Bad MAC address. PDK docs say these four bytes should always
+ be as above */
+ diag_printf("Bad EEPROM MAC address %02x:02x:%02x:%02x:%02x:%02x. Disabling AX88796\n",
+ dp->esa[0], dp->esa[1], dp->esa[2], dp->esa[3], dp->esa[4], dp->esa[5]);
+ // Turn off PHY and stop chip
+ DP_OUT(dp->base, 0x17, 0x40);
+ dp->base = 0;
+ return;
+ }
+
+ // Set ESA into chip
+ DP_OUT(dp->base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); // Select page 1
+ for (i = 0; i < 6; i++)
+ DP_OUT(dp->base, DP_P1_PAR0+i, dp->esa[i]);
+
+ DP_OUT(dp->base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); // Select page 0
+#endif
+}
diff --git a/ecos/packages/devs/eth/h8300/aki3068net/current/ChangeLog b/ecos/packages/devs/eth/h8300/aki3068net/current/ChangeLog
new file mode 100644
index 0000000..0e200e0
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/aki3068net/current/ChangeLog
@@ -0,0 +1,46 @@
+2002-12-10 Yoshinori Sato <ysato@users.sourceforge.jp>
+ * include/devs_eth_h8300_aki3068net.inl: interrupt no fix.
+
+2002-08-14 Yoshinori Sato <qzb04471@nifty.ne.jp>
+2002-08-14 Jonathan Larmour <jifl@ecoscentric.com>
+
+ * include/devs_eth_h8300_aki3068net.inl: Allow to build with
+ if_dp83902a.c changes.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_aki3068net.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-05-28 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_aki3068net.c: Remove unused includes.
+
+2002-04-24 Yoshinori Sato <qzb04471@nifty.ne.jp>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/h8300/aki3068net/current/cdl/h8300_aki3068net_eth_drivers.cdl b/ecos/packages/devs/eth/h8300/aki3068net/current/cdl/h8300_aki3068net_eth_drivers.cdl
new file mode 100644
index 0000000..8c28b56
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/aki3068net/current/cdl/h8300_aki3068net_eth_drivers.cdl
@@ -0,0 +1,130 @@
+# ====================================================================
+#
+# h8300_aki3068net_eth_drivers.cdl
+#
+# Ethernet drivers - support for DP83902A(RTL8019AS)
+# ethernet controller on the Akizuki H8/3068 Network micom.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):
+# Contributors:
+# Date:
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_H8300_AKI3068NET {
+ display "aki3068net board ethernet driver"
+ description "
+ Ethernet driver for Akizuki
+ H8/3068 Netwotk Micom board"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_H8300_H8300H_AKI3068NET
+ compile -library=libextras.a if_aki3068net.c
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the NS DP83902A package
+ cdl_interface CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED {
+ display "NS dp83902a ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_INL <cyg/io/devs_eth_h8300_aki3068net.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_CFG <pkgconf/devs_eth_h8300_aki3068net.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_H8300_AKI3068NET_ETH0 {
+ display "Ethernet port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ implements CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_H8300_AKI3068NET_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ RTL8019AS ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_H8300_AKI3068NET_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_H8300_AKI3068NET_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x00, 0x00, 0x00, 0x00, 0x01}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_H8300_AKI3068NET_OPTIONS {
+ display "PCMCIA ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_CF_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the PCMCIA ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/h8300/aki3068net/current/include/devs_eth_h8300_aki3068net.inl b/ecos/packages/devs/eth/h8300/aki3068net/current/include/devs_eth_h8300_aki3068net.inl
new file mode 100644
index 0000000..c28b7c1
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/aki3068net/current/include/devs_eth_h8300_aki3068net.inl
@@ -0,0 +1,95 @@
+//==========================================================================
+//
+// devs_eth_h8300_aki3068net.inl
+//
+// DP83902(RTL8019AS) ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):
+// Contributors:
+// Date:
+// Purpose: aki3068net ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+#include <cyg/hal/hal_if.h>
+
+#define CYGHWR_NS_DP83902A_PLF_INIT ns_dp83902a_plf_init
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_H8300_AKI3068NET_ETH0
+
+static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
+ base: (cyg_uint8 *)0x200000,
+ interrupt: 17,
+ tx_buf1: 0x40,
+ tx_buf2: 0x48,
+ rx_buf_start: 0x50,
+ rx_buf_end: 0x80,
+#ifdef CYGSEM_DEVS_ETH_H8300_AKI3068NET_ETH0_SET_ESA
+ hardwired_esa: true,
+ mac_address: CYGDAT_DEVS_ETH_H8300_AKI3068NET_ETH0_ESA
+#else
+ hardwired_esa: false,
+#endif
+};
+
+ETH_DRV_SC(dp83902a_sc,
+ &dp83902a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_H8300_AKI3068NET_ETH0_NAME,
+ dp83902a_start,
+ dp83902a_stop,
+ dp83902a_control,
+ dp83902a_can_send,
+ dp83902a_send,
+ dp83902a_recv,
+ dp83902a_deliver, // "pseudoDSR" called from fast net thread
+ dp83902a_poll, // poll function, encapsulates ISR and DSR
+ dp83902a_int_vector);
+
+NETDEVTAB_ENTRY(dp83902a_netdev,
+ "dp83902a_" CYGDAT_DEVS_ETH_H8300_AKI3068NET_ETH0_NAME,
+ dp83902a_init,
+ &dp83902a_sc);
+
+void ns_dp83902a_plf_init(dp83902a_priv_data_t *dp);
+
+#endif // CYGPKG_DEVS_ETH_H8300_AKI3068NET_ETH0
+#endif
+// EOF devs_eth_h8300_aki3068net.inl
diff --git a/ecos/packages/devs/eth/h8300/aki3068net/current/src/if_aki3068net.c b/ecos/packages/devs/eth/h8300/aki3068net/current/src/if_aki3068net.c
new file mode 100644
index 0000000..4fe0585
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/aki3068net/current/src/if_aki3068net.c
@@ -0,0 +1,114 @@
+//==========================================================================
+//
+// if_aki3068net.c
+//
+// Ethernet device driver for Akizuki H8/3068 Netwotk micom
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):
+// Contributors:
+// Date:
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/netdev.h>
+
+#define DP_CARD_RESET 0x1f
+
+#include <cyg/io/dp83902a.h>
+
+void ns_dp83902a_plf_init(dp83902a_priv_data_t *dp)
+{
+ static struct {
+ unsigned short offset;
+ unsigned short data;
+ } init_data[] = {
+ {DP_DCR, 0x48}, // Bytewide access
+ {DP_RBCH, 0}, // Remote byte count
+ {DP_RBCL, 0},
+ {DP_ISR, 0xFF}, // Clear any pending interrupts
+ {DP_IMR, 0x00}, // Mask all interrupts
+ {DP_RCR, 0x20}, // Monitor
+ {DP_TCR, 0x02}, // loopback
+ {DP_RBCH, 32}, // Remote byte count
+ {DP_RBCL, 0},
+ {DP_RSAL, 0}, // Remote address
+ {DP_RSAH, 0},
+ {DP_CR, DP_CR_START|DP_CR_RDMA} // Read data
+ };
+ unsigned char prom[32];
+ int cnt,tmp;
+
+ HAL_READ_UINT8(dp->base+DP_CARD_RESET, tmp);
+ HAL_WRITE_UINT8(dp->base+DP_CARD_RESET, tmp);
+ dp->data = dp->base+DP_DATAPORT;
+ // Wait for card
+ do {
+ int cnt;
+ DP_IN(dp->base, DP_ISR, tmp);
+ for (cnt=0; cnt< 1024; cnt++);
+ } while (0 == (tmp & DP_ISR_RESET));
+
+ if (dp->hardwired_esa)
+ return ;
+
+ for (cnt=0; cnt<sizeof(init_data)/sizeof(init_data[0]); cnt++)
+ DP_OUT(dp->base, init_data[cnt].offset, init_data[cnt].data);
+ for (cnt = 0; cnt < 32; cnt++)
+ DP_IN_DATA(dp->data, prom[cnt]);
+ if ((prom[0] == 0xff) && (prom[2] == 0xff) && (prom[4] == 0xff)) {
+ dp->base = 0;
+ return ;
+ }
+ DP_OUT(dp->base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1);
+ for (cnt = 0; cnt < 6; cnt ++) {
+ DP_OUT(dp->base, DP_P1_PAR0+cnt, prom[cnt*2]);
+ }
+}
diff --git a/ecos/packages/devs/eth/h8300/edosk2674/current/ChangeLog b/ecos/packages/devs/eth/h8300/edosk2674/current/ChangeLog
new file mode 100644
index 0000000..607afa8
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/edosk2674/current/ChangeLog
@@ -0,0 +1,28 @@
+2003-02-26 Yoshinori Sato <ysato@users.sourceforge.jp>
+
+ * Initial version of support for LAN91CXX ethernet controller
+ on the HMSE EDOSK-2674 board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/h8300/edosk2674/current/cdl/h8300_edosk2674_eth_drivers.cdl b/ecos/packages/devs/eth/h8300/edosk2674/current/cdl/h8300_edosk2674_eth_drivers.cdl
new file mode 100644
index 0000000..b9473a9
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/edosk2674/current/cdl/h8300_edosk2674_eth_drivers.cdl
@@ -0,0 +1,112 @@
+# ====================================================================
+#
+# edosk2674_eth_drivers.cdl
+#
+# Ethernet drivers - support for LAN91CXX ethernet controller
+# on the EDOSK-2674 board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): yoshinori sato
+# Contributors: yoshinori sato
+# Date: 2003-02-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_H8300_EDOSK2674 {
+
+ display "EDOSK-2674 SMC91C96 ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_H8300_H8S_EDOSK2674
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
+ implements CYGSEM_DEVS_ETH_SMSC_LAN91CXX_8_BIT
+
+ description "Ethernet driver for EDOSK-2674 boards."
+
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL <cyg/io/devs_eth_edosk2674.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG <pkgconf/devs_eth_h8300_edosk2674.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+
+ cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
+ display "SMSC LAN91CXX driver required"
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_H8300_EDOSK2674_NAME {
+ display "Device name for the ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ ethernet port."
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_H8300_EDOSK2674_ESA {
+ display "The ethernet station address (MAC)"
+ flavor data
+ default_value {"{0x12, 0x13, 0x14, 0x15, 0x16, 0x17}"}
+ description "A static ethernet station address.
+ Caution: Booting two systems with the same MAC on the same
+ network, will cause severe conflicts."
+ active_if !CYGSEM_DEVS_ETH_ARM_FLEXANET_REDBOOT_ESA
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_H8300_EDOSK2674_ETH0_SET_ESA {
+ display "Use the RedBoot ESA (MAC address)"
+ default_value 0
+ flavor bool
+ description "
+ Use the ESA that is stored as a RedBoot variable instead of
+ a static ESA."
+ }
+
+}
+
+# EOF flexanet_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/h8300/edosk2674/current/include/devs_eth_edosk2674.inl b/ecos/packages/devs/eth/h8300/edosk2674/current/include/devs_eth_edosk2674.inl
new file mode 100644
index 0000000..0843d5a
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/edosk2674/current/include/devs_eth_edosk2674.inl
@@ -0,0 +1,87 @@
+//==========================================================================
+//
+// devs/eth/h8300/edosk2674/...../include/devs_eth_edosk2674.inl
+//
+// EDOSK-2674 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Yoshinori Sato <ysato@users.sourceforge.jp>
+// Contributors: ysato
+// Date: 2003-02-25
+// Purpose: EDOSK-2674 ethernet definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_h8300_edosk2674.h>
+#include <cyg/hal/hal_intr.h>
+
+// MAC address is stored as a Redboot config option
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#endif
+
+static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_H8300_EDOSK2674_ETH0_SET_ESA
+ enaddr : CYGDAT_DEVS_ETH_H8300_EDOSK2674_ESA,
+#endif
+ base : (unsigned short *)0xf80000,
+ interrupt : 16
+};
+
+ETH_DRV_SC(lan91cxx_sc,
+ &lan91cxx_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_H8300_EDOSK2674_NAME, // Name for device
+ lan91cxx_start,
+ lan91cxx_stop,
+ lan91cxx_control,
+ lan91cxx_can_send,
+ lan91cxx_send,
+ lan91cxx_recv,
+ lan91cxx_deliver,
+ lan91cxx_poll,
+ lan91cxx_int_vector
+);
+
+NETDEVTAB_ENTRY(lan91cxx_netdev,
+ "lan91cxx_" CYGDAT_DEVS_ETH_H8300_EDOSK2674_NAME,
+ smsc_lan91cxx_init,
+ &lan91cxx_sc);
+
+//EOF devs_eth_flexanet.inl
+
+
diff --git a/ecos/packages/devs/eth/h8300/h8max/current/ChangeLog b/ecos/packages/devs/eth/h8300/h8max/current/ChangeLog
new file mode 100644
index 0000000..269dae6
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/h8max/current/ChangeLog
@@ -0,0 +1,31 @@
+2002-05-28 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_aki3068net.c: Remove unused includes.
+
+2002-04-24 Yoshinori Sato <qzb04471@nifty.ne.jp>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/h8300/h8max/current/cdl/h8300_h8max_eth_drivers.cdl b/ecos/packages/devs/eth/h8300/h8max/current/cdl/h8300_h8max_eth_drivers.cdl
new file mode 100644
index 0000000..3a58d97
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/h8max/current/cdl/h8300_h8max_eth_drivers.cdl
@@ -0,0 +1,129 @@
+# ====================================================================
+#
+# h8300_h8max_eth_drivers.cdl
+#
+# Ethernet drivers - support for DP83902A(RTL8019AS)
+# ethernet controller on the H8MAX board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ysato
+# Contributors: ysato
+# Date: 2002-08-10
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_H8300_H8MAX {
+ display "H8MAX board ethernet driver"
+ description "
+ Ethernet driver for H8MAX"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_H8300_H8300H_H8MAX
+ compile -library=libextras.a if_h8max.c
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the NS DP83902A package
+ cdl_interface CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED {
+ display "NS dp83902a ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_INL <cyg/io/devs_eth_h8300_h8max.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_CFG <pkgconf/devs_eth_h8300_h8max.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_H8300_H8MAX_ETH0 {
+ display "Ethernet port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ implements CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_H8300_H8MAX_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ RTL8019AS ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_H8300_H8MAX_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_H8300_H8MAX_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x00, 0x00, 0x00, 0x00, 0x01}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_H8300_AKI3068NET_OPTIONS {
+ display "PCMCIA ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_CF_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the PCMCIA ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/h8300/h8max/current/include/devs_eth_h8300_h8max.inl b/ecos/packages/devs/eth/h8300/h8max/current/include/devs_eth_h8300_h8max.inl
new file mode 100644
index 0000000..dfdcf38
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/h8max/current/include/devs_eth_h8300_h8max.inl
@@ -0,0 +1,100 @@
+//==========================================================================
+//
+// devs_eth_h8300_h8max.inl
+//
+// DP83902(RTL8019AS) ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Yoshinori Sato
+// Contributors: Yoshinori Sato
+// Date: 2002-08-10
+// Purpose: h8max ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+#include <cyg/hal/hal_if.h>
+
+#define CYGHWR_NS_DP83902A_PLF_INIT ns_dp83902a_plf_init
+#define CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+#define BIGEND
+#define DELAY()
+#define DP_IN(_b_, _o_, _d_) HAL_READ_UINT8 ((cyg_addrword_t)(_b_)+((_o_)<<1)+1, (_d_))
+#define DP_OUT(_b_, _o_, _d_) HAL_WRITE_UINT16((cyg_addrword_t)(_b_)+((_o_)<<1), (_d_))
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_H8300_H8MAX_ETH0
+
+static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
+ base: (cyg_uint8 *)0x800600,
+ interrupt: 16,
+ tx_buf1: 0x40,
+ tx_buf2: 0x48,
+ rx_buf_start: 0x50,
+ rx_buf_end: 0x80,
+#ifdef CYGSEM_DEVS_ETH_H8300_H8MAX_ETH0_SET_ESA
+ hardwired_esa: true,
+ mac_address: CYGDAT_DEVS_ETH_H8300_H8MAX_ETH0_ESA
+#else
+ hardwired_esa: false,
+#endif
+};
+
+ETH_DRV_SC(dp83902a_sc,
+ &dp83902a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_H8300_H8MAX_ETH0_NAME,
+ dp83902a_start,
+ dp83902a_stop,
+ dp83902a_control,
+ dp83902a_can_send,
+ dp83902a_send,
+ dp83902a_recv,
+ dp83902a_deliver, // "pseudoDSR" called from fast net thread
+ dp83902a_poll, // poll function, encapsulates ISR and DSR
+ dp83902a_int_vector);
+
+NETDEVTAB_ENTRY(dp83902a_netdev,
+ "dp83902a_" CYGDAT_DEVS_ETH_H8300_H8MAX_ETH0_NAME,
+ dp83902a_init,
+ &dp83902a_sc);
+
+void ns_dp83902a_plf_init(dp83902a_priv_data_t *dp);
+
+#endif // CYGPKG_DEVS_ETH_H8300_H8MAX_ETH0
+#endif
+// EOF devs_eth_h8300_h8max.inl
diff --git a/ecos/packages/devs/eth/h8300/h8max/current/src/if_h8max.c b/ecos/packages/devs/eth/h8300/h8max/current/src/if_h8max.c
new file mode 100644
index 0000000..03857e1
--- /dev/null
+++ b/ecos/packages/devs/eth/h8300/h8max/current/src/if_h8max.c
@@ -0,0 +1,100 @@
+//==========================================================================
+//
+// if_h8max.c
+//
+// Ethernet device driver for H8MAX board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/netdev.h>
+
+#define DP_CARD_RESET 0x1f
+
+#include <cyg/io/dp83902a.h>
+
+void ns_dp83902a_plf_init(dp83902a_priv_data_t *dp)
+{
+ static struct {
+ unsigned short offset;
+ unsigned short data;
+ } init_data[] = {
+ {DP_DCR, 0x49}, // Wordwide access
+ {DP_RBCH, 0}, // Remote byte count
+ {DP_RBCL, 0},
+ {DP_ISR, 0xFF}, // Clear any pending interrupts
+ {DP_IMR, 0x00}, // Mask all interrupts
+ {DP_RCR, 0x20}, // Monitor
+ {DP_TCR, 0x02}, // loopback
+ {DP_RBCH, 32/2}, // Remote byte count
+ {DP_RBCL, 0},
+ {DP_RSAL, 0}, // Remote address
+ {DP_RSAH, 0},
+ {DP_CR, DP_CR_START|DP_CR_RDMA} // Read data
+ };
+ unsigned short prom[32];
+ int cnt,tmp;
+
+ HAL_READ_UINT8(dp->base+(DP_CARD_RESET<<1)+1, tmp);
+ HAL_WRITE_UINT16(dp->base+(DP_CARD_RESET<<1), tmp);
+ dp->data = dp->base+(DP_DATAPORT<<1);
+ // Wait for card
+ do {
+ int cnt;
+ DP_IN(dp->base, DP_ISR, tmp);
+ for (cnt=0; cnt< 1024; cnt++);
+ } while (0 == (tmp & DP_ISR_RESET));
+ if (dp->hardwired_esa)
+ return ;
+
+ for (cnt=0; cnt<sizeof(init_data)/sizeof(init_data[0]); cnt++)
+ DP_OUT(dp->base, init_data[cnt].offset, init_data[cnt].data);
+ for (cnt = 0; cnt < 32/2; cnt++) {
+ DP_IN_DATA(dp->data, prom[cnt]);
+ }
+ if ((prom[0] == 0xffff) && (prom[1] == 0xffff) && (prom[2] == 0xffff)) {
+ dp->base = 0;
+ return ;
+ }
+ DP_OUT(dp->base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1);
+ for (cnt = 0; cnt < 6; cnt ++) {
+ DP_OUT(dp->base, DP_P1_PAR0+cnt, prom[cnt] >> 8);
+ }
+}
diff --git a/ecos/packages/devs/eth/i386/pc/i82544/current/ChangeLog b/ecos/packages/devs/eth/i386/pc/i82544/current/ChangeLog
new file mode 100644
index 0000000..0ee6e32
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/i82544/current/ChangeLog
@@ -0,0 +1,30 @@
+2001-11-27 Nick Garnett <nickg@redhat.com>
+
+ * include/devs_eth_i386_pc_i82544.inl:
+ * cdl/i386_pc_i82544_eth_drivers.cdl:
+ Platform specific configury and definitions to use the generic
+ i82543/i82544 driver for PC platforms.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/i386/pc/i82544/current/cdl/i386_pc_i82544_eth_drivers.cdl b/ecos/packages/devs/eth/i386/pc/i82544/current/cdl/i386_pc_i82544_eth_drivers.cdl
new file mode 100644
index 0000000..c86f8fb
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/i82544/current/cdl/i386_pc_i82544_eth_drivers.cdl
@@ -0,0 +1,108 @@
+# ====================================================================
+#
+# i386_pc_eth_drivers.cdl
+#
+# Ethernet drivers - support for i82544 ethernet controller
+# on the PC.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov, nickg
+# Contributors: jskov
+# Date: 2001-11-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_I386_PC_I82544 {
+ display "PC board ethernet driver"
+ description "Ethernet driver for PC."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_I386_PC
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82544 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82544_REQUIRED {
+ display "Intel i82544 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82544_INL <cyg/io/devs_eth_i386_pc_i82544.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82544_CFG <pkgconf/devs_eth_i386_pc_i82544.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_I386_PC_I82544_ETH0 {
+ display "Ethernet port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82544_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_I386_PC_I82544_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ i82544 ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_I386_PC_I82544_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_I386_PC_I82544_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x00, 0x00, 0x00, 0x00, 0x01}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/i386/pc/i82544/current/include/devs_eth_i386_pc_i82544.inl b/ecos/packages/devs/eth/i386/pc/i82544/current/include/devs_eth_i386_pc_i82544.inl
new file mode 100644
index 0000000..488ef30
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/i82544/current/include/devs_eth_i386_pc_i82544.inl
@@ -0,0 +1,112 @@
+//==========================================================================
+//
+// devs/eth/mips/ocelot/include/devs_eth_mips_rm7000_ocelot.inl
+//
+// PC i82544 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, nickg
+// Contributors:jskov
+// Date: 2001-11-25
+// Purpose: PC i82544 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#ifdef CYGPKG_DEVS_ETH_I386_PC_I82544_ETH0
+
+#define CYGHWR_INTEL_I82544_PCI_MEM_MAP_BASE (CYGARC_UNCACHED_ADDRESS(CYGMEM_SECTION_pci_window))
+#define CYGHWR_INTEL_I82544_PCI_MEM_MAP_SIZE CYGMEM_SECTION_pci_window_SIZE
+
+static I82544 i82544_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_I386_PC_I82544_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_I386_PC_I82544_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82544_sc0,
+ &i82544_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_I386_PC_I82544_ETH0_NAME, // Name for device
+ i82544_start,
+ i82544_stop,
+ i82544_ioctl,
+ i82544_can_send,
+ i82544_send,
+ i82544_recv,
+ i82544_deliver,
+ i82544_poll,
+ i82544_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82544_netdev0,
+ "i82544_" CYGDAT_DEVS_ETH_I386_PC_I82544_ETH0_NAME,
+ i82544_init,
+ &i82544_sc0);
+
+#endif // CYGPKG_DEVS_ETH_I386_PC_I82544_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+I82544 *
+i82544_priv_array[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_I386_PC_I82544_ETH0
+ &i82544_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82544_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_I386_PC_I82544_ETH0
+ &i82544_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+i82544_sc_array[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_I386_PC_I82544_ETH0
+ &i82544_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// EOF devs_eth_i386_pc_i82544.inl
diff --git a/ecos/packages/devs/eth/i386/pc/i82559/current/ChangeLog b/ecos/packages/devs/eth/i386/pc/i82559/current/ChangeLog
new file mode 100644
index 0000000..1cfe4ae
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/i82559/current/ChangeLog
@@ -0,0 +1,35 @@
+2001-04-26 Nick Garnett <nickg@cygnus.co.uk>
+
+ * cdl/i386_pc_i82559_eth_drivers.cdl: Fixed configuration to fetch
+ MAC address from EEPROM, as it should.
+
+2001-03-06 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/devs_eth_i386_pc_i82559.inl:
+ * cdl/i386_pc_i82559_eth_drivers.cdl:
+ Platform specific configury and definitions to use the generic
+ i82559 driver for PC platforms.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/i386/pc/i82559/current/cdl/i386_pc_i82559_eth_drivers.cdl b/ecos/packages/devs/eth/i386/pc/i82559/current/cdl/i386_pc_i82559_eth_drivers.cdl
new file mode 100644
index 0000000..5cdc5b6
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/i82559/current/cdl/i386_pc_i82559_eth_drivers.cdl
@@ -0,0 +1,108 @@
+# ====================================================================
+#
+# i386_pc_eth_drivers.cdl
+#
+# Ethernet drivers - support for i82559 ethernet controller
+# on the PC.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-01-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_I386_PC_I82559 {
+ display "PC board ethernet driver"
+ description "Ethernet driver for PC."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_I386_PC
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82559 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
+ display "Intel i82559 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_i386_pc_i82559.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_i386_pc_i82559.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_I386_PC_I82559_ETH0 {
+ display "Ethernet port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_I386_PC_I82559_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ i82559 ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_I386_PC_I82559_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_I386_PC_I82559_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x00, 0x00, 0x00, 0x00, 0x01}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/i386/pc/i82559/current/include/devs_eth_i386_pc_i82559.inl b/ecos/packages/devs/eth/i386/pc/i82559/current/include/devs_eth_i386_pc_i82559.inl
new file mode 100644
index 0000000..13db265
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/i82559/current/include/devs_eth_i386_pc_i82559.inl
@@ -0,0 +1,112 @@
+//==========================================================================
+//
+// devs/eth/mips/ocelot/include/devs_eth_mips_rm7000_ocelot.inl
+//
+// PC i82559 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-01-25
+// Purpose: PC i82559 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#ifdef CYGPKG_DEVS_ETH_I386_PC_I82559_ETH0
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE (CYGARC_UNCACHED_ADDRESS(CYGMEM_SECTION_pci_window))
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE CYGMEM_SECTION_pci_window_SIZE
+
+static I82559 i82559_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_I386_PC_I82559_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_I386_PC_I82559_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc0,
+ &i82559_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_I386_PC_I82559_ETH0_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev0,
+ "i82559_" CYGDAT_DEVS_ETH_I386_PC_I82559_ETH0_NAME,
+ i82559_init,
+ &i82559_sc0);
+
+#endif // CYGPKG_DEVS_ETH_I386_PC_I82559_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+I82559 *
+i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_I386_PC_I82559_ETH0
+ &i82559_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_I386_PC_I82559_ETH0
+ &i82559_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_I386_PC_I82559_ETH0
+ &i82559_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// EOF devs_eth_i386_pc_i82559.inl
diff --git a/ecos/packages/devs/eth/i386/pc/lancepci/current/ChangeLog b/ecos/packages/devs/eth/i386/pc/lancepci/current/ChangeLog
new file mode 100644
index 0000000..69de8ff
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/lancepci/current/ChangeLog
@@ -0,0 +1,28 @@
+2002-07-17 Iztok Zupet <iz@vsr.si>
+
+ * all: Platform specific information to use generic AMD Lance
+ PCI driver for the PC platform
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/i386/pc/lancepci/current/cdl/i386_pc_lancepci_eth_drivers.cdl b/ecos/packages/devs/eth/i386/pc/lancepci/current/cdl/i386_pc_lancepci_eth_drivers.cdl
new file mode 100644
index 0000000..e8c53db
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/lancepci/current/cdl/i386_pc_lancepci_eth_drivers.cdl
@@ -0,0 +1,128 @@
+# ====================================================================
+#
+# pc_lancepci_eth_drivers.cdl
+#
+# Ethernet drivers - support for AMD Lance PCI ethernet controller
+# on the i386 PC (also wmWare)
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): iz
+# Contributors:
+# Date: 2002-07-17
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_I386_PC_LANCEPCI {
+ display "PC Lance PCI board ethernet driver"
+ description "Ethernet driver for PCI Lance."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the AMD_LANCEPCI package
+ cdl_interface CYGINT_DEVS_ETH_AMD_LANCEPCI_REQUIRED {
+ display "AMD Lance PCI ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_LANCEPCI_INL <cyg/io/devs_eth_i386_pc_lancepci.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_LANCEPCI_CFG <pkgconf/devs_eth_i386_pc_lancepci.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_I386_PC_LANCEPCI_ETH0 {
+ display "Lance PCI ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ PC (vmWare) Lance PCI port 0."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_AMD_LANCEPCI_REQUIRED
+
+ cdl_option CYGNUM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_RX_RING_SIZE {
+ display "Size of RX ring for ETH0"
+ flavor data
+ default_value 4
+ legal_values { 4 8 16 32 64 128 }
+ description "
+ This option sets the size of the RX ring."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_TX_RING_SIZE {
+ display "Size of TX ring for ETH0"
+ flavor data
+ default_value 4
+ legal_values { 4 8 16 32 64 128 }
+ description "
+ This option sets the size of the TX ring."
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_I386_PC_LANCEPCI_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ PC Lance port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_I386_PC_LANCEPCI_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/i386/pc/lancepci/current/include/devs_eth_i386_pc_lancepci.inl b/ecos/packages/devs/eth/i386/pc/lancepci/current/include/devs_eth_i386_pc_lancepci.inl
new file mode 100644
index 0000000..622f82a
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/lancepci/current/include/devs_eth_i386_pc_lancepci.inl
@@ -0,0 +1,110 @@
+//==========================================================================
+//
+// devs/eth/i386/pc/include/devs_eth_i386_pc_lancepci.inl
+//
+// PC Lance PCI ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): iz
+// Contributors:
+// Date: 2002-07-17
+// Purpose: PC Lance PCI (VLANCE device in vmWare) ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#ifdef __WANT_CONFIG
+#define CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_BASE (CYGARC_UNCACHED_ADDRESS(CYGMEM_SECTION_pci_window))
+#define CYGHWR_AMD_LANCEPCI_PCI_MEM_MAP_SIZE CYGMEM_SECTION_pci_window_SIZE
+#define HAL_PCI_CPU_TO_BUS(__cpu_addr, __bus_addr) \
+ CYG_MACRO_START \
+ (__bus_addr) = CYGARC_PHYSICAL_ADDRESS(__cpu_addr); \
+ CYG_MACRO_END
+#endif // __WANT_CONFIG
+
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_I386_PC_LANCEPCI_ETH0
+
+static lancepci_priv_data amd_lancepci_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_I386_PC_LANCEPCI_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+ config_esa : NULL, // rely on the hardwired address for now
+ rx_ring : NULL,
+ rx_ring_cnt : CYGNUM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_RX_RING_SIZE,
+ rx_ring_log_cnt : 2,
+ tx_ring : NULL,
+ tx_ring_cnt : CYGNUM_DEVS_ETH_I386_PC_LANCEPCI_ETH0_TX_RING_SIZE,
+ tx_ring_log_cnt : 2,
+};
+
+ETH_DRV_SC(amd_lancepci_sc,
+ &amd_lancepci_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_I386_PC_LANCEPCI_ETH0_NAME,
+ lancepci_start,
+ lancepci_stop,
+ lancepci_control,
+ lancepci_can_send,
+ lancepci_send,
+ lancepci_recv,
+ lancepci_deliver, // "pseudoDSR" called from fast net thread
+ lancepci_poll, // poll function, encapsulates ISR and DSR
+ lancepci_int_vector);
+
+NETDEVTAB_ENTRY(lancepci_netdev,
+ "lancepci_" CYGDAT_DEVS_ETH_I386_PC_LANCEPCI_ETH0_NAME,
+ amd_lancepci_init,
+ &amd_lancepci_sc);
+#endif // CYGPKG_DEVS_ETH_I386_PC_LANCEPCI_ETH0
+
+// These arrays are used for sanity checking of pointers
+struct lancepci_priv_data *
+lancepci_priv_array[CYGNUM_DEVS_ETH_AMD_LANCEPCI_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_I386_PC_LANCEPCI_ETH0
+ &amd_lancepci_eth0_priv_data,
+#endif
+};
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_pc_lancepci.inl
diff --git a/ecos/packages/devs/eth/i386/pc/rltk8139/current/ChangeLog b/ecos/packages/devs/eth/i386/pc/rltk8139/current/ChangeLog
new file mode 100644
index 0000000..4277efd
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/rltk8139/current/ChangeLog
@@ -0,0 +1,34 @@
+2005-03-03 Bob Koninckx <bob.koninckx@fmtc.be>
+
+ * include/devs_eth_i386_pc_rltk8139.inl:
+ Added support for a second rltl8139 interface
+
+2003-07-09 Eric Doenges <Eric.Doenges@DynaPel.com>
+
+ * include/devs_eth_i386_pc_rltk8139.inl:
+ * cdl/i386_pc_rltk8139_eth_drivers.cdl:
+ New package - RTL8139 PCI ethernet card driver
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/i386/pc/rltk8139/current/cdl/i386_pc_rltk8139_eth_drivers.cdl b/ecos/packages/devs/eth/i386/pc/rltk8139/current/cdl/i386_pc_rltk8139_eth_drivers.cdl
new file mode 100644
index 0000000..b9e98d6
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/rltk8139/current/cdl/i386_pc_rltk8139_eth_drivers.cdl
@@ -0,0 +1,110 @@
+# ====================================================================
+#
+# i386_pc_rltk8139_eth_drivers.cdl
+#
+# Ethernet drivers - support for RealTek 8139 ethernet controller
+# on i386 PC target
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Eric Doenges
+# Contributors:
+# Date: 2003-07-16
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_I386_PC_RLTK8139 {
+ display "PC RealTek 8139 ethernet driver"
+ description "Ethernet driver for standard PC's."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_I386_PC
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the RealTek_8139 package ?
+ cdl_interface CYGINT_DEVS_ETH_RLTK_8139_REQUIRED {
+ display "RealTek 8139 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_RLTK_8139_INL <cyg/io/devs_eth_i386_pc_rltk8139.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_RLTK_8139_CFG <pkgconf/devs_eth_i386_pc_rltk8139.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_I386_PC_RLTK8139_ETH0 {
+ display "Ethernet port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_RLTK_8139_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_I386_PC_RLTK8139_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ RealTek 8139 ethernet port 0."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_I386_PC_RLTK8139_ETH1 {
+ display "Ethernet port 1 driver"
+ flavor bool
+ default_value 0
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH1
+ implements CYGINT_DEVS_ETH_RLTK_8139_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_I386_PC_RLTK8139_ETH1_NAME {
+ display "Device name for the ETH1 ethernet port 1 driver"
+ flavor data
+ default_value {"\"eth1\""}
+ description "
+ This option sets the name of the ethernet device for the
+ RealTek 8139 ethernet port 1."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/i386/pc/rltk8139/current/include/devs_eth_i386_pc_rltk8139.inl b/ecos/packages/devs/eth/i386/pc/rltk8139/current/include/devs_eth_i386_pc_rltk8139.inl
new file mode 100644
index 0000000..28a8fe5
--- /dev/null
+++ b/ecos/packages/devs/eth/i386/pc/rltk8139/current/include/devs_eth_i386_pc_rltk8139.inl
@@ -0,0 +1,120 @@
+//==========================================================================
+//
+// devs/eth/i386/pc/rltk8139/include/devs_eth_i386_pc_rltk8139.inl
+//
+// i386 PC RealTek 8139 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Eric Doenges
+// Contributors:
+// Date: 2003-07-16
+// Purpose: i386 PC RealTek 8139 ethernet definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+//
+// CAUTION! This driver has *not* been tested on PC hardware. It may work
+// or not :-) If there are problems, they are probably cache related.
+// If you find such, please let us know.
+//
+//#define CYGPKG_DEVS_ETH_RLTK_8139_SOFTWARE_CACHE_COHERENCY
+
+#define CACHE_ALIGNED __attribute__ ((aligned (HAL_DCACHE_LINE_SIZE)))
+
+#ifdef CYGPKG_DEVS_ETH_I386_PC_RLTK8139_ETH0
+
+static cyg_uint8 rltk8139_eth0_rx_ring[RX_BUF_TOT_LEN] CACHE_ALIGNED;
+static cyg_uint8
+rltk8139_eth0_tx_buffer[(TX_BUF_TOT_LEN + HAL_DCACHE_LINE_SIZE - 1)
+ & ~(HAL_DCACHE_LINE_SIZE - 1)] CACHE_ALIGNED;
+static Rltk8139_t rltk8139_eth0_priv_data = {
+ 0, rltk8139_eth0_rx_ring, rltk8139_eth0_tx_buffer
+};
+
+ETH_DRV_SC(rltk8139_sc0,
+ &rltk8139_eth0_priv_data,
+ CYGDAT_DEVS_ETH_I386_PC_RLTK8139_ETH0_NAME,
+ rltk8139_start,
+ rltk8139_stop,
+ rltk8139_control,
+ rltk8139_can_send,
+ rltk8139_send,
+ rltk8139_recv,
+ rltk8139_deliver,
+ rltk8139_poll,
+ rltk8139_int_vector
+ );
+
+NETDEVTAB_ENTRY(rltk8139_netdev0,
+ "rltk8139_" CYGDAT_DEVS_ETH_I386_PC_RLTK8139_ETH0_NAME,
+ rltk8139_init,
+ &rltk8139_sc0);
+
+#endif // CYGPKG_DEVS_ETH_I386_PC_RLTK8139_ETH0
+
+#ifdef CYGPKG_DEVS_ETH_I386_PC_RLTK8139_ETH1
+
+static cyg_uint8 rltk8139_eth1_rx_ring[RX_BUF_TOT_LEN] CACHE_ALIGNED;
+static cyg_uint8
+rltk8139_eth1_tx_buffer[(TX_BUF_TOT_LEN + HAL_DCACHE_LINE_SIZE - 1)
+ & ~(HAL_DCACHE_LINE_SIZE - 1)] CACHE_ALIGNED;
+static Rltk8139_t rltk8139_eth1_priv_data = {
+ 1, rltk8139_eth1_rx_ring, rltk8139_eth1_tx_buffer
+};
+
+ETH_DRV_SC(rltk8139_sc1,
+ &rltk8139_eth1_priv_data,
+ CYGDAT_DEVS_ETH_I386_PC_RLTK8139_ETH1_NAME,
+ rltk8139_start,
+ rltk8139_stop,
+ rltk8139_control,
+ rltk8139_can_send,
+ rltk8139_send,
+ rltk8139_recv,
+ rltk8139_deliver,
+ rltk8139_poll,
+ rltk8139_int_vector
+ );
+
+NETDEVTAB_ENTRY(rltk8139_netdev1,
+ "rltk8139_" CYGDAT_DEVS_ETH_I386_PC_RLTK8139_ETH1_NAME,
+ rltk8139_init,
+ &rltk8139_sc1);
+
+#endif // CYGPKG_DEVS_ETH_I386_PC_RLTK8139_ETH1
+
+// EOF devs_eth_i386_pc_rltk8139.inl
diff --git a/ecos/packages/devs/eth/intel/i21143/current/ChangeLog b/ecos/packages/devs/eth/intel/i21143/current/ChangeLog
new file mode 100644
index 0000000..817098c
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i21143/current/ChangeLog
@@ -0,0 +1,78 @@
+2001-10-05 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i21143.c (MII_DELAY): Greatly reduce this, now it's
+ working, so that we can poll for link status changes. I don't see
+ any other way to do this, since we would not necessarily be
+ transmitting (to get a link fail code) when a person re-plugs the
+ line.
+ (i21143_status_changed): New function; a quicker test for
+ negotiated line status changed. Polled from the deliver routine.
+
+2001-10-05 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i21143.c (i21143_ioctl): Implement SNMP statistics.
+ (i21143_can_send): Enable the "unsticking" poll of tx and rx
+ states; it seems not necessary, but it's also definitely not
+ harmful.
+ (generally): manage getting the link status better; it takes time
+ so cache the answer. Reset the system if it changed between
+ _stop() and _start().
+
+2001-10-04 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i21143.c (i21143_reset): Set the "store and forward" bit
+ so that we can keep up with large transmits at 100Mbit. Otherwise
+ it underflows for packets of 700 bytes or so.
+
+2001-10-04 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i21143.c: Got ESA filtering set up OK by using perfect
+ filtering instead, with all the broadcast address except one with
+ our true ESA. Various changes to the debug printing too.
+
+2001-09-28 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i21143.c (i21143_init): Read the good ESA (MAC address)
+ from the serial EEPROM (or ROM) and use it if valid.
+
+2001-09-28 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i21143.c: Duh. Fix dangerously aliased local variable.
+ Having a thing like int fred[0] on the stack tends to screw up
+ other random variables.
+
+2001-09-27 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/intel_i21143_eth_drivers.cdl: New file.
+
+ * src/if_i21143.c: New file. Not working yet.
+ Reception only occurs if "Receive All" CSR_OPMODE_RA is set.
+ No transmission occurs to the wire though the machinery all works
+ beautifully.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/intel/i21143/current/cdl/intel_i21143_eth_drivers.cdl b/ecos/packages/devs/eth/intel/i21143/current/cdl/intel_i21143_eth_drivers.cdl
new file mode 100644
index 0000000..dd8095c
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i21143/current/cdl/intel_i21143_eth_drivers.cdl
@@ -0,0 +1,101 @@
+# ====================================================================
+#
+# intel_i21143_eth_drivers.cdl
+#
+# Intel 21143 ethernet driver
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): hmt
+# Original data:
+# Contributors:
+# Date: 2000-09-17
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_INTEL_I21143 {
+ display "Intel 21143 ethernet driver"
+ description "Ethernet driver for Intel 21143 controller."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGINT_DEVS_ETH_INTEL_I21143_REQUIRED
+
+ include_dir cyg/devs/eth
+
+ compile -library=libextras.a if_i21143.c
+
+ cdl_option CYGDBG_DEVS_ETH_INTEL_I21143_CHATTER {
+ display "Prints ethernet device status info during startup"
+ default_value 0
+ description "
+ The ethernet device initialization code can print lots of info
+ to confirm that it has found the devices on the PCI bus, read
+ the MAC address from EEPROM correctly, and so on, and also
+ displays the mode (10/100MHz, half/full duplex) of the
+ connection."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT {
+ display "Number of supported interfaces."
+ calculated { CYGINT_DEVS_ETH_INTEL_I21143_REQUIRED }
+ flavor data
+ description "
+ This option selects the number of PCI ethernet interfaces to
+ be supported by the driver."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_INTEL_I21143_OPTIONS {
+ display "Intel 21143 ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_INTEL_I21143_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Intel 21143 ethernet driver
+ package. These flags are used in addition to the set of
+ global flags."
+ }
+ }
+}
+# EOF intel_i21143_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/intel/i21143/current/src/if_i21143.c b/ecos/packages/devs/eth/intel/i21143/current/src/if_i21143.c
new file mode 100644
index 0000000..d89efcf
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i21143/current/src/if_i21143.c
@@ -0,0 +1,2843 @@
+//==========================================================================
+//
+// if_i21143.c
+//
+// Intel 21143 ethernet driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors:
+// Date: 2000-09-17
+// Purpose:
+// Description: hardware driver for 21143 Intel PRO/100+ ethernet
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#ifdef CYGPKG_IO_ETH_DRIVERS
+#include <pkgconf/io_eth_drivers.h>
+#endif
+#include <pkgconf/devs_eth_intel_i21143.h>
+
+// Config for the instantiating package:
+#include CYGDAT_DEVS_ETH_INTEL_I21143_CFG
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h> // HAL_DCACHE_STORE
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <net/if.h> /* Needed for struct ifnet */
+#endif
+
+#ifdef CYGPKG_IO_PCI
+#include <cyg/io/pci.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+#else
+#error "Need PCI package here"
+#endif
+
+// ------------------------------------------------------------------------
+// Exported statistics and the like
+// defined in <cyg/io/eth/eth_drv_stats.h> - already included.
+
+#define KEEP_STATISTICS
+
+#ifdef KEEP_STATISTICS
+# define INCR_STAT( _x_ ) (p_i21143->stats. _x_ ++)
+#else
+# define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
+#endif
+
+// ------------------------------------------------------------------------
+//
+// DEVICES AND PACKET QUEUES
+//
+// ------------------------------------------------------------------------
+
+#define RX_DESCRIPTORS (4) // 4 packets.
+#define RX_BUFFERS RX_DESCRIPTORS
+#define TX_DESCRIPTORS MAX_ETH_DRV_SG // Enough for one tx, even if fragmented
+
+#define MAX_RX_PACKET_SIZE 1536 // maximum Rx packet size
+#define MAX_TX_PACKET_SIZE 1536 // maximum Tx packet size
+
+// ------------------------------------------------------------------------
+
+typedef struct buffer_descriptor {
+ volatile cyg_uint32 des0;
+ volatile cyg_uint32 des1;
+ volatile cyg_uint32 buf1;
+ volatile cyg_uint32 buf2;
+} BUFDES;
+
+
+typedef struct i21143 {
+ cyg_uint8 // (split up for atomic byte access)
+ found:1, // was hardware discovered?
+ mac_addr_ok:1, // can we bring up?
+ active:1, // has this if been brung up?
+ hardwired_esa:1, // set if ESA is hardwired via CDL
+ spare1:4;
+ cyg_uint8 tx_endbuf; // transmit in progress flag too
+#define NO_TX_IN_PROGRESS (255)
+ cyg_uint8 index; // 0 or 1 or whatever
+ cyg_uint8 line_status; // line status when last inspected
+ cyg_uint32 devid; // PCI device id
+ cyg_uint32 io_address; // memory mapped I/O address
+ cyg_uint8 mac_address[6]; // mac (hardware) address
+ cyg_uint16 phy_autoneg_remote; // remote link status cache
+ void *ndp; // Network Device Pointer
+
+ int next_rx_descriptor; // descriptor index for buffers
+ volatile BUFDES *rx_ring; // location of Rx descriptors
+
+ volatile BUFDES *tx_ring; // location of Tx descriptors
+ unsigned long tx_keys[1]; // keys for tx q management
+
+ // Interrupt handling stuff
+ cyg_vector_t vector; // interrupt vector
+ cyg_handle_t interrupt_handle; // handle for int.handler
+ cyg_interrupt interrupt_object;
+
+ // Refer to following items only though uncached addresses from the
+ // tx_ring and rxring pointers:
+ volatile BUFDES _tx[TX_DESCRIPTORS];
+ volatile BUFDES _rx[RX_DESCRIPTORS];
+
+ cyg_uint8 _rxbufs[ RX_BUFFERS ] [ MAX_RX_PACKET_SIZE ] ;
+
+#ifdef KEEP_STATISTICS
+ struct stats {
+ unsigned int tx_good;
+ unsigned int tx_max_collisions;
+ unsigned int tx_late_collisions;
+ unsigned int tx_underrun;
+ unsigned int tx_carrier_loss;
+ unsigned int tx_deferred;
+ unsigned int tx_sqetesterrors;
+ unsigned int tx_single_collisions;
+ unsigned int tx_mult_collisions;
+ unsigned int tx_total_collisions;
+
+ unsigned int rx_good;
+ unsigned int rx_crc_errors;
+ unsigned int rx_align_errors;
+ unsigned int rx_resource_errors;
+// unsigned int rx_overrun_errors;
+ unsigned int rx_collisions;
+ unsigned int rx_short_frames;
+ unsigned int rx_too_long_frames;
+ unsigned int rx_symbol_errors;
+
+ unsigned int interrupts;
+ unsigned int rx_count;
+ unsigned int rx_deliver;
+ unsigned int rx_resource;
+ unsigned int rx_restart;
+
+ unsigned int tx_count;
+ unsigned int tx_complete;
+ unsigned int tx_dropped;
+ } stats;
+#endif // KEEP_STATISTICS
+} I21143;
+
+// ------------------------------------------------------------------------
+// After defining that, now we can instantiate the device(s):
+
+
+#include CYGDAT_DEVS_ETH_INTEL_I21143_INL
+
+// ------------------------------------------------------------------------
+// Access to cached/uncached/physical memory, to map from CPU-view
+// addresses to PCI-bus master's view - however that is:
+//
+// We'll use these macros, so that different platforms can define them
+// externally:
+// o CYGHWR_PCI_VIRT_TO_BUS( x )
+// - address for the PCI device to use
+// o CYGHWR_CACHED_TO_UNCACHED( x )
+// - access to memory that the PCI device will look at
+// o CYGHWR_BUS_TO_UNCACHED( x )
+// - back from an address in the PCI structures to one for us to look at
+// to see what it said.
+
+#ifndef CYGHWR_PCI_VIRT_TO_BUS
+# ifdef CYGARC_PHYSICAL_ADDRESS
+# define CYGHWR_PCI_VIRT_TO_BUS( _x_ ) CYGARC_PHYSICAL_ADDRESS( (_x_) )
+# else
+# error No CYGHWR_PCI_VIRT_TO_BUS() defined!
+//#define CYGHWR_PCI_VIRT_TO_BUS( _x_ ) (_x_)
+# endif
+#endif
+
+#ifndef CYGHWR_CACHED_TO_UNCACHED
+# ifdef CYGARC_UNCACHED_ADDRESS
+# define CYGHWR_CACHED_TO_UNCACHED( _x_ ) CYGARC_UNCACHED_ADDRESS( (_x_) )
+# else
+# define CYGHWR_CACHED_TO_UNCACHED( _x_ ) (_x_)
+# endif
+#endif
+
+#ifndef CYGHWR_BUS_TO_UNCACHED
+# ifdef CYGARC_UNCACHED_ADDRESS
+# define CYGHWR_BUS_TO_UNCACHED( _x_ ) CYGARC_UNCACHED_ADDRESS( (_x_) )
+# else
+# define CYGHWR_BUS_TO_UNCACHED( _x_ ) (_x_)
+# endif
+#endif
+
+// ------------------------------------------------------------------------
+// Prototypes and declarations
+
+static int pci_init_find_21143s( void );
+static int i21143_configure(struct i21143* p_i21143, int promisc);
+static void i21143_reset(struct i21143* p_i21143);
+static void InitTxRing(struct i21143* p_i21143);
+static void InitRxRing(struct i21143* p_i21143);
+static void eth_set_mac_address( struct i21143* p_i21143, cyg_uint8 *addr );
+
+static void mii_write_register( int ioaddr, int regnum, int value );
+static int mii_read_register( int ioaddr, int regnum );
+
+static int get_eeprom_size( int ioaddr );
+static int read_eeprom_word( int ioaddr, int addrbits, int address );
+
+// ------------------------------------------------------------------------
+//
+// 21143 GENERAL STATUS REGISTER
+//
+// ------------------------------------------------------------------------
+#define GEN_STATUS_FDX 0x04 // 1 = full duplex, 0 = half
+#define GEN_STATUS_100MBPS 0x02 // 1 = 100 Mbps, 0 = 10 Mbps
+#define GEN_STATUS_LINK 0x01 // 1 = link up, 0 = link down
+
+// returns status in terms of the above:
+static int i21143_status( struct i21143* p_i21143 );
+
+// A cheap check for changes: true if changed, is all:
+static int i21143_status_changed( struct i21143* p_i21143 );
+
+// ------------------------------------------------------------------------
+
+#define CYGDAT_DEVS_ETH_DESCRIPTION "Intel i21143 10/100 Ethernet [DEC]"
+
+#define ETH_DEV_DOT3STATSETHERCHIPSET 1,3,6,1,2,1,10,7,8,2,5
+
+// ------------------------------------------------------------------------
+
+#ifdef CYGDBG_DEVS_ETH_INTEL_I21143_CHATTER
+#define nDEBUG_TRAFFIC // This one prints stuff as packets come and go
+#define DEBUG // Startup printing mainly
+#define nDEBUG_EE // Some EEPROM specific retries &c
+#define nDEBUG_TRAFFIC_TXDETAILS // tx bufs layout
+#define nDEBUG_DUMP_REGS
+#define nDEBUG_MAC
+#define nDEBUG_STARTSTOPRESET
+#endif
+
+// ------------------------------------------------------------------------
+// I/O access macros as inlines for type safety
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST)
+
+#define HAL_CTOLE32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))
+#define HAL_LE32TOC(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))
+
+#define HAL_CTOLE16(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+#define HAL_LE16TOC(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+
+//static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address)
+//{
+// HAL_WRITE_UINT8( io_address, value);
+//}
+//
+//static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)
+//{
+// HAL_WRITE_UINT16( io_address, (((value & 0xff) << 8) | ((value & 0xff00) >> 8)) );
+//}
+
+static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address)
+{
+ HAL_WRITE_UINT32( io_address,
+ ((((value) & 0xff) << 24) | (((value) & 0xff00) << 8) | (((value) & 0xff0000) >> 8) | (((value) >> 24) & 0xff)) );
+}
+
+//static inline cyg_uint8 INB(cyg_uint32 io_address)
+//{
+// cyg_uint8 d;
+// HAL_READ_UINT8( io_address, d );
+// return d;
+//}
+//
+//static inline cyg_uint16 INW(cyg_uint32 io_address)
+//{
+// cyg_uint16 d;
+// HAL_READ_UINT16( io_address, d );
+// return (((d & 0xff) << 8) | ((d & 0xff00) >> 8));
+//}
+
+static inline cyg_uint32 INL(cyg_uint32 io_address)
+{
+ cyg_uint32 d;
+ HAL_READ_UINT32( io_address, d );
+ return ((((d) & 0xff) << 24) | (((d) & 0xff00) << 8) | (((d) & 0xff0000) >> 8) | (((d) >> 24) & 0xff));
+}
+#else
+
+// Maintaining the same styleee as above...
+#define HAL_CTOLE32(x) ((((x))))
+#define HAL_LE32TOC(x) ((((x))))
+
+#define HAL_CTOLE16(x) ((((x))))
+#define HAL_LE16TOC(x) ((((x))))
+
+//static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address)
+//{ HAL_WRITE_UINT8( io_address, value ); }
+//
+//static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)
+//{ HAL_WRITE_UINT16( io_address, value ); }
+
+static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address)
+{ HAL_WRITE_UINT32( io_address, value ); }
+
+//static inline cyg_uint8 INB(cyg_uint32 io_address)
+// { cyg_uint8 _t_; HAL_READ_UINT8( io_address, _t_ ); return _t_; }
+//
+//static inline cyg_uint16 INW(cyg_uint32 io_address)
+// { cyg_uint16 _t_; HAL_READ_UINT16( io_address, _t_ ); return _t_; }
+
+static inline cyg_uint32 INL(cyg_uint32 io_address)
+ { cyg_uint32 _t_; HAL_READ_UINT32( io_address, _t_ ); return _t_; }
+
+#endif // byteorder
+
+// ------------------------------------------------------------------------
+
+static inline void udelay(int delay)
+{
+ CYGACC_CALL_IF_DELAY_US(delay);
+}
+
+// ------------------------------------------------------------------------
+#ifdef DEBUG_DUMP_REGS
+#define MII 1
+#define ETH 2
+#define BOTH 3
+void debug_dump_regs( cyg_uint32 ioaddr, int which )
+{
+ int i;
+
+ if ( MII & which )
+ for ( i = 0; i <= 0x19 ; i++ ) {
+ int v;
+ if ( 0x08 == i ) i = 0x10;
+ v = mii_read_register( ioaddr, i );
+ diag_printf( "MII/PHY register %2x%c = %04x\n", i, 'h', v );
+ }
+ if ( ETH & which )
+ for ( i = 0; i < 16; i++ ) {
+ cyg_uint32 v;
+ v = INL( (ioaddr + (i << 3)) );
+ diag_printf( "21143 register CSR%2d (at %2x%c) = %08x\n", i, (i << 3), 'h', v );
+ }
+}
+#endif
+// ------------------------------------------------------------------------
+//
+// REGISTERS (CSRs) and THEIR BITS
+//
+// ------------------------------------------------------------------------
+
+// All registers are 32bit entities on 64bit boundaries.
+
+#define CSR0 (ioaddr + ( 0 << 3))
+#define CSR1 (ioaddr + ( 1 << 3))
+#define CSR2 (ioaddr + ( 2 << 3))
+#define CSR3 (ioaddr + ( 3 << 3))
+#define CSR4 (ioaddr + ( 4 << 3))
+#define CSR5 (ioaddr + ( 5 << 3))
+#define CSR6 (ioaddr + ( 6 << 3))
+#define CSR7 (ioaddr + ( 7 << 3))
+#define CSR8 (ioaddr + ( 8 << 3))
+#define CSR9 (ioaddr + ( 9 << 3))
+#define CSR10 (ioaddr + (10 << 3))
+#define CSR11 (ioaddr + (11 << 3))
+#define CSR12 (ioaddr + (12 << 3))
+#define CSR13 (ioaddr + (13 << 3))
+#define CSR14 (ioaddr + (14 << 3))
+#define CSR15 (ioaddr + (15 << 3))
+
+#define CSR1_PM CSR1
+#define CSR2_PM CSR2
+
+#define CSR_BUSMODE CSR0
+#define CSR_TXPOLL CSR1
+#define CSR_RXPOLL CSR2
+#define CSR_RXBASE CSR3
+#define CSR_TXBASE CSR4
+#define CSR_STATUS CSR5
+#define CSR_OPMODE CSR6
+#define CSR_INTR_ENABLE CSR7
+#define CSR_MISS_OFL_COUNT CSR8
+#define CSR_ROM_MII_MGT CSR9
+#define CSR_ROM_PGM_ADDR CSR10
+#define CSR_INTR_MITIGATION CSR11
+#define CSR_SIA_STATUS CSR12
+#define CSR_SIA_CONN CSR13
+#define CSR_SIA_TXRX CSR14
+#define CSR_SIA_GPPORT CSR15
+
+#define CSR_WUFILTER CSR1_PM
+#define CSR_WUEVENTS CSR2_PM
+
+// -------- BUSMODE
+#define CSR_BUSMODE_PM (1<<26)
+#define CSR_BUSMODE_WIE (1<<24)
+#define CSR_BUSMODE_RLE (1<<23)
+#define CSR_BUSMODE_RME (1<<21)
+#define CSR_BUSMODE_DBO_BE (1<<20)
+#define CSR_BUSMODE_DBO_LE ( 0 )
+#define CSR_BUSMODE_TAP_SHIFT (17)
+#define CSR_BUSMODE_CAL_SHIFT (14)
+#define CSR_BUSMODE_PBL_SHIFT ( 8)
+#define CSR_BUSMODE_ENDIAN_BE (1<< 7)
+#define CSR_BUSMODE_ENDIAN_LE ( 0 )
+#define CSR_BUSMODE_DSL_SHIFT ( 2)
+#define CSR_BUSMODE_BAR (1<< 1)
+#define CSR_BUSMODE_RESET (1<< 0)
+
+// -------- STATUS
+#define CSR_STATUS_LC (1<<27)
+#define CSR_STATUS_GPI (1<<26)
+#define CSR_STATUS_EB (7 << 23)
+
+#define CSR_STATUS_TXSTATUS (7 << 20)
+#define CSR_STATUS_TXSTATUS_STOPPED (0 << 20)
+#define CSR_STATUS_TXSTATUS_SUSPENDED (6 << 20)
+
+#define CSR_STATUS_RXSTATUS (7 << 17)
+#define CSR_STATUS_RXSTATUS_STOPPED (0 << 17)
+#define CSR_STATUS_RXSTATUS_SUSPENDED (4 << 17)
+
+#define CSR_STATUS_NIS (1<<16)
+#define CSR_STATUS_AIS (1<<15)
+#define CSR_STATUS_ERI (1<<14)
+#define CSR_STATUS_FBE (1<<13)
+#define CSR_STATUS_LNF (1<<12)
+#define CSR_STATUS_GTE (1<<11)
+#define CSR_STATUS_ETI (1<<10)
+#define CSR_STATUS_RWT (1<< 9)
+#define CSR_STATUS_RX_STOPPED (1<< 8)
+#define CSR_STATUS_RBU (1<< 7)
+#define CSR_STATUS_RX_INTR (1<< 6)
+#define CSR_STATUS_UNF (1<< 5)
+#define CSR_STATUS_LNP_ANC (1<< 4)
+#define CSR_STATUS_TJT (1<< 3)
+#define CSR_STATUS_TBU (1<< 2)
+#define CSR_STATUS_TX_STOPPED (1<< 1)
+#define CSR_STATUS_TX_INTR (1<< 0)
+
+// -------- OPMODE
+
+#define CSR_OPMODE_SC (1<<31)
+#define CSR_OPMODE_RA (1<<30)
+#define CSR_OPMODE_IGNOREMSB (1<<26)
+#define CSR_OPMODE_MUST_BE_ONE (1<<25)
+#define CSR_OPMODE_SCR (1<<24)
+#define CSR_OPMODE_PCS (1<<23)
+#define CSR_OPMODE_TTM (1<<22)
+#define CSR_OPMODE_SF (1<<21)
+#define CSR_OPMODE_HBD (1<<19)
+#define CSR_OPMODE_PS (1<<18)
+#define CSR_OPMODE_PS_MIISYM (1<<18)
+#define CSR_OPMODE_CA (1<<17)
+#define CSR_OPMODE_TX_THRES_SHIFT (14)
+#define CSR_OPMODE_TX_START (1<<13)
+#define CSR_OPMODE_FC (1<<12)
+#define CSR_OPMODE_LOOPBACK_SHIFT (10)
+#define CSR_OPMODE_FD (1<< 9)
+#define CSR_OPMODE_MULTICAST (1<< 7)
+#define CSR_OPMODE_PROMISC (1<< 6)
+#define CSR_OPMODE_SB (1<< 5)
+#define CSR_OPMODE_IF (1<< 4)
+#define CSR_OPMODE_PB (1<< 3)
+#define CSR_OPMODE_HO (1<< 2)
+#define CSR_OPMODE_RX_START (1<< 1)
+#define CSR_OPMODE_HP (1<< 0)
+
+// -------- INTR_ENABLE
+// uses the same bits as STATUS, hurrah!
+
+// -------- MISS_OFL_COUNT
+#define CSR_MISS_OFL_COUNT_NO_RXBUFS_MASK (0x0001ffff)
+#define CSR_MISS_OFL_COUNT_NO_RXBUFS_SHIFT ( 0)
+#define CSR_MISS_OFL_COUNT_NO_RXFIFO_MASK (0x1ffe0000)
+#define CSR_MISS_OFL_COUNT_NO_RXFIFO_SHIFT (17)
+
+// -------- ROM_MII_MGT
+#define CSR_ROM_MII_MGT_MDI (1<<19)
+#define CSR_ROM_MII_MGT_MOM (1<<18)
+#define CSR_ROM_MII_MGT_MOM_READ (1<<18)
+#define CSR_ROM_MII_MGT_MDO (1<<17)
+#define CSR_ROM_MII_MGT_MDC (1<<16)
+#define CSR_ROM_MII_MGT_RD (1<<14)
+#define CSR_ROM_MII_MGT_WR (1<<13)
+#define CSR_ROM_MII_MGT_BR (1<<12)
+#define CSR_ROM_MII_MGT_SR (1<<11)
+#define CSR_ROM_MII_MGT_REG (1<<10)
+#define CSR_ROM_MII_MGT_SR_DO (1<< 3)
+#define CSR_ROM_MII_MGT_SR_DI (1<< 2)
+#define CSR_ROM_MII_MGT_SR_CK (1<< 1)
+#define CSR_ROM_MII_MGT_SR_CS (1<< 0)
+
+#define CSR_ROM_MII_MGT_DATA (0xff)
+
+// -------- SIA defaults
+#define CSR_SIA_CONN_DEFAULT (0)
+#define CSR_SIA_TXRX_DEFAULT (0)
+#define CSR_SIA_GPPORT_DEFAULT (8)
+
+// ------------------------------------------------------------------------
+//
+// RECEIVE/TRANSMIT FRAME DESCRIPTORS
+//
+// ------------------------------------------------------------------------
+
+
+//#if (CYG_BYTEORDER == CYG_MSBFIRST)
+
+// Common to both Rx and Tx DES0
+#define DES0_STATUS_OWN (1<<31)
+#define DES0_STATUS_OWN_DONE (0<<31)
+#define DES0_STATUS_OWN_OPEN (1<<31)
+
+#define DES0_STATUS_ERROR (1<<15)
+
+// Rx specific results:
+#define RDES0_STATUS_FF (1<<30)
+#define RDES0_STATUS_DE (1<<14)
+#define RDES0_STATUS_RF (1<<11)
+#define RDES0_STATUS_MF (1<<10)
+#define RDES0_STATUS_FIRST (1<< 9)
+#define RDES0_STATUS_LAST (1<< 8)
+#define RDES0_STATUS_TOOLONG (1<< 7)
+#define RDES0_STATUS_LATECOLL (1<< 6)
+#define RDES0_STATUS_FT (1<< 5)
+#define RDES0_STATUS_RW (1<< 4)
+#define RDES0_STATUS_RE (1<< 3)
+#define RDES0_STATUS_DB (1<< 2)
+#define RDES0_STATUS_CRC (1<< 1)
+#define RDES0_STATUS_ZERO (1<< 0)
+
+#define RDES0_COUNT_MASK (0x3fff0000)
+#define RDES0_COUNT_SHIFT ( 16 )
+
+// Tx specific results:
+#define TDES0_STATUS_TJTO (1<<14)
+#define TDES0_STATUS_LO (1<<11)
+#define TDES0_STATUS_NC (1<<10)
+#define TDES0_STATUS_LC (1<< 9)
+#define TDES0_STATUS_EC (1<< 8)
+#define TDES0_STATUS_HF (1<< 7)
+#define TDES0_STATUS_LF (1<< 2)
+#define TDES0_STATUS_UFL (1<< 1)
+#define TDES0_STATUS_DE (1<< 0)
+#define TDES0_STATUS_CC_MASK (0x78)
+#define TDES0_STATUS_CC_SHIFT ( 3 )
+
+// Common to both Rx and Tx DES1
+#define DES1_ENDRING (1<<25)
+#define DES1_2ACHAIN (1<<24)
+#define DES1_B2SIZE_MASK (0x7ff << 11)
+#define DES1_B2SIZE_SHIFT (11)
+#define DES1_B1SIZE_MASK (0x7ff)
+#define DES1_B1SIZE_SHIFT (0)
+
+// Rx DES1 has no special bits - Rx descriptors have no "controls"
+
+// Tx specific controls in DES1:
+#define TDES1_CONTROL_INTERRUPT (1<<31)
+#define TDES1_CONTROL_LAST (1<<30)
+#define TDES1_CONTROL_FIRST (1<<29)
+#define TDES1_CONTROL_SETUP_FT1 (1<<28)
+#define TDES1_CONTROL_SETUP (1<<27)
+#define TDES1_CONTROL_NO_CRC (1<<26)
+#define TDES1_CONTROL_NO_PAD (1<<23)
+#define TDES1_CONTROL_SETUP_FT0 (1<<22)
+
+// ------------------------------------------------------------------------
+//
+// PHY common constants - registers are read over MII.
+//
+// I don't know how much they have in common, but I think MII is pretty
+// standard, and the "mandated" registers ought to be common.
+
+#define PHY_CONTROL_REG (0)
+#define PHY_STATUS_REG (1)
+#define PHY_ID_ONE (2)
+#define PHY_ID_TWO (3)
+#define PHY_AUTONEG_ADVERT (4)
+#define PHY_AUTONEG_REMOTE (5)
+
+#define PHY_CONTROL_RESET (1<<15)
+#define PHY_CONTROL_LOOPBACK (1<<14)
+#define PHY_CONTROL_SPEED100 (1<<13)
+#define PHY_CONTROL_AUTONEG_EN (1<<12)
+#define PHY_CONTROL_POWERDOWN (1<<11)
+#define PHY_CONTROL_MII_DIS (1<<10)
+#define PHY_CONTROL_AUTONEG_RST (1<< 9)
+#define PHY_CONTROL_DPLX_FULL (1<< 8)
+#define PHY_CONTROL_COLLTEST (1<< 7)
+
+#define PHY_STATUS_CAP_T4 (1<<15)
+#define PHY_STATUS_CAP_100TXF (1<<14)
+#define PHY_STATUS_CAP_100TXH (1<<13)
+#define PHY_STATUS_CAP_10TF (1<<12)
+#define PHY_STATUS_CAP_10TH (1<<11)
+#define PHY_STATUS_CAP_SUPR (1<< 6)
+#define PHY_STATUS_AUTONEG_ACK (1<< 5)
+#define PHY_STATUS_REMOTEFAULT (1<< 4)
+#define PHY_STATUS_CAP_AUTONEG (1<< 3)
+#define PHY_STATUS_LINK_OK (1<< 2)
+#define PHY_STATUS_JABBER (1<< 1)
+#define PHY_STATUS_EXTREGS (1<< 0)
+
+// These are the same for both AUTONEG registers
+#define PHY_AUTONEG_NEXT (1<<15)
+#define PHY_AUTONEG_ACK (1<<14)
+#define PHY_AUTONEG_REMOTEFAULT (1<<13)
+#define PHY_AUTONEG_100BASET4 (1<< 9)
+#define PHY_AUTONEG_100BASETX_FDX (1<< 8)
+#define PHY_AUTONEG_100BASETX_HDX (1<< 7)
+#define PHY_AUTONEG_10BASET_FDX (1<< 6)
+#define PHY_AUTONEG_10BASET_HDX (1<< 5)
+#define PHY_AUTONEG_CSMA_802_3 (1<< 0)
+
+// ------------------------------------------------------------------------
+//
+// DEVICES AND PACKET QUEUES
+//
+// ------------------------------------------------------------------------
+
+// Use arrays provided by platform header to verify pointers.
+#ifdef CYGDBG_USE_ASSERTS
+#define CHECK_NDP_SC_LINK() \
+ CYG_MACRO_START \
+ int zzz, valid_netdev = 0, valid_sc = 0; \
+ for(zzz = 0; zzz < CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT; zzz++) { \
+ if (i21143_netdev_array[zzz] == ndp) valid_netdev = 1; \
+ if (i21143_sc_array[zzz] == sc) valid_sc = 1; \
+ if (valid_sc || valid_netdev) break; \
+ } \
+ CYG_ASSERT( valid_netdev, "Bad ndp" ); \
+ CYG_ASSERT( valid_sc, "Bad sc" ); \
+ CYG_ASSERT( (void *)p_i21143 == i21143_sc_array[zzz]->driver_private, \
+ "sc pointer bad" ); \
+ CYG_MACRO_END
+#else
+#define CHECK_NDP_SC_LINK()
+#endif
+
+#define IF_BAD_21143( _p_ ) \
+if (({ \
+ int zzz, valid_p = 0; \
+ for(zzz = 0; zzz < CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT; zzz++) { \
+ if (i21143_priv_array[zzz] == (_p_)) { \
+ valid_p = 1; \
+ break; \
+ } \
+ } \
+ CYG_ASSERT(valid_p, "Bad pointer-to-i21143"); \
+ (!valid_p); \
+}))
+
+
+
+#if defined( DEBUG_TRAFFIC_TXDETAILS ) || defined( DEBUG_MAC )
+static void dump_tx_details( struct i21143 *p_i21143, char *s )
+{
+ int i;
+ cyg_uint32 prev = 0x0f0f0f0f;
+ for ( i = 0; i < TX_DESCRIPTORS ; i++ ) {
+ if ( 0 != (p_i21143->tx_ring[i].des1 |
+ p_i21143->tx_ring[i].buf1 |
+ p_i21143->tx_ring[i].buf2)
+ || ((p_i21143->tx_ring[i].des0 != prev ) ) ) {
+ prev = p_i21143->tx_ring[i].des0;
+ diag_printf( "%10s: bd[%2d] = %08x %08x %8x %x",
+ s,
+ i,
+ p_i21143->tx_ring[i].des0,
+ p_i21143->tx_ring[i].des1,
+ p_i21143->tx_ring[i].buf1,
+ p_i21143->tx_ring[i].buf2 );
+ diag_printf( " %s, %s%s %s\n",
+ p_i21143->tx_ring[i].des0 & DES0_STATUS_OWN_OPEN ? "Open" : "Done" ,
+ p_i21143->tx_ring[i].des1 & TDES1_CONTROL_FIRST ? "First" : "" ,
+ p_i21143->tx_ring[i].des1 & TDES1_CONTROL_LAST ? "Last" : "" ,
+ p_i21143->tx_ring[i].des1 & TDES1_CONTROL_INTERRUPT ? "Interrupt" : "" );
+ }
+ }
+}
+#endif
+
+// ------------------------------------------------------------------------
+//
+// NETWORK INTERFACE INITIALIZATION
+//
+// Function : i21143_init
+//
+// Description :
+// This routine resets, configures, and initializes the chip.
+//
+// ------------------------------------------------------------------------
+static bool
+i21143_init(struct cyg_netdevtab_entry * ndp)
+{
+ static int initialized = 0; // only probe PCI et al *once*
+
+ struct eth_drv_sc *sc;
+ struct i21143 *p_i21143;
+ cyg_uint8 mac_address[ETHER_ADDR_LEN];
+
+#ifdef DEBUG
+ diag_printf("intel_i21143_init\n");
+#endif
+
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+ p_i21143 = (struct i21143 *)(sc->driver_private);
+
+ IF_BAD_21143( p_i21143 ) {
+#ifdef DEBUG
+ diag_printf( "Bad device private pointer %x\n", sc->driver_private );
+#endif
+ return 0;
+ }
+
+ CHECK_NDP_SC_LINK();
+
+ p_i21143->ndp = (void *)ndp;
+
+ if ( 0 == initialized++ ) {
+ // then this is the first time ever:
+ if ( ! pci_init_find_21143s() ) {
+#ifdef DEBUG
+ diag_printf( "pci_init_find_21143s failed" );
+#endif
+ return 0;
+ }
+ }
+
+ // If this device is not present, exit
+ if (0 == p_i21143->found)
+ return 0;
+
+ p_i21143->mac_addr_ok = 0;
+
+ if ( p_i21143->hardwired_esa )
+ eth_set_mac_address( p_i21143, NULL ); // use that already there
+ // (actually a NOP because !active)
+ else {
+ int ee_addrbits;
+ int val[3];
+ int good = 0;
+
+ ee_addrbits = get_eeprom_size( p_i21143->io_address );
+#ifdef DEBUG_EE
+ diag_printf( "EEPROM size = %d\n", ee_addrbits );
+#endif
+ if ( 6 == ee_addrbits || 8 == ee_addrbits ) {
+ int i;
+ for ( i = 0; i < 3; i++ ) {
+ val[i] = read_eeprom_word( p_i21143->io_address,
+ ee_addrbits,
+ i );
+#ifdef DEBUG_EE
+ diag_printf( "EEPROM: word at %04x = %04x\n", i, val[i] );
+#endif
+ }
+ if ( 0x0000 != (val[0] | val[1] | val[2] ) && // some nonzero bits
+ 0xffff != (val[0] & val[1] & val[2] ) && // not all ones
+ 0x0000 == (val[0] & 0x80) ) { // not multicast
+ mac_address[0] = val[0] & 0xff;
+ mac_address[1] = val[0] >> 8;
+ mac_address[2] = val[1] & 0xff;
+ mac_address[3] = val[1] >> 8;
+ mac_address[4] = val[2] & 0xff;
+ mac_address[5] = val[2] >> 8;
+ good = 1;
+#ifdef DEBUG_MAC
+ diag_printf( "EEPROM ESA OK: %04x %04x %04x\n",
+ val[0], val[1], val[2] );
+#endif
+ }
+ }
+ if ( !good ) {
+ // Invent one
+ mac_address[0] = 0x01;
+ mac_address[1] = 0x23;
+ mac_address[2] = 0x45;
+ mac_address[3] = 0x67;
+ mac_address[4] = 0x98;
+ mac_address[5] = 0x76;
+ }
+ // Just copy into the structure - not into hardware 'cos !active
+ eth_set_mac_address( p_i21143, &mac_address[0] );
+ }
+
+#if defined( DEBUG ) || defined( DEBUG_MAC )
+ diag_printf("MAC Address %s, ESA = %02X %02X %02X %02X %02X %02X\n",
+ p_i21143->mac_addr_ok ? "OK" : "**BAD**",
+ p_i21143->mac_address[0],
+ p_i21143->mac_address[1],
+ p_i21143->mac_address[2],
+ p_i21143->mac_address[3],
+ p_i21143->mac_address[4],
+ p_i21143->mac_address[5]);
+#endif
+
+ // Initialize upper level driver
+ if ( p_i21143->mac_addr_ok )
+ (sc->funs->eth_drv->init)(sc, &(p_i21143->mac_address[0]) );
+ else
+ (sc->funs->eth_drv->init)(sc, NULL );
+
+ return (1);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i21143_start
+//
+// ------------------------------------------------------------------------
+static void
+i21143_start( struct eth_drv_sc *sc, unsigned char *enaddr, int flags )
+{
+ struct i21143 *p_i21143;
+ cyg_uint32 ioaddr;
+ cyg_uint32 l;
+#ifdef CYGPKG_NET
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+
+ p_i21143 = (struct i21143 *)sc->driver_private;
+ ioaddr = p_i21143->io_address; // get 21143's I/O address
+
+ IF_BAD_21143( p_i21143 ) {
+#ifdef DEBUG
+ diag_printf( "i21143_start: Bad device pointer %x\n", p_i21143 );
+#endif
+ return;
+ }
+
+ if ( ! p_i21143->mac_addr_ok ) {
+#ifdef DEBUG
+ diag_printf("i21143_start %d: invalid MAC address, "
+ "can't bring up interface\n",
+ p_i21143->index );
+#endif
+ return;
+ }
+
+#ifdef DEBUG
+ diag_printf( "i21143_start: enters\n" );
+#endif
+
+ if ( p_i21143->active )
+ i21143_stop( sc );
+
+ // Update the cached copy of the status reg just in case
+ l = i21143_status( p_i21143 );
+ if ( l != p_i21143->line_status ) {
+ // It has changed!
+ i21143_reset(p_i21143); // sets line_status itself
+ }
+
+ // Enable device
+ p_i21143->active = 1;
+
+ // Initialize tx status
+ p_i21143->tx_endbuf = NO_TX_IN_PROGRESS;
+
+ eth_set_mac_address( p_i21143, NULL ); // to put it in the device
+
+ // After eth_set_mac_address() initialize the data structs for use:
+ InitRxRing( p_i21143 );
+ InitTxRing( p_i21143 );
+
+ // Enable promiscuous mode if requested.
+ i21143_configure(p_i21143, 0
+#ifdef CYGPKG_NET
+ || !!(ifp->if_flags & IFF_PROMISC)
+#endif
+#ifdef ETH_DRV_FLAGS_PROMISC_MODE
+ || !!(flags & ETH_DRV_FLAGS_PROMISC_MODE)
+#endif
+
+ );
+#ifdef DEBUG
+ {
+ int status = p_i21143->line_status;
+ diag_printf("i21143_start %d flg %x Link = %s, %s Mbps, %s Duplex\n",
+ p_i21143->index,
+ *(int *)p_i21143,
+ (GEN_STATUS_LINK & status) ? "Up" : "Down",
+ (GEN_STATUS_100MBPS & status) ? "100" : "10",
+ (GEN_STATUS_FDX & status) ? "Full" : "Half");
+ }
+#endif
+
+ // Load pointer to Rx Ring and enable receiver
+ OUTL( CYGHWR_PCI_VIRT_TO_BUS( (cyg_uint32)p_i21143->rx_ring ), CSR_RXBASE );
+ // Enable receive interrupts
+ l = INL( CSR_INTR_ENABLE );
+ l |= 0
+ | CSR_STATUS_NIS
+ | CSR_STATUS_AIS
+ // CSR_STATUS_ERI
+ // CSR_STATUS_FBE
+ // CSR_STATUS_LNF
+ // CSR_STATUS_GTE
+ // CSR_STATUS_ETI
+ // CSR_STATUS_RWT
+ | CSR_STATUS_RX_STOPPED
+ | CSR_STATUS_RBU
+ | CSR_STATUS_RX_INTR
+ // CSR_STATUS_UNF
+ // CSR_STATUS_LNP_ANC
+ // CSR_STATUS_TJT
+ | CSR_STATUS_TBU
+ | CSR_STATUS_TX_STOPPED
+ | CSR_STATUS_TX_INTR
+ ;
+ OUTL( l, CSR_INTR_ENABLE );
+ // and start the receiver
+ l = INL( CSR_OPMODE );
+ l |= (CSR_OPMODE_RX_START);
+ OUTL( l, CSR_OPMODE );
+ INCR_STAT( rx_restart );
+#ifdef DEBUG_DUMP_REGS
+ debug_dump_regs( ioaddr, BOTH );
+#endif
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i21143_status
+//
+// ------------------------------------------------------------------------
+int
+i21143_status( struct i21143* p_i21143 )
+{
+ int status;
+ int i, j;
+ cyg_uint32 ioaddr;
+
+ IF_BAD_21143( p_i21143 ) {
+#ifdef DEBUG
+ diag_printf( "i21143_status: Bad device pointer %x\n", p_i21143 );
+#endif
+ return 0;
+ }
+
+ ioaddr = p_i21143->io_address; // get 21143's I/O address
+
+ // Some of these bits latch and only reflect "the truth" on a 2nd reading.
+ // So read and discard.
+ status = mii_read_register( ioaddr, PHY_CONTROL_REG );
+ status = mii_read_register( ioaddr, PHY_STATUS_REG );
+ // Use the "and" of the local and remote capabilities words to infer
+ // what is selected:
+ status = 0;
+ i = mii_read_register( ioaddr, PHY_STATUS_REG );
+ if ( PHY_STATUS_LINK_OK & i )
+ status |= GEN_STATUS_LINK;
+
+ i = mii_read_register( ioaddr, PHY_AUTONEG_ADVERT );
+ j = mii_read_register( ioaddr, PHY_AUTONEG_REMOTE );
+ p_i21143->phy_autoneg_remote = j;
+#if defined( DEBUG_TRAFFIC ) || defined( DEBUG_IOCTL )
+ diag_printf( "MII: capabilities are %04x, %04x; common %04x\n",
+ i, j, i & j );
+#endif
+ j &= i; // select only common capabilities
+
+ if ( (PHY_AUTONEG_100BASET4 |
+ PHY_AUTONEG_100BASETX_FDX |
+ PHY_AUTONEG_100BASETX_HDX) & j )
+ status |= GEN_STATUS_100MBPS;
+ if ( (PHY_AUTONEG_100BASETX_FDX | PHY_AUTONEG_10BASET_FDX) & j )
+ status |= GEN_STATUS_FDX;
+
+ return status;
+}
+
+int
+i21143_status_changed( struct i21143* p_i21143 )
+{
+ cyg_uint32 ioaddr;
+ int j;
+ ioaddr = p_i21143->io_address; // get 21143's I/O address
+
+ j = mii_read_register( ioaddr, PHY_AUTONEG_REMOTE );
+ return ( j != p_i21143->phy_autoneg_remote );
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i21143_stop
+//
+// ------------------------------------------------------------------------
+
+static void
+i21143_stop( struct eth_drv_sc *sc )
+{
+ struct i21143 *p_i21143;
+
+ p_i21143 = (struct i21143 *)sc->driver_private;
+
+ IF_BAD_21143( p_i21143 ) {
+#ifdef DEBUG
+ diag_printf( "i21143_stop: Bad device pointer %x\n", p_i21143 );
+#endif
+ return;
+ }
+
+#ifdef DEBUG_STARTSTOPRESET
+ diag_printf("i21143_stop %d flg %x\n", p_i21143->index, *(int *)p_i21143 );
+#endif
+
+ p_i21143->active = 0; // stop people tormenting it
+
+ if ( NO_TX_IN_PROGRESS != p_i21143->tx_endbuf) {
+ cyg_uint32 key;
+
+ CYG_ASSERT( TX_DESCRIPTORS > p_i21143->tx_endbuf, "tx_endbuf range" );
+
+ key = p_i21143->tx_keys[ 0 ];
+ // Common "done" code - key nonzero => report done
+ if (key) {
+ p_i21143->tx_keys[ 0 ] = 0;
+ p_i21143->tx_endbuf = NO_TX_IN_PROGRESS;
+ // Then tell the stack we are done:
+ INCR_STAT( tx_complete );
+ (sc->funs->eth_drv->tx_done)( sc, key, 0 );
+ }
+ }
+
+ i21143_reset(p_i21143); // that should stop it
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : InitRxRing
+//
+// ------------------------------------------------------------------------
+static void
+InitRxRing(struct i21143* p_i21143)
+{
+ int i;
+ volatile BUFDES *bp;
+
+ p_i21143->rx_ring =
+ (BUFDES *)CYGHWR_CACHED_TO_UNCACHED( &(p_i21143->_rx[0]) );
+
+ bp = p_i21143->rx_ring;
+ for ( i = 0 ; i < RX_DESCRIPTORS; i++ ) {
+ bp->des0 = DES0_STATUS_OWN_OPEN; // NIC owns it, not the CPU
+ bp->des1 = (MAX_RX_PACKET_SIZE << DES1_B1SIZE_SHIFT);
+ bp->buf1 = CYGHWR_PCI_VIRT_TO_BUS( &( p_i21143->_rxbufs[i][0] ) );
+ bp->buf2 = 0;
+ bp++;
+ }
+ bp--; // last one
+ bp->des1 |= DES1_ENDRING;
+
+ p_i21143->next_rx_descriptor = 0;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : PacketRxReady (Called from delivery thread & foreground)
+//
+// ------------------------------------------------------------------------
+static void
+PacketRxReady(struct i21143* p_i21143)
+{
+ volatile BUFDES *bp;
+ int index;
+ struct eth_drv_sc *sc;
+ int count;
+ {
+ struct cyg_netdevtab_entry *ndp;
+ ndp = (struct cyg_netdevtab_entry *)(p_i21143->ndp);
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+ CHECK_NDP_SC_LINK();
+ }
+
+ CYG_ASSERT( 0 <= p_i21143->next_rx_descriptor, "rx descriptor underflow" );
+ CYG_ASSERT( RX_DESCRIPTORS > p_i21143->next_rx_descriptor, "rx descriptor overflow" );
+
+ index = p_i21143->next_rx_descriptor;
+
+ // Scan receive buffers
+ for ( count = 0; count < RX_DESCRIPTORS; count++ ) {
+ cyg_uint32 ldes0;
+ int length;
+
+ bp = &p_i21143->rx_ring[ index ];
+
+ CYG_ASSERT( 0 == bp->buf2, "Corrupt bp->buf2" );
+ CYG_ASSERT( 0 != bp->buf1, "Null bp->buf1" );
+ CYG_ASSERT( (MAX_RX_PACKET_SIZE << DES1_B1SIZE_SHIFT) == (bp->des1 &~ DES1_ENDRING),
+ "Corrupt bp->des1" );
+
+ ldes0 = bp->des0;
+
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "PacketRxReady: index %d des0 = %08x, %s, %s, %d bytes\n",
+ index, ldes0,
+ (ldes0 & DES0_STATUS_OWN) ? "open" : "done",
+ ((RDES0_STATUS_FIRST | RDES0_STATUS_LAST | DES0_STATUS_ERROR) & ldes0)
+ == (RDES0_STATUS_FIRST | RDES0_STATUS_LAST) ? "OK" : "--",
+ (RDES0_COUNT_MASK & ldes0) >> RDES0_COUNT_SHIFT );
+#endif
+
+ if ( DES0_STATUS_OWN_OPEN == (ldes0 & DES0_STATUS_OWN) )
+ // This buffer bilong the device
+ break;
+
+ INCR_STAT( rx_count );
+
+ // Otherwise, this one is for us
+ if ( ((RDES0_STATUS_FIRST | RDES0_STATUS_LAST | DES0_STATUS_ERROR) & ldes0)
+ == (RDES0_STATUS_FIRST | RDES0_STATUS_LAST) ) {
+ // A complete packet and no error bit
+
+ length = (RDES0_COUNT_MASK & ldes0) >> RDES0_COUNT_SHIFT;
+
+ CYG_ASSERT( MAX_RX_PACKET_SIZE >= length, "Oversize Rx" );
+
+ // tell the callback the right packet
+ p_i21143->next_rx_descriptor = index;
+
+ INCR_STAT( rx_good );
+
+#ifdef CYGPKG_NET
+ if ( length > sizeof( struct ether_header ) )
+ // then it is acceptable; offer the data to the network stack
+#endif
+ (sc->funs->eth_drv->recv)( sc, length );
+
+ // All done!
+ }
+#ifdef KEEP_STATISTICS
+ else {
+ if ( RDES0_STATUS_LAST & ldes0 ) {
+ // Then we have good error info; analyse and count the errors
+ if ( ldes0 & ( RDES0_STATUS_CRC ) )
+ INCR_STAT( rx_crc_errors );
+ if ( ldes0 & ( RDES0_STATUS_DB ) )
+ INCR_STAT( rx_align_errors );
+ if ( ldes0 & ( RDES0_STATUS_LATECOLL ) )
+ INCR_STAT( rx_collisions );
+ if ( ldes0 & ( RDES0_STATUS_TOOLONG ) )
+ INCR_STAT( rx_too_long_frames );
+ if ( ldes0 & ( RDES0_STATUS_RF ) )
+ INCR_STAT( rx_short_frames );
+ if ( ldes0 & ( RDES0_STATUS_RE ) )
+ INCR_STAT( rx_symbol_errors );
+ }
+ else
+ // Dunno what went wrong really...
+ INCR_STAT( rx_resource_errors );
+ }
+#endif // KEEP_STATISTICS
+
+ // Open the buffer for the device to use
+ bp->des0 = DES0_STATUS_OWN_OPEN; // NIC owns it, not the CPU
+
+ // Step i around the ring buffer...
+ index++;
+ if ( index >= RX_DESCRIPTORS )
+ index = 0;
+ }
+
+ // record the right packet for next time
+ p_i21143->next_rx_descriptor = index;
+
+ CYG_ASSERT( 0 <= p_i21143->next_rx_descriptor, "rx descriptor underflow" );
+ CYG_ASSERT( RX_DESCRIPTORS > p_i21143->next_rx_descriptor, "rx descriptor overflow" );
+
+ { // We should not have needed ioaddr before this point.
+ cyg_uint32 ioaddr;
+ cyg_uint32 l;
+
+ // Now examine the state of the receive engine and prompt it accordingly.
+ ioaddr = p_i21143->io_address; // get 21143's I/O address
+ l = INL( CSR_STATUS );
+
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "PacketRxReady: done scan, next %d, status %08x %s\n",
+ p_i21143->next_rx_descriptor, l,
+ (CSR_STATUS_RXSTATUS & l) != CSR_STATUS_RXSTATUS_STOPPED ?
+ "Running" : "Stopped" );
+#endif
+
+ if ( (CSR_STATUS_RXSTATUS & l) != CSR_STATUS_RXSTATUS_STOPPED ) {
+ // Then ping it into life
+ OUTL( 0, CSR_RXPOLL );
+ }
+ else {
+ // Oh dear, it's stopped; we must initialize and start the rx machine
+ InitRxRing( p_i21143 );
+ OUTL( CYGHWR_PCI_VIRT_TO_BUS( (cyg_uint32)p_i21143->rx_ring ), CSR_RXBASE );
+ l = INL( CSR_OPMODE );
+ l |= CSR_OPMODE_RX_START;
+ OUTL( l, CSR_OPMODE );
+ INCR_STAT( rx_resource );
+ INCR_STAT( rx_restart );
+ }
+ }
+}
+
+
+// and the callback function
+
+static void
+i21143_recv( struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len )
+{
+ volatile BUFDES *bp;
+ struct i21143 *p_i21143;
+ cyg_uint32 from_p;
+ int total_len;
+ struct eth_drv_sg *last_sg;
+
+ p_i21143 = (struct i21143 *)(sc->driver_private);
+
+ CYG_ASSERT( 0 <= p_i21143->next_rx_descriptor, "rx descriptor underflow" );
+ CYG_ASSERT( RX_DESCRIPTORS > p_i21143->next_rx_descriptor, "rx descriptor overflow" );
+
+ bp = &p_i21143->rx_ring[ p_i21143->next_rx_descriptor ];
+
+ CYG_ASSERT( 0 == bp->buf2, "Corrupt bp->buf2" );
+ CYG_ASSERT( 0 != bp->buf1, "Null bp->buf1" );
+ CYG_ASSERT( DES0_STATUS_OWN_DONE == (bp->des0 & DES0_STATUS_OWN), "bp not done" );
+
+ // Copy the data to the network stack
+ from_p = CYGHWR_BUS_TO_UNCACHED( bp->buf1 );
+ total_len = (RDES0_COUNT_MASK & bp->des0) >> RDES0_COUNT_SHIFT;
+
+#ifdef DEBUG_TRAFFIC
+ diag_printf("Recv callback: index %d des0 = %08x: %d sg's, %d bytes\n",
+ p_i21143->next_rx_descriptor, bp->des0, sg_len, total_len);
+#endif
+
+ // check we have memory to copy into; we would be called even if
+ // caller was out of memory in order to maintain our state.
+ if ( 0 == sg_len || 0 == sg_list )
+ return; // caller was out of mbufs
+
+ INCR_STAT( rx_deliver );
+
+ CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
+ CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
+
+ for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
+ cyg_uint8 *to_p;
+ int l;
+
+ to_p = (cyg_uint8 *)(sg_list->buf);
+ l = sg_list->len;
+
+ CYG_ASSERT( 0 <= l, "sg length -ve" );
+
+ if ( 0 >= l || 0 == to_p )
+ return; // caller was out of mbufs
+
+ if ( l > total_len )
+ l = total_len;
+
+ memcpy( to_p, (unsigned char *)from_p, l );
+ from_p += l;
+ total_len -= l;
+ }
+
+ CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" );
+ CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" );
+ CYG_ASSERT( CYGHWR_BUS_TO_UNCACHED( bp->buf1 ) < from_p, "from_p wild in rx" );
+ CYG_ASSERT( CYGHWR_BUS_TO_UNCACHED( bp->buf1 ) + MAX_RX_PACKET_SIZE >= from_p,
+ "from_p overflow in rx" );
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : InitTxRing
+//
+// ------------------------------------------------------------------------
+static void
+InitTxRing(struct i21143* p_i21143)
+{
+ int i;
+ volatile BUFDES *bp;
+
+ p_i21143->tx_ring =
+ (BUFDES *)CYGHWR_CACHED_TO_UNCACHED( &(p_i21143->_tx[0]) );
+
+ bp = p_i21143->tx_ring;
+ for ( i = 0 ; i < TX_DESCRIPTORS; i++ ) {
+ bp->des0 = DES0_STATUS_OWN_DONE; // CPU owns it, not the NIC
+ bp->des1 = 0;
+ bp->buf1 = bp->buf2 = 0;
+ bp++;
+ }
+ bp--; // last one
+ bp->des1 |= DES1_ENDRING;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : TxDone (Called from delivery thread)
+//
+// This returns Tx's from the Tx Machine to the stack (ie. reports
+// completion) - allowing for missed interrupts, and so on.
+// ------------------------------------------------------------------------
+
+static void
+TxDone(struct i21143* p_i21143)
+{
+ struct eth_drv_sc *sc;
+ unsigned long key = 0;
+ cyg_uint32 ioaddr;
+
+ {
+ struct cyg_netdevtab_entry *ndp;
+ ndp = (struct cyg_netdevtab_entry *)(p_i21143->ndp);
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+ CHECK_NDP_SC_LINK();
+ }
+
+ ioaddr = p_i21143->io_address; // get 21143's I/O address
+
+#ifdef DEBUG_TRAFFIC_TXDETAILS
+ dump_tx_details( p_i21143, "TxDone" );
+#endif
+
+ if ( NO_TX_IN_PROGRESS != p_i21143->tx_endbuf) {
+ cyg_uint32 l;
+ volatile BUFDES *bp;
+ cyg_uint32 des;
+
+ CYG_ASSERT( TX_DESCRIPTORS > p_i21143->tx_endbuf, "tx_endbuf range" );
+
+ l = INL( CSR_STATUS ); // Important: read this first
+
+ bp = p_i21143->tx_ring;
+ bp += p_i21143->tx_endbuf; // The descriptor with the "end" marker
+
+ // It's not clear where error status gets written if the error is
+ // *before* the end-marked bufdesc. We'll see.
+
+ des = bp->des1;
+ CYG_ASSERT( TDES1_CONTROL_LAST & des , "Last buf not marked" );
+ CYG_ASSERT( TDES1_CONTROL_INTERRUPT & des , "No interrupt req" );
+ CYG_ASSERT( 0 == (DES1_2ACHAIN & des), "Buffer chained" );
+ CYG_ASSERT( 0 == ((TDES1_CONTROL_SETUP |
+ TDES1_CONTROL_SETUP_FT1 |
+ TDES1_CONTROL_SETUP_FT0 |
+ TDES1_CONTROL_NO_CRC |
+ TDES1_CONTROL_NO_PAD)
+ & des), "Buffer wierd flags" );
+ des = bp->des0;
+ if ( DES0_STATUS_OWN_DONE == (des & DES0_STATUS_OWN) ) {
+ // Then it finished; somehow...
+ key = p_i21143->tx_keys[ 0 ];
+#ifdef DEBUG_TRAFFIC
+ diag_printf("TxDone: KEY %x, %d descs, status %08x\n",
+ key, p_i21143->tx_endbuf+1, des );
+#endif
+#ifdef KEEP_STATISTICS
+ // Then look for an error code from the tx records...
+ if ( ! ( DES0_STATUS_ERROR & des ) )
+ INCR_STAT( tx_good );
+ // Not all the following are errors, so check all
+ if ( des & ( TDES0_STATUS_LO | TDES0_STATUS_NC ) )
+ INCR_STAT( tx_carrier_loss );
+ if ( des & ( TDES0_STATUS_LC ) )
+ INCR_STAT( tx_late_collisions );
+ if ( des & ( TDES0_STATUS_EC ) )
+ INCR_STAT( tx_max_collisions );
+ if ( des & ( TDES0_STATUS_LF ) )
+ INCR_STAT( tx_sqetesterrors );
+ if ( des & ( TDES0_STATUS_UFL ) )
+ INCR_STAT( tx_underrun );
+ if ( des & ( TDES0_STATUS_DE ) )
+ INCR_STAT( tx_deferred );
+ // Now count collisions per se:
+ des = ((des & TDES0_STATUS_CC_MASK) >> TDES0_STATUS_CC_SHIFT);
+ if ( 0 < des ) {
+ INCR_STAT( tx_total_collisions );
+ if ( 1 < des )
+ INCR_STAT( tx_mult_collisions );
+ else
+ INCR_STAT( tx_single_collisions );
+ }
+#endif // KEEP_STATISTICS
+ }
+ else {
+ // a Tx is in progress, but it has not yet completed;
+ // probably wise to check on the tx machine status.
+ if ( ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_STOPPED) ||
+ ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_SUSPENDED) ) {
+ // then it's not active right now!
+ key = p_i21143->tx_keys[ 0 ];
+#ifdef DEBUG_TRAFFIC
+ diag_printf("TxDone STOPPED! KEY %x, %d descs, status %08x, CSR_STATUS %08x\n",
+ key, p_i21143->tx_endbuf, des, l );
+#endif
+ INCR_STAT( tx_underrun ); // at a guess...
+ }
+ }
+
+ // Common "done" code - key nonzero => report done
+ if (key) {
+ p_i21143->tx_keys[ 0 ] = 0;
+ p_i21143->tx_endbuf = NO_TX_IN_PROGRESS;
+ // Then tell the stack we are done:
+ INCR_STAT( tx_complete );
+ (sc->funs->eth_drv->tx_done)( sc, key, 0 );
+ }
+ }
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : i21143_can_send
+//
+// ------------------------------------------------------------------------
+
+static int
+i21143_can_send(struct eth_drv_sc *sc)
+{
+ struct i21143 *p_i21143;
+
+ p_i21143 = (struct i21143 *)sc->driver_private;
+
+ IF_BAD_21143( p_i21143 ) {
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_can_send: Bad device pointer %x\n", p_i21143 );
+#endif
+ return 0;
+ }
+
+ if ( p_i21143->active ) {
+ if ( NO_TX_IN_PROGRESS != p_i21143->tx_endbuf )
+ // Poll for Tx completion
+ TxDone( p_i21143 );
+
+ // Poll for receptions
+ PacketRxReady( p_i21143 );
+ }
+
+#ifdef neverDEBUG_TRAFFIC
+ diag_printf( "i21143_can_send: returning %d\n",
+ (NO_TX_IN_PROGRESS == p_i21143->tx_endbuf) && p_i21143->active );
+#endif
+
+ return (NO_TX_IN_PROGRESS == p_i21143->tx_endbuf) && p_i21143->active;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i21143_send
+//
+// ------------------------------------------------------------------------
+
+static void
+i21143_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list, int sg_len, int total_len,
+ unsigned long key)
+{
+ struct i21143 *p_i21143;
+ cyg_uint32 ioaddr;
+ struct eth_drv_sg *last_sg;
+ volatile BUFDES *bp;
+ int bufcount;
+ cyg_uint32 x;
+
+ p_i21143 = (struct i21143 *)sc->driver_private;
+
+ IF_BAD_21143( p_i21143 ) {
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_send: Bad device pointer %x\n", p_i21143 );
+#endif
+ return;
+ }
+
+ if ( NO_TX_IN_PROGRESS != p_i21143->tx_endbuf) {
+ // Then we cannot do this
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_send: tx busy %x, %d bufs key %x\n",
+ p_i21143, p_i21143->tx_endbuf, p_i21143->tx_keys[0] );
+#endif
+ CYG_FAIL( "Send call when already busy" );
+ INCR_STAT( tx_dropped );
+ return;
+ }
+
+ ioaddr = p_i21143->io_address;
+
+ bp = p_i21143->tx_ring;
+ bufcount = 0;
+
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_send() key %x\n", key );
+#endif
+
+ INCR_STAT( tx_count );
+
+ for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
+ cyg_uint8 *from_p;
+ int l;
+
+ from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address
+ l = sg_list->len;
+
+ if ( l > total_len )
+ l = total_len;
+
+ // Ensure the mbuf contents really is in RAM where DMA can see it.
+ // (Must round to cache lines apparantly for some MIPS)
+ HAL_DCACHE_STORE( ((CYG_ADDRESS)from_p) &~(HAL_DCACHE_LINE_SIZE-1),
+ l + HAL_DCACHE_LINE_SIZE );
+
+ // There are two pointer, length pairs in each descriptor. We only
+ // bother using the first one - the code saved is small but so is
+ // the overhead of memory.
+ bp->buf1 = CYGHWR_PCI_VIRT_TO_BUS( from_p ); // uncached real RAM address
+ bp->buf2 = 0;
+ // Record length and add endring flag iff end of ring - never leave
+ // it blank in memory!
+ x = (l << DES1_B1SIZE_SHIFT) & DES1_B1SIZE_MASK; // plus zero buf2 size.
+ if ( (TX_DESCRIPTORS-1) == bufcount )
+ x |= DES1_ENDRING;
+ bp->des1 = x;
+
+ // Leave writing the zeroth bufdesc DES0 until all are complete:
+ // the tx engine will be stopped looking there.
+ if ( 0 < bufcount ) // then we can write DES0 also.
+ bp->des0 = DES0_STATUS_OWN_OPEN;
+
+ total_len -= l;
+ bp++;
+ bufcount++;
+
+ if ( 0 > total_len )
+ break; // Should exit via sg_last normally
+ }
+
+ CYG_ASSERT( 0 == total_len, "length mismatch in tx" );
+ CYG_ASSERT( last_sg == sg_list, "sg count mismatch in tx" );
+
+ CYG_ASSERT( bp > &p_i21143->tx_ring[0], "bp underflow" );
+
+ bp--; // back to the last-used bp.
+ bufcount--;
+ p_i21143->tx_endbuf = bufcount; // record that we are busy
+ p_i21143->tx_keys[0] = key; // and the key to return
+
+ CYG_ASSERT( bp < &p_i21143->tx_ring[ TX_DESCRIPTORS ], "bp underflow" );
+
+ // Mark this the last valid buffer.
+ bp->des1 |= TDES1_CONTROL_LAST | TDES1_CONTROL_INTERRUPT;
+
+ CYG_ASSERT( &(p_i21143->tx_ring[bufcount]) == bp, "Bp/bufcount misstep" );
+
+ bp++;
+ bufcount++;
+
+ // Make the rest be null links
+ for ( /* bp */ ; bp < &p_i21143->tx_ring[ TX_DESCRIPTORS ]; bp++ ) {
+ bp->buf1 = 0;
+ bp->buf2 = 0;
+ x = 0; // zero size for both buffers
+ if ( (TX_DESCRIPTORS-1) == bufcount )
+ x |= DES1_ENDRING;
+ bp->des1 = x;
+ bp->des0 = DES0_STATUS_OWN_OPEN;
+ bufcount++;
+ }
+
+ // Now it's safe to write the zeroth descriptor:
+ p_i21143->tx_ring->des1 |= TDES1_CONTROL_FIRST;
+ p_i21143->tx_ring->des0 = DES0_STATUS_OWN_OPEN;
+
+#ifdef DEBUG_TRAFFIC_TXDETAILS
+ dump_tx_details( p_i21143, "i21143_send" );
+#endif
+
+ // And start off the tx system
+ x = INL( CSR_STATUS );
+
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_send: ready, status %08x %s\n",
+ x,
+ (CSR_STATUS_TXSTATUS & x) != CSR_STATUS_TXSTATUS_STOPPED ?
+ "Running" : "Stopped" );
+#endif
+
+ if ( CSR_STATUS_TXSTATUS_STOPPED == (CSR_STATUS_TXSTATUS & x) ) {
+ cyg_uint32 l;
+ // Then we must initialize and start the tx machine
+ OUTL( CYGHWR_PCI_VIRT_TO_BUS( (cyg_uint32)p_i21143->tx_ring ), CSR_TXBASE );
+ l = INL( CSR_OPMODE );
+ l |= CSR_OPMODE_TX_START;
+ OUTL( l, CSR_OPMODE );
+ }
+ else if ( CSR_STATUS_TXSTATUS_SUSPENDED == (CSR_STATUS_TXSTATUS & x) ) {
+ // Then we just have to ping it
+ OUTL( 0, CSR_TXPOLL );
+ }
+ else {
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_send: tx not ready %x CSR_STATUS %08x\n", p_i21143, x );
+#endif
+ CYG_FAIL( "Tx is not ready to tx" );
+
+ // Try to recover by brutal means...
+ i21143_stop( sc ); // will return the key
+ i21143_start( sc, NULL, 0 );
+ }
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i21143_reset
+//
+// ------------------------------------------------------------------------
+static void
+i21143_reset(struct i21143* p_i21143)
+{
+ cyg_uint32 ioaddr = p_i21143->io_address;
+ cyg_uint32 l;
+ int i, status;
+ // First stop the tx and rx engines - doc suggests that's necessary
+ // before writing the reset reg, but it seems a little paranoid.
+
+ l = INL( CSR_OPMODE );
+ l &=~ (CSR_OPMODE_RX_START | CSR_OPMODE_TX_START);
+ OUTL( l, CSR_OPMODE );
+
+ for ( i = 0; i < 10000; i++) {
+ l = INL( CSR_STATUS );
+ if ( ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_STOPPED) &&
+ ((CSR_STATUS_RXSTATUS & l) == CSR_STATUS_RXSTATUS_STOPPED) )
+ break;
+ }
+#ifdef DEBUG_STARTSTOPRESET
+ diag_printf( "i21143_reset: rx and tx idle after %d iters, status %x\n",
+ i, l );
+#endif
+
+ // Acknowledge all the interrupts from these activities
+ // within the device:
+ OUTL( 0xffffffff, CSR_STATUS ); // clear all bits
+
+ // Now reset the device. We are going to re-init all params anyway, so
+ // ignore other settings:
+ OUTL( CSR_BUSMODE_RESET, CSR_BUSMODE );
+
+ udelay( 100 ); // let reset take effect. "50 PCI clock cycles"
+
+ for ( i = 0; i < 10000; i++) {
+ l = INL( CSR_BUSMODE );
+ if ( (CSR_BUSMODE_RESET & l) == 0 )
+ break;
+ }
+#ifdef DEBUG_STARTSTOPRESET
+ diag_printf( "i21143_reset: reset zero after %d iters, busmode %x\n",
+ i, l );
+#endif
+
+ // Gross initialization
+ OUTL( 0 // No other options
+ // CSR_BUSMODE_PM
+ // CSR_BUSMODE_WIE
+ // CSR_BUSMODE_RLE
+ // CSR_BUSMODE_RME
+ // CSR_BUSMODE_DBO_BE
+ // CSR_BUSMODE_DBO_LE
+ // CSR_BUSMODE_TAP_SHIFT
+ | (1 << CSR_BUSMODE_CAL_SHIFT)
+ | (4 << CSR_BUSMODE_PBL_SHIFT)
+ // CSR_BUSMODE_ENDIAN_BE
+ // CSR_BUSMODE_ENDIAN_LE
+ // CSR_BUSMODE_DSL_SHIFT
+ // CSR_BUSMODE_BAR
+ // CSR_BUSMODE_RESET
+
+ , CSR_BUSMODE );
+
+ // No interrupt sources enabled yet
+ OUTL( 0, CSR_INTR_ENABLE );
+
+ OUTL( 0
+ // CSR_ROM_MII_MGT_MDI
+ | CSR_ROM_MII_MGT_MOM_READ
+ // CSR_ROM_MII_MGT_MDO
+ // CSR_ROM_MII_MGT_MDC
+ // CSR_ROM_MII_MGT_RD
+ // CSR_ROM_MII_MGT_WR
+ // CSR_ROM_MII_MGT_BR
+ // CSR_ROM_MII_MGT_SR
+ // CSR_ROM_MII_MGT_REG
+ // CSR_ROM_MII_MGT_SR_DO
+ // CSR_ROM_MII_MGT_SR_DI
+ // CSR_ROM_MII_MGT_SR_CK
+ // CSR_ROM_MII_MGT_SR_CS
+ | 0xff,
+
+ CSR_ROM_MII_MGT );
+
+ // -----------------------------------
+ // Now find out about the status of the PHY via MII
+#if 0
+ // Try resetting the PHY and power-cycling it:
+ mii_write_register( ioaddr, PHY_CONTROL_REG, PHY_CONTROL_RESET | PHY_CONTROL_AUTONEG_EN);
+ while (1) {
+ int v;
+ v = mii_read_register( ioaddr, PHY_CONTROL_REG );
+ if ( 0 == (v & PHY_CONTROL_RESET) )
+ break;
+ }
+
+ mii_write_register( ioaddr, PHY_CONTROL_REG,
+ PHY_CONTROL_POWERDOWN | PHY_CONTROL_MII_DIS | PHY_CONTROL_AUTONEG_EN );
+ udelay( 1000 );
+ mii_write_register( ioaddr, PHY_CONTROL_REG, PHY_CONTROL_AUTONEG_EN | PHY_CONTROL_AUTONEG_RST );
+
+ udelay( 1000 );
+
+ while (1) {
+ int v;
+ v = mii_read_register( ioaddr, PHY_STATUS_REG );
+ if ( PHY_STATUS_AUTONEG_ACK & v )
+ break;
+ }
+#endif
+
+#ifdef DEBUG_DUMP_REGS
+ debug_dump_regs( ioaddr, MII );
+#endif
+
+ status = i21143_status( p_i21143 );
+ p_i21143->line_status = status; // record it for SNMP info
+#ifdef DEBUG_STARTSTOPRESET
+ diag_printf("i21143_reset %d flg %x Link = %s, %s Mbps, %s Duplex\n",
+ p_i21143->index,
+ *(int *)p_i21143,
+ (GEN_STATUS_LINK & status) ? "Up" : "Down",
+ (GEN_STATUS_100MBPS & status) ? "100" : "10",
+ (GEN_STATUS_FDX & status) ? "Full" : "Half");
+#endif
+
+ OUTL( -1, CSR_ROM_PGM_ADDR );
+ OUTL( 0, CSR_INTR_MITIGATION );
+
+ // CSR13, 14 = 0; select SIA mode temporarily.
+// OUTL( CSR_OPMODE_MUST_BE_ONE, CSR_OPMODE);
+ OUTL( CSR_SIA_CONN_DEFAULT, CSR_SIA_CONN );
+ OUTL( CSR_SIA_TXRX_DEFAULT, CSR_SIA_TXRX );
+ OUTL( CSR_SIA_GPPORT_DEFAULT, CSR_SIA_GPPORT );
+
+ // Last one, CSR6
+ l = 0
+ | CSR_OPMODE_SC
+ // CSR_OPMODE_RA
+ // CSR_OPMODE_IGNOREMSB
+ | CSR_OPMODE_MUST_BE_ONE
+ // CSR_OPMODE_SCR do not set for MII mode
+ // CSR_OPMODE_PCS do not set for MII mode
+ // CSR_OPMODE_TTM set for 10Mb, not set for 100Mb
+ | CSR_OPMODE_SF // Set the store&forward bit so we can keep-
+ | CSR_OPMODE_HBD // -up at 100Mbit
+ | CSR_OPMODE_PS_MIISYM
+ | CSR_OPMODE_CA
+ // CSR_OPMODE_TX_THRES_SHIFT
+ // CSR_OPMODE_TX_START
+ // CSR_OPMODE_FC
+ // (0 << CSR_OPMODE_LOOPBACK_SHIFT)
+ // CSR_OPMODE_FD
+ // CSR_OPMODE_MULTICAST // Pass all multicast
+ // CSR_OPMODE_PROMISC // Promisc mode
+ // CSR_OPMODE_SB
+ // CSR_OPMODE_IF // Inverse filtering (!)
+ // CSR_OPMODE_PB
+ // CSR_OPMODE_HO // 0: Perfect filter
+ // CSR_OPMODE_RX_START // 1: hashing for /all/ addresses
+ // CSR_OPMODE_HP // 0: Perfect filter of N address
+ ; // 1: imperfect hash filter + 1 fixed addr
+
+ if ( GEN_STATUS_FDX & status )
+ l |= CSR_OPMODE_FD;
+ if ( ! (GEN_STATUS_100MBPS & status) )
+ l |= CSR_OPMODE_TTM;
+
+ OUTL( l, CSR_OPMODE );
+
+}
+
+// ------------------------------------------------------------------------
+//
+// INTERRUPT HANDLERS
+//
+// ------------------------------------------------------------------------
+
+static cyg_uint32
+eth_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_drv_interrupt_mask( vector );
+
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_isr, vector %d\n", vector );
+#endif
+
+ return CYG_ISR_CALL_DSR; // schedule DSR
+}
+
+
+// An indirection is used because (if we have multiple devices) we don't
+// know all the "sc" values at the time the interrupts are created.
+static
+void eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct i21143* p_i21143 = (struct i21143 *)data;
+ struct cyg_netdevtab_entry *ndp =
+ (struct cyg_netdevtab_entry *)(p_i21143->ndp);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ INCR_STAT( interrupts );
+
+ // but here, it must be a *sc:
+ eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+}
+
+// ------------------------------------------------------------------------
+// Deliver routine:
+
+void
+i21143_deliver(struct eth_drv_sc *sc)
+{
+ struct i21143* p_i21143 = (struct i21143 *)(sc->driver_private);
+ cyg_uint32 status;
+ cyg_uint32 ioaddr;
+
+ IF_BAD_21143( p_i21143 ) {
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_deliver: Bad device pointer %x\n", p_i21143 );
+#endif
+ return;
+ }
+
+ ioaddr = p_i21143->io_address;
+ status = INL( CSR_STATUS );
+
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_deliver: status %08x\n", status );
+#endif
+
+ // Acknowledge all INT sources that were active
+ OUTL( status, CSR_STATUS );
+
+ // Search for link status changes
+ if ( i21143_status_changed( p_i21143 ) ) {
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_can_send: status changed\n" );
+#endif
+ i21143_stop( sc );
+ i21143_start( sc, NULL, 0 );
+ }
+
+ if ( (CSR_STATUS_TBU | CSR_STATUS_TX_STOPPED | CSR_STATUS_TX_INTR)
+ & status ) {
+ TxDone( p_i21143 );
+ }
+
+ if ( (CSR_STATUS_RX_STOPPED | CSR_STATUS_RBU | CSR_STATUS_RX_INTR)
+ & status ) {
+ PacketRxReady( p_i21143 );
+ }
+
+ cyg_drv_interrupt_acknowledge(p_i21143->vector);
+ cyg_drv_interrupt_unmask( p_i21143->vector );
+}
+
+// ------------------------------------------------------------------------
+// Device table entry to operate the chip in a polled mode.
+// Only diddle the interface we were asked to!
+
+void
+i21143_poll(struct eth_drv_sc *sc)
+{
+ struct i21143 *p_i21143;
+ p_i21143 = (struct i21143 *)sc->driver_private;
+
+ IF_BAD_21143( p_i21143 ) {
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_poll: Bad device pointer %x\n", p_i21143 );
+#endif
+ return;
+ }
+
+ // As it happens, this driver always requests the DSR to be called:
+ (void)eth_isr( p_i21143->vector, (cyg_addrword_t)p_i21143 );
+
+ // (no harm in calling this ints-off also, when polled)
+ i21143_deliver( sc );
+}
+
+// ------------------------------------------------------------------------
+// Determine interrupt vector used by a device - for attaching GDB stubs
+// packet handler.
+int
+i21143_int_vector(struct eth_drv_sc *sc)
+{
+ struct i21143 *p_i21143;
+ p_i21143 = (struct i21143 *)sc->driver_private;
+ return (p_i21143->vector);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : pci_init_find_21143s
+//
+// This is called exactly once at the start of time to:
+// o scan the PCI bus for objects
+// o record them in the device table
+// o acquire all the info needed for the driver to access them
+// o instantiate interrupts for them
+// o attach those interrupts appropriately
+// ------------------------------------------------------------------------
+static cyg_pci_match_func find_21143s_match_func;
+
+static cyg_bool
+find_21143s_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+{
+ return
+ (/* (0x8086 == v) || */ (0x1011 == v)) && // (Intel or) DEC
+ (0x0019 == d); // [DC21142/3][PCI/CardBus 10/100 Mbit Ethernet Ctlr]
+}
+
+static int
+pci_init_find_21143s( void )
+{
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+ cyg_uint32 l;
+ int device_index;
+ int found_devices = 0;
+
+#ifdef DEBUG
+ diag_printf("pci_init_find_21143s()\n");
+#endif
+
+ cyg_pci_init();
+#ifdef DEBUG
+ diag_printf("Finished cyg_pci_init();\n");
+#endif
+
+ devid = CYG_PCI_NULL_DEVID;
+
+ for (device_index = 0;
+ device_index < CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT;
+ device_index++) {
+ struct i21143 *p_i21143 = i21143_priv_array[device_index];
+
+ p_i21143->index = device_index;
+
+ // See above for find_21143s_match_func - it selects any of several
+ // variants. This is necessary in case we have multiple mixed-type
+ // devices on one board in arbitrary orders.
+ if (cyg_pci_find_matching( &find_21143s_match_func, NULL, &devid )) {
+#ifdef DEBUG
+ diag_printf("eth%d = 21143\n", device_index);
+#endif
+ cyg_pci_get_device_info(devid, &dev_info);
+
+ p_i21143->interrupt_handle = 0; // Flag not attached.
+ if (cyg_pci_translate_interrupt(&dev_info, &p_i21143->vector)) {
+#ifdef DEBUG
+ diag_printf(" Wired to HAL vector %d\n", p_i21143->vector);
+#endif
+ cyg_drv_interrupt_create(
+ p_i21143->vector,
+ 0, // Priority - unused
+ (CYG_ADDRWORD)p_i21143, // Data item passed to ISR & DSR
+ eth_isr, // ISR
+ eth_dsr, // DSR
+ &p_i21143->interrupt_handle, // handle to intr obj
+ &p_i21143->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(p_i21143->interrupt_handle);
+
+ cyg_drv_interrupt_configure( p_i21143->vector, 1, 0 );
+
+ // Don't unmask the interrupt yet, that could get us into a
+ // race.
+ }
+ else {
+ p_i21143->vector=0;
+#ifdef DEBUG
+ diag_printf(" Does not generate interrupts.\n");
+#endif
+ }
+
+ if (cyg_pci_configure_device(&dev_info)) {
+#ifdef DEBUG
+ int i;
+ diag_printf("Found device on bus %d, devfn 0x%02x:\n",
+ CYG_PCI_DEV_GET_BUS(devid),
+ CYG_PCI_DEV_GET_DEVFN(devid));
+
+ if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
+ diag_printf(" Note that board is active. Probed"
+ " sizes and CPU addresses invalid!\n");
+ }
+ diag_printf(" Vendor 0x%04x", dev_info.vendor);
+ diag_printf("\n Device 0x%04x", dev_info.device);
+ diag_printf("\n Command 0x%04x, Status 0x%04x\n",
+ dev_info.command, dev_info.status);
+
+ diag_printf(" Class/Rev 0x%08x", dev_info.class_rev);
+ diag_printf("\n Header 0x%02x\n", dev_info.header_type);
+
+ diag_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+ dev_info.header.normal.sub_vendor,
+ dev_info.header.normal.sub_id);
+
+ for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
+ diag_printf(" BAR[%d] 0x%08x /", i, dev_info.base_address[i]);
+ diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
+ dev_info.base_size[i], dev_info.base_map[i]);
+ }
+ diag_printf(" eth%d configured\n", device_index);
+#endif
+ found_devices++;
+ p_i21143->found = 1;
+ p_i21143->active = 0;
+ p_i21143->devid = devid;
+ p_i21143->io_address = dev_info.base_map[0];
+#ifdef DEBUG
+ diag_printf(" I/O address = 0x%08x\n", dev_info.base_map[0]);
+#endif
+
+#ifdef pciDEBUG
+ diag_printf( "Before wakeup\n" );
+ for ( i = 0; i <= 0xe0; i += 4 ) {
+ if ( i == 0x18 ) i = 0x28;
+ if ( i == 0x58 ) i = 0xdc;
+ cyg_pci_read_config_uint32( devid, i, &l );
+ diag_printf( "PCI Config reg %02x = 0x%08x\n", i, l );
+ }
+#endif
+ // Awaken the device through the CFDD device-specific
+ // register - which boots up with it asleep - great.
+ l = 0;
+ cyg_pci_write_config_uint32( devid, 0x40, l );
+#ifdef pciDEBUG
+ diag_printf( "After wakeup\n" );
+ for ( i = 0; i <= 0xe0; i += 4 ) {
+ if ( i == 0x18 ) i = 0x28;
+ if ( i == 0x58 ) i = 0xdc;
+ cyg_pci_read_config_uint32( devid, i, &l );
+ diag_printf( "PCI Config reg %02x = 0x%08x\n", i, l );
+ }
+#endif
+ // Now the PCI part of the device is configured, reset
+ // it. This should make it safe to enable the
+ // interrupt
+ i21143_reset(p_i21143);
+
+ // This is the indicator for "uses an interrupt"
+ if (p_i21143->interrupt_handle != 0) {
+ cyg_drv_interrupt_acknowledge(p_i21143->vector);
+ cyg_drv_interrupt_unmask(p_i21143->vector);
+ }
+#ifdef DEBUG
+ diag_printf(" **** Device enabled for I/O only and Bus Master\n");
+#endif
+ }
+ else {
+ p_i21143->found = 0;
+ p_i21143->active = 0;
+#ifdef DEBUG
+ diag_printf("Failed to configure device %d\n",device_index);
+#endif
+ }
+ }
+ else {
+ p_i21143->found = 0;
+ p_i21143->active = 0;
+#ifdef DEBUG
+ diag_printf("eth%d not found\n", device_index);
+#endif
+ }
+ }
+
+ if (0 == found_devices)
+ return 0;
+
+ // Now a delay to ensure the hardware has "come up" before you try to
+ // use it.
+ udelay( 1000 );
+ return 1;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i21143_configure
+//
+// Return : 0 = It worked.
+// non0 = It failed.
+// ------------------------------------------------------------------------
+
+static int i21143_configure(struct i21143* p_i21143, int promisc )
+{
+ cyg_uint32 ioaddr;
+ cyg_uint32 l;
+
+ IF_BAD_21143( p_i21143 ) {
+#ifdef DEBUG
+ diag_printf( "configure: Bad device pointer %x\n",
+ p_i21143 );
+#endif
+ return -1;
+ }
+
+ ioaddr = p_i21143->io_address;
+
+ l = INL( CSR_OPMODE );
+ if ( promisc )
+ l |= CSR_OPMODE_PROMISC;
+ else
+ l &=~ CSR_OPMODE_PROMISC;
+ OUTL( l, CSR_OPMODE );
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i21143_ioctl
+//
+// ------------------------------------------------------------------------
+static int
+i21143_ioctl(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ struct i21143 *p_i21143;
+
+ p_i21143 = (struct i21143 *)sc->driver_private;
+
+ IF_BAD_21143( p_i21143 ) {
+#ifdef DEBUG
+ diag_printf( "i21143_ioctl/control: Bad device pointer %x\n", p_i21143 );
+#endif
+ return -1;
+ }
+
+#ifdef DEBUG_TRAFFIC
+ diag_printf( "i21143_ioctl: device eth%d at %x; key is 0x%x, data at %x[%d]\n",
+ p_i21143->index, p_i21143, key, data, data_length );
+#endif
+
+ switch ( key ) {
+
+#ifdef ETH_DRV_SET_MAC_ADDRESS
+ case ETH_DRV_SET_MAC_ADDRESS: {
+ int act;
+ if ( 6 != data_length )
+ return -2;
+ act = p_i21143->active;
+ i21143_stop( sc );
+ eth_set_mac_address( p_i21143, data );
+ if ( act )
+ i21143_start( sc, NULL, 0 );
+ return 0;
+ }
+#endif
+
+#ifdef ETH_DRV_GET_IF_STATS_UD
+ case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+// ETH_STATS_INIT( sc ); // so UPDATE the statistics structure
+#endif
+ // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+ case ETH_DRV_GET_IF_STATS:
+#endif
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+ {
+ struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+ int i;
+ static unsigned char my_chipset[]
+ = { ETH_DEV_DOT3STATSETHERCHIPSET };
+
+ strcpy( p->description, CYGDAT_DEVS_ETH_DESCRIPTION );
+ CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+ for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+ if ( 0 == (p->snmp_chipset[i] = my_chipset[i]) )
+ break;
+
+ i = p_i21143->line_status; // use cached copy - else sloooow
+
+ if ( !( i & GEN_STATUS_LINK) ) {
+ p->operational = 2; // LINK DOWN
+ p->duplex = 1; // UNKNOWN
+ p->speed = 0;
+ }
+ else {
+ p->operational = 3; // LINK UP
+ p->duplex = (i & GEN_STATUS_FDX) ? 3 : 2; // 2 = SIMPLEX, 3 = DUPLEX
+ p->speed = ((i & GEN_STATUS_100MBPS) ? 100 : 10) * 1000000;
+ }
+
+#ifdef KEEP_STATISTICS
+ {
+ struct stats *ps = &p_i21143->stats;
+
+ // Admit to it...
+ p->supports_dot3 = true;
+
+ // Those commented out are not available on this chip.
+
+ p->tx_good = ps->tx_good ;
+ p->tx_max_collisions = ps->tx_max_collisions ;
+ p->tx_late_collisions = ps->tx_late_collisions ;
+ p->tx_underrun = ps->tx_underrun ;
+ p->tx_carrier_loss = ps->tx_carrier_loss ;
+ p->tx_deferred = ps->tx_deferred ;
+ p->tx_sqetesterrors = ps->tx_sqetesterrors ;
+ p->tx_single_collisions = ps->tx_single_collisions;
+ p->tx_mult_collisions = ps->tx_mult_collisions ;
+ p->tx_total_collisions = ps->tx_total_collisions ;
+
+ p->rx_good = ps->rx_good ;
+ p->rx_crc_errors = ps->rx_crc_errors ;
+ p->rx_align_errors = ps->rx_align_errors ;
+ p->rx_resource_errors = ps->rx_resource_errors ;
+// p->rx_overrun_errors = ps->rx_overrun_errors ;
+ p->rx_collisions = ps->rx_collisions ;
+ p->rx_short_frames = ps->rx_short_frames ;
+ p->rx_too_long_frames = ps->rx_too_long_frames ;
+ p->rx_symbol_errors = ps->rx_symbol_errors ;
+
+ p->interrupts = ps->interrupts ;
+ p->rx_count = ps->rx_count ;
+ p->rx_deliver = ps->rx_deliver ;
+ p->rx_resource = ps->rx_resource ;
+ p->rx_restart = ps->rx_restart ;
+
+ p->tx_count = ps->tx_count ;
+ p->tx_complete = ps->tx_complete ;
+ p->tx_dropped = ps->tx_dropped ;
+ }
+#endif // KEEP_STATISTICS
+
+ p->tx_queue_len = 1;
+
+ return 0; // OK
+ }
+#endif
+
+ default:
+ break;
+ }
+ return -1;
+}
+
+// ------------------------------------------------------------------------
+
+static void
+eth_set_mac_address( struct i21143* p_i21143, cyg_uint8 *addr )
+{
+ cyg_uint32 ioaddr = p_i21143->io_address;
+ cyg_uint32 l;
+ int i;
+ volatile BUFDES *bp;
+ cyg_uint8 *datap;
+
+#define SETUP_SIZE (192)
+
+ cyg_uint32 buf[ SETUP_SIZE/4 ]; // for word alignment
+
+ // We need to send a pseudo-transmit which contains setup data.
+
+ if ( NULL == addr )
+ addr = &p_i21143->mac_address[0];
+ else {
+ p_i21143->mac_address[0] = addr[0];
+ p_i21143->mac_address[1] = addr[1];
+ p_i21143->mac_address[2] = addr[2];
+ p_i21143->mac_address[3] = addr[3];
+ p_i21143->mac_address[4] = addr[4];
+ p_i21143->mac_address[5] = addr[5];
+ }
+
+ if ( ! p_i21143->active ) {
+ // Then do not torment the hardware - starting
+ // the interface will do that.
+ p_i21143->mac_addr_ok = 1;
+ return;
+ }
+
+ InitTxRing( p_i21143 ); // Since we are about to use this struct
+
+ bp = p_i21143->tx_ring;
+
+ bp->des0 = DES0_STATUS_OWN_DONE; // Safety: not for the NIC yet
+
+ bp->buf1 = CYGHWR_PCI_VIRT_TO_BUS( ((cyg_uint32)&buf[0]) );
+ bp->buf2 = 0;
+
+ datap = (cyg_uint8 *)CYGHWR_BUS_TO_UNCACHED( bp->buf1 );
+
+ bp->des1 =
+ DES1_ENDRING |
+ TDES1_CONTROL_SETUP |
+ //TDES1_CONTROL_SETUP_FT0 | // 0,0 <=> perfect filtering
+ //TDES1_CONTROL_SETUP_FT1 |
+ (SETUP_SIZE << DES1_B1SIZE_SHIFT);
+ // The filtering type is 00 = perfect filtering of 16 addresses
+ // (including the broadcast address, I think)
+
+ for ( i = 0; i < SETUP_SIZE ; i++ )
+ datap[i] = 0xff; // fill the space with the broadcast address
+
+ // Insert the address: do it in an endian agnostic fashion.
+ // [If we were doing perfect plus hash table it would be slot
+ // 13 at offset 156. Lower halfwords only.]
+ // So we'll use slot 13 anyway; the other slots are all FFs.
+
+ datap[156] = addr[0];
+ datap[157] = addr[1];
+ datap[158] = addr[1];
+ datap[159] = addr[0];
+ datap[160] = addr[2];
+ datap[161] = addr[3];
+ datap[162] = addr[3];
+ datap[163] = addr[2];
+ datap[164] = addr[4];
+ datap[165] = addr[5];
+ datap[166] = addr[5];
+ datap[167] = addr[4];
+
+ // Make the rest be null links
+ for ( i = 1; i < TX_DESCRIPTORS; i++ ) {
+ int x;
+ p_i21143->tx_ring[ i ].buf1 = 0;
+ p_i21143->tx_ring[ i ].buf2 = 0;
+ x = 0; // zero size for both buffers
+ if ( (TX_DESCRIPTORS-1) == i )
+ x |= DES1_ENDRING;
+ p_i21143->tx_ring[ i ].des1 = x;
+ p_i21143->tx_ring[ i ].des0 = DES0_STATUS_OWN_OPEN;
+ }
+
+ // Tell the device the address
+ OUTL( CYGHWR_PCI_VIRT_TO_BUS( (cyg_uint32)bp ), CSR_TXBASE );
+ // Open the descriptor to the device
+ bp->des0 = DES0_STATUS_OWN_OPEN;
+
+#ifdef DEBUG_MAC
+ dump_tx_details( p_i21143, "set_mac starting:" );
+#endif
+ // And set it going
+ l = INL( CSR_OPMODE );
+ l |= CSR_OPMODE_TX_START;
+ OUTL( l, CSR_OPMODE );
+
+ // Wait for the buffer to be closed
+ for ( i = 0; i < 10000; i++ )
+ if ( DES0_STATUS_OWN_DONE == (DES0_STATUS_OWN & bp->des0) )
+ break;
+#ifdef DEBUG_MAC
+ diag_printf( "eth_set_mac_address: %d loops: bufdesc status tdes0 %08x, tdes1 %08x\n",
+ i, bp->des0, bp->des1 );
+#endif
+
+ // Wait for it to be done
+ for ( i = 0; i < 10000; i++ ) {
+ l = INL( CSR_STATUS );
+ if ( ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_STOPPED) ||
+ ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_SUSPENDED) )
+ break;
+ }
+
+#ifdef DEBUG_MAC
+ diag_printf( "eth_set_mac_address: tx done after %d iters; status %x\n",
+ i, l );
+#endif
+
+#ifdef DEBUG_MAC
+ dump_tx_details( p_i21143, "set_mac all done:" );
+#endif
+
+ // Kill the tx engine
+ l = INL( CSR_OPMODE );
+ l &=~ CSR_OPMODE_TX_START;
+ OUTL( l, CSR_OPMODE );
+
+ for ( i = 0; i < 10000; i++ ) {
+ l = INL( CSR_STATUS );
+ if ( ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_STOPPED) )
+ break;
+ }
+#ifdef DEBUG_MAC
+ diag_printf( "eth_set_mac_address: tx stopped after %d iters; status %x\n",
+ i, l );
+#endif
+
+ // Acknowledge all the interrupts from these activities
+ // within the device:
+ OUTL( 0xffffffff, CSR_STATUS ); // clear all bits
+
+ p_i21143->mac_addr_ok = 1;
+
+}
+
+// ------------------------------------------------------------------------
+//
+// MDIO
+//
+// Device-specific bit-twiddling and line driving side-effects
+
+// CYGACC_CALL_IF_DELAY_US() drags in huge amounts of scheduler locking and
+// the like 'cos it's a VV call! We only want a delay of 1uS tops, so:
+
+#define MII_DELAY() do { int z; for ( z = 0; z < 20; z++ ) ; } while (0)
+
+#if 0
+# define MII_PRINTF diag_printf
+# define MII_STUFF "%4s | %4s | %4s | %4s [%08x]\n", \
+ (l & (1<<19)) ? "MDI" : "---", \
+ (l & (1<<18)) ? "Read" : "Wr", \
+ (l & (1<<17)) ? "MDO" : "---", \
+ (l & (1<<16)) ? "CLK" : "clk", \
+ l
+#else
+# define MII_PRINTF( foo )
+# define MII_STUFF
+#endif
+
+static inline void mii_clock_up( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( CSR_ROM_MII_MGT );
+ l |= CSR_ROM_MII_MGT_MDC;
+ OUTL( l, CSR_ROM_MII_MGT );
+ MII_PRINTF( "mii_clock_up : " MII_STUFF );
+ MII_DELAY();
+}
+
+static inline void mii_clock_down( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( CSR_ROM_MII_MGT );
+ l &=~ CSR_ROM_MII_MGT_MDC;
+ OUTL( l, CSR_ROM_MII_MGT );
+ MII_PRINTF( "mii_clock_down: " MII_STUFF );
+ MII_DELAY();
+}
+
+static inline void mii_read_mode( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( CSR_ROM_MII_MGT );
+ l |= CSR_ROM_MII_MGT_MOM_READ;
+ OUTL( l, CSR_ROM_MII_MGT );
+ MII_PRINTF( "mii_read_mode : " MII_STUFF );
+ MII_DELAY();
+}
+
+static inline int mii_read_data_bit( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( CSR_ROM_MII_MGT );
+ MII_PRINTF( "mii_read_data : " MII_STUFF );
+ return CSR_ROM_MII_MGT_MDI == (CSR_ROM_MII_MGT_MDI & l);
+}
+
+static inline void mii_write_data_bit( int ioaddr, int databit )
+{
+ cyg_uint32 l;
+ l = INL( CSR_ROM_MII_MGT );
+ if ( databit )
+ l |= CSR_ROM_MII_MGT_MDO;
+ else
+ l &=~ CSR_ROM_MII_MGT_MDO;
+ l &=~ CSR_ROM_MII_MGT_MOM; // drive the mdio line
+ OUTL( l, CSR_ROM_MII_MGT );
+ MII_PRINTF( "mii_write_data: " MII_STUFF );
+ MII_DELAY();
+}
+
+// Pass ioaddr around "invisibly"
+#define MII_CLOCK_UP() mii_clock_up(ioaddr)
+#define MII_CLOCK_DOWN() mii_clock_down(ioaddr)
+#define MII_READ_MODE() mii_read_mode(ioaddr)
+#define MII_READ_DATA_BIT() mii_read_data_bit(ioaddr)
+#define MII_WRITE_DATA_BIT( _d_ ) mii_write_data_bit(ioaddr,(_d_))
+
+// ------------------------------------------------------------------------
+//
+// MDIO
+//
+// Management data over the MII interface - nasty hand driven serial stuff
+//
+
+static void mii_write_bits( int ioaddr, int val, int bitcount )
+{
+ int i;
+ // These are deliberately signed ints so that we can send an overlong
+ // preamble if we want by saying "send -1 of width 40 bits and relying
+ // on sign extension.
+ for ( i = bitcount - 1; i >= 0; i-- ) {
+ MII_CLOCK_DOWN();
+ MII_WRITE_DATA_BIT( (val >> i) & 1 );
+ MII_CLOCK_UP();
+ }
+}
+
+static int mii_read_bits( int ioaddr, int bitcount )
+{
+ int i;
+ int val = 0;
+ for ( i = bitcount - 1; i >= 0; i-- ) {
+ MII_CLOCK_DOWN();
+ val <<= 1;
+ val |= MII_READ_DATA_BIT();
+ MII_CLOCK_UP();
+ }
+ return val;
+}
+
+#define MII_WRITE_BITS( val, bitcount ) mii_write_bits( ioaddr, val, bitcount )
+#define MII_READ_BITS( bitcount ) mii_read_bits( ioaddr, bitcount )
+
+// Now define subsections of the protocol in terms of the above
+
+#define MII_WRITE_PREAMBLE() MII_WRITE_BITS( -1, 40 ) // >32 x 1s
+#define MII_WRITE_START() MII_WRITE_BITS( 1, 2 ) // 01
+#define MII_WRITE_WRITE_CMD() MII_WRITE_BITS( 1, 2 ) // 01
+#define MII_WRITE_READ_CMD() MII_WRITE_BITS( 2, 2 ) // 10
+
+#define PHY_ADDRESS (1)
+
+#define MII_WRITE_PHY_ADDR() MII_WRITE_BITS( PHY_ADDRESS, 5 )
+#define MII_WRITE_REGNUM( _r_ ) MII_WRITE_BITS( (_r_), 5 )
+
+#define MII_WRITE_TURNAROUND() MII_WRITE_BITS( 2, 2 )
+
+#define MII_READ_TURNAROUND() CYG_MACRO_START \
+ MII_READ_MODE(); /* to turn off driving the line */ \
+ (void)(MII_READ_BITS( 2 )); /* discard TA "bits" */ \
+CYG_MACRO_END
+
+#define MII_IDLE() CYG_MACRO_START \
+ MII_READ_MODE(); /* to turn off driving the line */ \
+ ((void)MII_READ_BITS( 5 )); /* extra clocks in Hi-Z mode */ \
+ MII_CLOCK_DOWN(); \
+CYG_MACRO_END
+
+#define MII_READ_REGVAL() MII_READ_BITS( 16 )
+#define MII_WRITE_REGVAL( _v_ ) MII_WRITE_BITS( (_v_), 16 )
+
+static int mii_read_register( int ioaddr, int regnum )
+{
+ int value;
+ MII_WRITE_PREAMBLE();
+ MII_WRITE_START();
+ MII_WRITE_READ_CMD();
+ MII_WRITE_PHY_ADDR();
+ MII_WRITE_REGNUM( regnum );
+ MII_READ_TURNAROUND();
+ value = MII_READ_REGVAL();
+ MII_IDLE();
+ return value;
+}
+
+static void mii_write_register( int ioaddr, int regnum, int value )
+{
+ MII_WRITE_PREAMBLE();
+ MII_WRITE_START();
+ MII_WRITE_WRITE_CMD();
+ MII_WRITE_PHY_ADDR();
+ MII_WRITE_REGNUM( regnum );
+ MII_WRITE_TURNAROUND();
+ MII_WRITE_REGVAL( value );
+ MII_IDLE();
+}
+
+// ------------------------------------------------------------------------
+//
+// Serial EEPROM access - much like the other Intel ethernet
+//
+
+// CYGACC_CALL_IF_DELAY_US() drags in huge amounts of scheduler locking and
+// the like 'cos it's a VV call! Waste of time, mostly.
+
+#define EE_DELAY() do { int z; for ( z = 0; z < 0x1000; z++ ) ; } while (0)
+
+#if 0
+# define EE_PRINTF diag_printf
+# define EE_STUFF "%4s | %4s | %4s | %4s [%08x]\n", \
+ (l & (1<<2)) ? "eeDI" : "---", \
+ (l & (1<<0)) ? "eeCS" : "--", \
+ (l & (1<<3)) ? "eeDO" : "---", \
+ (l & (1<<1)) ? "CLK" : "clk", \
+ l & 0xfffff
+#else
+# define EE_PRINTF( foo )
+# define EE_STUFF
+#endif
+
+
+static inline void ee_select( int ioaddr )
+{
+ cyg_uint32 l;
+ l = CSR_ROM_MII_MGT_SR | CSR_ROM_MII_MGT_RD
+ | CSR_ROM_MII_MGT_MOM_READ; // Keep MII in read mode
+ OUTL( l, CSR_ROM_MII_MGT );
+ EE_DELAY();
+ l |= CSR_ROM_MII_MGT_SR_CS;
+ OUTL( l, CSR_ROM_MII_MGT );
+ EE_PRINTF( "ee_select : " EE_STUFF );
+ EE_DELAY();
+}
+
+static inline void ee_deselect( int ioaddr )
+{
+ cyg_uint32 l;
+ l = CSR_ROM_MII_MGT_SR | CSR_ROM_MII_MGT_RD
+ | CSR_ROM_MII_MGT_MOM_READ; // Keep MII in read mode
+ OUTL( l, CSR_ROM_MII_MGT );
+ EE_PRINTF( "ee_deselect 1: " EE_STUFF );
+ EE_DELAY();
+ EE_DELAY();
+ EE_DELAY();
+ l = 0
+ | CSR_ROM_MII_MGT_MOM_READ; // Keep MII in read mode
+ OUTL( l, CSR_ROM_MII_MGT );
+ EE_PRINTF( "ee_deselect 2: " EE_STUFF );
+ EE_DELAY();
+ EE_DELAY();
+ EE_DELAY();
+}
+
+static inline void ee_clock_up( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( CSR_ROM_MII_MGT );
+ l |= CSR_ROM_MII_MGT_SR_CK;
+ OUTL( l, CSR_ROM_MII_MGT );
+ EE_PRINTF( "ee_clock_up : " EE_STUFF );
+ EE_DELAY();
+}
+
+static inline void ee_clock_down( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( CSR_ROM_MII_MGT );
+ l &=~ CSR_ROM_MII_MGT_SR_CK;
+ OUTL( l, CSR_ROM_MII_MGT );
+ EE_PRINTF( "ee_clock_down: " EE_STUFF );
+ EE_DELAY();
+}
+
+static inline int ee_read_data_bit( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( CSR_ROM_MII_MGT );
+ EE_PRINTF( "ee_read_data : " EE_STUFF );
+ return CSR_ROM_MII_MGT_SR_DO == (CSR_ROM_MII_MGT_SR_DO & l);
+}
+
+static inline void ee_write_data_bit( int ioaddr, int databit )
+{
+ cyg_uint32 l;
+ l = INL( CSR_ROM_MII_MGT );
+ if ( databit )
+ l |= CSR_ROM_MII_MGT_SR_DI;
+ else
+ l &=~ CSR_ROM_MII_MGT_SR_DI;
+ OUTL( l, CSR_ROM_MII_MGT );
+ EE_PRINTF( "ee_write_data: " EE_STUFF );
+ EE_DELAY();
+}
+
+// Pass ioaddr around "invisibly"
+#define EE_SELECT() ee_select(ioaddr)
+#define EE_DESELECT() ee_deselect(ioaddr)
+#define EE_CLOCK_UP() ee_clock_up(ioaddr)
+#define EE_CLOCK_DOWN() ee_clock_down(ioaddr)
+#define EE_READ_DATA_BIT() ee_read_data_bit(ioaddr)
+#define EE_WRITE_DATA_BIT( _d_ ) ee_write_data_bit(ioaddr,(_d_))
+
+// ------------------------------------------------------------------------
+
+static int
+get_eeprom_size( int ioaddr )
+{
+ int i, addrbits, tmp;
+
+ // Should already be not-selected, but anyway:
+ EE_SELECT();
+
+ // Shift the read command bits out.
+ for (i = 3; i >= 0; i--) { // Doc says to shift out a zero then:
+ tmp = (6 & (1 << i)) ? 1 : 0; // "6" is the "read" command.
+ EE_WRITE_DATA_BIT(tmp);
+ EE_CLOCK_UP();
+ EE_CLOCK_DOWN();
+ }
+ // Now clock out address zero, looking for the dummy 0 data bit
+ for ( i = 1; i <= 12; i++ ) {
+ EE_WRITE_DATA_BIT(0);
+ EE_CLOCK_UP();
+ tmp = EE_READ_DATA_BIT();
+ EE_CLOCK_DOWN();
+ if ( !tmp )
+ break;
+ }
+
+#ifdef DEBUG_EE
+ diag_printf( "eeprom data bits %d\n", i );
+#endif
+
+ if ( 6 != i && 8 != i && 1 != i) {
+#ifdef DEBUG_EE
+ diag_printf( "*****EEPROM data bits not 6, 8 or 1*****\n" );
+#endif
+ addrbits = 1; // Flag no eeprom here.
+ }
+ else
+ addrbits = i;
+
+ // read in the data regardless
+ tmp = 0;
+ for (i = 15; i >= 0; i--) {
+ EE_CLOCK_UP();
+ if ( EE_READ_DATA_BIT() )
+ tmp |= (1<<i);
+ EE_CLOCK_DOWN();
+ }
+
+#ifdef DEBUG_EE
+ diag_printf( "eeprom first data word %x\n", tmp );
+#endif
+
+ // Terminate the EEPROM access.
+ EE_DESELECT();
+
+ return addrbits;
+}
+
+static int
+read_eeprom_word( int ioaddr, int addrbits, int address )
+{
+ int i, tmp;
+
+ // Should already be not-selected, but anyway:
+ EE_SELECT();
+
+ // Shift the read command bits out.
+ for (i = 3; i >= 0; i--) { // Doc says to shift out a zero then:
+ tmp = (6 & (1 << i)) ? 1 : 0; // "6" is the "read" command.
+ EE_WRITE_DATA_BIT(tmp);
+ EE_CLOCK_UP();
+ EE_CLOCK_DOWN();
+ }
+ // Now clock out address
+ for ( i = addrbits - 1; i >= 0 ; i-- ) {
+ tmp = (address & (1<<i)) ? 1 : 0;
+ EE_WRITE_DATA_BIT(tmp);
+ EE_CLOCK_UP();
+ tmp = EE_READ_DATA_BIT();
+ EE_CLOCK_DOWN();
+
+ CYG_ASSERT( (0 == tmp) == (0 == i), "Looking for zero handshake bit" );
+ }
+
+ // read in the data
+ tmp = 0;
+ for (i = 15; i >= 0; i--) {
+ EE_CLOCK_UP();
+ if ( EE_READ_DATA_BIT() )
+ tmp |= (1<<i);
+ EE_CLOCK_DOWN();
+ }
+
+ // Terminate the EEPROM access.
+ EE_DESELECT();
+
+#ifdef DEBUG_EE
+ diag_printf( "eeprom address %4x: data %4x\n", address, tmp );
+#endif
+
+ return tmp;
+}
+
+// ------------------------------------------------------------------------
+
+// EOF if_i21143.c
+
diff --git a/ecos/packages/devs/eth/intel/i82544/current/ChangeLog b/ecos/packages/devs/eth/intel/i82544/current/ChangeLog
new file mode 100644
index 0000000..a922089
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i82544/current/ChangeLog
@@ -0,0 +1,107 @@
+2003-01-17 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/if_i82544.c: Fixed a few compiler warnings.
+
+2004-01-15 Kevin Lemay <kevin.lemay@agilent.com>
+
+ * src/if_i82544.c: Added support for the i82540 device.
+
+2003-05-16 Mark Salter <msalter@redhat.com>
+
+ * include/i82544_info.h: Add link flag.
+ * src/if_i82544.c: Allow booting when not using ASD and link is down.
+
+2003-03-19 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82544.c (i82544_setup): More 82546 EEPROM fixes (EE_PRES
+ appears to be unreliable).
+
+2003-03-17 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82544.c: Fix 82546 EEPROM access. Fix ESA address for second
+ port of 82546.
+
+2003-03-11 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82544.c (find_82544s_match_func): Add 82546 devid.
+
+2003-02-05 Nick Garnett <nickg@calivar.com>
+
+ * src/if_i82544.c (BUS_TO_VIRT): Added default definition of this
+ macro.
+
+2002-11-12 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_i82544.c: Minor fixes - use HAL_DELAY_US(), additional
+ PCI device type (0x100D) which is present on the NPWR Linux Engine.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_i82544.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-02-25 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82544.c: Don't call PacketRxReady in standalone configuration
+ unless ready to accept a packet. Limit packet delivery to one packet at
+ a time in standalone configuration.
+
+2002-02-22 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82544.c: Remove unnecessary eth_dsr declaration.
+
+2002-02-19 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82544.c (pci_init_find_82544s): Don't use IRQ support if
+ CYGPKG_IO_ETH_DRIVERS_STAND_ALONE.
+
+2002-01-22 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82544.c (i82544_send): Add HAL_DCACHE_STORE before passing
+ buffer to NIC.
+
+2002-01-21 Mark Salter <msalter@redhat.com>
+
+ * cdl/intel_i82544_eth_drivers.cdl: Add
+ CYGNUM_DEVS_ETH_INTEL_I82544_MAX_RX_DESCRIPTORS and
+ CYGNUM_DEVS_ETH_INTEL_I82544_MAX_TX_DESCRIPTORS.
+
+ * src/if_i82544.c: Add appropriate BUS_TO_VIRT and VIRT_TO_BUS
+ conversions.
+ Remove check that assumes driver owns entire PCI window.
+ (i82544_setup): Add option to use auto-speed detection.
+
+2001-11-27 Nick Garnett <nickg@redhat.com>
+
+ * cdl/intel_i82544_eth_drivers.cdl:
+ * include/i82544_info.h:
+ * src/if_i82544.c:
+ Created driver by copying i82559 driver and editing.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/intel/i82544/current/cdl/intel_i82544_eth_drivers.cdl b/ecos/packages/devs/eth/intel/i82544/current/cdl/intel_i82544_eth_drivers.cdl
new file mode 100644
index 0000000..514a963
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i82544/current/cdl/intel_i82544_eth_drivers.cdl
@@ -0,0 +1,182 @@
+# ====================================================================
+#
+# intel_i82544_eth_drivers.cdl
+#
+# Intel 82544 ethernet driver
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): nickg, from i82559 original
+# Original data: hmt
+# Contributors: hmt, gthomas, jskov
+# Date: 2001-10-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_INTEL_I82544 {
+ display "Intel 82544 ethernet driver"
+ description "Ethernet driver for Intel 82544 Gigabit controller."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ active_if CYGINT_DEVS_ETH_INTEL_I82544_REQUIRED
+
+ include_dir cyg/devs/eth
+
+ # SNMP demands to know stuff; this sadly makes us break the neat
+ # abstraction of the device having nothing exported.
+ include_files include/i82544_info.h
+ # and tell them that it is available
+ define_proc {
+ puts $::cdl_system_header \
+ "#define CYGBLD_DEVS_ETH_DEVICE_H <pkgconf/devs_eth_intel_i82544.h>"
+
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_INTEL_I82544_CFG";
+ }
+
+ compile -library=libextras.a if_i82544.c
+
+ cdl_option CYGDBG_DEVS_ETH_INTEL_I82544_CHATTER {
+ display "Prints ethernet device status info during startup"
+ default_value 0
+ description "
+ The ethernet device initialization code can print lots of info
+ to confirm that it has found the devices on the PCI bus, read
+ the MAC address from EEPROM correctly, and so on, and also
+ displays the mode (10/100MHz, half/full duplex) of the
+ connection."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT {
+ display "Number of supported interfaces."
+ calculated { CYGINT_DEVS_ETH_INTEL_I82544_REQUIRED }
+ flavor data
+ description "
+ This option selects the number of PCI ethernet interfaces to
+ be supported by the driver."
+ }
+
+ cdl_component CYGDBG_DEVS_ETH_INTEL_I82544_KEEP_STATISTICS {
+ display "Keep Ethernet statistics"
+ default_value 0
+ description "
+ The ethernet device can maintain statistics about the network,
+ specifically a great variety of error rates which are useful
+ for network management. SNMP for example uses this
+ information. There is some performance cost in maintaining
+ this information; disable this option to recoup that."
+
+ cdl_option CYGDBG_DEVS_ETH_INTEL_I82544_KEEP_82544_STATISTICS {
+ display "Keep i82544 Internal statistics"
+ default_value 1
+ description "
+ The i82544 keeps internal counters, and it is possible to
+ acquire these. But the i82544 (reputedly) does not service
+ the network whilst uploading the data to RAM from its
+ internal registers. If throughput is a problem, disable
+ this option to acquire only those statistics gathered by
+ software, so that the i82544 never sleeps."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_INTEL_I82544_WRITE_EEPROM {
+ display "SIOCSIFHWADDR records MAC address in EEPROM"
+ default_value 0
+ description "
+ The ioctl() socket call with operand SIOCSIFHWADDR sets the
+ interface hardware address - the MAC address or ethernet
+ address. This option causes the new MAC address to be written
+ into the EEPROM associated with the interface, so that the new
+ MAC address is permanently recorded. Doing this should be a
+ carefully chosen decision, hence this option."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_INTEL_I82544_MAX_RX_DESCRIPTORS {
+ display "Maximum number of RX descriptors"
+ flavor data
+ default_value { CYGPKG_REDBOOT ? 8 : 128 }
+ define MAX_RX_DESCRIPTORS
+ description "
+ An RX descriptor is used for each ethernet frame required
+ to be passed to the upper networking layers. This option
+ sets the maximum number of these. Higher numbers use more
+ memory, lower numbers will reduce performance. The system
+ appears to work OK with as few as 8 descriptors but limps
+ painfully with only 4. Performance is better with more than
+ 8, but assuming the size of non-cached (so useless for anything
+ else) memory window is 1Mb, we might as well use it all.
+ 128 RX and TX descriptors uses the whole 1Mb, near enough."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_INTEL_I82544_MAX_TX_DESCRIPTORS {
+ display "Maximum number of TX descriptors"
+ flavor data
+ default_value { CYGPKG_REDBOOT ? 8 : 128 }
+ define MAX_TX_DESCRIPTORS
+ description "
+ A TX descriptor is used for each ethernet frame passed down
+ from upper networking layers for transmission. This option
+ sets the maximum number of these. Higher numbers use more
+ memory, lower numbers will reduce performance. The system
+ appears to work OK with as few as 8 descriptors but limps
+ painfully with only 4. Performance is better with more than
+ 8, but assuming the size of non-cached (so useless for anything
+ else) memory window is 1Mb, we might as well use it all.
+ 128 RX and TX descriptors uses the whole 1Mb, near enough."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_INTEL_I82544_OPTIONS {
+ display "Intel 82544 ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_INTEL_I82544_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Intel 82544 ethernet driver
+ package. These flags are used in addition to the set of
+ global flags."
+ }
+ }
+}
+# EOF intel_i82544_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/intel/i82544/current/include/i82544_info.h b/ecos/packages/devs/eth/intel/i82544/current/include/i82544_info.h
new file mode 100644
index 0000000..236b917
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i82544/current/include/i82544_info.h
@@ -0,0 +1,212 @@
+#ifndef CYGONCE_DEVS_ETH_INTEL_I82544_INFO_H
+#define CYGONCE_DEVS_ETH_INTEL_I82544_INFO_H
+/*==========================================================================
+//
+// i82544_info.h
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 2000-05-03
+// Description:
+//
+//####DESCRIPTIONEND####
+*/
+
+#include <pkgconf/devs_eth_intel_i82544.h>
+
+#ifdef CYGDBG_DEVS_ETH_INTEL_I82544_KEEP_STATISTICS
+# define KEEP_STATISTICS
+# define nDISPLAY_STATISTICS
+# define nDISPLAY_82544_STATISTICS
+#else
+# define nKEEP_STATISTICS
+# define nDISPLAY_STATISTICS
+# define nDISPLAY_82544_STATISTICS
+#endif
+
+
+// ------------------------------------------------------------------------
+//
+// STATISTICAL COUNTER STRUCTURE
+//
+// ------------------------------------------------------------------------
+#ifdef KEEP_STATISTICS
+typedef struct {
+/* 0 */ cyg_uint32 tx_good;
+/* 4 */ cyg_uint32 tx_max_collisions;
+/* 8 */ cyg_uint32 tx_late_collisions;
+/* 12 */ cyg_uint32 tx_underrun;
+/* 16 */ cyg_uint32 tx_carrier_loss;
+/* 20 */ cyg_uint32 tx_deferred;
+/* 24 */ cyg_uint32 tx_single_collisions;
+/* 28 */ cyg_uint32 tx_mult_collisions;
+/* 32 */ cyg_uint32 tx_total_collisions;
+/* 36 */ cyg_uint32 rx_good;
+/* 40 */ cyg_uint32 rx_crc_errors;
+/* 44 */ cyg_uint32 rx_align_errors;
+/* 48 */ cyg_uint32 rx_resource_errors;
+/* 52 */ cyg_uint32 rx_overrun_errors;
+/* 56 */ cyg_uint32 rx_collisions; // Always 0
+/* 60 */ cyg_uint32 rx_short_frames;
+// In this setup; can also be flow-control counts after.
+// If these are to be used, a config command (as in set promiscuous mode)
+// must be issued at start, to let those stats escape. Params are in
+// comments around the config command setup...
+/* 64 */ cyg_uint32 done;
+} I82544_COUNTERS;
+
+
+typedef struct {
+ cyg_uint32 interrupts;
+ cyg_uint32 rx_count;
+ cyg_uint32 rx_deliver;
+ cyg_uint32 rx_resource;
+ cyg_uint32 rx_restart;
+ cyg_uint32 tx_count;
+ cyg_uint32 tx_complete;
+ cyg_uint32 tx_dropped;
+} STATISTICS;
+
+
+extern STATISTICS statistics[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT];
+#ifdef CYGDBG_DEVS_ETH_INTEL_I82544_KEEP_82544_STATISTICS
+extern I82544_COUNTERS i82544_counters[CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT];
+#endif
+
+#endif // KEEP_STATISTICS
+
+// ------------------------------------------------------------------------
+//
+// DEVICES AND PACKET QUEUES
+//
+// ------------------------------------------------------------------------
+// The system seems to work OK with as few as 8 of RX and TX descriptors.
+// It limps very painfully with only 4.
+// Performance is better with more than 8.
+// But the size of non-cached (so useless for anything else)
+// memory window is 1Mb, so we might as well use it all.
+//
+// 128 for these uses the whole 1Mb, near enough.
+
+#ifndef MAX_RX_DESCRIPTORS
+#define MAX_RX_DESCRIPTORS 128 // number of Rx descriptors
+#endif
+#ifndef MAX_TX_DESCRIPTORS
+#define MAX_TX_DESCRIPTORS 128 // number of Tx descriptors
+#endif
+
+typedef struct i82544 {
+ cyg_uint8 // (split up for atomic byte access)
+ found:1, // was hardware discovered?
+ mac_addr_ok:1, // can we bring up?
+ active:1, // has this if been brung up?
+ hardwired_esa:1, // set if ESA is hardwired via CDL
+ link:1, // set if link is up
+ spare1:3;
+ cyg_uint8 // Count nested sends to reject
+ within_send:8; // nested requests to send
+ cyg_uint8
+ tx_in_progress:1, // transmit in progress flag
+ tx_queue_full:1, // all Tx descriptors used flag
+ spare3:6;
+
+ cyg_uint8 index; // 0 or 1 or whatever
+ cyg_uint32 devid; // PCI device id
+ cyg_uint32 device; // Device code from hardware
+ cyg_uint32 io_address; // memory mapped I/O address
+ cyg_uint8 mac_address[6]; // mac (hardware) address
+ void *ndp; // Network Device Pointer
+
+ cyg_int32 next_rx_descriptor; // descriptor index for callback
+ cyg_int32 rx_pointer; // descriptor index for ring head
+ CYG_ADDRESS rx_ring; // location of Rx descriptors
+
+ cyg_int32 tx_pointer; // next TXB to check for status.
+ CYG_ADDRESS tx_ring; // location of Tx descriptors
+ unsigned long tx_keys[MAX_TX_DESCRIPTORS]; // keys for tx q management
+
+ // Interrupt handling stuff
+ cyg_vector_t vector; // interrupt vector
+ cyg_handle_t interrupt_handle; // handle for int.handler
+ cyg_interrupt interrupt_object;
+
+#ifdef KEEP_STATISTICS
+ void *p_statistics; // pointer to statistical counters
+#endif
+
+ cyg_uint32 platform_timeout; // Some platforms use a timeout
+ int tx_descriptor_timeout; // Is it fixated on this tx?
+
+} I82544;
+
+
+// ------------------------------------------------------------------------
+//
+// 82544 GENERAL STATUS REGISTER
+//
+// ------------------------------------------------------------------------
+#define GEN_STATUS_FDX 0x01 // 1 = full duplex, 0 = half
+#define GEN_STATUS_BPS 0xC0 // 0 = 10M, 01 = 100M, 10&11 = 1000M
+#define GEN_STATUS_BPS_SHIFT 6
+#define GEN_STATUS_LINK 0x02 // 1 = link up, 0 = link down
+
+extern int i82544_status( struct eth_drv_sc *sc );
+
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+void update_statistics(struct i82544* p_i82544);
+#endif
+
+
+#ifdef CYGDBG_DEVS_ETH_INTEL_I82544_KEEP_82544_STATISTICS
+#define ETH_STATS_INIT( p ) \
+ update_statistics( (struct i82544 *)((p)->driver_private) )
+#else
+#define ETH_STATS_INIT( p ) // otherwise do nothing
+#endif
+
+#define CYGDAT_DEVS_ETH_DESCRIPTION "Intel Gigabit Ethernet Controller (i82544)"
+
+#define ETH_DEV_DOT3STATSETHERCHIPSET 1,3,6,1,2,1,10,7,8,2,5
+
+#endif /* ifndef CYGONCE_DEVS_ETH_INTEL_I82544_INFO_H */
+
+/* EOF i82544_info.h */
+
diff --git a/ecos/packages/devs/eth/intel/i82544/current/src/if_i82544.c b/ecos/packages/devs/eth/intel/i82544/current/src/if_i82544.c
new file mode 100644
index 0000000..d2f2b34
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i82544/current/src/if_i82544.c
@@ -0,0 +1,2916 @@
+//==========================================================================
+//
+// if_i82544.c
+//
+// Intel 82544 ethernet driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt, gthomas
+// Contributors: Ron Spence, Pacific Softworks, jskov
+// Date: 2000-02-01
+// Purpose:
+// Description: hardware driver for 82544 Intel PRO/100+ ethernet
+// Notes: CU commands such as dump and config should, according
+// to the docs, set the CU active state while executing.
+// That does not seem to be the case though, and the
+// driver polls the completion bit in the packet status
+// word instead.
+//
+// Platform code may provide this vector:
+// CYGNUM_DEVS_ETH_INTEL_I82544_SEPARATE_MUX_INTERRUPT if it
+// requires the interrupts to be handled via demuxers
+// attached to a distinct interrupt.
+//
+// Platform code may alternatively define:
+// CYGHWR_DEVS_ETH_INTEL_I82544_DEMUX_ALL if it is necessary
+// to demux all interrupt sources - for example if they are
+// wire-or'd together on some hardware but distinct on
+// others. In this circumstance it is permitted for
+// cyg_pci_translate_interrupt [HAL_PCI_TRANSLATE_INTERRUPT]
+// to return invalid for 2nd and subsequent devices.
+//
+// Platform code can also define these three:
+// CYGPRI_DEVS_ETH_INTEL_I82544_MASK_INTERRUPTS(p_i82544,old)
+// CYGPRI_DEVS_ETH_INTEL_I82544_UNMASK_INTERRUPTS(p_i82544,old)
+// CYGPRI_DEVS_ETH_INTEL_I82544_ACK_INTERRUPTS(p_i82544)
+// which are particularly useful when nested interrupt
+// management is needed (which is always IMHO).
+//
+// Platform code can define this:
+// CYGHWR_DEVS_ETH_INTEL_I82544_MISSED_INTERRUPT(p_i82544)
+// to detect a dropped interrupt and loop again or
+// direct-call the DSR to reschedule the delivery routine.
+// Only a problem on edge-triggered interrupt systems.
+//
+// Platform code can also provide this macro:
+// CYGPRI_DEVS_ETH_INTEL_I82544_INTERRUPT_ACK_LOOP(p_i82544)
+// to handle delaying for acks to register on the interrupt
+// controller as necessary on the EBSA.
+//
+// Platform can define CYGHWR_DEVS_ETH_INTEL_I82544_GET_ESA()
+// as an external means to get ESAs, possibly from RedBoot
+// configuration info that's stored in flash memory.
+//
+// Platform def CYGHWR_DEVS_ETH_INTEL_I82544_HAS_NO_EEPROM
+// removes all code for dealing with the EEPROM for those
+// targets where there is none fitted. Either an external
+// means to get ESAs should be used, or we must rely on
+// hard-wiring the ESA's into each executable by means of the
+// usual CDL configuration.
+//
+// Platform def CYGHWR_DEVS_ETH_INTEL_I82544_HAS_ONE_EEPROM
+// is for hardware with multiple devices, but only one with a
+// serial EEPROM installed. The 2nd device would get either
+// the same ESA - because they are certain to be on different
+// segment and internets - or the same ESA incremented by
+// CYGHWR_DEVS_ETH_INTEL_I82544_HAS_ONE_EEPROM_MAC_ADJUST.
+// CYGHWR_DEVS_ETH_INTEL_I82544_HAS_ONE_EEPROM should be the
+// number (0 or 1) of the device that does have the EEPROM.
+//
+// CYGHWR_DEVS_ETH_INTEL_I82544_PCIMEM_DISCONTIGUOUS enables
+// checking code for breaks in the physical address of PCI
+// window memory. This can happen on some boards where a
+// smaller SDRAM is fitted than the hardware allows, so some
+// higher-order address bits are ignored. We make SDRAM
+// contiguous in mapped memory, but what the i82544 sees
+// might be discontiguous. The checking code skips any
+// allocated chunk who appears to contain such a break, and
+// tries again.
+//
+// CYGHWR_DEVS_ETH_INTEL_I82544_RESET_TIMEOUT( int32 )
+// CYGHWR_DEVS_ETH_INTEL_I82544_TIMEOUT_FIRED( int32 ) if
+// both defined give the driver a means to detect that we
+// have been fixated on the same transmit operation for too
+// long - we missed an interrupt or the device crashed. The
+// int32 argument is used to hold a eg. the value of a
+// fast-running hardware timer.
+//
+// Platform def CYGHWR_DEVS_ETH_INTEL_I82544_USE_ASD is
+// used to select Auto Speed Detection for setting up the
+// link parameters.
+//
+// FIXME: replace -1/-2 return values with proper E-defines
+// FIXME: For 82557/8 compatibility i82544_configure() function
+// probably needs some tweaking - config bits differ
+// slightly but crucially.
+// FIXME: EEPROM code not tested on a BE system.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#ifdef CYGPKG_IO_ETH_DRIVERS
+#include <pkgconf/io_eth_drivers.h>
+#endif
+#include <pkgconf/devs_eth_intel_i82544.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <net/if.h> /* Needed for struct ifnet */
+#endif
+
+#ifdef CYGPKG_IO_PCI
+#include <cyg/io/pci.h>
+// So we can check the validity of the PCI window against the MLTs opinion,
+// and thereby what the malloc heap consumes willy-nilly:
+#include CYGHWR_MEMORY_LAYOUT_H
+#else
+#error "Need PCI package here"
+#endif
+
+#include <cyg/devs/eth/i82544_info.h>
+
+#include CYGDAT_DEVS_ETH_INTEL_I82544_INL
+
+// ------------------------------------------------------------------------
+
+#ifdef CYGDBG_DEVS_ETH_INTEL_I82544_CHATTER
+#define DEBUG_82544 // This one prints stuff as packets come and go
+#define DEBUG // Startup printing mainly
+#define noDEBUG_EE // Some EEPROM specific retries &c
+#endif
+
+#ifdef CYGDBG_USE_ASSERTS
+static struct {
+ int can_send;
+ int deliver;
+ int stats;
+ int waitcmd_timeouts;
+ int waitcmd_timeouts_cu;
+ int lockup_timeouts;
+ int bad_cu_idles;
+} missed_interrupt = { 0,0,0, 0,0, 0, 0 };
+#endif
+
+#ifndef CYGPKG_REDBOOT
+
+#define os_printf diag_printf
+#define db_printf diag_printf
+
+#else
+
+static void os_printf( char *fmt, ... )
+{
+ extern int start_console(void);
+ extern void end_console(int);
+ va_list a;
+ int old_console;
+ va_start( a, fmt );
+ old_console = start_console();
+ diag_vprintf( fmt, a );
+ end_console(old_console);
+ va_end( a );
+}
+
+#define db_printf os_printf
+
+#endif
+
+// ------------------------------------------------------------------------
+//
+// MEMORY ADDRESSING
+//
+// ------------------------------------------------------------------------
+// Macros for writing shared memory structures - no need for byte flipping
+
+#define READMEM8( _reg_, _val_ ) ((CYG_BYTE)(_val_) = *((volatile CYG_BYTE *)(_reg_)))
+#define WRITEMEM8( _reg_, _val_ ) (*((volatile CYG_BYTE *)(_reg_)) = (CYG_BYTE)(_val_))
+#define READMEM16( _reg_, _val_ ) ((CYG_WORD16)(_val_) = *((volatile CYG_WORD16 *)(_reg_)))
+#define WRITEMEM16( _reg_, _val_ ) (*((volatile CYG_WORD16 *)(_reg_)) = (CYG_WORD16)(_val_))
+#define READMEM32( _reg_, _val_ ) ((CYG_WORD32)(_val_) = *((volatile CYG_WORD32 *)(_reg_)))
+#define WRITEMEM32( _reg_, _val_ ) (*((volatile CYG_WORD32 *)(_reg_)) = (CYG_WORD32)(_val_))
+#define READMEM64( _reg_, _val_ ) ((CYG_WORD64)(_val_) = *((volatile CYG_WORD64 *)(_reg_)))
+#define WRITEMEM64( _reg_, _val_ ) (*((volatile CYG_WORD64 *)(_reg_)) = (CYG_WORD64)(_val_))
+
+#define OUTL( _v_, _a_ ) WRITEMEM32( _a_, _v_ )
+
+static inline cyg_uint32 INL(cyg_uint32 io_address)
+ { cyg_uint32 _t_; READMEM32( io_address, _t_ ); return _t_; }
+
+
+// ------------------------------------------------------------------------
+// Map from CPU-view addresses to PCI-bus master's view - however that is:
+
+#ifdef CYGHWR_INTEL_I82544_PCI_VIRT_TO_BUS
+
+#define VIRT_TO_BUS( _x_ ) CYGHWR_INTEL_I82544_PCI_VIRT_TO_BUS( _x_ )
+#define BUS_TO_VIRT( _x_ ) CYGHWR_INTEL_I82544_PCI_BUS_TO_VIRT( _x_ )
+
+#else // use default mappings: get a physical address to give to the device
+
+#define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_))
+static inline cyg_uint32 virt_to_bus(cyg_uint32 p_memory)
+{ return CYGARC_PHYSICAL_ADDRESS(p_memory); }
+
+#define BUS_TO_VIRT( _x_ ) bus_to_virt((cyg_uint32)(_x_))
+static inline cyg_uint32 bus_to_virt(cyg_uint32 p_bus)
+{ return CYGARC_UNCACHED_ADDRESS(p_bus); }
+
+#endif // not defined CYGHWR_INTEL_I82544_PCI_VIRT_TO_BUS
+
+// ------------------------------------------------------------------------
+//
+// 82544 REGISTER OFFSETS
+//
+// ------------------------------------------------------------------------
+
+// General registers
+#define I82544_CTRL 0x00000
+#define I82544_STATUS 0x00008
+#define I82544_EECD 0x00010
+#define I82544_CTRL_EXT 0x00018
+#define I82544_MDIC 0x00020
+#define I82544_FCAL 0x00028
+#define I82544_FCAH 0x0002c
+#define I82544_FCT 0x00030
+#define I82544_VET 0x00038
+#define I82544_FCTTV 0x00170
+#define I82544_TXCW 0x00178
+#define I82544_RXCW 0x00180
+#define I82544_PBA 0x01000
+
+// Interrupt control registers
+#define I82544_ICR 0x000c0
+#define I82544_ICS 0x000c8
+#define I82544_IMS 0x000d0
+#define I82544_IMC 0x000d8
+
+// Receive registers
+#define I82544_RCTL 0x00100
+#define I82544_FCRTL 0x02160
+#define I82544_FCRTH 0x02168
+#define I82544_RDBAL 0x02800
+#define I82544_RDBAH 0x02804
+#define I82544_RDLEN 0x02808
+#define I82544_RDH 0x02810
+#define I82544_RDT 0x02818
+#define I82544_RDTR 0x02820
+#define I82544_RXDCTL 0x02828
+#define I82544_RXCSUM 0x05000
+#define I82544_MTA 0x05200
+#define I82544_RAT 0x05400
+#define I82544_VFTA 0x05600
+
+#define I82544_RCTL_EN (1<<1)
+#define I82544_RCTL_BAM (1<<15)
+
+// Transmit registers
+#define I82544_TCTL 0x00400
+#define I82544_TIPG 0x00410
+#define I82544_TBT 0x00448
+#define I82544_AIT 0x00458
+#define I82544_TXDMAC 0x03000
+#define I82544_TDBAL 0x03800
+#define I82544_TDBAH 0x03804
+#define I82544_TDLEN 0x03808
+#define I82544_TDH 0x03810
+#define I82544_TDT 0x03818
+#define I82544_TIDV 0x03820
+#define I82544_TXDCTL 0x03828
+#define I82544_TSPMT 0x03830
+
+
+#define I82544_TCTL_EN (1<<1)
+#define I82544_TCTL_PSP (1<<3)
+
+
+// ------------------------------------------------------------------------
+//
+// 82544 DEVICE CONTROL WORD DEFNITIONS
+//
+// ------------------------------------------------------------------------
+
+#define I82544_CTRL_FD (1<<0)
+#define I82544_CTRL_BEM (1<<1)
+#define I82544_CTRL_LRST (1<<3)
+#define I82544_CTRL_ASDE (1<<5)
+#define I82544_CTRL_SLU (1<<6)
+#define I82544_CTRL_ILOS (1<<7)
+#define I82544_CTRL_SPEED (3<<8)
+#define I82544_CTRL_FRCSPD (1<<11)
+#define I82544_CTRL_FRCDPLX (1<<12)
+#define I82544_CTRL_SWDPINSLO (15<<18)
+#define I82544_CTRL_SWDPINSIO (15<<22)
+#define I82544_CTRL_RST (1<<26)
+#define I82544_CTRL_RFCE (1<<27)
+#define I82544_CTRL_TFCE (1<<28)
+#define I82544_CTRL_VME (1<<30)
+#define I82544_CTRL_PHY_RST (1<<31)
+
+#define I82544_CTRL_PHY_RESET (1<<18)
+#define I82544_CTRL_PHY_RESET_DIR (1<<22)
+#define I82544_CTRL_MDIO (1<<20)
+#define I82544_CTRL_MDIO_DIR (1<<24)
+#define I82544_CTRL_MDC (1<<21)
+#define I82544_CTRL_MDC_DIR (1<<25)
+
+#define I82544_CTRL_EXT_PHY_RESET4 (1<<4)
+#define I82544_CTRL_EXT_PHY_RESET_DIR4 (1<<8)
+
+#define PHY_ADDRESS 1
+
+// ------------------------------------------------------------------------
+//
+// 82544 DEVICE STATUS WORD DEFNITIONS
+//
+// ------------------------------------------------------------------------
+
+#define I82544_STATUS_FD 0x0001
+#define I82544_STATUS_LU 0x0002
+#define I82544_STATUS_TXOFF 0x0010
+#define I82544_STATUS_TBIMODE 0x0020
+#define I82544_STATUS_SPEED 0x00C0
+#define I82544_STATUS_ASDV 0x0300
+#define I82544_STATUS_PCI_SPD 0x0800
+#define I82544_STATUS_BUS64 0x1000
+#define I82544_STATUS_PCIX_MODE 0x2000
+#define I82544_STATUS_PCIXSPD 0xC000
+
+// ------------------------------------------------------------------------
+//
+// 82544 EEPROM INTERFACE
+//
+// ------------------------------------------------------------------------
+
+// EEPROM_Ctrl bits.
+#define EE_SHIFT_CLK 0x01 // EEPROM shift clock.
+#define EE_CS 0x02 // EEPROM chip select.
+#define EE_DATA_WRITE 0x04 // EEPROM chip data in.
+#define EE_DATA_READ 0x08 // EEPROM chip data out.
+#define EE_REQ 0x40 // EEPROM request (82546 only)
+#define EE_GNT 0x80 // EEPROM grant (82546 only)
+#define EE_PRES 0x100 // EEPROM present (82546 only)
+#define EE_SIZE 0x200 // EEPROM size (82546 only)
+#define EE_ENB (0x10|EE_CS)
+
+
+// ------------------------------------------------------------------------
+//
+// RECEIVE DESCRIPTORS
+//
+// ------------------------------------------------------------------------
+
+#define I82544_RD_BUFFER 0
+#define I82544_RD_LENGTH 8
+#define I82544_RD_CSUM 10
+#define I82544_RD_STATUS 12
+#define I82544_RD_ERRORS 13
+#define I82544_RD_SPECIAL 14
+#define I82544_RD_SIZE 16
+
+#define I82544_RD_STATUS_DD (1<<0)
+#define I82544_RD_STATUS_EOP (1<<1)
+#define I82544_RD_STATUS_IXSM (1<<2)
+#define I82544_RD_STATUS_VP (1<<3)
+#define I82544_RD_STATUS_TCPCS (1<<5)
+#define I82544_RD_STATUS_IPCS (1<<6)
+#define I82544_RD_STATUS_PIF (1<<7)
+
+// ------------------------------------------------------------------------
+//
+// TRANSMIT DESCRIPTORS
+//
+// ------------------------------------------------------------------------
+
+// Currently we only use the legacy Tx descriptor
+
+#define I82544_TD_BUFFER 0
+#define I82544_TD_LENGTH 8
+#define I82544_TD_CSO 10
+#define I82544_TD_CMD 11
+#define I82544_TD_STATUS 12
+#define I82544_TD_CSS 13
+#define I82544_TD_SPECIAL 14
+#define I82544_TD_SIZE 16
+
+#define I82544_TD_CMD_EOP (1<<0)
+#define I82544_TD_CMD_IFCS (1<<1)
+#define I82544_TD_CMD_IC (1<<2)
+#define I82544_TD_CMD_RS (1<<3)
+#define I82544_TD_CMD_RPS (1<<4)
+#define I82544_TD_CMD_DEXT (1<<5)
+#define I82544_TD_CMD_VLE (1<<6)
+#define I82544_TD_CMD_IDE (1<<7)
+
+#define I82544_TD_STATUS_DD (1<<0)
+#define I82544_TD_STATUS_EC (1<<1)
+#define I82544_TD_STATUS_LC (1<<2)
+#define I82544_TD_STATUS_TU (1<<3)
+
+// ------------------------------------------------------------------------
+//
+// DEVICES AND PACKET QUEUES
+//
+// ------------------------------------------------------------------------
+
+#define MAX_RX_PACKET_SIZE 1536 // maximum Rx packet size
+#define MAX_TX_PACKET_SIZE 1536 // maximum Tx packet size
+
+
+// ------------------------------------------------------------------------
+// Use arrays provided by platform header to verify pointers.
+
+#ifdef CYGDBG_USE_ASSERTS
+#define CHECK_NDP_SC_LINK() \
+ CYG_MACRO_START \
+ int i, valid_netdev = 0, valid_sc = 0; \
+ for(i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT; i++) { \
+ if (i82544_netdev_array[i] == ndp) valid_netdev = 1; \
+ if (i82544_sc_array[i] == sc) valid_sc = 1; \
+ if (valid_sc || valid_netdev) break; \
+ } \
+ CYG_ASSERT( valid_netdev, "Bad ndp" ); \
+ CYG_ASSERT( valid_sc, "Bad sc" ); \
+ CYG_ASSERT( (void *)p_i82544 == i82544_sc_array[i]->driver_private, \
+ "sc pointer bad" ); \
+ CYG_MACRO_END
+#else
+#define CHECK_NDP_SC_LINK()
+#endif
+
+#define IF_BAD_82544( _p_ ) \
+if (({ \
+ int i, valid_p = 0; \
+ for(i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT; i++) { \
+ if (i82544_priv_array[i] == (_p_)) { \
+ valid_p = 1; \
+ break; \
+ } \
+ } \
+ CYG_ASSERT(valid_p, "Bad pointer-to-i82544"); \
+ (!valid_p); \
+}))
+
+// ------------------------------------------------------------------------
+//
+// Managing the memory that is windowed onto the PCI bus
+//
+// ------------------------------------------------------------------------
+
+static cyg_uint32 i82544_heap_size;
+static cyg_uint8 *i82544_heap_base;
+static cyg_uint8 *i82544_heap_free;
+
+static void *mem_reserved_ioctl = (void*)0;
+// uncacheable memory reserved for ioctl calls
+
+// ------------------------------------------------------------------------
+//
+// FUNCTION PROTOTYPES
+//
+// ------------------------------------------------------------------------
+
+static int pci_init_find_82544s(void);
+
+static void i82544_reset(struct i82544* p_i82544);
+static void i82544_setup(struct i82544* p_i82544);
+static int eth_set_mac_address(struct i82544* p_i82544, cyg_uint8 *addr, int eeprom );
+
+static void InitRxRing(struct i82544* p_i82544);
+static void InitTxRing(struct i82544* p_i82544);
+
+static cyg_uint32
+eth_isr(cyg_vector_t vector, cyg_addrword_t data);
+
+static int i82544_configure(struct i82544* p_i82544, int promisc, int oversized);
+
+// debugging/logging only:
+//void dump_txcb(TxCB* p_txcb);
+void DisplayStatistics(void);
+void update_statistics(struct i82544* p_i82544);
+//void dump_rfd(RFD* p_rfd, int anyway );
+void dump_all_rfds( int intf );
+void dump_packet(cyg_uint8 *p_buffer, int length);
+
+static void i82544_stop( struct eth_drv_sc *sc );
+
+// ------------------------------------------------------------------------
+
+static void
+udelay(int delay)
+{
+ CYGACC_CALL_IF_DELAY_US(delay);
+}
+
+// ------------------------------------------------------------------------
+// If we are demuxing for all interrupt sources, we must mask and unmask
+// *all* interrupt sources together.
+
+static inline int
+Mask82544Interrupt(struct i82544* p_i82544)
+{
+ cyg_drv_interrupt_mask(p_i82544->vector);
+
+ return 1;
+}
+
+static inline void
+UnMask82544Interrupt(struct i82544* p_i82544, int old)
+{
+ if (old & 1)
+ cyg_drv_interrupt_unmask(p_i82544->vector);
+}
+
+
+static inline void
+Acknowledge82544Interrupt(struct i82544* p_i82544)
+{
+ cyg_drv_interrupt_acknowledge(p_i82544->vector);
+}
+
+// ------------------------------------------------------------------------
+// Memory management
+//
+// Simply carve off from the front of the PCI mapped window into real memory
+
+static CYG_ADDRESS
+pciwindow_mem_alloc(int size)
+{
+ CYG_ADDRESS p_memory;
+ int _size = size;
+
+#ifdef DEBUG
+// db_printf("pciwindow_mem_alloc %d\n",size);
+#endif
+
+ CYG_ASSERT(
+ (CYGHWR_INTEL_I82544_PCI_MEM_MAP_BASE <= (int)i82544_heap_free)
+ &&
+ ((CYGHWR_INTEL_I82544_PCI_MEM_MAP_BASE +
+ CYGHWR_INTEL_I82544_PCI_MEM_MAP_SIZE) > (int)i82544_heap_free)
+ &&
+ (0 < i82544_heap_size)
+ &&
+ (CYGHWR_INTEL_I82544_PCI_MEM_MAP_SIZE >= i82544_heap_size)
+ &&
+ (CYGHWR_INTEL_I82544_PCI_MEM_MAP_BASE == (int)i82544_heap_base),
+ "Heap variables corrupted" );
+
+ p_memory = 0;
+ size = (size + 3) & ~3;
+ if ( (i82544_heap_free+size) < (i82544_heap_base+i82544_heap_size) ) {
+ cyg_uint32 *p;
+ p_memory = (CYG_ADDRESS)i82544_heap_free;
+ i82544_heap_free += size;
+ for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 )
+ *p++ = 0;
+ }
+
+ CYG_ASSERT(
+ NULL == p_memory ||
+ VIRT_TO_BUS( p_memory ) + size == VIRT_TO_BUS( i82544_heap_free ),
+ "Discontiguous PCI memory in real addresses" );
+
+ return p_memory;
+}
+
+
+// ------------------------------------------------------------------------
+//
+// MDIO
+//
+// Device-specific bit-twiddling and line driving side-effects
+
+// CYGACC_CALL_IF_DELAY_US() drags in huge amounts of scheduler locking and
+// the like 'cos it's a VV call! We only want a delay of 1uS tops, so:
+
+#define MII_DELAY() do { int z; for ( z = 0; z < 100; z++ ) ; } while (0)
+
+#if 0
+# define MII_PRINTF diag_printf
+# define MII_STUFF "%4s | %4s | %4s | %4s [%08x]\n", \
+ (*_ctrl & (1<<20)) ? "MDIO" : "---", \
+ (*_ctrl & (1<<24)) ? "Wr" : "Rd", \
+ (*_ctrl & (1<<21)) ? "CLK" : "clk", \
+ *_ctrl
+#else
+# define MII_PRINTF( foo )
+# define MII_STUFF
+#endif
+
+static inline cyg_uint32 mii_init( int ioaddr )
+{
+ cyg_uint32 ctrl;
+ cyg_uint32 *_ctrl = &ctrl;
+ *_ctrl = INL( ioaddr + I82544_CTRL );
+ *_ctrl &=~ I82544_CTRL_MDC;
+ *_ctrl |= I82544_CTRL_MDC_DIR;
+ *_ctrl &= ~I82544_CTRL_MDIO_DIR;
+ *_ctrl &= ~I82544_CTRL_MDIO;
+ OUTL( *_ctrl, ioaddr + I82544_CTRL );
+ MII_PRINTF( "mii_init : " MII_STUFF );
+ MII_DELAY();
+ return *_ctrl;
+}
+
+static inline void mii_clock_up( int ioaddr, cyg_uint32 *_ctrl )
+{
+ *_ctrl |= I82544_CTRL_MDC;
+ OUTL( *_ctrl, ioaddr + I82544_CTRL );
+ MII_PRINTF( "mii_clock_up : " MII_STUFF );
+ MII_DELAY();
+}
+
+static inline void mii_clock_down( int ioaddr, cyg_uint32 *_ctrl )
+{
+ *_ctrl &=~ I82544_CTRL_MDC;
+ OUTL( *_ctrl, ioaddr + I82544_CTRL );
+ MII_PRINTF( "mii_clock_down: " MII_STUFF );
+ MII_DELAY();
+}
+
+static inline void mii_read_mode( int ioaddr, cyg_uint32 *_ctrl )
+{
+ *_ctrl &= ~I82544_CTRL_MDIO_DIR;
+ *_ctrl &= ~I82544_CTRL_MDIO;
+ OUTL( *_ctrl, ioaddr + I82544_CTRL );
+ MII_PRINTF( "mii_read_mode : " MII_STUFF );
+ MII_DELAY();
+}
+
+static inline int mii_read_data_bit( int ioaddr, cyg_uint32 *_ctrl )
+{
+ *_ctrl = INL( ioaddr + I82544_CTRL );
+ MII_PRINTF( "mii_read_data : " MII_STUFF );
+ return I82544_CTRL_MDIO == (I82544_CTRL_MDIO & *_ctrl);
+}
+
+static inline void mii_write_data_bit( int ioaddr, int databit, cyg_uint32 *_ctrl )
+{
+ if ( databit )
+ *_ctrl |= I82544_CTRL_MDIO;
+ else
+ *_ctrl &= ~I82544_CTRL_MDIO;
+ *_ctrl |= I82544_CTRL_MDIO_DIR; // drive the mdio line
+ OUTL( *_ctrl, ioaddr + I82544_CTRL );
+ MII_PRINTF( "mii_write_data: " MII_STUFF );
+ MII_DELAY();
+}
+
+// Pass ioaddr around "invisibly"
+#define MII_INIT() cyg_uint32 _ctrl_val = mii_init(ioaddr); \
+ cyg_uint32 *_ctrl = &_ctrl_val;
+
+#define MII_CLOCK_UP() mii_clock_up(ioaddr, _ctrl)
+#define MII_CLOCK_DOWN() mii_clock_down(ioaddr, _ctrl)
+#define MII_READ_MODE() mii_read_mode(ioaddr, _ctrl)
+#define MII_READ_DATA_BIT() mii_read_data_bit(ioaddr, _ctrl)
+#define MII_WRITE_DATA_BIT( _d_ ) mii_write_data_bit(ioaddr,(_d_),_ctrl)
+
+// ------------------------------------------------------------------------
+//
+// MDIO
+//
+// Management data over the MII interface - nasty hand driven serial stuff
+//
+
+static void mii_write_bits( int ioaddr, int val, int bitcount, cyg_uint32 *_ctrl )
+{
+ int i;
+ // These are deliberately signed ints so that we can send an overlong
+ // preamble if we want by saying "send -1 of width 40 bits" and relying
+ // on sign extension.
+ for ( i = bitcount - 1; i >= 0; i-- ) {
+ MII_WRITE_DATA_BIT( (val >> i) & 1 );
+ MII_DELAY();
+ MII_CLOCK_UP();
+ MII_CLOCK_DOWN();
+ }
+}
+
+static int mii_read_bits( int ioaddr, int bitcount, cyg_uint32 *_ctrl )
+{
+ int i;
+ int val = 0;
+ for ( i = bitcount - 1; i >= 0; i-- ) {
+ MII_CLOCK_DOWN();
+ val <<= 1;
+ val |= MII_READ_DATA_BIT();
+ MII_CLOCK_UP();
+ }
+ return val;
+}
+
+#define MII_WRITE_BITS( val, bitcount ) mii_write_bits( ioaddr, val, bitcount, _ctrl )
+#define MII_READ_BITS( bitcount ) mii_read_bits( ioaddr, bitcount, _ctrl )
+
+// Now define subsections of the protocol in terms of the above
+
+#define MII_WRITE_PREAMBLE() MII_WRITE_BITS( -1, 32 ) // >32 x 1s
+#define MII_WRITE_START() MII_WRITE_BITS( 1, 2 ) // 01
+#define MII_WRITE_WRITE_CMD() MII_WRITE_BITS( 1, 2 ) // 01
+#define MII_WRITE_READ_CMD() MII_WRITE_BITS( 2, 2 ) // 10
+
+#define MII_WRITE_PHY_ADDR(_p_) MII_WRITE_BITS( _p_, 5 )
+#define MII_WRITE_REGNUM( _r_ ) MII_WRITE_BITS( (_r_), 5 )
+
+#define MII_WRITE_TURNAROUND() MII_WRITE_BITS( 2, 2 )
+
+#define MII_READ_TURNAROUND() CYG_MACRO_START \
+ MII_READ_MODE(); /* to turn off driving the line */ \
+ (void)(MII_READ_BITS( 2 )); /* discard TA "bits" */ \
+CYG_MACRO_END
+
+#define MII_IDLE() CYG_MACRO_START \
+ MII_READ_MODE(); /* to turn off driving the line */ \
+ ((void)MII_READ_BITS( 5 )); /* extra clocks in Hi-Z mode */ \
+ MII_CLOCK_DOWN(); \
+CYG_MACRO_END
+
+#define MII_READ_REGVAL() MII_READ_BITS( 16 )
+#define MII_WRITE_REGVAL( _v_ ) MII_WRITE_BITS( (_v_), 16 )
+
+static int mii_read_register( struct i82544 *p_i82544, int phy, int regnum )
+{
+ int value = 0;
+ cyg_uint32 ioaddr = p_i82544->io_address;
+
+ if( p_i82544->device == 0x1004 )
+ {
+ // An 82543, read MII register via software defined pins in
+ // CTRL register.
+
+ MII_INIT();
+ MII_WRITE_PREAMBLE();
+ MII_WRITE_START();
+ MII_WRITE_READ_CMD();
+ MII_WRITE_PHY_ADDR(phy);
+ MII_WRITE_REGNUM( regnum );
+ MII_READ_TURNAROUND();
+ value = MII_READ_REGVAL();
+ MII_IDLE();
+ }
+ else
+ {
+ // Others, read MII register via MDIC register.
+
+ cyg_uint32 mdic = (2<<26) | (phy<<21) | (regnum<<16);
+
+ OUTL( mdic, ioaddr + I82544_MDIC );
+
+ // Wait for ready
+ do
+ {
+ mdic = INL( ioaddr + I82544_MDIC );
+ } while( (mdic & (1<<28)) == 0 );
+
+ value = mdic & 0xFFFF;
+ }
+ return value;
+}
+
+#ifndef CYGHWR_DEVS_ETH_INTEL_I82544_USE_ASD
+static void mii_write_register( struct i82544 *p_i82544, int phy, int regnum, int value )
+{
+ cyg_uint32 ioaddr = p_i82544->io_address;
+
+ if( p_i82544->device == 0x1004 )
+ {
+ // An 82543, write MII register via software defined pins in
+ // CTRL register.
+
+ MII_INIT();
+ MII_WRITE_PREAMBLE();
+ MII_WRITE_START();
+ MII_WRITE_WRITE_CMD();
+ MII_WRITE_PHY_ADDR(phy);
+ MII_WRITE_REGNUM( regnum );
+ MII_WRITE_TURNAROUND();
+ MII_WRITE_REGVAL( value );
+ MII_IDLE();
+ }
+ else
+ {
+ // Others, write MII register via MDIC register.
+
+ cyg_uint32 mdic = (1<<26) | (phy<<21) | (regnum<<16) | (value&0xFFFF);
+
+ OUTL( mdic, ioaddr + I82544_MDIC );
+
+ // Wait for ready
+ do
+ {
+ mdic = INL( ioaddr + I82544_MDIC );
+ } while( (mdic & (1<<28)) == 0 );
+ }
+}
+#endif
+
+#ifdef DEBUG
+// dump out the PHY registers
+static void show_phy( struct i82544 *p_i82544, int phy )
+{
+ int i;
+
+ os_printf("PHY %d regs:",phy);
+ for( i = 0; i < 32; i++ )
+ {
+ cyg_uint32 mdic;
+
+ mdic = mii_read_register( p_i82544, phy, i );
+
+ if( (i%8)==0 ) os_printf("\n");
+
+ os_printf("%04x ",mdic);
+ }
+ os_printf("\n");
+}
+#endif
+
+// ------------------------------------------------------------------------
+//
+// GET EEPROM SIZE
+//
+// ------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------
+//
+// Serial EEPROM access - much like the other Intel ethernet
+//
+
+// CYGACC_CALL_IF_DELAY_US() drags in huge amounts of scheduler locking and
+// the like 'cos it's a VV call! Waste of time, mostly.
+
+#define EE_DELAY() do { int z; for ( z = 0; z < 10000; z++ ) ; } while (0)
+
+#if 0
+# define EE_PRINTF diag_printf
+# define EE_STUFF "%4s | %4s | %4s | %4s [%08x]\n", \
+ (l & EE_SHIFT_CLK) ? "CLK" : "clk", \
+ (l & EE_CS) ? "eeCS" : "--", \
+ (l & EE_DATA_WRITE) ? "eeDW" : "---", \
+ (l & EE_DATA_READ) ? "eeDR" : "---", \
+ l & 0xfffff
+#else
+# define EE_PRINTF( foo )
+# define EE_STUFF
+#endif
+
+
+static inline void ee_select( int ioaddr, struct i82544 *p_i82544 )
+{
+ cyg_uint32 l;
+ l = INL( ioaddr + I82544_EECD );
+ if (p_i82544->device == 0x1010 ||
+ p_i82544->device == 0x100e) {
+ // i82546 requires REQ/GNT before EEPROM access
+ l |= EE_REQ;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+ while ((l & EE_GNT) == 0)
+ l = INL( ioaddr + I82544_EECD );
+ }
+ l &= ~0x3f;
+ l |= EE_ENB;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+ l |= EE_CS;
+ OUTL( l, ioaddr + I82544_EECD );
+ l = INL( ioaddr + I82544_EECD );
+ EE_PRINTF( "ee_select : " EE_STUFF );
+ EE_DELAY();
+}
+
+static inline void ee_deselect( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( ioaddr + I82544_EECD ) & ~0x3f;
+ l |= EE_ENB;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_PRINTF( "ee_deselect 1 : " EE_STUFF );
+ EE_DELAY();
+ EE_DELAY();
+ EE_DELAY();
+ l &= ~EE_CS;
+ OUTL( l, ioaddr + I82544_EECD );
+ l = INL( ioaddr + I82544_EECD );
+ EE_PRINTF( "ee_deselect 2 : " EE_STUFF );
+ EE_DELAY();
+ EE_DELAY();
+ EE_DELAY();
+ if (l & EE_REQ) {
+ l &= ~EE_REQ;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+ }
+}
+
+static inline void ee_clock_up( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( ioaddr + I82544_EECD );
+ l |= EE_SHIFT_CLK;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+ l = INL( ioaddr + I82544_EECD );
+ EE_PRINTF( "ee_clock_up : " EE_STUFF );
+ EE_DELAY();
+}
+
+static inline void ee_clock_down( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( ioaddr + I82544_EECD );
+ l &=~ EE_SHIFT_CLK;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+ l = INL( ioaddr + I82544_EECD );
+ EE_PRINTF( "ee_clock_down : " EE_STUFF );
+ EE_DELAY();
+}
+
+static inline int ee_read_data_bit( int ioaddr )
+{
+ cyg_uint32 l;
+ l = INL( ioaddr + I82544_EECD );
+ EE_PRINTF( "ee_read_data : " EE_STUFF );
+ return EE_DATA_READ == (EE_DATA_READ & l);
+}
+
+static inline void ee_write_data_bit( int ioaddr, int databit )
+{
+ cyg_uint32 l;
+ l = INL( ioaddr + I82544_EECD );
+ if ( databit )
+ l |= EE_DATA_WRITE;
+ else
+ l &= ~EE_DATA_WRITE;
+ OUTL( l, ioaddr + I82544_EECD );
+ l = INL( ioaddr + I82544_EECD );
+ EE_PRINTF( "ee_write_data : " EE_STUFF );
+ EE_DELAY();
+}
+
+// Pass ioaddr around "invisibly"
+#define EE_SELECT() ee_select(ioaddr, p_i82544)
+#define EE_DESELECT() ee_deselect(ioaddr)
+#define EE_CLOCK_UP() ee_clock_up(ioaddr)
+#define EE_CLOCK_DOWN() ee_clock_down(ioaddr)
+#define EE_READ_DATA_BIT() ee_read_data_bit(ioaddr)
+#define EE_WRITE_DATA_BIT( _d_ ) ee_write_data_bit(ioaddr,(_d_))
+
+// ------------------------------------------------------------------------
+
+static int
+get_eeprom_size( struct i82544 *p_i82544 )
+{
+ cyg_uint32 l, ioaddr = p_i82544->io_address;
+ int i, tmp, addrbits;
+
+ l = INL( ioaddr + I82544_EECD );
+
+#ifdef DEBUG_EE
+ diag_printf( "get_eeprom_size\n" );
+#endif
+
+ if (p_i82544->device == 0x1010 ||
+ p_i82544->device == 0x100e) {
+
+ l |= EE_REQ;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+ while ((l & EE_GNT) == 0)
+ l = INL( ioaddr + I82544_EECD );
+ l &= ~0x3f;
+ l |= EE_ENB;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+ l |= EE_CS;
+ OUTL( l, ioaddr + I82544_EECD );
+ l = INL( ioaddr + I82544_EECD );
+ EE_DELAY();
+
+ for (i = 3; i >= 0; i--) { // Doc says to shift out a zero then:
+ tmp = (6 & (1 << i)) ? 1 : 0; // "6" is the "read" command.
+ EE_WRITE_DATA_BIT(tmp);
+ EE_CLOCK_UP();
+ EE_CLOCK_DOWN();
+ }
+ // Now clock out address zero, looking for the dummy 0 data bit
+ for ( i = 1; i <= 10; i++ ) {
+ EE_WRITE_DATA_BIT(0);
+ EE_CLOCK_UP();
+ EE_CLOCK_DOWN();
+ if (EE_READ_DATA_BIT() == 0)
+ break; // The dummy zero est arrive'
+ }
+
+ if (6 != i && 8 != i)
+ diag_printf("no EEPROM found\n");
+
+ addrbits = i;
+
+ tmp = 0;
+ for (i = 15; i >= 0; i--) {
+ EE_CLOCK_UP();
+ if (EE_READ_DATA_BIT())
+ tmp |= (1<<i);
+ EE_CLOCK_DOWN();
+ }
+
+ l = INL( ioaddr + I82544_EECD ) & ~0x3f;
+ l |= EE_ENB;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+ EE_DELAY();
+ EE_DELAY();
+ l &= ~EE_CS;
+ OUTL( l, ioaddr + I82544_EECD );
+ l = INL( ioaddr + I82544_EECD );
+ EE_DELAY();
+ EE_DELAY();
+ EE_DELAY();
+
+ l &= ~EE_REQ;
+ OUTL( l, ioaddr + I82544_EECD );
+ EE_DELAY();
+
+ return addrbits;
+ }
+
+ return 6;
+}
+
+static int
+read_eeprom_word( struct i82544 *p_i82544, int addrbits, int address )
+{
+ int i, tmp;
+ cyg_uint32 ioaddr = p_i82544->io_address;
+
+ // Should already be not-selected, but anyway:
+ EE_SELECT();
+
+ // Shift the read command bits out.
+ for (i = 3; i >= 0; i--) { // Doc says to shift out a zero then:
+ tmp = (6 & (1 << i)) ? 1 : 0; // "6" is the "read" command.
+ EE_WRITE_DATA_BIT(tmp);
+ EE_CLOCK_UP();
+ EE_CLOCK_DOWN();
+ }
+
+ // Now clock out address
+ for ( i = addrbits - 1; i >= 0 ; i-- ) {
+ tmp = (address & (1<<i)) ? 1 : 0;
+ EE_WRITE_DATA_BIT(tmp);
+ EE_CLOCK_UP();
+ tmp = EE_READ_DATA_BIT();
+ EE_CLOCK_DOWN();
+
+// CYG_ASSERT( (0 == tmp) == (0 == i), "Looking for zero handshake bit" );
+ }
+
+ // read in the data
+ tmp = 0;
+ for (i = 15; i >= 0; i--) {
+ EE_CLOCK_UP();
+ if ( EE_READ_DATA_BIT() )
+ tmp |= (1<<i);
+ EE_CLOCK_DOWN();
+ }
+
+ // Terminate the EEPROM access.
+ EE_DESELECT();
+
+#ifdef DEBUG_EE
+// diag_printf( "eeprom address %4x: data %4x\n", address, tmp );
+#endif
+
+ return tmp;
+}
+
+// ------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------
+//
+// NETWORK INTERFACE INITIALIZATION
+//
+// Function : Init82544
+//
+// Description :
+// This routine resets, configures, and initializes the chip.
+// It also clears the ethernet statistics structure, and selects
+// which statistics are supported by this driver.
+//
+// ------------------------------------------------------------------------
+
+static bool
+i82544_init(struct cyg_netdevtab_entry * ndp)
+{
+ static int initialized = 0; // only probe PCI et al *once*
+
+ struct eth_drv_sc *sc;
+ cyg_uint32 ioaddr;
+ int count;
+ struct i82544 *p_i82544;
+ cyg_uint8 mac_address[ETHER_ADDR_LEN];
+
+#ifdef DEBUG
+ db_printf("i82544_init\n");
+#endif
+
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+ p_i82544 = (struct i82544 *)(sc->driver_private);
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG
+ os_printf( "Bad device private pointer %x\n", sc->driver_private );
+#endif
+ return 0;
+ }
+
+ CHECK_NDP_SC_LINK();
+
+ if ( 0 == initialized++ ) {
+ // then this is the first time ever:
+ if ( ! pci_init_find_82544s() ) {
+#ifdef DEBUG
+ os_printf( "pci_init_find_82544s failed\n" );
+#endif
+ return 0;
+ }
+ }
+
+ // If this device is not present, exit
+ if (0 == p_i82544->found)
+ return 0;
+
+ p_i82544->mac_addr_ok = 0;
+
+ ioaddr = p_i82544->io_address; // get I/O address for 82544
+
+#ifdef DEBUG
+ os_printf("Init82544 %d @ %x\n", p_i82544->index, (int)ndp);
+#endif
+
+ // Reset device
+ i82544_reset(p_i82544);
+
+ i82544_setup(p_i82544);
+
+ InitRxRing(p_i82544);
+ InitTxRing(p_i82544);
+
+
+ if (p_i82544->hardwired_esa) {
+ // Hardwire the address without consulting the EEPROM.
+ // When this flag is set, the p_i82544 will already contain
+ // the ESA. Copy it to a mac_address for call to set_mac_addr
+ mac_address[0] = p_i82544->mac_address[0];
+ mac_address[1] = p_i82544->mac_address[1];
+ mac_address[2] = p_i82544->mac_address[2];
+ mac_address[3] = p_i82544->mac_address[3];
+ mac_address[4] = p_i82544->mac_address[4];
+ mac_address[5] = p_i82544->mac_address[5];
+
+ eth_set_mac_address(p_i82544, mac_address, 0);
+
+ } else {
+
+ // Acquire the ESA either from extenal means (probably RedBoot
+ // variables) or from the attached EEPROM - if there is one.
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82544_GET_ESA
+ int ok = false;
+ CYGHWR_DEVS_ETH_INTEL_I82544_GET_ESA( p_i82544, mac_address, ok );
+ if ( ok )
+ eth_set_mac_address(p_i82544, mac_address, 0);
+
+#else // ! CYGHWR_DEVS_ETH_INTEL_I82544_GET_ESA
+
+#ifndef CYGHWR_DEVS_ETH_INTEL_I82544_HAS_NO_EEPROM
+ int addr_length, i;
+ cyg_uint16 checksum;
+
+ // read eeprom and get 82544's mac address
+ addr_length = get_eeprom_size(p_i82544);
+ // (this is the length of the *EEPROM*s address, not MAC address)
+
+ // If length is 1, it _probably_ means there's no EEPROM
+ // present. Couldn't find an explicit mention of this in the
+ // docs, but length=1 appears to be the behaviour in that case.
+ if (1 == addr_length) {
+#ifdef DEBUG_EE
+ os_printf("Error: No EEPROM present for device %d\n",
+ p_i82544->index);
+#endif
+ } else {
+ for (checksum = 0, i = 0, count = 0; count < 64; count++) {
+ cyg_uint16 value;
+ // read word from eeprom
+ value = read_eeprom_word(p_i82544, addr_length, count);
+#ifdef DEBUG_EE
+ os_printf( "%02x: %04x\n", count, value );
+#endif
+ checksum += value;
+ if (count < 3) {
+ mac_address[i++] = value & 0xFF;
+ mac_address[i++] = (value >> 8) & 0xFF;
+ }
+ }
+
+#ifndef CYGHWR_DEVS_ETH_INTEL_I82544_HAS_ONE_EEPROM_WITHOUT_CRC
+ // If the EEPROM checksum is wrong, the MAC address read
+ // from the EEPROM is probably wrong as well. In that
+ // case, we don't set mac_addr_ok, but continue the
+ // initialization. If then somebody calls i82544_start
+ // without calling eth_set_mac_address() first, we refuse
+ // to bring up the interface, because running with an
+ // invalid MAC address is not a very brilliant idea.
+
+ if ((checksum & 0xFFFF) != 0xBABA) {
+ // selftest verified checksum, verify again
+#ifdef DEBUG_EE
+ os_printf("Warning: Invalid EEPROM checksum %04X for device %d\n",
+ checksum, p_i82544->index);
+#endif
+ } else // trailing block
+#endif
+ {
+ p_i82544->mac_addr_ok = 1;
+#ifdef DEBUG_EE
+ os_printf("Valid EEPROM checksum\n");
+#endif
+ // Second port of dual-port 82546 uses EEPROM ESA | 1
+ if (p_i82544->device == 0x1010 ||
+ p_i82544->device == 0x100e) {
+ cyg_uint8 devfn = CYG_PCI_DEV_GET_DEVFN(p_i82544->devid);
+ if (CYG_PCI_DEV_GET_FN(devfn) == 1)
+ mac_address[5] |= 1;
+ }
+ eth_set_mac_address(p_i82544, mac_address, 0);
+ }
+ }
+
+ // record the MAC address in the device structure
+ p_i82544->mac_address[0] = mac_address[0];
+ p_i82544->mac_address[1] = mac_address[1];
+ p_i82544->mac_address[2] = mac_address[2];
+ p_i82544->mac_address[3] = mac_address[3];
+ p_i82544->mac_address[4] = mac_address[4];
+ p_i82544->mac_address[5] = mac_address[5];
+
+#endif // ! CYGHWR_DEVS_ETH_INTEL_I82544_HAS_NO_EEPROM
+#endif // ! CYGHWR_DEVS_ETH_INTEL_I82544_GET_ESA
+ }
+
+#ifdef DEBUG
+ os_printf("i82544_init: MAC Address = %02X %02X %02X %02X %02X %02X\n",
+ p_i82544->mac_address[0], p_i82544->mac_address[1],
+ p_i82544->mac_address[2], p_i82544->mac_address[3],
+ p_i82544->mac_address[4], p_i82544->mac_address[5]);
+#endif
+
+ // and record the net dev pointer
+ p_i82544->ndp = (void *)ndp;
+
+ p_i82544->within_send = 0; // init recursion level
+
+ // Initialize upper level driver
+ if ( p_i82544->mac_addr_ok )
+ (sc->funs->eth_drv->init)(sc, &(p_i82544->mac_address[0]) );
+ else
+ {
+ (sc->funs->eth_drv->init)(sc, NULL );
+ }
+
+
+#ifdef DEBUG
+
+ os_printf("CTRL %08x\n",INL( ioaddr + I82544_CTRL ));
+ os_printf("STATUS %08x\n",INL( ioaddr + I82544_STATUS ));
+
+#endif
+
+ return (1);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82544_setup
+//
+// ------------------------------------------------------------------------
+
+static void
+i82544_setup( struct i82544 *p_i82544 )
+{
+ cyg_uint32 ioaddr;
+ cyg_uint32 ctrl;
+#ifndef CYGHWR_DEVS_ETH_INTEL_I82544_USE_ASD
+ cyg_uint32 ctrl_ext;
+#endif
+
+ ioaddr = p_i82544->io_address; // get 82544's I/O address
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82544_USE_ASD
+ // Use Auto-negotiation
+
+ ctrl = INL( ioaddr + I82544_CTRL );
+
+ // Set link up bit
+ ctrl |= I82544_CTRL_SLU | I82544_CTRL_ASDE;
+ ctrl &= ~(I82544_CTRL_ILOS | I82544_CTRL_FRCSPD | I82544_CTRL_FRCDPLX);
+ OUTL( ctrl, ioaddr + I82544_CTRL );
+ udelay(20);
+
+ // we can assume link is up with autonegotiation
+ p_i82544->link = 1;
+
+ // wait up to 5 seconds for link to come up
+ {
+ int delay_cnt = 500;
+ while ((mii_read_register( p_i82544, PHY_ADDRESS, 1 ) & 0x4) == 0) {
+ udelay(10000);
+ if (--delay_cnt <= 0)
+ break;
+ }
+ }
+
+#else
+ // The following sequence of resets and bit twiddling seem to be
+ // necessary to get the 82543 working. Not sure what is necessary
+ // for the 82544.
+
+ ctrl = INL( ioaddr + I82544_CTRL );
+
+ // Set link up bit
+ ctrl |= I82544_CTRL_SLU;
+ ctrl &= ~I82544_CTRL_ILOS;
+ OUTL( ctrl, ioaddr + I82544_CTRL );
+ udelay(20);
+
+ // Force PHY physical reset
+ // We can only access the PHY after we have done this.
+
+ ctrl_ext = INL( ioaddr + I82544_CTRL_EXT );
+ ctrl_ext |= I82544_CTRL_EXT_PHY_RESET_DIR4;
+ OUTL( ctrl_ext, ioaddr + I82544_CTRL_EXT );
+ udelay( 20000 );
+
+ ctrl_ext = INL( ioaddr + I82544_CTRL_EXT );
+ ctrl_ext &= ~I82544_CTRL_EXT_PHY_RESET4;
+ OUTL( ctrl_ext, ioaddr + I82544_CTRL_EXT );
+ udelay( 20000 );
+
+ ctrl_ext = INL( ioaddr + I82544_CTRL_EXT );
+ ctrl_ext |= I82544_CTRL_EXT_PHY_RESET4;
+ OUTL( ctrl_ext, ioaddr + I82544_CTRL_EXT );
+ udelay( 20000 );
+
+#ifdef DEBUG
+ show_phy( p_i82544, PHY_ADDRESS );
+#endif
+
+#if 0
+ // Reset PHY
+ // Does not appear to be necessary.
+ {
+ cyg_uint16 phy_ctrl;
+ phy_ctrl = mii_read_register( p_i82544, PHY_ADDRESS, 0 );
+ phy_ctrl = 0x9000;
+// os_printf("PHY ctrl %04x\n",phy_ctrl);
+ mii_write_register( p_i82544, PHY_ADDRESS, 0, phy_ctrl );
+ do {
+ phy_ctrl = mii_read_register( p_i82544, PHY_ADDRESS, 0 );
+// os_printf("PHY ctrl %04x\n",phy_ctrl);
+ } while( phy_ctrl & 0x8000 );
+ }
+ show_phy( p_i82544, PHY_ADDRESS );
+#endif
+
+#if 0
+ // Tinker with PHY configuration.
+ // Only on 82543? May not be necessary at all, since disabling
+ // this does not see to make any difference.
+ {
+ cyg_uint16 data;
+
+ // Set CRS on Tx bit in PHY specific CR
+ data = mii_read_register( p_i82544, PHY_ADDRESS, 16 );
+ os_printf("PSCR %04x\n",data);
+ data |= 0x0800;
+ mii_write_register( p_i82544, PHY_ADDRESS, 16, data );
+
+ // Set TX clock to 25MHz in PHY extended CR
+ data = mii_read_register( p_i82544, PHY_ADDRESS, 20 );
+ os_printf("PSECR %04x\n",data);
+ data |= 0x0070;
+ mii_write_register( p_i82544, PHY_ADDRESS, 20, data );
+ }
+ show_phy( p_i82544, PHY_ADDRESS );
+#endif
+
+#if 1
+ // Force speed renegotiation.
+
+ {
+ cyg_uint16 phy_ctrl;
+ cyg_uint16 phy_stat;
+ int delay_cnt = 100 * 5; // wait five seconds, then give up
+
+ p_i82544->link = 0;
+ phy_ctrl = mii_read_register( p_i82544, PHY_ADDRESS, 0 );
+ phy_ctrl |= 0x1200;
+// os_printf("PHY ctrl %04x\n",phy_ctrl);
+ mii_write_register( p_i82544, PHY_ADDRESS, 0, phy_ctrl );
+ // Wait for it to complete
+ do {
+ udelay(10000);
+ phy_stat = mii_read_register( p_i82544, PHY_ADDRESS, 1 );
+ phy_stat = mii_read_register( p_i82544, PHY_ADDRESS, 1 );
+ } while( (phy_stat & 0x0020) == 0 && (delay_cnt-- > 0) );
+
+ if (phy_stat & 0x0020)
+ p_i82544->link = 1;
+ }
+
+#ifdef DEBUG
+ show_phy( p_i82544, PHY_ADDRESS );
+#endif
+#endif
+
+#if 0
+ // Reset link
+ OUTL( ctrl | I82544_CTRL_LRST, ioaddr + I82544_CTRL );
+ udelay(20);
+ OUTL( ctrl, ioaddr + I82544_CTRL );
+ udelay(20);
+ show_phy( p_i82544, PHY_ADDRESS );
+#endif
+
+
+
+ // Transfer speed and duplicity settings from PHY to MAC
+
+ // In theory the MAC is supposed to auto-configure from what the
+ // PHY has autonegotiated. In practice this does not seem to work
+ // (on the 82543 at least, it always thinks it is 1000MHz full
+ // duplex) and we have to transfer the settings from the PHY by
+ // hand. Additionally, the settings in the PHY ctrl register seem
+ // bogus, so we read the values out of the PHY specific status
+ // register instead.
+
+ if (p_i82544->link) {
+ cyg_uint16 phy_pssr;
+
+ phy_pssr = mii_read_register( p_i82544, PHY_ADDRESS, 17 );
+
+ ctrl = INL( ioaddr + I82544_CTRL );
+// os_printf("CTRL %08x\n",ctrl);
+ ctrl &= ~(I82544_CTRL_SPEED | I82544_CTRL_FD);
+ if( phy_pssr & (1<<13) )
+ ctrl |= I82544_CTRL_FD;
+
+ // Transfer speed
+ ctrl |= ((phy_pssr>>14)&3)<<8;
+
+ ctrl |= I82544_CTRL_FRCDPLX | I82544_CTRL_FRCSPD;
+
+ OUTL( ctrl, ioaddr + I82544_CTRL );
+// os_printf("CTRL %08x\n",ctrl);
+ }
+
+
+#if 0
+#ifdef DEBUG
+ {
+ int status = i82544_status( sc );
+ static int speed[4] = { 10, 100, 1000, 1000 };
+ os_printf("i82544_start %d flg %x Link = %s, %d Mbps, %s Duplex\n",
+ p_i82544->index,
+ *(int *)p_i82544,
+ status & GEN_STATUS_LINK ? "Up" : "Down",
+ speed[(status & GEN_STATUS_BPS)>>GEN_STATUS_BPS_SHIFT],
+ status & GEN_STATUS_FDX ? "Full" : "Half");
+ }
+#endif
+#endif
+
+ // Hang around here for a bit to let the device settle down. We
+ // don't seem to get away without this.
+
+ udelay( 1000000 );
+
+#if 0
+
+ // Having done all that, the interface still does not work
+ // properly, UNLESS I now wait >= 45 seconds here. After that it
+ // seems happy. I cannot find any difference in the state of the
+ // PHY or the 82543 to explain this.
+
+ show_phy( p_i82544, PHY_ADDRESS );
+ os_printf("CTRL %08x\n",INL( ioaddr + I82544_CTRL ));
+ os_printf("STATUS %08x\n",INL( ioaddr + I82544_STATUS ));
+ os_printf("ICR %08x\n",INL( ioaddr + I82544_ICR ));
+ os_printf("RCTL %08x\n",INL( ioaddr + I82544_RCTL ));
+ os_printf("TCTL %08x\n",INL( ioaddr + I82544_TCTL ));
+
+ os_printf("Waiting 45 seconds\n");
+ {
+ int i;
+ cyg_uint32 status = INL( ioaddr + I82544_STATUS );
+// for( i = 0; i < 60; i++ ) // works
+// for( i = 0; i < 45; i++ ) // works
+// for( i = 0; i < 40; i++ ) // fails
+// for( i = 0; i < 35; i++ ) // fails
+// for( i = 0; i < 30; i++ ) // fails
+ {
+ cyg_uint32 s;
+ PC_WRITE_SCREEN_32( 60, i );
+ udelay(1000000);
+ s = INL( ioaddr + I82544_STATUS );
+ if( s != status )
+ {
+ os_printf("%d STATUS change %08x\n",i,s);
+ status = s;
+ }
+ }
+ }
+
+ show_phy( p_i82544, PHY_ADDRESS );
+ os_printf("CTRL %08x\n",INL( ioaddr + I82544_CTRL ));
+ os_printf("STATUS %08x\n",INL( ioaddr + I82544_STATUS ));
+ os_printf("ICR %08x\n",INL( ioaddr + I82544_ICR ));
+ os_printf("RCTL %08x\n",INL( ioaddr + I82544_RCTL ));
+ os_printf("TCTL %08x\n",INL( ioaddr + I82544_TCTL ));
+
+#endif
+#endif // CYGHWR_DEVS_ETH_INTEL_I82544_USE_ASD
+
+ // Set up interrupts
+
+ // Clear any pending interrupts
+ ctrl = INL( ioaddr + I82544_ICR );
+
+ // clear all mask bits
+ OUTL( 0xFFFFFFFF, ioaddr + I82544_IMC );
+
+ // Set interrupt bits for:
+ // 1 = Transmit queue empty
+ // 7 = Receiver timeout interrupt
+ OUTL( (1<<1)|(1<<7), ioaddr + I82544_IMS );
+
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82544_start
+//
+// ------------------------------------------------------------------------
+
+static void
+i82544_start( struct eth_drv_sc *sc, unsigned char *enaddr, int flags )
+{
+ struct i82544 *p_i82544;
+ cyg_uint32 ioaddr;
+ cyg_uint32 txctl, rxctl;
+
+#ifdef CYGPKG_NET
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+#ifdef DEBUG
+ db_printf("i82544_start\n");
+#endif
+
+ p_i82544 = (struct i82544 *)sc->driver_private;
+ ioaddr = p_i82544->io_address; // get 82544's I/O address
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG
+ os_printf( "i82544_start: Bad device pointer %x\n", p_i82544 );
+#endif
+ return;
+ }
+
+ if ( ! p_i82544->mac_addr_ok ) {
+#ifdef DEBUG
+ os_printf("i82544_start %d: invalid MAC address, "
+ "can't bring up interface\n",
+ p_i82544->index );
+#endif
+ return;
+ }
+
+ if ( p_i82544->active )
+ i82544_stop( sc );
+
+ // Enable device
+ p_i82544->active = 1;
+
+ /* Enable promiscuous mode if requested, reception of oversized frames always.
+ * The latter is needed for VLAN support and shouldn't hurt even if we're not
+ * using VLANs.
+ */
+ i82544_configure(p_i82544, 0
+#ifdef CYGPKG_NET
+ || !!(ifp->if_flags & IFF_PROMISC)
+#endif
+#ifdef ETH_DRV_FLAGS_PROMISC_MODE
+ || !!(flags & ETH_DRV_FLAGS_PROMISC_MODE)
+#endif
+ , 1);
+
+ // enable receiver
+ rxctl = INL( ioaddr + I82544_RCTL );
+ rxctl |= I82544_RCTL_EN;
+ OUTL( rxctl, ioaddr + I82544_RCTL );
+
+ // Enable transmitter
+ txctl = INL( ioaddr + I82544_TCTL );
+ txctl |= I82544_TCTL_EN;
+ OUTL( txctl, ioaddr + I82544_TCTL );
+
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82544_status
+//
+// ------------------------------------------------------------------------
+int
+i82544_status( struct eth_drv_sc *sc )
+{
+ int status;
+ struct i82544 *p_i82544;
+ cyg_uint32 ioaddr;
+#ifdef DEBUG
+ db_printf("i82544_status\n");
+#endif
+
+ p_i82544 = (struct i82544 *)sc->driver_private;
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG
+ os_printf( "i82544_status: Bad device pointer %x\n", p_i82544 );
+#endif
+ return 0;
+ }
+
+ ioaddr = p_i82544->io_address; // get 82544's I/O address
+
+ status = INL(ioaddr + I82544_STATUS);
+
+ return status;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : BringDown82544
+//
+// ------------------------------------------------------------------------
+
+static void
+i82544_stop( struct eth_drv_sc *sc )
+{
+ struct i82544 *p_i82544;
+ cyg_uint32 ioaddr;
+ cyg_uint32 txctl, rxctl;
+
+#ifdef DEBUG
+ db_printf("i82544_stop\n");
+#endif
+
+ p_i82544 = (struct i82544 *)sc->driver_private;
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG
+ os_printf( "i82544_stop: Bad device pointer %x\n", p_i82544 );
+#endif
+ return;
+ }
+
+#ifdef DEBUG
+ os_printf("i82544_stop %d flg %x\n", p_i82544->index, *(int *)p_i82544 );
+#endif
+
+ p_i82544->active = 0; // stop people tormenting it
+
+ ioaddr = p_i82544->io_address;
+
+ // disable receiver
+ rxctl = INL( ioaddr + I82544_RCTL );
+ rxctl &= ~I82544_RCTL_EN;
+ OUTL( rxctl, ioaddr + I82544_RCTL );
+
+ // Enable transmitter
+ txctl = INL( ioaddr + I82544_TCTL );
+ txctl &= ~I82544_TCTL_EN;
+ OUTL( txctl, ioaddr + I82544_TCTL );
+
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : InitRxRing
+//
+// ------------------------------------------------------------------------
+
+static void
+InitRxRing(struct i82544* p_i82544)
+{
+ int i;
+ CYG_ADDRESS rxring;
+ cyg_uint32 ioaddr = p_i82544->io_address;
+ cyg_uint32 rxctl;
+
+#ifdef DEBUG_82544
+ os_printf("InitRxRing %d\n", p_i82544->index);
+#endif
+
+ // Allocate array of Rx desriptors
+ rxring = pciwindow_mem_alloc(
+ MAX_RX_DESCRIPTORS * I82544_RD_SIZE + 32 );
+
+ // assign ring structure, aligning it on a 16 byte boudary.
+ p_i82544->rx_ring = (rxring + 15) & ~15;
+
+ // Allocate and fill in buffer pointers
+ for ( i = 0; i < MAX_RX_DESCRIPTORS; i++) {
+ CYG_ADDRESS rd = p_i82544->rx_ring + (i*I82544_RD_SIZE);
+ CYG_ADDRESS buf = pciwindow_mem_alloc(MAX_RX_PACKET_SIZE);
+ WRITEMEM64( rd + I82544_RD_BUFFER, VIRT_TO_BUS(buf) );
+ }
+
+ // Set the receiver queue registers
+
+ OUTL( VIRT_TO_BUS(p_i82544->rx_ring), ioaddr + I82544_RDBAL );
+ OUTL( 0, ioaddr + I82544_RDBAH );
+ OUTL( MAX_RX_DESCRIPTORS * I82544_RD_SIZE, ioaddr + I82544_RDLEN );
+ OUTL( 0, ioaddr + I82544_RDH );
+ OUTL( MAX_RX_DESCRIPTORS - 5, ioaddr + I82544_RDT );
+
+ // zero out RAT
+
+ for( i = 0; i < 32; i++ )
+ OUTL( 0, ioaddr + I82544_RAT +(i*4) );
+
+ // Zero out MTA
+ for( i = 0; i < 128; i++ )
+ OUTL( 0, ioaddr + I82544_MTA +(i*4) );
+
+ // Set up receiver to accept broadcasts
+ rxctl = INL( ioaddr + I82544_RCTL );
+ rxctl |= I82544_RCTL_BAM;
+ OUTL( rxctl, ioaddr + I82544_RCTL );
+
+#ifdef DEBUG_82544
+ os_printf("RCTL %08x\n",rxctl);
+#endif
+
+ p_i82544->next_rx_descriptor = 0;
+ p_i82544->rx_pointer = 0;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : PacketRxReady (Called from delivery thread & foreground)
+//
+// ------------------------------------------------------------------------
+
+static void
+PacketRxReady(struct i82544* p_i82544)
+{
+ struct cyg_netdevtab_entry *ndp;
+ struct eth_drv_sc *sc;
+ cyg_int32 rxp;
+ cyg_uint32 ioaddr;
+
+#ifdef DEBUG_82544
+// db_printf("PacketRxReady\n");
+#endif
+
+ ndp = (struct cyg_netdevtab_entry *)(p_i82544->ndp);
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ CHECK_NDP_SC_LINK();
+
+ ioaddr = p_i82544->io_address;
+
+
+ rxp = p_i82544->rx_pointer;
+
+ for(;;)
+ {
+ cyg_int32 rxh, rxt;
+ CYG_ADDRESS dp;
+ cyg_uint8 status;
+
+ rxh = INL( ioaddr + I82544_RDH );
+
+#if 0 //def DEBUG_82544
+ os_printf("rxp %04d rxh %04x\n",rxp,rxh);
+#endif
+
+ // If the head pointer has not advanced, there have been no
+ // packets received.
+ if( rxh == rxp )
+ break;
+
+ // Form packet address
+ dp = p_i82544->rx_ring + (rxp * I82544_RD_SIZE);
+
+ // Get status
+ READMEM8( dp + I82544_RD_STATUS, status );
+
+#if 0 //def DEBUG_82544
+ {
+ cyg_uint16 length;
+ READMEM16( dp + I82544_RD_LENGTH, length );
+ os_printf("rxp %04d status %02x length %d\n",rxp,status,length);
+ }
+#endif
+
+ if( status & I82544_RD_STATUS_EOP )
+ {
+ cyg_uint16 length;
+
+ READMEM16( dp + I82544_RD_LENGTH, length );
+
+#ifdef DEBUG_82544
+ os_printf("rxp %04d length %d\n",rxp,length);
+#endif
+ CYG_ASSERT( MAX_RX_PACKET_SIZE >= length, "Oversize Rx" );
+
+ // tell the callback the right packet
+ p_i82544->next_rx_descriptor = rxp;
+
+#ifdef CYGPKG_NET
+ if ( length > sizeof( struct ether_header ) )
+ // then it is acceptable; offer the data to the network stack
+#endif
+ (sc->funs->eth_drv->recv)( sc, length );
+
+ // All done!
+ }
+
+ // Advance rxp pointer
+ rxp = ( rxp + 1 ) % MAX_RX_DESCRIPTORS;
+
+ // We can now also advance the tail pointer by 1
+ rxt = INL( ioaddr + I82544_RDT );
+ dp = p_i82544->rx_ring + (rxt * I82544_RD_SIZE);
+ WRITEMEM8( dp + I82544_RD_STATUS, status );
+ rxt = ( rxt + 1 ) % MAX_RX_DESCRIPTORS;
+ OUTL( rxt, ioaddr + I82544_RDT );
+
+#ifdef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ // Can't deliver more than one packet in polled standalone mode
+ break;
+#endif
+ }
+
+ // Save next rx pointer for next time.
+ p_i82544->rx_pointer = rxp;
+
+}
+
+// and the callback function
+
+static void
+i82544_recv( struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len )
+{
+ struct i82544 *p_i82544;
+ cyg_int32 rxp;
+ CYG_ADDRESS dp;
+ CYG_ADDRESS from_p;
+ cyg_uint16 total_len;
+ struct eth_drv_sg *last_sg;
+
+#ifdef DEBUG_82544
+ db_printf("i82544_recv\n");
+#endif
+
+ p_i82544 = (struct i82544 *)sc->driver_private;
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG_82544
+ os_printf( "i82544_recv: Bad device pointer %x\n", p_i82544 );
+#endif
+ return;
+ }
+
+ rxp = p_i82544->next_rx_descriptor;
+ // Form packet address
+ dp = p_i82544->rx_ring + (rxp * I82544_RD_SIZE);
+
+#if 0 //def DEBUG_82544
+ {
+ int i;
+ os_printf("RxD %08x",dp);
+ for( i = 0; i < 16; i++ )
+ {
+ cyg_uint8 b;
+ if( (i%8) == 0 ) os_printf("\n");
+ READMEM8( dp + i, b );
+ os_printf("%02x ",b);
+ }
+ os_printf("\n");
+ }
+#endif
+ // Copy the data to the network stack
+ READMEM64( dp + I82544_RD_BUFFER, from_p );
+ from_p = BUS_TO_VIRT(from_p);
+ READMEM16( dp + I82544_RD_LENGTH, total_len );
+
+#ifdef DEBUG_82544
+ db_printf("RXP: %04x len %d\n",rxp,total_len);
+#endif
+
+ // check we have memory to copy into; we would be called even if
+ // caller was out of memory in order to maintain our state.
+ if ( 0 == sg_len || 0 == sg_list )
+ return; // caller was out of mbufs
+
+ CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
+ CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
+
+ for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
+ cyg_uint8 *to_p;
+ int l;
+
+ to_p = (cyg_uint8 *)(sg_list->buf);
+ l = sg_list->len;
+
+ CYG_ASSERT( 0 <= l, "sg length -ve" );
+
+ if ( 0 >= l || 0 == to_p )
+ return; // caller was out of mbufs
+
+ if ( l > total_len )
+ l = total_len;
+
+#if 0 //def DEBUG_82544
+ {
+ int i,ll = l;
+ os_printf("Pkt len %d",l);
+ if( ll > 32 ) ll = 32;
+ for( i = 0; i < ll; i++ )
+ {
+ cyg_uint8 b;
+ if( (i%8) == 0 ) os_printf("\n %04x: ",i);
+ b = ((cyg_uint8 *)from_p)[i];
+ os_printf("%02x ",b);
+ }
+ os_printf("\n");
+
+ }
+#endif
+ memcpy( to_p, (unsigned char *)from_p, l );
+ from_p += l;
+ total_len -= l;
+ }
+
+ CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" );
+ CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" );
+
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : InitTxRing
+//
+// ------------------------------------------------------------------------
+
+static void
+InitTxRing(struct i82544* p_i82544)
+{
+ int i;
+ cyg_uint32 ioaddr = p_i82544->io_address;
+ CYG_ADDRESS txring;
+ cyg_uint32 txctl;
+
+#ifdef DEBUG_82544
+ os_printf("InitTxRing %d\n", p_i82544->index);
+#endif
+
+ // Allocate array of Tx desriptors
+ txring = pciwindow_mem_alloc(
+ MAX_TX_DESCRIPTORS * I82544_TD_SIZE + 32 );
+
+ // assign ring structure, aligning it on a 16 byte boudary.
+ p_i82544->tx_ring = (txring + 15) & ~15;
+
+ // Allocate and fill in buffer pointers
+ for ( i = 0; i < MAX_TX_DESCRIPTORS; i++) {
+ CYG_ADDRESS td = p_i82544->tx_ring + (i*I82544_TD_SIZE);
+ WRITEMEM64( td + I82544_TD_BUFFER, 0 );
+ }
+
+ // Set the transmitter queue registers
+
+ OUTL( VIRT_TO_BUS(p_i82544->tx_ring), ioaddr + I82544_TDBAL );
+ OUTL( 0, ioaddr + I82544_TDBAH );
+ OUTL( MAX_TX_DESCRIPTORS * I82544_TD_SIZE, ioaddr + I82544_TDLEN );
+ OUTL( 0, ioaddr + I82544_TDH );
+ OUTL( 0, ioaddr + I82544_TDT );
+
+ // Set IPG values
+ OUTL( 8 | (8<<10) | (6<<20), ioaddr + I82544_TIPG );
+
+ // Program tx ctrl register
+ txctl = INL( ioaddr + I82544_TCTL );
+ txctl |= (15<<4); // collision threshold
+ txctl |= (64<<12); // collision distance
+ txctl |= I82544_TCTL_PSP;
+ OUTL( txctl, ioaddr + I82544_TCTL );
+
+ p_i82544->tx_in_progress = 0;
+ p_i82544->tx_pointer = 0;
+
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : TxDone (Called from delivery thread)
+//
+// This returns Tx's from the Tx Machine to the stack (ie. reports
+// completion) - allowing for missed interrupts, and so on.
+// ------------------------------------------------------------------------
+
+static void
+TxDone(struct i82544* p_i82544)
+{
+ struct cyg_netdevtab_entry *ndp;
+ struct eth_drv_sc *sc;
+ cyg_uint32 ioaddr;
+ cyg_int32 txp = p_i82544->tx_pointer;
+
+#ifdef DEBUG_82544
+// db_printf("TxDone\n");
+#endif
+
+ ndp = (struct cyg_netdevtab_entry *)(p_i82544->ndp);
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ CHECK_NDP_SC_LINK();
+
+ ioaddr = p_i82544->io_address; // get device I/O address
+
+ if( !p_i82544->active )
+ return;
+
+ for(;;)
+ {
+ cyg_uint8 status;
+ cyg_uint8 cmd;
+ CYG_ADDRESS dp;
+ cyg_int32 txh;
+
+ txh = INL( ioaddr + I82544_TDH );
+
+ // If there has been no advance on the transmit header,
+ // nothing to do.
+ if( txh == txp )
+ break;
+
+#ifdef DEBUG_82544
+ os_printf("TxDone: TxH %04d TxP %04d\n",txh,txp);
+#endif
+
+ // Get descriptor address
+ dp = p_i82544->tx_ring + (txp * I82544_TD_SIZE);
+
+ READMEM8( dp + I82544_TD_CMD, cmd );
+ READMEM8( dp + I82544_TD_STATUS, status );
+#ifdef DEBUG_82544
+ os_printf("cmd %02x status %02x\n",cmd,status);
+#endif
+
+ // Zero out buffer and command
+ WRITEMEM64( dp + I82544_TD_BUFFER, 0 );
+ WRITEMEM8( dp + I82544_TD_CMD, 0 );
+
+ if( cmd & I82544_TD_CMD_EOP )
+ {
+ // A done end of packet descrptor
+
+ if( p_i82544->tx_keys[txp] != 0 )
+ {
+ // Call network stack with correct value of txp in structure.
+ // There may be recursive calls in here, so we need to make sure
+ // that txp is updated correctly.
+ p_i82544->tx_pointer = ( txp + 1 ) % MAX_TX_DESCRIPTORS;
+ (sc->funs->eth_drv->tx_done)( sc, p_i82544->tx_keys[txp], 0 );
+ txp = p_i82544->tx_pointer;
+ continue;
+ }
+ }
+
+ // Advance tx pointer
+ txp = ( txp + 1 ) % MAX_TX_DESCRIPTORS;
+
+ }
+
+ // restore txp to data structure.
+ p_i82544->tx_pointer = txp;
+
+}
+
+
+static cyg_bool
+check_link(struct i82544 *p_i82544)
+{
+ if ( p_i82544->link == 0 )
+ {
+ cyg_uint16 phy_pssr;
+ cyg_uint16 phy_stat;
+
+ phy_stat = mii_read_register( p_i82544, PHY_ADDRESS, 1 );
+ if (phy_stat & 0x20)
+ {
+ cyg_uint32 ioaddr;
+ cyg_uint32 ctrl;
+
+ p_i82544->link = 1;
+
+ ioaddr = p_i82544->io_address; // get device I/O address
+
+ phy_pssr = mii_read_register( p_i82544, PHY_ADDRESS, 17 );
+
+ ctrl = INL( ioaddr + I82544_CTRL );
+ ctrl &= ~(I82544_CTRL_SPEED | I82544_CTRL_FD);
+ if( phy_pssr & (1<<13) )
+ ctrl |= I82544_CTRL_FD;
+
+ // Transfer speed
+ ctrl |= ((phy_pssr>>14)&3)<<8;
+ ctrl |= I82544_CTRL_FRCDPLX | I82544_CTRL_FRCSPD;
+
+ OUTL( ctrl, ioaddr + I82544_CTRL );
+ }
+ }
+
+ return p_i82544->link == 1;
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : i82544_can_send
+//
+// ------------------------------------------------------------------------
+
+static int
+i82544_can_send(struct eth_drv_sc *sc)
+{
+ struct i82544 *p_i82544;
+ cyg_uint32 ioaddr;
+
+#ifdef DEBUG_82544
+// db_printf("i82544_can_send\n");
+#endif
+
+ p_i82544 = (struct i82544 *)sc->driver_private;
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG_82544
+ os_printf( "i82544_send: Bad device pointer %x\n", p_i82544 );
+#endif
+ return 0;
+ }
+
+ ioaddr = p_i82544->io_address; // get device I/O address
+
+ if ( p_i82544->active )
+ {
+ cyg_int32 txh, txt, diff;
+
+
+ if (!check_link(p_i82544))
+ return 0;
+
+ // Poll for Tx completion
+ TxDone( p_i82544 );
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ // We are not prepared to receive a packet now if we are in a polled
+ // standalone configuration.
+
+ // Poll for receptions
+ PacketRxReady( p_i82544 );
+#endif
+
+ // Now see whether the Tx queue has space for another
+ // transmit. We look at the difference between the head and
+ // tail pointer, and if there is space for at least 5 more
+ // descriptors, we allow a new transmission to go ahead.
+ txh = INL( ioaddr + I82544_TDH );
+ txt = INL( ioaddr + I82544_TDT );
+
+ diff = (txh-1) - txt;
+ if( diff < 0 ) diff += MAX_TX_DESCRIPTORS;
+#ifdef DEBUG_82544
+// os_printf("TxH %04d TxT %04d diff %04d\n",txh,txt,diff);
+#endif
+ return diff > 5;
+ }
+
+ return false;
+
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82544_send
+//
+// ------------------------------------------------------------------------
+
+static void
+i82544_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list, int sg_len, int total_len,
+ unsigned long key)
+{
+ struct i82544 *p_i82544;
+ cyg_uint32 ioaddr;
+ struct eth_drv_sg *last_sg;
+ cyg_int32 txt;
+
+
+#ifdef DEBUG_82544
+ db_printf("i82544_send\n");
+#endif
+
+ p_i82544 = (struct i82544 *)sc->driver_private;
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG_82544
+ os_printf( "i82544_send: Bad device pointer %x\n", p_i82544 );
+#endif
+ return;
+ }
+
+#ifdef DEBUG_82544
+ os_printf("Tx %d %x: %d sg's, %d bytes, KEY %x\n",
+ p_i82544->index, (int)p_i82544, sg_len, total_len, key );
+#endif
+
+ if ( ! p_i82544->active )
+ return; // device inactive, no return
+ ioaddr = p_i82544->io_address; // get device I/O address
+
+ // Get the tx tail pointer
+ txt = INL( ioaddr + I82544_TDT );
+
+ for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ )
+ {
+ cyg_uint8 *from_p;
+ cyg_uint8 cmd = 0;
+ CYG_ADDRESS dp;
+ int l;
+
+ from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address
+ l = sg_list->len;
+
+ if ( l > total_len )
+ l = total_len;
+
+ // Get the descriptor address from the tail pointer.
+ dp = p_i82544->tx_ring + (txt * I82544_TD_SIZE);
+
+ total_len -= l;
+
+#ifdef HAL_DCACHE_STORE
+ HAL_DCACHE_STORE( ((CYG_ADDRESS)from_p) &~(HAL_DCACHE_LINE_SIZE-1),
+ l + (HAL_DCACHE_LINE_SIZE-1) );
+#endif
+
+ WRITEMEM64( dp + I82544_TD_BUFFER, VIRT_TO_BUS(from_p) );
+ WRITEMEM16( dp + I82544_TD_LENGTH, l );
+
+ // Set EOP bit on last packet
+ if( total_len <= 0 )
+ cmd |= I82544_TD_CMD_EOP;
+
+ // Get status back
+// cmd |= I82544_TD_CMD_RPS | I82544_TD_CMD_RS;
+
+ cmd |= I82544_TD_CMD_IFCS;
+
+ // Write command byte
+ WRITEMEM8( dp + I82544_TD_CMD, cmd );
+
+ // Zero out rest of fields
+ WRITEMEM8( dp + I82544_TD_STATUS, 0 );
+ WRITEMEM8( dp + I82544_TD_CSO, 0 );
+ WRITEMEM8( dp + I82544_TD_CSS, 0 );
+ WRITEMEM16( dp + I82544_TD_SPECIAL, 0 );
+
+ // Store the key for this transmission in the matching slot
+ // for the descriptor.
+ p_i82544->tx_keys[txt] = key;
+
+ // Increment tx tail pointer
+ txt = (txt + 1) % MAX_TX_DESCRIPTORS;
+
+ }
+
+ // And finally, cause the transmission to happen by setting the
+ // tail pointer in the hardware.
+ OUTL( txt, ioaddr + I82544_TDT );
+
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82544_reset
+//
+// ------------------------------------------------------------------------
+static void
+i82544_reset(struct i82544* p_i82544)
+{
+ cyg_uint32 ioaddr = p_i82544->io_address;
+ cyg_uint32 ctrl;
+
+#ifdef DEBUG
+ db_printf("i82544_reset\n");
+#endif
+
+ ctrl = INL( ioaddr + I82544_CTRL );
+
+ // reset controller
+ OUTL( ctrl | I82544_CTRL_RST, ioaddr + I82544_CTRL );
+ udelay(20);
+ ctrl = INL( ioaddr + I82544_CTRL );
+
+}
+
+// ------------------------------------------------------------------------
+//
+// INTERRUPT HANDLERS
+//
+// ------------------------------------------------------------------------
+
+static cyg_uint32
+eth_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct i82544* p_i82544 = (struct i82544 *)data;
+ cyg_uint16 status;
+ cyg_uint32 ioaddr;
+
+#ifdef DEBUG_82544
+// db_printf("eth_isr\n");
+#endif
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG_82544
+ os_printf( "i82544_isr: Bad device pointer %x\n", p_i82544 );
+#endif
+ return 0;
+ }
+
+ ioaddr = p_i82544->io_address;
+
+ status = INL( ioaddr + I82544_ICR );
+
+#ifdef DEBUG_82544
+ db_printf("eth_isr %04x\n",status);
+#endif
+
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // schedule DSR
+}
+
+
+// ------------------------------------------------------------------------
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+static void
+eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct i82544* p_i82544 = (struct i82544 *)data;
+ struct cyg_netdevtab_entry *ndp =
+ (struct cyg_netdevtab_entry *)(p_i82544->ndp);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+#ifdef DEBUG_82544
+ db_printf("eth_dsr\n");
+#endif
+
+ eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+
+ cyg_drv_interrupt_acknowledge(p_i82544->vector);
+}
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+
+// ------------------------------------------------------------------------
+// Deliver routine:
+
+void
+i82544_deliver(struct eth_drv_sc *sc)
+{
+ struct i82544* p_i82544 = (struct i82544 *)(sc->driver_private);
+
+#ifdef DEBUG
+ db_printf("i82544_deliver\n");
+#endif
+
+ // First pass any rx data up the stack
+ PacketRxReady(p_i82544);
+
+ // Then scan for completed Tx and inform the stack
+ TxDone(p_i82544);
+}
+
+// ------------------------------------------------------------------------
+// Device table entry to operate the chip in a polled mode.
+// Only diddle the interface we were asked to!
+
+void
+i82544_poll(struct eth_drv_sc *sc)
+{
+ struct i82544 *p_i82544;
+ p_i82544 = (struct i82544 *)sc->driver_private;
+
+#ifdef DEBUG
+ db_printf("i82544_poll\n");
+#endif
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG
+ os_printf( "i82544_poll: Bad device pointer %x\n", p_i82544 );
+#endif
+ return;
+ }
+
+ if (!check_link(p_i82544))
+ return;
+
+ // As it happens, this driver always requests the DSR to be called:
+ (void)eth_isr( p_i82544->vector, (cyg_addrword_t)p_i82544 );
+
+ // (no harm in calling this ints-off also, when polled)
+ i82544_deliver( sc );
+}
+
+// ------------------------------------------------------------------------
+// Determine interrupt vector used by a device - for attaching GDB stubs
+// packet handler.
+
+int
+i82544_int_vector(struct eth_drv_sc *sc)
+{
+ struct i82544 *p_i82544;
+ p_i82544 = (struct i82544 *)sc->driver_private;
+ return (p_i82544->vector);
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : pci_init_find_82544s
+//
+// This is called exactly once at the start of time to:
+// o scan the PCI bus for objects
+// o record them in the device table
+// o acquire all the info needed for the driver to access them
+// o instantiate interrupts for them
+// o attach those interrupts appropriately
+// ------------------------------------------------------------------------
+
+static cyg_pci_match_func find_82544s_match_func;
+
+// Intel 82543 and 82544 are virtually identical, with different
+// dev codes
+static cyg_bool
+find_82544s_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+{
+ return ((0x8086 == v) &&
+ ((0x1004 == d) || // 82543
+ (0x100d == d) || // 82543
+ (0x1008 == d) || // 82544
+ (0x1010 == d) || // 82546
+ (0x100e == d) // 82540EM
+ )
+ );
+}
+
+static int
+pci_init_find_82544s( void )
+{
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+ cyg_uint16 cmd;
+ int device_index;
+ int found_devices = 0;
+
+#ifdef DEBUG
+ db_printf("pci_init_find_82544s()\n");
+#endif
+
+ // allocate memory to be used in ioctls later
+ if (mem_reserved_ioctl != (void*)0) {
+#ifdef DEBUG
+ db_printf("pci_init_find_82544s() called > once\n");
+#endif
+ return 0;
+ }
+
+ // First initialize the heap in PCI window'd memory
+ i82544_heap_size = CYGHWR_INTEL_I82544_PCI_MEM_MAP_SIZE;
+ i82544_heap_base = (cyg_uint8 *)CYGHWR_INTEL_I82544_PCI_MEM_MAP_BASE;
+ i82544_heap_free = i82544_heap_base;
+
+// mem_reserved_ioctl = pciwindow_mem_alloc(MAX_MEM_RESERVED_IOCTL);
+
+ cyg_pci_init();
+#ifdef DEBUG
+ db_printf("Finished cyg_pci_init();\n");
+#endif
+
+ devid = CYG_PCI_NULL_DEVID;
+
+ for (device_index = 0;
+ device_index < CYGNUM_DEVS_ETH_INTEL_I82544_DEV_COUNT;
+ device_index++) {
+ struct i82544 *p_i82544 = i82544_priv_array[device_index];
+
+ p_i82544->index = device_index;
+
+ // See above for find_82544s_match_func
+ if (cyg_pci_find_matching( &find_82544s_match_func, NULL, &devid )) {
+#ifdef DEBUG
+ db_printf("eth%d = 8254x\n", device_index);
+#endif
+ cyg_pci_get_device_info(devid, &dev_info);
+
+ p_i82544->interrupt_handle = 0; // Flag not attached.
+ if (cyg_pci_translate_interrupt(&dev_info, &p_i82544->vector)) {
+#ifdef DEBUG
+ db_printf(" Wired to HAL vector %d\n", p_i82544->vector);
+#endif
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ cyg_drv_interrupt_create(
+ p_i82544->vector,
+ 0, // Priority - unused
+ (CYG_ADDRWORD)p_i82544, // Data item passed to ISR & DSR
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82544_DEMUX_ALL
+ eth_mux_isr, // ISR
+#else
+ eth_isr, // ISR
+#endif
+ eth_dsr, // DSR
+ &p_i82544->interrupt_handle, // handle to intr obj
+ &p_i82544->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(p_i82544->interrupt_handle);
+
+ // Don't unmask the interrupt yet, that could get us into a
+ // race.
+#ifdef CYGNUM_DEVS_ETH_INTEL_I82544_SEPARATE_MUX_INTERRUPT
+ // ALSO attach it to MUX interrupt for multiplexed
+ // interrupts. This is for certain boards where the
+ // PCI backplane is wired "straight through" instead of
+ // with a rotation of interrupt lines in the different
+ // slots.
+ {
+ static cyg_handle_t mux_interrupt_handle = 0;
+ static cyg_interrupt mux_interrupt_object;
+
+ if ( ! mux_interrupt_handle ) {
+#ifdef DEBUG
+ db_printf(" Also attaching to HAL vector %d\n",
+ CYGNUM_DEVS_ETH_INTEL_I82544_SEPARATE_MUX_INTERRUPT);
+#endif
+ cyg_drv_interrupt_create(
+ CYGNUM_DEVS_ETH_INTEL_I82544_SEPARATE_MUX_INTERRUPT,
+ 0, // Priority - unused
+ (CYG_ADDRWORD)p_i82544,// Data item passed to ISR and DSR
+ eth_mux_isr, // ISR
+ eth_dsr, // DSR
+ &mux_interrupt_handle,
+ &mux_interrupt_object );
+
+ cyg_drv_interrupt_attach(mux_interrupt_handle);
+ }
+ }
+#endif // CYGNUM_DEVS_ETH_INTEL_I82544_SEPARATE_MUX_INTERRUPT
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ }
+ else {
+ p_i82544->vector=0;
+#ifdef DEBUG
+ db_printf(" Does not generate interrupts.\n");
+#endif
+ }
+
+ if (cyg_pci_configure_device(&dev_info)) {
+#ifdef DEBUG
+ int i;
+ db_printf("Found device on bus %d, devfn 0x%02x:\n",
+ CYG_PCI_DEV_GET_BUS(devid),
+ CYG_PCI_DEV_GET_DEVFN(devid));
+
+ if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
+ db_printf(" Note that board is active. Probed"
+ " sizes and CPU addresses invalid!\n");
+ }
+ db_printf(" Vendor 0x%04x", dev_info.vendor);
+ db_printf("\n Device 0x%04x", dev_info.device);
+ db_printf("\n Command 0x%04x, Status 0x%04x\n",
+ dev_info.command, dev_info.status);
+
+ db_printf(" Class/Rev 0x%08x", dev_info.class_rev);
+ db_printf("\n Header 0x%02x\n", dev_info.header_type);
+
+ db_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+ dev_info.header.normal.sub_vendor,
+ dev_info.header.normal.sub_id);
+
+ for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
+ db_printf(" BAR[%d] 0x%08x /", i, dev_info.base_address[i]);
+ db_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
+ dev_info.base_size[i], dev_info.base_map[i]);
+ }
+ db_printf(" eth%d configured\n", device_index);
+#endif
+ found_devices++;
+ p_i82544->found = 1;
+ p_i82544->active = 0;
+ p_i82544->devid = devid;
+ p_i82544->device = dev_info.device;
+ p_i82544->io_address = dev_info.base_map[0];
+#ifdef DEBUG
+ db_printf(" I/O address = 0x%08x device = %04x\n", dev_info.base_map[0],
+ dev_info.device);
+#endif
+
+ // Don't use cyg_pci_set_device_info since it clears
+ // some of the fields we want to print out below.
+ cyg_pci_read_config_uint16(dev_info.devid,
+ CYG_PCI_CFG_COMMAND, &cmd);
+ cmd |= (CYG_PCI_CFG_COMMAND_IO // enable I/O space
+ | CYG_PCI_CFG_COMMAND_MEMORY // enable memory space
+ | CYG_PCI_CFG_COMMAND_MASTER); // enable bus master
+ cyg_pci_write_config_uint16(dev_info.devid,
+ CYG_PCI_CFG_COMMAND, cmd);
+
+ // Now the PCI part of the device is configured, reset
+ // it. This should make it safe to enable the
+ // interrupt
+ i82544_reset(p_i82544);
+
+ // This is the indicator for "uses an interrupt"
+ if (p_i82544->interrupt_handle != 0) {
+ cyg_drv_interrupt_acknowledge(p_i82544->vector);
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ cyg_drv_interrupt_unmask(p_i82544->vector);
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ }
+#ifdef DEBUG
+ db_printf(" **** Device enabled for I/O and Memory "
+ "and Bus Master\n");
+#endif
+ }
+ else {
+ p_i82544->found = 0;
+ p_i82544->active = 0;
+#ifdef DEBUG
+ db_printf("Failed to configure device %d\n",device_index);
+#endif
+ }
+ }
+ else {
+ p_i82544->found = 0;
+ p_i82544->active = 0;
+#ifdef DEBUG
+ db_printf("eth%d not found\n", device_index);
+#endif
+ }
+ }
+
+ if (0 == found_devices)
+ return 0;
+
+#ifdef CYGNUM_DEVS_ETH_INTEL_I82544_SEPARATE_MUX_INTERRUPT
+ // Now enable the mux shared interrupt if it is in use
+ if (mux_interrupt_handle) {
+ cyg_drv_interrupt_acknowledge(CYGNUM_DEVS_ETH_INTEL_I82544_SEPARATE_MUX_INTERRUPT);
+ cyg_drv_interrupt_unmask(CYGNUM_DEVS_ETH_INTEL_I82544_SEPARATE_MUX_INTERRUPT);
+ }
+#endif
+
+ // Now a delay to ensure the hardware has "come up" before you try to
+ // use it. Yes, really, the full 2 seconds. It's only really
+ // necessary if DEBUG is off - otherwise all that printout wastes
+ // enough time. No kidding.
+ udelay( 2000000 );
+ return 1;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82544_configure
+//
+// Return : 0 = It worked.
+// non0 = It failed.
+// ------------------------------------------------------------------------
+
+static int i82544_configure(struct i82544* p_i82544, int promisc, int oversized)
+{
+ cyg_uint32 ioaddr;
+// volatile CFG *ccs;
+// volatile cyg_uint8* config_bytes;
+// cyg_uint16 status;
+// int count;
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG
+ os_printf( "eth_set_promiscuous_mode: Bad device pointer %x\n",
+ p_i82544 );
+#endif
+ return -1;
+ }
+
+ ioaddr = p_i82544->io_address;
+
+ // Not currently supported
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : eth_set_mac_address
+//
+// Return : 0 = It worked.
+// non0 = It failed.
+// ------------------------------------------------------------------------
+
+static int
+eth_set_mac_address(struct i82544* p_i82544, cyg_uint8 *addr, int eeprom)
+{
+ cyg_uint32 ioaddr;
+ cyg_uint32 maclo, machi;
+
+#ifdef DEBUG
+ db_printf("eth_set_mac_address\n");
+#endif
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG
+ os_printf( "eth_set_mac_address : Bad device pointer %x\n",
+ p_i82544 );
+#endif
+ return -1;
+ }
+
+ ioaddr = p_i82544->io_address;
+
+ // Write MAC address to RAT[0]
+
+ maclo = addr[0] | (addr[1]<<8) | (addr[2]<<16) | (addr[3]<<24);
+ machi = (1<<31) | (0<<16) | addr[4] | (addr[5]<<8);
+
+#ifdef DEBUG
+ os_printf("setting: lo %08x hi %08x\n",maclo,machi);
+#endif
+
+ OUTL( maclo , ioaddr + I82544_RAT );
+ OUTL( machi, ioaddr + I82544_RAT + 4 );
+
+
+ // record the MAC address in the device structure
+ p_i82544->mac_address[0] = addr[0];
+ p_i82544->mac_address[1] = addr[1];
+ p_i82544->mac_address[2] = addr[2];
+ p_i82544->mac_address[3] = addr[3];
+ p_i82544->mac_address[4] = addr[4];
+ p_i82544->mac_address[5] = addr[5];
+ p_i82544->mac_addr_ok = 1;
+
+#ifdef DEBUG
+ os_printf( "Set MAC Address = %02X %02X %02X %02X %02X %02X (ok %d)\n",
+ p_i82544->mac_address[0],
+ p_i82544->mac_address[1],
+ p_i82544->mac_address[2],
+ p_i82544->mac_address[3],
+ p_i82544->mac_address[4],
+ p_i82544->mac_address[5],
+ p_i82544->mac_addr_ok );
+#endif
+
+ return p_i82544->mac_addr_ok ? 0 : 1;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : eth_get_mac_address
+//
+// ------------------------------------------------------------------------
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+static int
+eth_get_mac_address(struct i82544* p_i82544, char *addr)
+{
+#ifdef DEBUG
+ db_printf("eth_get_mac_address\n");
+#endif
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG
+ os_printf( "eth_get_mac_address : Bad device pointer %x\n",
+ p_i82544 );
+#endif
+ return -1;
+ }
+
+ memcpy( addr, (char *)(&p_i82544->mac_address[0]), 6 );
+ return 0;
+}
+#endif
+// ------------------------------------------------------------------------
+//
+// Function : i82544_ioctl
+//
+// ------------------------------------------------------------------------
+static int
+i82544_ioctl(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ struct i82544 *p_i82544;
+
+#ifdef DEBUG
+ db_printf("i82544_ioctl\n");
+#endif
+
+ p_i82544 = (struct i82544 *)sc->driver_private;
+
+ IF_BAD_82544( p_i82544 ) {
+#ifdef DEBUG
+ os_printf( "i82544_ioctl/control: Bad device pointer %x\n", p_i82544 );
+#endif
+ return -1;
+ }
+
+#ifdef ioctlDEBUG
+ db_printf( "i82544_ioctl: device eth%d at %x; key is 0x%x, data at %x[%d]\n",
+ p_i82544->index, p_i82544, key, data, data_length );
+#endif
+
+ switch ( key ) {
+
+#ifdef ETH_DRV_SET_MAC_ADDRESS
+ case ETH_DRV_SET_MAC_ADDRESS:
+ if ( 6 != data_length )
+ return -2;
+ return eth_set_mac_address( p_i82544, data, 1 /* do write eeprom */ );
+#endif
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ return eth_get_mac_address( p_i82544, data );
+#endif
+
+ default:
+ break;
+ }
+ return -1;
+}
+
+// ------------------------------------------------------------------------
+
+// EOF if_i82544.c
diff --git a/ecos/packages/devs/eth/intel/i82559/current/ChangeLog b/ecos/packages/devs/eth/intel/i82559/current/ChangeLog
new file mode 100644
index 0000000..d4ef92f
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i82559/current/ChangeLog
@@ -0,0 +1,833 @@
+2007-06-12 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/if_i82559.c (eth_dsr): Fixed the previous change which broken
+ linkage under some conditions.
+
+2006-11-23 David Fernandez <dfernandez@cct.co.uk>
+
+ * src/if_i82559.c Modifications to remove compile warnings.
+
+2005-01-22 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/if_i82559.c Added string.h to remove compiler warnings.
+
+2004-08-12 Jani Monoses <jani@iv.ro>
+
+ * src/if_i82559.c: Fix builing with lwip.
+
+2004-01-15 Jeff Daly <jeffrey.daly@intel.com>
+
+ * src/if_i82559.c: support for large EEPROMs
+
+2004-01-05 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_i82559.c: Names of FLASH config types changed.
+
+2003-02-27 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82559.c (eth_set_mac_address): Correct writing
+ of wrong address to EEPROM.
+
+2003-02-22 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82559.c: Fix endian issues with EEPROM writing.
+ Use read-modify-write to set EEPROM mac address. Support
+ writing to EEPROM the mac address obtained from
+ CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA.
+
+2003-02-12 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82559.c: Remove restriction preventing combination of
+ *_GET_ESA and *_HAS_EEPROM.
+
+2003-01-03 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_i82559.c:
+ * cdl/intel_i82559_eth_drivers.cdl: Allow finer control over
+ debug (chatter) by making control booldata.
+
+2002-12-17 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82559.c (CYGHWR_DEVS_ETH_INTEL_I82559_ENDIAN_NEUTRAL_IO): New
+ flag to support systems where PCI IO operations are not affected by
+ CPU endianess.
+
+2002-10-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/if_i82559.c (pci_init_find_82559s): Changed scope of
+ max_interrupt_handle since its needed in other places.
+ * src/if_i82559.c (i82559_stop): Corrected wrong name of variable
+ in a diag_printf function.
+
+2002-07-24 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_i82559.c (pci_init_find_82559s):
+ Allow platform to define CYGHWR_DEVS_ETH_INTEL_I82559_USE_MEMORY
+ which forces use of memory instead of I/O space for device access.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_i82559.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-04-09 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (i82559_stop): Free up any pending transmissions
+ to prevent MBUF store leaks if the calling thread - the one that's
+ shutting down the interface - priority ends up higher than (or
+ same as) the network service threads.
+
+2002-03-26 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_i82559.c (wait_for_cmd_done): Don't assert if RUC_ADDR_LOAD
+ command doesn't clear - on some chips it never does.
+
+2002-03-18 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (pci_init_find_82559s): Move allocation of
+ statistics pointer for each device to here, out of
+ i82559_start(). It used to leak PCI window store every time the
+ interface cycled down/up. [Case 107110]
+
+2002-02-25 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82559.c: Don't call PacketRxReady in standalone configuration
+ unless ready to accept a packet. Limit packet delivery to one packet at
+ a time in standalone configuration.
+
+2002-02-20 Hugo Tyson <hmt@redhat.com>
+
+ * include/i82559_info.h: New fields to record/control multicast
+ all reception, oversized packet reception and promiscuous mode
+ neatly.
+
+ * src/if_i82559.c: Initial support for multicast address reception
+ filtering.
+ (i82559_restart): New routine to restart the device after fiddling
+ with its setup - a tail recursion from i82559_start().
+ (i82559_configure): More generic flags passed in and handled.
+ (i82559_set_multicast): Routine to pass a set of addresses into
+ the device; it works out the bitmap et al for us!
+ (i82559_ioctl): Handle new case arms ETH_DRV_SET_MC_LIST and
+ ETH_DRV_SET_MC_ALL if defined. Reset and restart the device,
+ diddling its status between.
+
+2002-02-19 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82559.c (pci_init_find_82559s): Don't use IRQ support if
+ CYGPKG_IO_ETH_DRIVERS_STAND_ALONE.
+
+2002-01-28 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82559.c (pci_init_find_82559s): Removed CYG_ASSERT which
+ assumed system PCI window exists.
+
+2002-01-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_i82559.c (find_82559s_match_func): Add some more compatible PCI
+ ids.
+
+2002-01-03 Mark Salter <msalter@redhat.com>
+
+ * src/if_i82559.c (pci_init_find_82559s): Remove check that
+ assumes driver owns entire PCI window.
+
+ * cdl/intel_i82559_eth_drivers.cdl: Add
+ CYGNUM_DEVS_ETH_INTEL_I82559_MAX_TX_DESCRIPTORS and
+ CYGNUM_DEVS_ETH_INTEL_I82559_MAX_RX_DESCRIPTORS.
+
+2001-11-19 Hugo Tyson <hmt@redhat.com>
+2001-11-19 Anssi Pulkkinen <Anssi.Pulkkinen@ascom.ch>
+
+ * src/if_i82559.c (TxMachine): The test to see if there is a new
+ tx to start must also say "go" if the tx queue is full. Normally,
+ if the txqueue is full, a tx will be occurring at all times - so
+ one will complete soon, so the tx queue full flag will soon be
+ cleared, and this condition will recover. I suspect a subtle race
+ which effectively means a new tx is queued and fills the queue in
+ between two tx's, so no TxDone() follows, causes the hang which we
+ get without this extra test under high load. [CASE 106686]
+
+2001-09-20 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_i82559.c: Add declaration of 'i82559_stop' to quiet warning.
+
+2001-09-13 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/intel_i82559_eth_drivers.cdl:
+ * src/if_i82559.c:
+ Remove the tickle thread from this driver. The functionality is
+ now in the network timeout functionality which handles the
+ "deliver" calls. So it's only called if the net is quiet.
+
+2001-09-12 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (TxDone): Defensive programming; zero the Tx key
+ in the global data before making the callback. This change
+ appeared useful in our forebear, the EBSA-specific driver.
+
+2001-08-29 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/intel_i82559_eth_drivers.cdl: New CDL options called
+ CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD, .._PRIORITY and
+ .._DELAY to control the thread. By default this is all disabled
+ because it is not needed for a real network application which
+ itself proactively tries to use the net - it's only needed when
+ the app is totally passive, so the driver otherwise does not get
+ CPU time at all.
+
+ * src/if_i82559.c (starti82559ticklethread): New code to start a
+ thread (!) to catch lost interrupts and thus restart jammed
+ hardware. It's only possible if KERNEL and NET - RedBoot is
+ unaffected, and it's not needed for RedBoot 'cos RedBoot polls.
+ (TxMachine): An assert about the CU idle status sometimes fired;
+ made the code more conservative wrt timing here.
+ (comments): more documentation on the possible external configury
+ by .inl file, described the two TIMEOUT macros that can be set,
+ and indeed must be to use the tickling thread meaningfully.
+
+2001-08-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_i82559.c:
+ printf() is no longer a part of RedBoot. Thus all programs
+ must use diag_printf() and related functions instead.
+
+2001-06-22 Jesper Skov <jskov@redhat.com>
+
+ * src/if_i82559.c (i82559_init): Handle EEPROMS without CRC.
+
+2001-05-16 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_i82559.c (udelay): Use virtual vector rather than assuming
+ hal_delay_us() exists.
+
+2001-04-09 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (pciwindow_mem_alloc): If asked, by
+ CYGHWR_DEVS_ETH_INTEL_I82559_PCIMEM_DISCONTIGUOUS, check for
+ breaks in the physical address of PCI window memory, and discard
+ any block with a break in it, then redo the alloc. This is for
+ targets where smaller SDRAM chips are fitted than the address
+ width, so they end up with gaps in (physical) memory.
+
+2001-04-09 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (i82559_init): Support hardware with only one
+ serial EEPROM attached to one device, but multiple devices. This
+ generally involves moving some decisions for eg. programming
+ EEPROM or not, optionally from compiletime to runtime. Improved
+ the diagnostics a bit also, and fixed some bugs.
+ (eth_set_mac_address): now takes an arg to say whether we want to
+ program the EEPROM, or are just setting up the chip.
+ (i82559_ioctl): This is the only place we set that arg to write
+ the EEPROM, startup never tries to write EEPROM from any external
+ source such as configured ESA or RedBoot params.
+
+2001-04-09 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (i82559_start): Warnings fixed; unused vars
+ following previous change.
+
+2001-04-09 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (i82559_start): Do not wait for command
+ completion after the initial DUMPSTATS operation. The code to
+ wait was bogus; it was looking at the structure in the wrong way.
+ In any case, there is no need to wait, the wait_for_cmd_done() in
+ any following activity is good enough.
+
+2001-03-28 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (update_statistics): Fix warning - only declare
+ op_i82559 if we use it - from previous change.
+
+2001-03-23 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (i82559_can_send, i82559_send): Count up and
+ down entries into these routines, and always say "no" to
+ can_send() if we are recursing, ie. within_send != 0. This is a
+ good idea because it limits stack usage. The recursion happens
+ because of the very neccessary polling of rx state within the tx
+ routines - which can deliver packets up into the stack, which can
+ trigger a response tx and so on... Also fixed a harmless bug
+ where, after polling, the p_i82559 current device state pointer
+ pointer to the wrong device, if we polled both devs regardless; it
+ only caused problems with the within_send recursion count.
+
+ * include/i82559_info.h (I82559): Add within_send field.
+
+2001-03-15 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (i82559_init): Support external macro
+ CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA(...), which if defined, is
+ used to acquire a MAC address, on the assumption that there is no
+ EEPROM present. CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+ confirms that there is no EEPROM attached to the 82559(s) so we
+ can omit all that code. It's in the negative sense because it's
+ the unusual case.
+
+2001-03-13 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL): Fully
+ enable "DEMUX_ALL" option; all devices are scanned for
+ activity/wedging/interrupts at every opportunity. Multiple
+ devices on the same interrupts are now supported.
+
+2001-03-12 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c (i82559_configure): New routine combines actions
+ of eth_set_promiscuous_mode() and eth_set_config() both of which
+ disappear. Thus the device is always configured correctly from
+ the start. [from a patch from Martin Buck <martin.buck@ascom.ch>
+ via the EBSA285 driver]
+ (eth_dsr): Do not call upper layer unless we are in a networked
+ [non-RedBoot, non-polled] environment. This is necessary because
+ we call our own DSR from foreground to unstick after a lost
+ interrupt.
+ (find_82559s_match_func): New routine to discover disparate
+ devices on the PCI bus. Used in pci_init_find_82559s().
+ (dump_txcb): Various junk debug functions removed.
+
+2001-03-12 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c: Some tidying up, and two main additions to the
+ mechanisms used for managing this nasty entomological device.
+ (i82559_can_send): [amongst other places] if it is defined, use
+ CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT(p_i82559) to detect
+ that we missed an interrupt - and if so, call the ISR and DSR
+ directly. This is necessary for edge-triggered interrupt
+ controllers being fed by this level-sending device, where an
+ internal event in the device can keep the line low after the code
+ thinks that all events have been handled.
+ (Check82559TxLockupTimeout): This routine runs a timeout (if the
+ HAL provides a pair of watchdog-like macros) which performs a
+ selective reset of the device if it takes too long to transmit.
+ This happens rarely, but when it happens this is the only way out;
+ the tx machine is fixated on one tx and never comes out of it.
+
+
+ Sadly these two techniques to escape lockup only work if the
+ driver is called (ie. the stack tries to tx); incoming packets
+ cannot unwedge a device. We might need to add a poll from the
+ stack in future if this causes problems.
+
+ * include/i82559_info.h (I82559): Added two words for managing tx
+ lockup timeouts since this must be per-device.
+
+2001-03-02 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c: Remove "Platform specific - defaults provided"
+ definitions for CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE/SIZE; all
+ platforms now provide these.
+ Added a little further disclaimer to the comment about LE/BE/GE.
+
+2001-03-01 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c: Global change: what was HAL_READ_UINTxx or
+ HAL_WRITE_UINTxx are now READMEMxx or WRITEMEMxx - just
+ convenience macros that do all the volatile casts we want there.
+ Definitions of INL, INW, INB and OUTL, OUTW, OUTB recast in terms
+ of HAL_READ_UINTxx or HAL_WRITE_UINTxx so that they will use
+ proper IO operations on those CISCy mainframes that have a special
+ way of doing IO.
+
+2001-03-01 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_i82559.c: Much more configury added, so that I can use it
+ with a new target board. Including, but not limited to:
+
+ o An essay about addressing, big endian, little endian and GIB
+ endian (sic) and how we treat the various types of access within
+ this module. In other words, a lot of comments.
+
+ o CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT to clarify
+ that such an interrupt is SEPARATE from any simplex intrs that are
+ also available.
+
+ o CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL for hardware where the
+ the only interrupt is a multiplexed (wire or'd) one. Plus
+ associated macros for direct manipulation of interrupt masks and
+ acknowledgments.
+
+ o Support for external definition from the platform HAL or driver
+ config module of CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE and SIZE.
+ Also CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS.
+
+ o LE definitions of a few macros that were missing.
+
+ o Separated definitions of structure offsets from BE/LE
+ definitions of consts within the words. Offsets vary with GIB
+ endian, for those CPUs who just flip bits. No change for BE
+ machines, needed for LE machines to work. To enable address-flip
+ within structures, define CYG_ADDRESSING_IS_GIBENDIAN.
+
+ o Re-org of mux/simplex deliver and isr's for new configuration.
+
+ o Couple of extra debug printouts.
+
+2001-01-26 Jesper Skov <jskov@redhat.com>
+
+ * src/if_i82559.c: Added FIXME for promiscuous mode.
+
+2001-01-25 Jesper Skov <jskov@redhat.com>
+
+ * src/if_i82559.c: Replace CYGNUM_HAL_INTERRUPT_PCI_IRQ with
+ CYGNUM_DEVS_ETH_INTEL_I82559_MUX_INTERRUPT which platform .inl
+ must provide when appropriate. Changed _deliver functions to match
+ _isr functions.
+ * include/i82559_info.h: Remove debug hacks.
+ Fix declaration.
+
+ * src/if_i82559.c: Moved device descriptors into platform header.
+ Allow individual devices to hardwire ESA. Handle N devices instead
+ of just 1 or 2.
+ * include/i82559_info.h: ESA hardwired flag added.
+ * cdl/intel_i82559_eth_drivers.cdl: Device details moved to
+ platform CDL.
+
+ * src/if_i82559.c (i82559_start): Poll status after dump command.
+
+2001-01-24 Jesper Skov <jskov@redhat.com>
+
+ * src/if_i82559.c: [changes from yesterday] Some more endian
+ fiddle, and the device coughs out the initial ARP packets.
+ (wait_for_cmd_done): semantics changed to wait for pending CU
+ cmds.
+ (i82559_reset): Cleaned up to spec. Init register bases after
+ reset.
+ Fix initialization of hardwired ESA.
+ Correct configuration command.
+ Fix rcv len masking.
+ (eth_set_mac_address): Set driver's ESA as well. Proper check for
+ completion.
+ Fix LE structure offsets.
+ (i82559_start): Call new eth_set_config to enable device. Last
+ hacks cleaned up.
+ Remove a few printfs.
+
+2001-01-23 Jesper Skov <jskov@redhat.com>
+
+ * src/if_i82559.c: Debug hackery and some endian issues resolved.
+
+2001-01-22 Jesper Skov <jskov@redhat.com>
+
+ * src/if_i82559.c: Major changes, getting rid of device structures
+ in favor of HAL IO accessor macros. Also added endian conversion
+ macros where required.
+ * include/i82559_info.h: Change type of device structures to char.
+
+2001-01-19 Jesper Skov <jskov@redhat.com>
+
+ * cdl/intel_i82559_eth_drivers.cdl: Hack for just one interface
+ now.
+ * src/if_i82559.c: Fix IO functions. Handle EEPROM not being
+ attached to device.
+
+ * src/if_i82559.c: Use uncached/physical address translation
+ macros.
+
+2001-01-15 Jesper Skov <jskov@redhat.com>
+
+ * src/if_i82559.c: Handle endian differences between controller
+ and CPU. Leave usdelay to HAL. Hack around PCI-base-at-0
+ assumption.
+ Increase SK_DELAY (not that it changed anything, but now it's to
+ the spec), hardwire static ESA.
+
+2001-01-12 Jesper Skov <jskov@redhat.com>
+
+ * src/if_i82559.c (pci_init_find_82559s): Check that device has
+ been found before accessing it.
+ (pci_init_find_82559s): Only delay if devices were
+ found. Recognize 82559ER code as well.
+
+2001-01-10 Jesper Skov <jskov@redhat.com>
+
+ * src/if_i82559.c: Minor hacks to get it to build.
+ * include/i82559_info.h: Same.
+ * cdl/intel_i82559_eth_drivers.cdl: Same.
+
+2000-12-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/intel_i82559_eth_drivers.cdl: Cloned from the EBSA driver.
+ * include/i82559_info.h: Same.
+ * src/if_i82559.c: Same.
+
+2000-11-19 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_ebsa285.c (pci_init_find_82559s): Intel has at least
+ two devices equivalent to the 82559. Support both (0x1229, 0x01030).
+
+2000-10-05 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_ebsa285.c: Deal with device interrupts in a nested
+ fashion - disable/restore is the semantics now, rather than
+ unconditionally unmasking. Also go directly to the 21285 PIC's
+ interrupt control registers to gain atomicity for these. Poll for
+ ready received packets when acknowledging an interrupt in the
+ tranmitting world; a race here could lose an Rx interrupt. Which
+ doesn't matter on a busy system, but in quieter times... there
+ will always be such a race because of the vague way the i82559's
+ status bits reflect how it's yanking the interrupt line; you have
+ to poll until the interrupt is gone before returning else spurious
+ interrupt failures occur. The issue is to close the window as
+ tightly as possible, which this change achieves at a minor cost in
+ performance - because of the time spent polling when not required.
+
+2000-09-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_poll): Only diddle the interface we
+ were asked to. This is more correct in terms of the intent of the
+ API, though it shouldn't really be necessary.
+
+2000-09-06 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (pci_init_find_82559s): Add asserts and an
+ unconditional check that the PCI window as configured matches the
+ address and size of the pci_window region from the MLT. This is
+ here because at present the MLT and CT cannot intercommunicate
+ enough. The separation of the PCI window is needed because
+ otherwise the malloc heap will eat all memory. [This is related
+ to CR 902624-CR, "MLT needs to be configuration aware"]
+
+2000-09-01 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * OVERVIEW: This is part of the change to the network stack to
+ greatly reduce latencies both of (other) DSRs and of thread
+ scheduling. All the work that the network stack *and* individual
+ ether drivers used to do in DSRs (including alarm callbacks and
+ data copies to/from the device memory) is moved into a "fast
+ network thread" instead. It calls a device's "deliver" function
+ to do the work that was previously in the DSR. This is a separate
+ thread so that it can be set higher priority than application
+ threads in order to minimize packet loss (depending on the
+ driver), if required (the application threads presumed to be
+ higher priority in turn than the network thread). A crucial
+ consequence of this is that we are no longer locking against DSRs,
+ so a plain mutex can be used rather than the global scheduler
+ lock, thus simplifying all the splfoo/splx() style functions.
+
+ * src/if_ebsa285.c: Minor: fix the big assert in i82559_send()
+ which suffered a race condition when called from the fast thread
+ rather than from a DSR. Major: Add a "deliver" entry to the
+ interface record for the "fast thread" implementation of the
+ network internal comms system. Provide a pass-up DSR to the
+ logical ether driver's DSR and appropriate delivery routine(s).
+ i82559_poll() now calls i82559_deliver() rather than the DSR. Add
+ valid data for mux'd DSR to pass on up.
+
+2000-09-01 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/test_net_realtime.h: Tighten up the latency requirements
+ by a factor of 5; it all seems happy, so committed.
+
+2000-08-25 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_ioctl): A little further diddling; have
+ a bool to say whether the dot3 info is filled in.
+
+2000-08-24 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Do not export a symbol for the
+ device info file (include/ebsa285_info.h) since nobody needs
+ (portably) to include it now.
+
+ * src/if_ebsa285.c (i82559_ioctl): Handle new ioctl calls
+ ETH_DRV_GET_IF_STATS_UD and ETH_DRV_GET_IF_STATS to get loads of
+ statistical information out. _UD means update. The nonUD one can
+ be used instead mostly, if we find the performance hit too large.
+ This should allow SNMP (a) to not explode, (b) to get useful info
+ out of other device implementations than this one.
+
+ * include/ebsa285_info.h: Remove all the macro cruft for feature
+ detecting of lots of individual statistics; we now just have a
+ catch-all struct that SNMP uses, defined in the common ether
+ driver environment.
+
+2000-08-15 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (PacketRxReady): Put back the check for very
+ small packets into the driver; the layer above checks for that
+ (defensive programming) but only *after* asserting that the size
+ is large enough, to help detect that scenario from other drivers.
+ I believe we only have struct ether_header available if CYGPKG_NET
+ but I could be wrong.
+ [CASE 104353]
+
+2000-08-08 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (eth_set_promiscuous_mode):
+ - ccs->config_bytes[18]=0x70;
+ + ccs->config_bytes[18]=0x72; // Keep the Padding Enable bit
+ ...otherwise short frame sends don't work in promisc mode.
+ [CASE 104289]
+
+2000-08-07 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_ebsa285.c (pciwindow_mem_alloc): Take out very noisy debug.
+
+2000-08-03 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_ebsa285.c: Changes for stand-alone mode.
+
+ * cdl/ebsa285_eth_drivers.cdl: Ethernet driver package hierarchy changed.
+ Add option to control number of interfaces.
+
+2000-07-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (PacketRxReady): Do not attempt to forward
+ short packets; eth_drv.c assumes there is at least a header there.
+ (i82559_recv): Also be more careful and ASSERTive about -ve buffer
+ sizes; be more defensive about sglists. [CASE 104206]
+
+2000-07-26 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_ebsa285.c: Update for new eth_drv interfaces.
+
+2000-07-18 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_poll): Fill in the flesh of this, it
+ just calls ISR and DSR repeatedly.
+ (i82559_start): Look in the device record for promiscuous mode
+ flag; it should be passed though the common layer, but it's not
+ [yet] - this change from Andrew Lunn/ASCOM. Also a fix and delay
+ to the promisc mode code per se.
+
+2000-07-17 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_poll): New function, just to fill in
+ the interface record; not used.
+
+2000-06-27 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Add sesquipedalian option
+ CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS in (now)
+ component CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_STATISTICS to control
+ keeping (well, harvesting really) the i82559's internal stats.
+ Reputedly, it doesn't service the net whilst this is happening, so
+ it could be viewed a bad thing. Hence the option.
+
+ * include/ebsa285_info.h: Only describe the I82559_COUNTERS
+ i82559_counters[2]; structs if full stats are to be kept.
+
+ * src/if_ebsa285.c (update_statistics): Only include this if full
+ stats are to be kept.
+
+2000-06-27 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (ResetRxRing): Re-do the management of the
+ RxRing; have an end-of-list flag (EL) in the last entry, and as
+ you unload filled slots, drag it round after you.
+
+2000-06-14 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Add option to control statistics
+ keeping.
+
+ * include/ebsa285_info.h: Act on it.
+
+2000-06-13 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Properly include the new header
+ file and define symbols to allow client code to get at it without
+ knowing the particular device driver name.
+
+ * include/ebsa285_info.h: New file: export various statistics
+ information about the driver for use by monitoring and
+ network-management systems. This requires exposing the
+ (otherwise) internal structures of the driver.
+
+ * src/if_ebsa285.c: remove a lot of structure definitions &c that
+ are now necessarily in the new header; add a couple of new
+ routines which provide status and update statistics from the
+ device into memory; tidy up control of whether stats-keeping is
+ enabled.
+
+2000-06-06 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl (define_proc): Add #define of
+ CYGDAT_DEVS_ETH_DESCRIPTION in the config file for information.
+
+2000-05-12 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/test_net_realtime.h (tnr_print_activity): New routine to
+ check the system is working, tidied up the API. It works!
+
+2000-05-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Added export of the test header
+ below, and config opts for controlling EEPROM writing and all the
+ status chatter as the device starts up.
+
+ * src/if_ebsa285.c: Reworked the code for reading and setting the
+ EEPROM that holds the MAC address. This is very ugly, but now
+ more reliable. Also tidied up printing cruft with neater
+ configury, and made it an option (for safety) whether it's
+ possible to write the EEPROM at all.
+
+ * tests/test_net_realtime.h: New file - it is intended to be used
+ by networking tests to verify that latency is not compromised by
+ the stack and driver. It's very platform specific, hence the
+ location in here. This is a preliminary version only.
+
+2000-04-27 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c: A serious re-write. This cuts out a lot of
+ code from the old version and improves the performance greatly.
+
+ The cruft was mainly doing lots of explicit event communication
+ between the ISR and DSR, when in fact all the state needed is
+ present in the tx/rx rings. So both ISRs and DSRs regard their
+ call as an opportunity to progress everything they can, rather
+ than only dealing with one interrupt cause at a time; the
+ connection between them is now rather looser.
+
+ Interrups can now be re-enabled after the ISR (in other words they
+ are not masked in the ISR), no need to wait for the DSR, but in
+ consequence some DSR code must mask/unmask intrs as it works.
+
+ The 82559 appears to be a little slow in reacting to commands and
+ state changes, so some interrupts were being lost - or persisting
+ beyond their desired life - so there's some kinda polling code to
+ deal with that also. We also rely on the foreground to kind of
+ poll in the same way, in the send/can_send calls - we know the
+ stack will re-try if necessary, though this is rare.
+
+ The driver now works (albeit at much reduced performance) with as
+ few as 6 rx and tx buffers - in other words the "queue full/out of
+ rx buffers" states have been tested and all is well. It works
+ generally fine with 8 buffers of each kind.
+
+ The mux ISR and DSR are now rather more polled than the old
+ versions; we just try to do things with both devices (if active)
+ by simply calling each unitary ISR/DSR respectively.
+
+ I also re-ordered some of the code, moving utilities to the end of
+ the file and grouping together Tx and Rx machines a bit better.
+
+2000-04-13 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c: Attribution to Ron Spence, Pacific Softworks
+ added as a contributor.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-03-29 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_recv): Be happy with NULLs in the
+ SGlist; it means the caller is out of memory so drop the packet on
+ the floor. Also remove a completely redundant test.
+
+2000-03-06 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (i82559_can_send): Update net driver to new
+ interface style. This is incomplete wrt promiscuous mode, but
+ that's probably about all.
+
+2000-02-14 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl: Update CDL to indicate multiple
+ interface support.
+
+2000-02-14 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (pci_init_find_82559s): Tidy comments somewhat
+ and set debug and stats collecting defines to most friendly
+ settings.
+
+2000-02-10 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c (PacketRxReady): Fix bug; current descriptor
+ was not being write back for the callback to use. Hence asserts
+ on state of rfd were firing in busy times - that leading rfd had
+ already been drained.
+
+ Also rationalized meaning of DEBUG printy symbols a bit - it's now
+ chatty during startup/foreground manipulations but not in any
+ performance related activities ie. rx or tx.
+
+2000-02-09 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/ebsa285_eth_drivers.cdl:
+
+ Reparent under CYGPKG_NET_ETH_DRIVERS and tidy display strings.
+
+2000-02-08 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_ebsa285.c: New File.
+ * cdl/ebsa285_eth_drivers.cdl: New File.
+
+ Initial Checkin of EBSA285 Ethernet driver.
+
+ It's one monolithic file at present, and should be split up into a
+ more generic Intel 82559 driver plus platform-specific parts (PCI
+ et al) plus eCos/Red-Hat-BSD-stack parts.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/intel/i82559/current/cdl/intel_i82559_eth_drivers.cdl b/ecos/packages/devs/eth/intel/i82559/current/cdl/intel_i82559_eth_drivers.cdl
new file mode 100644
index 0000000..33b1bdf
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i82559/current/cdl/intel_i82559_eth_drivers.cdl
@@ -0,0 +1,186 @@
+# ====================================================================
+#
+# intel_i82559_eth_drivers.cdl
+#
+# Intel 82559 ethernet driver
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): hmt
+# Original data: hmt
+# Contributors: hmt, gthomas, jskov
+# Date: 2000-02-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_INTEL_I82559 {
+ display "Intel 82559 ethernet driver"
+ description "Ethernet driver for Intel 82559 controller."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ active_if CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+ implements CYGINT_IO_ETH_MULTICAST
+
+ include_dir cyg/devs/eth
+
+ # SNMP demands to know stuff; this sadly makes us break the neat
+ # abstraction of the device having nothing exported.
+ include_files include/i82559_info.h
+ # and tell them that it is available
+ define_proc {
+ puts $::cdl_system_header \
+ "#define CYGBLD_DEVS_ETH_DEVICE_H <pkgconf/devs_eth_intel_i82559.h>"
+
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_INTEL_I82559_CFG";
+ }
+
+ compile -library=libextras.a if_i82559.c
+
+ cdl_option CYGDBG_DEVS_ETH_INTEL_I82559_CHATTER {
+ display "Prints ethernet device status info during startup"
+ flavor booldata
+ default_value 0
+ description "
+ Definining this will cause the ethernet device initialization code
+ to print lots of info
+ to confirm that it has found the devices on the PCI bus, read
+ the MAC address from EEPROM correctly, and so on, and also
+ displays the mode (10/100MHz, half/full duplex) of the
+ connection. If the value is set higher than one then
+ additional information about each packet sent will be printed."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT {
+ display "Number of supported interfaces."
+ calculated { CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED }
+ flavor data
+ description "
+ This option selects the number of PCI ethernet interfaces to
+ be supported by the driver."
+ }
+
+ cdl_component CYGDBG_DEVS_ETH_INTEL_I82559_KEEP_STATISTICS {
+ display "Keep Ethernet statistics"
+ default_value 1
+ description "
+ The ethernet device can maintain statistics about the network,
+ specifically a great variety of error rates which are useful
+ for network management. SNMP for example uses this
+ information. There is some performance cost in maintaining
+ this information; disable this option to recoup that."
+
+ cdl_option CYGDBG_DEVS_ETH_INTEL_I82559_KEEP_82559_STATISTICS {
+ display "Keep i82559 Internal statistics"
+ default_value 1
+ description "
+ The i82559 keeps internal counters, and it is possible to
+ acquire these. But the i82559 (reputedly) does not service
+ the network whilst uploading the data to RAM from its
+ internal registers. If throughput is a problem, disable
+ this option to acquire only those statistics gathered by
+ software, so that the i82559 never sleeps."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_INTEL_I82559_WRITE_EEPROM {
+ display "SIOCSIFHWADDR records MAC address in EEPROM"
+ default_value 0
+ description "
+ The ioctl() socket call with operand SIOCSIFHWADDR sets the
+ interface hardware address - the MAC address or ethernet
+ address. This option causes the new MAC address to be written
+ into the EEPROM associated with the interface, so that the new
+ MAC address is permanently recorded. Doing this should be a
+ carefully chosen decision, hence this option."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_INTEL_I82559_MAX_RX_DESCRIPTORS {
+ display "Maximum number of RX descriptors"
+ flavor data
+ default_value { CYGPKG_REDBOOT ? 4 : 128 }
+ define MAX_RX_DESCRIPTORS
+ description "
+ An RX descriptor is used for each ethernet frame required
+ to be passed to the upper networking layers. This option
+ sets the maximum number of these. Higher numbers use more
+ memory, lower numbers will reduce performance. The system
+ appears to work OK with as few as 8 descriptors but limps
+ painfully with only 4. Performance is better with more than
+ 8, but assuming the size of non-cached (so useless for anything
+ else) memory window is 1Mb, we might as well use it all.
+ 128 RX and TX descriptors uses the whole 1Mb, near enough."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_INTEL_I82559_MAX_TX_DESCRIPTORS {
+ display "Maximum number of TX descriptors"
+ flavor data
+ default_value { CYGPKG_REDBOOT ? 4 : 128 }
+ define MAX_TX_DESCRIPTORS
+ description "
+ A TX descriptor is used for each ethernet frame passed down
+ from upper networking layers for transmission. This option
+ sets the maximum number of these. Higher numbers use more
+ memory, lower numbers will reduce performance. The system
+ appears to work OK with as few as 8 descriptors but limps
+ painfully with only 4. Performance is better with more than
+ 8, but assuming the size of non-cached (so useless for anything
+ else) memory window is 1Mb, we might as well use it all.
+ 128 RX and TX descriptors uses the whole 1Mb, near enough."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_INTEL_I82559_OPTIONS {
+ display "Intel 82559 ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_INTEL_I82559_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Intel 82559 ethernet driver
+ package. These flags are used in addition to the set of
+ global flags."
+ }
+ }
+}
+# EOF intel_i82559_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/intel/i82559/current/include/i82559_info.h b/ecos/packages/devs/eth/intel/i82559/current/include/i82559_info.h
new file mode 100644
index 0000000..4ca0487
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i82559/current/include/i82559_info.h
@@ -0,0 +1,220 @@
+#ifndef CYGONCE_DEVS_ETH_INTEL_I82559_INFO_H
+#define CYGONCE_DEVS_ETH_INTEL_I82559_INFO_H
+/*==========================================================================
+//
+// i82559_info.h
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 2000-05-03
+// Description:
+//
+//####DESCRIPTIONEND####
+*/
+
+#include <pkgconf/devs_eth_intel_i82559.h>
+
+#ifdef CYGDBG_DEVS_ETH_INTEL_I82559_KEEP_STATISTICS
+# define KEEP_STATISTICS
+# define nDISPLAY_STATISTICS
+# define nDISPLAY_82559_STATISTICS
+#else
+# define nKEEP_STATISTICS
+# define nDISPLAY_STATISTICS
+# define nDISPLAY_82559_STATISTICS
+#endif
+
+
+// ------------------------------------------------------------------------
+//
+// STATISTICAL COUNTER STRUCTURE
+//
+// ------------------------------------------------------------------------
+#ifdef KEEP_STATISTICS
+typedef struct {
+/* 0 */ cyg_uint32 tx_good;
+/* 4 */ cyg_uint32 tx_max_collisions;
+/* 8 */ cyg_uint32 tx_late_collisions;
+/* 12 */ cyg_uint32 tx_underrun;
+/* 16 */ cyg_uint32 tx_carrier_loss;
+/* 20 */ cyg_uint32 tx_deferred;
+/* 24 */ cyg_uint32 tx_single_collisions;
+/* 28 */ cyg_uint32 tx_mult_collisions;
+/* 32 */ cyg_uint32 tx_total_collisions;
+/* 36 */ cyg_uint32 rx_good;
+/* 40 */ cyg_uint32 rx_crc_errors;
+/* 44 */ cyg_uint32 rx_align_errors;
+/* 48 */ cyg_uint32 rx_resource_errors;
+/* 52 */ cyg_uint32 rx_overrun_errors;
+/* 56 */ cyg_uint32 rx_collisions; // Always 0
+/* 60 */ cyg_uint32 rx_short_frames;
+// In this setup; can also be flow-control counts after.
+// If these are to be used, a config command (as in set promiscuous mode)
+// must be issued at start, to let those stats escape. Params are in
+// comments around the config command setup...
+/* 64 */ cyg_uint32 done;
+} I82559_COUNTERS;
+
+
+typedef struct {
+ cyg_uint32 interrupts;
+ cyg_uint32 rx_count;
+ cyg_uint32 rx_deliver;
+ cyg_uint32 rx_resource;
+ cyg_uint32 rx_restart;
+ cyg_uint32 tx_count;
+ cyg_uint32 tx_complete;
+ cyg_uint32 tx_dropped;
+} STATISTICS;
+
+
+extern STATISTICS statistics[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT];
+#ifdef CYGDBG_DEVS_ETH_INTEL_I82559_KEEP_82559_STATISTICS
+extern I82559_COUNTERS i82559_counters[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT];
+#endif
+
+#endif // KEEP_STATISTICS
+
+// ------------------------------------------------------------------------
+//
+// DEVICES AND PACKET QUEUES
+//
+// ------------------------------------------------------------------------
+// The system seems to work OK with as few as 8 of RX and TX descriptors.
+// It limps very painfully with only 4.
+// Performance is better with more than 8.
+// But the size of non-cached (so useless for anything else)
+// memory window is 1Mb, so we might as well use it all.
+//
+// 128 for these uses the whole 1Mb, near enough.
+
+#ifndef MAX_RX_DESCRIPTORS
+#define MAX_RX_DESCRIPTORS 128 // number of Rx descriptors
+#endif
+#ifndef MAX_TX_DESCRIPTORS
+#define MAX_TX_DESCRIPTORS 128 // number of Tx descriptors
+#endif
+
+// Use packet type for selfdocumenting code
+typedef cyg_uint8 RFD;
+typedef cyg_uint8 TxCB;
+typedef cyg_uint8 CFG;
+
+typedef struct i82559 {
+ cyg_uint8 // (split up for atomic byte access)
+ found:1, // was hardware discovered?
+ mac_addr_ok:1, // can we bring up?
+ active:1, // has this if been brung up?
+ hardwired_esa:1, // set if ESA is hardwired via CDL
+ promisc:1, // set if in promisc mode
+ multicast_all:1, // set if MultiCastALL mode
+ oversized:1, // set if oversized packets are received (VLAN mode)
+ spare1:1;
+ cyg_uint8 // Count nested sends to reject
+ within_send:8; // nested requests to send
+ cyg_uint8
+ tx_in_progress:1, // transmit in progress flag
+ tx_queue_full:1, // all Tx descriptors used flag
+ spare3:6;
+ cyg_uint8 index; // 0 or 1 or whatever
+ cyg_uint32 devid; // PCI device id
+ cyg_uint32 memory_address; // PCI memory address
+ cyg_uint32 io_address; // memory mapped I/O address
+ cyg_uint8 mac_address[6]; // mac (hardware) address
+ void *ndp; // Network Device Pointer
+
+ int next_rx_descriptor; // descriptor index for RFDs
+ RFD* rx_ring[MAX_RX_DESCRIPTORS]; // location of Rx descriptors
+
+ int tx_descriptor_add; // descriptor index for additions
+ int tx_descriptor_active; // descriptor index for active tx
+ int tx_descriptor_remove; // descriptor index for remove
+
+ TxCB* tx_ring[MAX_TX_DESCRIPTORS]; // location of Tx descriptors
+ unsigned long tx_keys[MAX_TX_DESCRIPTORS];
+ // keys for tx q management
+
+ // Interrupt handling stuff
+ cyg_vector_t vector; // interrupt vector
+ cyg_handle_t interrupt_handle; // handle for int.handler
+ cyg_interrupt interrupt_object;
+
+#ifdef KEEP_STATISTICS
+ void *p_statistics; // pointer to statistical counters
+#endif
+
+ cyg_uint32 platform_timeout; // Some platforms use a timeout
+ int tx_descriptor_timeout; // Is it fixated on this tx?
+
+} I82559;
+
+
+// ------------------------------------------------------------------------
+//
+// 82559 GENERAL STATUS REGISTER
+//
+// ------------------------------------------------------------------------
+#define GEN_STATUS_FDX 0x04 // 1 = full duplex, 0 = half
+#define GEN_STATUS_100MBPS 0x02 // 1 = 100 Mbps, 0 = 10 Mbps
+#define GEN_STATUS_LINK 0x01 // 1 = link up, 0 = link down
+
+extern int i82559_status( struct eth_drv_sc *sc );
+
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+void update_statistics(struct i82559* p_i82559);
+#endif
+
+
+#ifdef CYGDBG_DEVS_ETH_INTEL_I82559_KEEP_82559_STATISTICS
+#define ETH_STATS_INIT( p ) \
+ update_statistics( (struct i82559 *)((p)->driver_private) )
+#else
+#define ETH_STATS_INIT( p ) // otherwise do nothing
+#endif
+
+#define CYGDAT_DEVS_ETH_DESCRIPTION "Intel EtherPRO 10/100+ (i82559)"
+
+#define ETH_DEV_DOT3STATSETHERCHIPSET 1,3,6,1,2,1,10,7,8,2,5
+
+#endif /* ifndef CYGONCE_DEVS_ETH_INTEL_I82559_INFO_H */
+
+/* EOF i82559_info.h */
+
diff --git a/ecos/packages/devs/eth/intel/i82559/current/src/if_i82559.c b/ecos/packages/devs/eth/intel/i82559/current/src/if_i82559.c
new file mode 100644
index 0000000..0b8dab3
--- /dev/null
+++ b/ecos/packages/devs/eth/intel/i82559/current/src/if_i82559.c
@@ -0,0 +1,3931 @@
+//==========================================================================
+//
+// if_i82559.c
+//
+// Intel 82559 ethernet driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt, gthomas
+// Contributors: Ron Spence, Pacific Softworks, jskov
+// Date: 2000-02-01
+// Purpose:
+// Description: hardware driver for 82559 Intel PRO/100+ ethernet
+// Notes: CU commands such as dump and config should, according
+// to the docs, set the CU active state while executing.
+// That does not seem to be the case though, and the
+// driver polls the completion bit in the packet status
+// word instead.
+//
+// Platform code may provide this vector:
+// CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT if it
+// requires the interrupts to be handled via demuxers
+// attached to a distinct interrupt.
+//
+// Platform code may alternatively define:
+// CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL if it is necessary
+// to demux all interrupt sources - for example if they are
+// wire-or'd together on some hardware but distinct on
+// others. In this circumstance it is permitted for
+// cyg_pci_translate_interrupt [HAL_PCI_TRANSLATE_INTERRUPT]
+// to return invalid for 2nd and subsequent devices.
+//
+// Platform code can also define these three:
+// CYGPRI_DEVS_ETH_INTEL_I82559_MASK_INTERRUPTS(p_i82559,old)
+// CYGPRI_DEVS_ETH_INTEL_I82559_UNMASK_INTERRUPTS(p_i82559,old)
+// CYGPRI_DEVS_ETH_INTEL_I82559_ACK_INTERRUPTS(p_i82559)
+// which are particularly useful when nested interrupt
+// management is needed (which is always IMHO).
+//
+// Platform code can define this:
+// CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT(p_i82559)
+// to detect a dropped interrupt and loop again or
+// direct-call the DSR to reschedule the delivery routine.
+// Only a problem on edge-triggered interrupt systems.
+//
+// Platform code can also provide this macro:
+// CYGPRI_DEVS_ETH_INTEL_I82559_INTERRUPT_ACK_LOOP(p_i82559)
+// to handle delaying for acks to register on the interrupt
+// controller as necessary on the EBSA.
+//
+// Platform can define CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA()
+// as an external means to get ESAs, possibly from RedBoot
+// configuration info that's stored in flash memory.
+//
+// Platform def CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+// removes all code for dealing with the EEPROM for those
+// targets where there is none fitted. Either an external
+// means to get ESAs should be used, or we must rely on
+// hard-wiring the ESA's into each executable by means of the
+// usual CDL configuration.
+//
+// Platform def CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM
+// is for hardware with multiple devices, but only one with a
+// serial EEPROM installed. The 2nd device would get either
+// the same ESA - because they are certain to be on different
+// segment and internets - or the same ESA incremented by
+// CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_MAC_ADJUST.
+// CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM should be the
+// number (0 or 1) of the device that does have the EEPROM.
+//
+// CYGHWR_DEVS_ETH_INTEL_I82559_PCIMEM_DISCONTIGUOUS enables
+// checking code for breaks in the physical address of PCI
+// window memory. This can happen on some boards where a
+// smaller SDRAM is fitted than the hardware allows, so some
+// higher-order address bits are ignored. We make SDRAM
+// contiguous in mapped memory, but what the i82559 sees
+// might be discontiguous. The checking code skips any
+// allocated chunk who appears to contain such a break, and
+// tries again.
+//
+// CYGHWR_DEVS_ETH_INTEL_I82559_RESET_TIMEOUT( int32 )
+// CYGHWR_DEVS_ETH_INTEL_I82559_TIMEOUT_FIRED( int32 ) if
+// both defined give the driver a means to detect that we
+// have been fixated on the same transmit operation for too
+// long - we missed an interrupt or the device crashed. The
+// int32 argument is used to hold a eg. the value of a
+// fast-running hardware timer.
+//
+// CYGHWR_DEVS_ETH_INTEL_I82559_ENDIAN_NEUTRAL_IO if PCI IO
+// access is not affected by CPU endianess.
+//
+// FIXME: replace -1/-2 return values with proper E-defines
+// FIXME: For 82557/8 compatibility i82559_configure() function
+// probably needs some tweaking - config bits differ
+// slightly but crucially.
+// FIXME: EEPROM code not tested on a BE system.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#ifdef CYGPKG_IO_ETH_DRIVERS
+#include <pkgconf/io_eth_drivers.h>
+#endif
+#include <pkgconf/devs_eth_intel_i82559.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#include <string.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <net/if.h> /* Needed for struct ifnet */
+#endif
+
+#ifdef CYGPKG_IO_PCI
+#include <cyg/io/pci.h>
+// So we can check the validity of the PCI window against the MLTs opinion,
+// and thereby what the malloc heap consumes willy-nilly:
+#include CYGHWR_MEMORY_LAYOUT_H
+#else
+#error "Need PCI package here"
+#endif
+
+// Exported statistics and the like
+#include <cyg/devs/eth/i82559_info.h>
+#include <cyg/io/eth/eth_drv_stats.h>
+#include CYGDAT_DEVS_ETH_INTEL_I82559_INL
+
+#include <cyg/hal/hal_if.h>
+
+// Use with care! Local variable defined!
+#define START_CONSOLE() \
+{ /* NEW BLOCK */ \
+ int _cur_console = \
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); \
+ { \
+ int i; \
+ if ( CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "info_console_force", &i, \
+ CYGNUM_FLASH_CFG_TYPE_CONFIG_BOOL ) ) { \
+ if ( i ) { \
+ if ( CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "info_console_number", &i, \
+ CYGNUM_FLASH_CFG_TYPE_CONFIG_INT ) ){ \
+ /* Then i is the console to force it to: */ \
+ CYGACC_CALL_IF_SET_CONSOLE_COMM( i ); \
+ } \
+ } \
+ } \
+ }
+
+#define END_CONSOLE() \
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(_cur_console); \
+} /* END BLOCK */
+
+void CheckRxRing(struct i82559* p_i82559, const char * func, int line);
+
+// ------------------------------------------------------------------------
+// Check on the environment.
+//
+// These are not CDL type config points; they are set up for your platform
+// in the platform driver's include file and that's that. These messages
+// are for the eCos driver writer, not config tool users.
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+#ifdef CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT
+#error Both a separate demux interrupt *and* DEMUX_ALL are defined
+#endif
+#endif
+
+#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_WRITE_EEPROM
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+#error This platform has no EEPROM, yet WRITE_EEPROM is enabled
+#endif
+#endif
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM
+#error This platform has no EEPROM, yet it also HAS_ONE_EEPROM
+#endif
+#endif
+
+// ------------------------------------------------------------------------
+
+#ifdef CYGDBG_DEVS_ETH_INTEL_I82559_CHATTER
+#define DEBUG // Startup printing mainly
+#define DEBUG_EE // Some EEPROM specific retries &c
+#if (CYGDBG_DEVS_ETH_INTEL_I82559_CHATTER > 1)
+#define DEBUG_82559 // This one prints stuff as packets come and go
+#endif
+#endif
+
+#ifdef CYGDBG_USE_ASSERTS
+static struct {
+ int can_send;
+ int deliver;
+ int stats;
+ int waitcmd_timeouts;
+ int waitcmd_timeouts_cu;
+ int lockup_timeouts;
+ int bad_cu_idles;
+} missed_interrupt = { 0,0,0, 0,0, 0, 0 };
+#endif
+
+int
+console_printf(const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ START_CONSOLE();
+
+ va_start(ap, fmt);
+ ret = diag_vprintf(fmt, ap);
+ va_end(ap);
+
+ END_CONSOLE();
+ return (ret);
+}
+
+#define os_printf console_printf
+#define db_printf console_printf
+
+// ------------------------------------------------------------------------
+//
+// MEMORY ADDRESSING
+//
+// There is scope for confusion here; we deal with LE/BE systems and
+// addressing issues in two separate ways depending on the type of access
+// in question.
+//
+// 1) IO-style access to the device regsiters over the PCI bus
+// 2) Memory access to build and read the structures in shared memory
+//
+// In detail:
+//
+// 1) IO-style access to the device regsiters over the PCI bus
+//
+// All such access is via macros which perform byte-swapping as necessary
+// for the endianness of the CPU. These macros are called INL, INW, INB
+// and OUTL, OUTW, OUTB - for Long (32) Word (16) and Byte (8). Intel
+// nomenclature seems to have crept in here for shorts.
+//
+// Consequently, all the constants only have to be expressed once, in their
+// true LE format - bit 15 is 0x8000, bit 0 is 1.
+//
+// All the offsets are also only expressed once. This is OK so long as GIB
+// endian addressing (sic, see below) is not employed - or so long as is
+// does not affect the PCI bus accesses.
+//
+//
+// 2) Memory access to build and read the structures in shared memory
+//
+// These accesses are by means of peek and poke to an address created from
+// a base + offset. No swapping occurs within the access so all constants
+// and flags need to be defined twice, once for BE and once for LE
+// accesses. Worse, for BE, constants need to be defined in flavours for
+// 16-bit versus 32-bit accesses, ie. 0x8000 sets bit 7 only in BE; for a
+// 32-bit access you must instead write 0x80000000 to set bit 7.
+//
+// Thus all constants are defined twice depending on the CPU's endianness.
+//
+// For most BE/LE machines, this is sufficient; the layout of memory is the
+// same. Specifically, within a 32-bit word, byte[0] will be data[0:7],
+// short[0] will be data [0:15] and so on. &byte[0] == &short[0] == &word
+// regardless. But data[0:7] *OF THE MEMORY SYSTEM* will hold either the
+// LSbyte (0xFF) on a LE machine, and the MSbyte (0xFF000000) on a BE
+// machine, for a 32-bit access.
+//
+// It is in terms of the memory system that the i82559 defines its view of
+// the world.
+//
+// Therefore the structure layouts remain the same for both BE and LE
+// machines. This means that the offsets for, specifically, the status
+// word in command blocks is always zero, and the offset for the command
+// word is always two.
+//
+// But there is one furter variant: so-called GIB endian. (BIG endian
+// backwards) Some architectures support BE only for software
+// compatibility; they allow code to run which relies on overlaid C
+// structures behaving in a certain way; specifically
+// *(char *)&i == (i >> 24)
+// ARM's BE mode is an example of this.
+//
+// But while such an operation would use data[0:7] for the char access in a
+// true BE or any LE system, in a GE system, data[24:31] are used here.
+// The implementation is that for memory accesses, A0 and A1 are inverted
+// before going outside to the memory system. So if &i == 0x1000,
+// accessing i uses address 0x1000, A0 and A1 being ignored for a 32-bit
+// access. But the 8-bit access to *(char *)&i also uses 0x1000 for the
+// address as the code sees it, the memory system sees a byte request for
+// address 0x1003, thus picking up the MSbyte, from data[24:31].
+//
+// For such addressing, offsets need to be redefined to swap bytes and
+// shorts within words. Therefore offsets are defined twice, once for
+// "normal" addressing, and once for "GIB endian" addressing.
+//
+// FIXME: this BE/GE configuration probably won't work with an ARM in its
+// BE mode - because that will define the global BE flags, yet it's not
+// true BE, it's GE.
+// Perhaps a solution whereby the GE flag CYG_ADDRESSING_IS_GIBENDIAN
+// overrides the BYTEORDER choices would be good; we want the constants to
+// be LE, but address offsets to be swapped per GE.
+//
+// Essay ends.
+//
+// ------------------------------------------------------------------------
+// I/O access macros as inlines for type safety
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST)
+
+#define HAL_CTOLE32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))
+#define HAL_LE32TOC(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))
+
+#define HAL_CTOLE16(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+#define HAL_LE16TOC(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+
+#else
+// Maintaining the same styleee as above...
+#define HAL_CTOLE32(x) ((((x))))
+#define HAL_LE32TOC(x) ((((x))))
+
+#define HAL_CTOLE16(x) ((((x))))
+#define HAL_LE16TOC(x) ((((x))))
+
+#endif
+
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST) && !defined(CYGHWR_DEVS_ETH_INTEL_I82559_ENDIAN_NEUTRAL_IO)
+
+static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address)
+{
+ HAL_WRITE_UINT8( io_address, value);
+}
+
+static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)
+{
+ HAL_WRITE_UINT16( io_address, (((value & 0xff) << 8) | ((value & 0xff00) >> 8)) );
+}
+
+static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address)
+{
+ HAL_WRITE_UINT32( io_address,
+ ((((value) & 0xff) << 24) | (((value) & 0xff00) << 8) | (((value) & 0xff0000) >> 8) | (((value) >> 24) & 0xff)) );
+}
+
+static inline cyg_uint8 INB(cyg_uint32 io_address)
+{
+ cyg_uint8 d;
+ HAL_READ_UINT8( io_address, d );
+ return d;
+}
+
+static inline cyg_uint16 INW(cyg_uint32 io_address)
+{
+ cyg_uint16 d;
+ HAL_READ_UINT16( io_address, d );
+ return (((d & 0xff) << 8) | ((d & 0xff00) >> 8));
+}
+
+static inline cyg_uint32 INL(cyg_uint32 io_address)
+{
+ cyg_uint32 d;
+ HAL_READ_UINT32( io_address, d );
+ return ((((d) & 0xff) << 24) | (((d) & 0xff00) << 8) | (((d) & 0xff0000) >> 8) | (((d) >> 24) & 0xff));
+}
+#else
+
+static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address)
+{ HAL_WRITE_UINT8( io_address, value ); }
+
+static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)
+{ HAL_WRITE_UINT16( io_address, value ); }
+
+static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address)
+{ HAL_WRITE_UINT32( io_address, value ); }
+
+static inline cyg_uint8 INB(cyg_uint32 io_address)
+ { cyg_uint8 _t_; HAL_READ_UINT8( io_address, _t_ ); return _t_; }
+
+static inline cyg_uint16 INW(cyg_uint32 io_address)
+ { cyg_uint16 _t_; HAL_READ_UINT16( io_address, _t_ ); return _t_; }
+
+static inline cyg_uint32 INL(cyg_uint32 io_address)
+ { cyg_uint32 _t_; HAL_READ_UINT32( io_address, _t_ ); return _t_; }
+
+#endif // byteorder
+
+// ------------------------------------------------------------------------
+// Macros for writing shared memory structures - no need for byte flipping
+
+#define READMEM8( _reg_, _val_ ) ((_val_) = *((volatile CYG_BYTE *)(_reg_)))
+#define WRITEMEM8( _reg_, _val_ ) (*((volatile CYG_BYTE *)(_reg_)) = (_val_))
+#define READMEM16( _reg_, _val_ ) ((_val_) = *((volatile CYG_WORD16 *)(_reg_)))
+#define WRITEMEM16( _reg_, _val_ ) (*((volatile CYG_WORD16 *)(_reg_)) = (_val_))
+#define READMEM32( _reg_, _val_ ) ((_val_) = *((volatile CYG_WORD32 *)(_reg_)))
+#define WRITEMEM32( _reg_, _val_ ) (*((volatile CYG_WORD32 *)(_reg_)) = (_val_))
+
+// ------------------------------------------------------------------------
+// Map from CPU-view addresses to PCI-bus master's view - however that is:
+
+#ifdef CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS
+
+#define VIRT_TO_BUS( _x_ ) CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS( _x_ )
+
+#else // use default mappings: get a physical address to give to the device
+
+#define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_))
+static inline cyg_uint32 virt_to_bus(cyg_uint32 p_memory)
+{ return CYGARC_PHYSICAL_ADDRESS(p_memory); }
+
+#endif // not defined CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS
+
+// ------------------------------------------------------------------------
+//
+// 82559 REGISTER OFFSETS (I/O SPACE)
+//
+// ------------------------------------------------------------------------
+#define SCBStatus 0 // Rx/Command Unit Status *Word*
+#define SCBIntAckByte 1 // Rx/Command Unit STAT/ACK byte
+#define SCBCmd 2 // Rx/Command Unit Command *Word*
+#define SCBIntrCtlByte 3 // Rx/Command Unit Intr.Control Byte
+#define SCBPointer 4 // General purpose pointer.
+#define SCBPort 8 // Misc. commands and operands.
+#define SCBflash 12 // Flash memory control.
+#define SCBeeprom 14 // EEPROM memory control.
+#define SCBCtrlMDI 16 // MDI interface control.
+#define SCBEarlyRx 20 // Early receive byte count.
+#define SCBGenControl 28 // 82559 General Control Register
+#define SCBGenStatus 29 // 82559 General Status register
+
+
+// ------------------------------------------------------------------------
+//
+// 82559 SCB STATUS WORD DEFNITIONS
+//
+// ------------------------------------------------------------------------
+#define SCB_STATUS_CX 0x8000 // CU finished command (transmit)
+#define SCB_STATUS_FR 0x4000 // frame received
+#define SCB_STATUS_CNA 0x2000 // CU left active state
+#define SCB_STATUS_RNR 0x1000 // receiver left ready state
+#define SCB_STATUS_MDI 0x0800 // MDI read/write cycle done
+#define SCB_STATUS_SWI 0x0400 // software generated interrupt
+#define SCB_STATUS_FCP 0x0100 // flow control pause interrupt
+
+#define SCB_INTACK_MASK 0xFD00 // all the above
+#define SCB_INTACK_MASK_BYTE 0xFD // all the above
+
+#define SCB_INTACK_TX (SCB_STATUS_CX | SCB_STATUS_CNA)
+#define SCB_INTACK_RX (SCB_STATUS_FR | SCB_STATUS_RNR)
+
+// ------------------------------------------------------------------------
+//
+// SYSTEM CONTROL BLOCK COMMANDS
+//
+// ------------------------------------------------------------------------
+// CU COMMANDS
+#define CU_NOP 0x0000
+#define CU_START 0x0010
+#define CU_RESUME 0x0020
+#define CU_STATSADDR 0x0040 // Load Dump Statistics ctrs addr
+#define CU_SHOWSTATS 0x0050 // Dump statistics counters.
+#define CU_ADDR_LOAD 0x0060 // Base address to add to CU commands
+#define CU_DUMPSTATS 0x0070 // Dump then reset stats counters.
+
+// RUC COMMANDS
+#define RUC_NOP 0x0000
+#define RUC_START 0x0001
+#define RUC_RESUME 0x0002
+#define RUC_ABORT 0x0004
+#define RUC_ADDR_LOAD 0x0006 // (seems not to clear on acceptance)
+#define RUC_RESUMENR 0x0007
+
+#define CU_CMD_MASK 0x00f0
+#define RU_CMD_MASK 0x0007
+
+#define SCB_M 0x0100 // 0 = enable interrupt, 1 = disable
+#define SCB_SWI 0x0200 // 1 - cause device to interrupt
+#define SCB_BYTE_M 0x01 // 0 = enable interrupt, 1 = disable
+#define SCB_BYTE_SWI 0x02 // 1 - cause device to interrupt
+
+#define CU_STATUS_MASK 0x00C0
+#define RU_STATUS_MASK 0x003C
+
+#define RU_STATUS_IDLE (0<<2)
+#define RU_STATUS_SUS (1<<2)
+#define RU_STATUS_NORES (2<<2)
+#define RU_STATUS_READY (4<<2)
+#define RU_STATUS_NO_RBDS_SUS ((1<<2)|(8<<2))
+#define RU_STATUS_NO_RBDS_NORES ((2<<2)|(8<<2))
+#define RU_STATUS_NO_RBDS_READY ((4<<2)|(8<<2))
+
+#define MAX_MEM_RESERVED_IOCTL 1000
+
+// ------------------------------------------------------------------------
+//
+// 82559 PORT INTERFACE COMMANDS
+//
+// ------------------------------------------------------------------------
+#define I82559_RESET 0x00000000 // software reset
+#define I82559_SELFTEST 0x00000001 // 82559 selftest command
+#define I82559_SELECTIVE_RESET 0x00000002
+#define I82559_DUMP 0x00000003
+#define I82559_DUMP_WAKEUP 0x00000007
+
+
+// ------------------------------------------------------------------------
+//
+// 82559 EEPROM INTERFACE
+//
+// ------------------------------------------------------------------------
+// EEPROM_Ctrl bits.
+#define EE_SHIFT_CLK 0x01 // EEPROM shift clock.
+#define EE_CS 0x02 // EEPROM chip select.
+#define EE_DATA_WRITE 0x04 // EEPROM chip data in.
+#define EE_DATA_READ 0x08 // EEPROM chip data out.
+#define EE_ENB (0x4800 | EE_CS)
+
+// Delay between EEPROM clock transitions.
+#define eeprom_delay(usec) udelay(usec);
+
+// The EEPROM commands include the always-set leading bit.
+#define EE_WRITE_CMD(a) (5 << (a))
+#define EE_READ_CMD(a) (6 << (a))
+#define EE_ERASE_CMD(a) (7 << (a))
+#define EE_WRITE_EN_CMD(a) (19 << ((a)-2))
+#define EE_WRITE_DIS_CMD(a) (16 << ((a)-2))
+#define EE_ERASE_ALL_CMD(a) (18 << ((a)-2))
+
+#define EE_TOP_CMD_BIT(a) ((a)+2) // Counts down to zero
+#define EE_TOP_DATA_BIT (15) // Counts down to zero
+
+#define EEPROM_ENABLE_DELAY (10) // Delay at chip select
+
+#define EEPROM_SK_DELAY (4) // Delay between clock edges *and* data
+ // read or transition; 3 of these per bit.
+#define EEPROM_DONE_DELAY (100) // Delay when all done
+
+
+// ------------------------------------------------------------------------
+//
+// RECEIVE FRAME DESCRIPTORS
+//
+// ------------------------------------------------------------------------
+
+// The status is split into two shorts to get atomic access to the EL bit;
+// the upper word is not written by the device, so we can just hit it,
+// leaving the lower word (which the device updates) alone. Otherwise
+// there's a race condition between software moving the end-of-list (EL)
+// bit round and the device writing into the previous slot.
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST)
+
+// Note that status bits are endian converted - so we don't need to
+// fiddle the byteorder when accessing the status word!
+#define RFD_STATUS_EL 0x00000080 // 1=last RFD in RFA
+#define RFD_STATUS_S 0x00000040 // 1=suspend RU after receiving frame
+#define RFD_STATUS_H 0x00001000 // 1=RFD is a header RFD
+#define RFD_STATUS_SF 0x00000800 // 0=simplified, 1=flexible mode
+#define RFD_STATUS_C 0x00800000 // completion of received frame
+#define RFD_STATUS_OK 0x00200000 // frame received with no errors
+
+#define RFD_STATUS_HI_EL 0x0080 // 1=last RFD in RFA
+#define RFD_STATUS_HI_S 0x0040 // 1=suspend RU after receiving frame
+#define RFD_STATUS_HI_H 0x1000 // 1=RFD is a header RFD
+#define RFD_STATUS_HI_SF 0x0800 // 0=simplified, 1=flexible mode
+
+#define RFD_STATUS_LO_C 0x0080 // completion of received frame
+#define RFD_STATUS_LO_OK 0x0020 // frame received with no errors
+
+
+#define RFD_COUNT_MASK 0x3fff
+#define RFD_COUNT_F 0x4000
+#define RFD_COUNT_EOF 0x8000
+
+#define RFD_RX_CRC 0x00080000 // crc error
+#define RFD_RX_ALIGNMENT 0x00040000 // alignment error
+#define RFD_RX_RESOURCE 0x00020000 // out of space, no resources
+#define RFD_RX_DMA_OVER 0x00010000 // DMA overrun
+#define RFD_RX_SHORT 0x80000000 // short frame error
+#define RFD_RX_LENGTH 0x20000000 //
+#define RFD_RX_ERROR 0x10000000 // receive error
+#define RFD_RX_NO_ADR_MATCH 0x04000000 // no address match
+#define RFD_RX_IA_MATCH 0x02000000 // individual address does not match
+#define RFD_RX_TCO 0x01000000 // TCO indication
+
+#else // Little-endian
+
+#define RFD_STATUS_EL 0x80000000 // 1=last RFD in RFA
+#define RFD_STATUS_S 0x40000000 // 1=suspend RU after receiving frame
+#define RFD_STATUS_H 0x00100000 // 1=RFD is a header RFD
+#define RFD_STATUS_SF 0x00080000 // 0=simplified, 1=flexible mode
+#define RFD_STATUS_C 0x00008000 // completion of received frame
+#define RFD_STATUS_OK 0x00002000 // frame received with no errors
+
+#define RFD_STATUS_HI_EL 0x8000 // 1=last RFD in RFA
+#define RFD_STATUS_HI_S 0x4000 // 1=suspend RU after receiving frame
+#define RFD_STATUS_HI_H 0x0010 // 1=RFD is a header RFD
+#define RFD_STATUS_HI_SF 0x0008 // 0=simplified, 1=flexible mode
+
+#define RFD_STATUS_LO_C 0x8000 // completion of received frame
+#define RFD_STATUS_LO_OK 0x2000 // frame received with no errors
+
+#define RFD_COUNT_MASK 0x3fff
+#define RFD_COUNT_F 0x4000
+#define RFD_COUNT_EOF 0x8000
+
+#define RFD_RX_CRC 0x00000800 // crc error
+#define RFD_RX_ALIGNMENT 0x00000400 // alignment error
+#define RFD_RX_RESOURCE 0x00000200 // out of space, no resources
+#define RFD_RX_DMA_OVER 0x00000100 // DMA overrun
+#define RFD_RX_SHORT 0x00000080 // short frame error
+#define RFD_RX_LENGTH 0x00000020 //
+#define RFD_RX_ERROR 0x00000010 // receive error
+#define RFD_RX_NO_ADR_MATCH 0x00000004 // no address match
+#define RFD_RX_IA_MATCH 0x00000002 // individual address does not match
+#define RFD_RX_TCO 0x00000001 // TCO indication
+
+#endif // CYG_BYTEORDER
+
+#ifndef CYG_ADDRESSING_IS_GIBENDIAN
+
+// Normal addressing
+#define RFD_STATUS 0
+#define RFD_STATUS_LO 0
+#define RFD_STATUS_HI 2
+#define RFD_LINK 4
+#define RFD_RDB_ADDR 8
+#define RFD_COUNT 12
+#define RFD_SIZE 14
+#define RFD_BUFFER 16
+#define RFD_SIZEOF 16
+
+#else // CYG_ADDRESSING_IS_GIBENDIAN
+
+// GIBENDIAN addressing; A0 and A1 are flipped:
+#define RFD_STATUS 0
+#define RFD_STATUS_LO 2 // swapped
+#define RFD_STATUS_HI 0 // swapped
+#define RFD_LINK 4
+#define RFD_RDB_ADDR 8
+#define RFD_COUNT 14 // swapped
+#define RFD_SIZE 12 // swapped
+#define RFD_BUFFER 16
+#define RFD_SIZEOF 16
+
+#endif // CYG_ADDRESSING_IS_GIBENDIAN
+
+
+
+// ------------------------------------------------------------------------
+//
+// TRANSMIT FRAME DESCRIPTORS
+//
+// ------------------------------------------------------------------------
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST)
+
+// Note that CMD/STATUS bits are endian converted - so we don't need
+// to fiddle the byteorder when accessing the CMD/STATUS word!
+
+#define TxCB_CMD_TRANSMIT 0x0400 // transmit command
+#define TxCB_CMD_SF 0x0800 // 0=simplified, 1=flexible mode
+#define TxCB_CMD_NC 0x0010 // 0=CRC insert by controller
+#define TxCB_CMD_I 0x0020 // generate interrupt on completion
+#define TxCB_CMD_S 0x0040 // suspend on completion
+#define TxCB_CMD_EL 0x0080 // last command block in CBL
+
+#define TxCB_COUNT_MASK 0x3fff
+#define TxCB_COUNT_EOF 0x8000
+
+#else // Little-endian layout
+
+#define TxCB_COUNT_MASK 0x3fff
+#define TxCB_COUNT_EOF 0x8000
+
+#define TxCB_CMD_TRANSMIT 0x0004 // transmit command
+#define TxCB_CMD_SF 0x0008 // 0=simplified, 1=flexible mode
+#define TxCB_CMD_NC 0x0010 // 0=CRC insert by controller
+#define TxCB_CMD_I 0x2000 // generate interrupt on completion
+#define TxCB_CMD_S 0x4000 // suspend on completion
+#define TxCB_CMD_EL 0x8000 // last command block in CBL
+
+#endif // CYG_BYTEORDER
+
+#ifndef CYG_ADDRESSING_IS_GIBENDIAN
+
+// Normal addressing
+#define TxCB_STATUS 0
+#define TxCB_CMD 2
+#define TxCB_LINK 4
+#define TxCB_TBD_ADDR 8
+#define TxCB_COUNT 12
+#define TxCB_TX_THRESHOLD 14
+#define TxCB_TBD_NUMBER 15
+#define TxCB_BUFFER 16
+#define TxCB_SIZEOF 16
+
+#else // CYG_ADDRESSING_IS_GIBENDIAN
+
+// GIBENDIAN addressing; A0 and A1 are flipped:
+#define TxCB_STATUS 2 // swapped
+#define TxCB_CMD 0 // swapped
+#define TxCB_LINK 4
+#define TxCB_TBD_ADDR 8
+#define TxCB_COUNT 14 // swapped
+#define TxCB_TX_THRESHOLD 13 // swapped
+#define TxCB_TBD_NUMBER 12 // swapped
+#define TxCB_BUFFER 16
+#define TxCB_SIZEOF 16
+#endif // CYG_ADDRESSING_IS_GIBENDIAN
+
+// ------------------------------------------------------------------------
+//
+// STRUCTURES ADDED FOR PROMISCUOUS MODE
+//
+// ------------------------------------------------------------------------
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST)
+
+// Note CFG CMD and STATUS swapped, so no need for endian conversion
+// in code.
+#define CFG_CMD_EL 0x0080
+#define CFG_CMD_SUSPEND 0x0040
+#define CFG_CMD_INT 0x0020
+#define CFG_CMD_IAS 0x0100 // individual address setup
+#define CFG_CMD_CONFIGURE 0x0200 // configure
+#define CFG_CMD_MULTICAST 0x0300 // Multicast-Setup
+
+#define CFG_STATUS_C 0x0080
+#define CFG_STATUS_OK 0x0020
+
+#else // Little-endian
+
+#define CFG_CMD_EL 0x8000
+#define CFG_CMD_SUSPEND 0x4000
+#define CFG_CMD_INT 0x2000
+#define CFG_CMD_IAS 0x0001 // individual address setup
+#define CFG_CMD_CONFIGURE 0x0002 // configure
+#define CFG_CMD_MULTICAST 0x0003 // Multicast-Setup
+
+#define CFG_STATUS_C 0x8000
+#define CFG_STATUS_OK 0x2000
+
+#endif // CYG_BYTEORDER
+
+#ifndef CYG_ADDRESSING_IS_GIBENDIAN
+
+// Normal addressing
+#define CFG_STATUS 0
+#define CFG_CMD 2
+#define CFG_CB_LINK_OFFSET 4
+#define CFG_BYTES 8
+#define CFG_SIZEOF 32
+
+#else // CYG_ADDRESSING_IS_GIBENDIAN
+
+// GIBENDIAN addressing; A0 and A1 are flipped:
+#define CFG_STATUS 2
+#define CFG_CMD 0
+#define CFG_CB_LINK_OFFSET 4
+#define CFG_BYTES 8
+#define CFG_SIZEOF 32
+
+#endif // CYG_ADDRESSING_IS_GIBENDIAN
+
+// Normal addressing
+#define CFG_MC_LIST_BYTES 8
+#define CFG_MC_LIST_DATA 10
+
+// ------------------------------------------------------------------------
+//
+// STATISTICAL COUNTER STRUCTURE
+//
+// ------------------------------------------------------------------------
+#ifdef KEEP_STATISTICS
+STATISTICS statistics[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT];
+I82559_COUNTERS i82559_counters[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT];
+#endif // KEEP_STATISTICS
+
+// ------------------------------------------------------------------------
+//
+// DEVICES AND PACKET QUEUES
+//
+// ------------------------------------------------------------------------
+
+#define MAX_RX_PACKET_SIZE 1536 // maximum Rx packet size
+#define MAX_TX_PACKET_SIZE 1536 // maximum Tx packet size
+
+
+// ------------------------------------------------------------------------
+// Use arrays provided by platform header to verify pointers.
+#ifdef CYGDBG_USE_ASSERTS
+#define CHECK_NDP_SC_LINK() \
+ CYG_MACRO_START \
+ int i, valid_netdev = 0, valid_sc = 0; \
+ for(i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT; i++) { \
+ if (i82559_netdev_array[i] == ndp) valid_netdev = 1; \
+ if (i82559_sc_array[i] == sc) valid_sc = 1; \
+ if (valid_sc || valid_netdev) break; \
+ } \
+ CYG_ASSERT( valid_netdev, "Bad ndp" ); \
+ CYG_ASSERT( valid_sc, "Bad sc" ); \
+ CYG_ASSERT( (void *)p_i82559 == i82559_sc_array[i]->driver_private, \
+ "sc pointer bad" ); \
+ CYG_MACRO_END
+#else
+#define CHECK_NDP_SC_LINK()
+#endif
+
+#define IF_BAD_82559( _p_ ) \
+if (({ \
+ int i, valid_p = 0; \
+ for(i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT; i++) { \
+ if (i82559_priv_array[i] == (_p_)) { \
+ valid_p = 1; \
+ break; \
+ } \
+ } \
+ CYG_ASSERT(valid_p, "Bad pointer-to-i82559"); \
+ (!valid_p); \
+}))
+
+// ------------------------------------------------------------------------
+//
+// Managing the memory that is windowed onto the PCI bus
+//
+// ------------------------------------------------------------------------
+
+static cyg_uint32 i82559_heap_size;
+static cyg_uint8 *i82559_heap_base;
+static cyg_uint8 *i82559_heap_free;
+
+static void *mem_reserved_ioctl = (void*)0;
+// uncacheable memory reserved for ioctl calls
+
+// ------------------------------------------------------------------------
+//
+// FUNCTION PROTOTYPES
+//
+// ------------------------------------------------------------------------
+
+static int pci_init_find_82559s(void);
+
+static void i82559_reset(struct i82559* p_i82559);
+static void i82559_restart(struct i82559 *p_i82559);
+static int eth_set_mac_address(struct i82559* p_i82559, cyg_uint8 *addr, int eeprom );
+
+static void InitRxRing(struct i82559* p_i82559);
+static void ResetRxRing(struct i82559* p_i82559);
+static void InitTxRing(struct i82559* p_i82559);
+static void ResetTxRing(struct i82559* p_i82559);
+
+#if defined(CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT) || \
+ defined(CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT) || \
+ !defined(CYGPKG_IO_ETH_DRIVERS_STAND_ALONE)
+static void
+eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+#endif
+static cyg_uint32
+eth_isr(cyg_vector_t vector, cyg_addrword_t data);
+
+static int i82559_configure(struct i82559* p_i82559, int promisc,
+ int oversized, int multicast_all);
+#ifdef ETH_DRV_SET_MC_LIST
+static int i82559_set_multicast(struct i82559* p_i82559,
+ int num_addrs,
+ cyg_uint8 *address_list );
+#endif // ETH_DRV_SET_MC_ALL
+#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_WRITE_EEPROM
+static void
+program_eeprom(cyg_uint32 ioaddr, cyg_uint32 eeprom_size, cyg_uint8 *data);
+static void
+write_eeprom(long ioaddr, int location, int addr_len, unsigned short value);
+static int
+write_enable_eeprom(long ioaddr, int addr_len);
+#endif
+
+// debugging/logging only:
+void dump_txcb(TxCB* p_txcb);
+void DisplayStatistics(void);
+void update_statistics(struct i82559* p_i82559);
+void dump_rfd(RFD* p_rfd, int anyway );
+void dump_all_rfds( int intf );
+void dump_packet(cyg_uint8 *p_buffer, int length);
+
+static void i82559_stop( struct eth_drv_sc *sc );
+
+// ------------------------------------------------------------------------
+// utilities
+// ------------------------------------------------------------------------
+
+typedef enum {
+ WAIT_RU, // wait before RU cmd
+ WAIT_CU // wait before CU cmd
+} cmd_wait_t;
+
+static inline
+void
+wait_for_cmd_done(long scb_ioaddr, cmd_wait_t type)
+{
+ register int status;
+ register int wait;
+
+ wait = 0x100000;
+ do status = INW(scb_ioaddr + SCBCmd) /* nothing */ ;
+ while( (0 != ((CU_CMD_MASK | RU_CMD_MASK) & status)) && --wait >= 0);
+
+ if ( wait <= 0 ) {
+ // Then we timed out; reset the device and try again...
+ OUTL(I82559_SELECTIVE_RESET, scb_ioaddr + SCBPort);
+#ifdef CYGDBG_USE_ASSERTS
+ missed_interrupt.waitcmd_timeouts++;
+#endif
+ wait = 0x100000;
+ do status = INW(scb_ioaddr + SCBCmd) /* nothing */;
+ while( (0 != ((CU_CMD_MASK | RU_CMD_MASK) & status)) && --wait >= 0);
+ }
+
+ // special case - don't complain about RUC_ADDR_LOAD as it doesn't clear
+ // on some silicon
+ if ( RUC_ADDR_LOAD != (status & RU_CMD_MASK) )
+ CYG_ASSERT( wait > 0, "wait_for_cmd_done: cmd busy" );
+
+ if (WAIT_CU == type) {
+ // Also check CU is idle
+ wait = 0x100000;
+ do status = INW(scb_ioaddr + SCBStatus) /* nothing */;
+ while( (status & CU_STATUS_MASK) && --wait >= 0);
+ if ( wait <= 0 ) {
+ // Then we timed out; reset the device and try again...
+ OUTL(I82559_SELECTIVE_RESET, scb_ioaddr + SCBPort);
+#ifdef CYGDBG_USE_ASSERTS
+ missed_interrupt.waitcmd_timeouts_cu++;
+#endif
+ wait = 0x100000;
+ do status = INW(scb_ioaddr + SCBCmd) /* nothing */;
+ while( (0 != ((CU_CMD_MASK | RU_CMD_MASK) & status)) && --wait >= 0);
+ }
+
+ CYG_ASSERT( wait > 0, "wait_for_cmd_done: CU busy" );
+
+ } else if (WAIT_RU == type) {
+ // Can't see any active state in the doc to check for
+ }
+}
+
+// ------------------------------------------------------------------------
+
+static void
+udelay(int delay)
+{
+ CYGACC_CALL_IF_DELAY_US(delay);
+}
+
+// ------------------------------------------------------------------------
+// If we are demuxing for all interrupt sources, we must mask and unmask
+// *all* interrupt sources together.
+
+static inline int
+Mask82559Interrupt(struct i82559* p_i82559)
+{
+ int old = 0;
+
+#ifdef CYGPRI_DEVS_ETH_INTEL_I82559_MASK_INTERRUPTS
+ CYGPRI_DEVS_ETH_INTEL_I82559_MASK_INTERRUPTS(p_i82559,old);
+#else
+// if (query_enabled)
+ old |= 1;
+ cyg_drv_interrupt_mask(p_i82559->vector);
+#ifdef CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT
+// if (query_enabled)
+ old |= 2;
+ cyg_drv_interrupt_mask(CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT);
+#endif
+#endif
+ /* it may prove necessary to do something like this
+ if ( mybits != (mybits & old) )
+ /# then at least one of them was disabled, so
+ # omit both from any restoration: #/
+ old = 0;
+ */
+
+ return old;
+}
+
+static inline void
+UnMask82559Interrupt(struct i82559* p_i82559, int old)
+{
+#ifdef CYGPRI_DEVS_ETH_INTEL_I82559_UNMASK_INTERRUPTS
+ CYGPRI_DEVS_ETH_INTEL_I82559_UNMASK_INTERRUPTS(p_i82559,old);
+#else
+ // We must only unmask (enable) those which were unmasked before,
+ // according to the bits in old.
+ if (old & 1)
+ cyg_drv_interrupt_unmask(p_i82559->vector);
+#ifdef CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT
+ if (old & 2)
+ cyg_drv_interrupt_mask(CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT);
+#endif
+#endif
+}
+
+
+static inline void
+Acknowledge82559Interrupt(struct i82559* p_i82559)
+{
+#ifdef CYGPRI_DEVS_ETH_INTEL_I82559_ACK_INTERRUPTS
+ CYGPRI_DEVS_ETH_INTEL_I82559_ACK_INTERRUPTS(p_i82559);
+#else
+ cyg_drv_interrupt_acknowledge(p_i82559->vector);
+#ifdef CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT
+ cyg_drv_interrupt_acknowledge(CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT);
+#endif
+#endif
+
+#ifdef CYGPRI_DEVS_ETH_INTEL_I82559_INTERRUPT_ACK_LOOP
+ CYGPRI_DEVS_ETH_INTEL_I82559_INTERRUPT_ACK_LOOP(p_i82559);
+#endif
+}
+
+
+static inline void
+Check82559TxLockupTimeout(struct i82559* p_i82559)
+{
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_RESET_TIMEOUT
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_TIMEOUT_FIRED
+ int ints = Mask82559Interrupt(p_i82559);
+ if ( p_i82559->tx_in_progress &&
+ (p_i82559->tx_descriptor_timeout == p_i82559->tx_descriptor_active) ) {
+ if ( CYGHWR_DEVS_ETH_INTEL_I82559_TIMEOUT_FIRED( p_i82559->platform_timeout ) ) {
+ // Then reset the device; the TX unit is locked up.
+ cyg_uint32 ioaddr = p_i82559->io_address;
+ // Wait some time afterwards for chip to settle.
+ OUTL(I82559_SELECTIVE_RESET, ioaddr + SCBPort);
+#ifdef CYGDBG_USE_ASSERTS
+ missed_interrupt.lockup_timeouts++;
+#endif
+ udelay(20);
+ }
+ }
+ else {
+ // All is well:
+ CYGHWR_DEVS_ETH_INTEL_I82559_RESET_TIMEOUT( p_i82559->platform_timeout );
+ p_i82559->tx_descriptor_timeout = p_i82559->tx_descriptor_active;
+ }
+ UnMask82559Interrupt(p_i82559,ints);
+#endif
+#endif
+}
+
+// ------------------------------------------------------------------------
+// Memory management
+//
+// Simply carve off from the front of the PCI mapped window into real memory
+
+static void*
+pciwindow_mem_alloc(int size)
+{
+ void *p_memory;
+ int _size = size;
+
+ CYG_ASSERT(
+ (CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE <= (int)i82559_heap_free)
+ &&
+ ((CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE +
+ CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE) > (int)i82559_heap_free)
+ &&
+ (0 < i82559_heap_size)
+ &&
+ (CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE >= i82559_heap_size)
+ &&
+ (CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE == (int)i82559_heap_base),
+ "Heap variables corrupted" );
+
+ p_memory = (void *)0;
+ size = (size + 3) & ~3;
+ if ( (i82559_heap_free+size) < (i82559_heap_base+i82559_heap_size) ) {
+ cyg_uint32 *p;
+ p_memory = (void *)i82559_heap_free;
+ i82559_heap_free += size;
+ for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 )
+ *p++ = 0;
+ }
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_PCIMEM_DISCONTIGUOUS
+ // Then the underlying physical address can have breaks in it.
+ // We cannot use such a block, clearly, so we just discard and re-do.
+ if ( p_memory ) {
+ char *bpm = (char *)VIRT_TO_BUS( p_memory );
+ char *bmf = (char *)VIRT_TO_BUS( i82559_heap_free );
+
+ if ( bpm + size != bmf ) {
+ // then we found a break; retry:
+ if ( (i82559_heap_free+size) < (i82559_heap_base+i82559_heap_size) ) {
+ cyg_uint32 *p;
+ p_memory = (void *)i82559_heap_free;
+ i82559_heap_free += size;
+ for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 )
+ *p++ = 0;
+ }
+ }
+ }
+#endif
+ CYG_ASSERT(
+ NULL == p_memory ||
+ VIRT_TO_BUS( p_memory ) + size == VIRT_TO_BUS( i82559_heap_free ),
+ "Discontiguous PCI memory in real addresses" );
+
+ return p_memory;
+}
+
+
+// ------------------------------------------------------------------------
+//
+// GET EEPROM SIZE
+//
+// ------------------------------------------------------------------------
+#ifndef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+static int
+get_eeprom_size(long ioaddr)
+{
+ unsigned short retval = 0;
+ int ee_addr = ioaddr + SCBeeprom;
+ int i, addrbits;
+
+ // Should already be not-selected, but anyway:
+ OUTW(EE_ENB & ~EE_CS, ee_addr);
+ eeprom_delay(EEPROM_ENABLE_DELAY);
+ OUTW(EE_ENB, ee_addr);
+ eeprom_delay(EEPROM_ENABLE_DELAY);
+
+ // Shift the read command bits out.
+ for (i = 2; i >= 0; i--) {
+ short dataval = (6 & (1 << i)) ? EE_DATA_WRITE : 0;
+ OUTW(EE_ENB | dataval , ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ OUTW(EE_ENB | dataval , ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ }
+ // Now clock out address zero, looking for the dummy 0 data bit
+ for ( i = 1; i <= 12; i++ ) {
+ OUTW(EE_ENB , ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ OUTW(EE_ENB , ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ retval = INW(ee_addr) & EE_DATA_READ;
+ if ( 0 == retval )
+ break; // The dummy zero est arrive'
+ }
+
+#ifdef DEBUG_EE
+ os_printf( "eeprom data bits %d (ioaddr %x)\n", i, ee_addr );
+#endif
+
+ if ( 6 != i && 8 != i && 1 != i) {
+#ifdef DEBUG_EE
+ os_printf( "*****EEPROM data bits not 6, 8 or 1*****\n" );
+#endif
+ i = 6; // guess, to complete this routine
+ addrbits = 1; // Flag no eeprom here.
+ }
+ else
+ addrbits = i;
+
+ // clear the dataval, leave the clock low to read in the data regardless
+ OUTW(EE_ENB, ee_addr);
+ eeprom_delay(1);
+
+ retval = INW(ee_addr);
+ if ( (EE_DATA_READ & retval) != 0 ) {
+#ifdef DEBUG_EE
+ os_printf( "Size EEPROM: Dummy data bit not 0, reg %x\n" , retval );
+#endif
+ }
+ eeprom_delay(1);
+
+ for (i = EE_TOP_DATA_BIT; i >= 0; i--) {
+ OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ retval = INW(ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ OUTW(EE_ENB, ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ }
+
+ // Terminate the EEPROM access.
+ OUTW(EE_ENB & ~EE_CS, ee_addr);
+ eeprom_delay(EEPROM_DONE_DELAY);
+
+ return addrbits;
+}
+
+
+// ------------------------------------------------------------------------
+//
+// READ EEPROM
+//
+// ------------------------------------------------------------------------
+static int
+read_eeprom(long ioaddr, int location, int addr_len)
+{
+ unsigned short retval = 0;
+ int ee_addr = ioaddr + SCBeeprom;
+ int read_cmd = location | EE_READ_CMD(addr_len);
+ int i, tries = 10;
+
+ try_again:
+ // Should already be not-selected, but anyway:
+ OUTW(EE_ENB & ~EE_CS, ee_addr);
+ eeprom_delay(EEPROM_ENABLE_DELAY);
+ OUTW(EE_ENB, ee_addr);
+ eeprom_delay(EEPROM_ENABLE_DELAY);
+
+ // Shift the read command bits out, changing only one bit per time.
+ for (i = EE_TOP_CMD_BIT(addr_len); i >= 0; i--) {
+ short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+ OUTW(EE_ENB | dataval , ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ OUTW(EE_ENB | dataval , ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ }
+
+ // clear the dataval, leave the clock low
+ OUTW(EE_ENB, ee_addr);
+ eeprom_delay(1);
+
+ retval = INW(ee_addr);
+ // This should show a zero in the data read bit to confirm that the
+ // address transfer is compelete. If not, go to the start and try
+ // again!
+ if ( (0 != (retval & EE_DATA_READ)) && (tries-- > 0) ) {
+ // Terminate the EEPROM access.
+ OUTW(EE_ENB & ~EE_CS, ee_addr);
+ eeprom_delay(EEPROM_DONE_DELAY);
+#ifdef DEBUG_EE
+ os_printf( "Warning: Retrying EEPROM read word %d, address %x, try %d\n",
+ location, ee_addr, tries+1 );
+#endif
+ goto try_again;
+ }
+
+ // This fires with one device on one of the customer boards!
+ // (but is OK on all other h/w. Worrying huh.)
+ if ( (EE_DATA_READ & retval) != 0 ) {
+#ifdef DEBUG_EE
+ os_printf( "Read EEPROM: Dummy data bit not 0, reg %x\n" , retval );
+#endif
+ }
+ eeprom_delay(1);
+ retval = 0;
+
+ for (i = EE_TOP_DATA_BIT; i >= 0; i--) {
+ OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ retval = (retval << 1) | ((INW(ee_addr) & EE_DATA_READ) ? 1 : 0);
+ eeprom_delay(EEPROM_SK_DELAY);
+ OUTW(EE_ENB, ee_addr);
+ eeprom_delay(EEPROM_SK_DELAY);
+ }
+
+ // Terminate the EEPROM access.
+ OUTW(EE_ENB & ~EE_CS, ee_addr);
+ eeprom_delay(EEPROM_DONE_DELAY);
+
+ return retval;
+}
+
+static int
+read_eeprom_esa(struct i82559 *p_i82559, cyg_uint8 *addr)
+{
+ int addr_length, i, count;
+ cyg_uint16 checksum;
+ cyg_uint32 ioaddr = p_i82559->io_address;
+
+ // read eeprom and get 82559's mac address
+ addr_length = get_eeprom_size(ioaddr);
+ // (this is the length of the *EEPROM*s address, not MAC address)
+
+ // If length is 1, it _probably_ means there's no EEPROM
+ // present. Couldn't find an explicit mention of this in the
+ // docs, but length=1 appears to be the behaviour in that case.
+ if (1 == addr_length) {
+#ifdef DEBUG_EE
+ os_printf("Error: No EEPROM present for device %d\n",
+ p_i82559->index);
+#endif
+ } else {
+ for (checksum = 0, i = 0, count = 0; count < (1 << addr_length); count++) {
+ cyg_uint16 value;
+ // read word from eeprom
+ value = read_eeprom(ioaddr, count, addr_length);
+#ifdef DEBUG_EE
+ os_printf( "%2d: %04x\n", count, value );
+#endif
+ checksum += value;
+ if (count < 3) {
+ addr[i++] = value & 0xFF;
+ addr[i++] = (value >> 8) & 0xFF;
+ }
+ }
+
+#ifndef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_WITHOUT_CRC
+ // If the EEPROM checksum is wrong, the MAC address read
+ // from the EEPROM is probably wrong as well. In that
+ // case, we don't set mac_addr_ok, but continue the
+ // initialization. If then somebody calls i82559_start
+ // without calling eth_set_mac_address() first, we refuse
+ // to bring up the interface, because running with an
+ // invalid MAC address is not a very brilliant idea.
+
+ if ((checksum & 0xFFFF) != 0xBABA) {
+ // selftest verified checksum, verify again
+#ifdef DEBUG_EE
+ os_printf("Warning: Invalid EEPROM checksum %04X for device %d\n",
+ checksum, p_i82559->index);
+#endif
+ } else // trailing block
+#endif // ! CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_WITHOUT_CRC
+ {
+#ifdef DEBUG_EE
+ os_printf("Valid EEPROM checksum\n");
+#endif
+ return 1;
+ }
+ }
+ return 0;
+}
+#endif // ! CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+
+// ------------------------------------------------------------------------
+//
+// NETWORK INTERFACE INITIALIZATION
+//
+// Function : Init82559
+//
+// Description :
+// This routine resets, configures, and initializes the chip.
+// It also clears the ethernet statistics structure, and selects
+// which statistics are supported by this driver.
+//
+// ------------------------------------------------------------------------
+static bool
+i82559_init(struct cyg_netdevtab_entry * ndp)
+{
+ static int initialized = 0; // only probe PCI et al *once*
+
+ struct eth_drv_sc *sc;
+ cyg_uint32 selftest;
+ volatile cyg_uint32 *p_selftest;
+ cyg_uint32 ioaddr;
+ int count;
+ int ints;
+ struct i82559 *p_i82559;
+ cyg_uint8 mac_address[ETHER_ADDR_LEN];
+
+#ifdef DEBUG
+ // db_printf("intel_i82559_init\n");
+#endif
+
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+ p_i82559 = (struct i82559 *)(sc->driver_private);
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "Bad device private pointer %x\n", sc->driver_private );
+#endif
+ return 0;
+ }
+
+ CHECK_NDP_SC_LINK();
+
+ if ( 0 == initialized++ ) {
+ // then this is the first time ever:
+ if ( ! pci_init_find_82559s() ) {
+#ifdef DEBUG
+ os_printf( "pci_init_find_82559s failed\n" );
+#endif
+ return 0;
+ }
+ }
+
+ // If this device is not present, exit
+ if (0 == p_i82559->found)
+ return 0;
+
+ p_i82559->mac_addr_ok = 0;
+
+ ioaddr = p_i82559->io_address; // get I/O address for 82559
+
+#ifdef DEBUG
+ os_printf("Init82559 %d @ %x\n82559 Self Test\n",
+ p_i82559->index, (int)ndp);
+#endif
+
+ ints = Mask82559Interrupt(p_i82559);
+
+ // Reset device
+ i82559_reset(p_i82559);
+
+ // Perform a system self-test. (get enough mem to round address)
+ if ( (selftest = (cyg_uint32)pciwindow_mem_alloc(32) ) == 0)
+ return (0);
+ p_selftest = (cyg_uint32 *) ((selftest + 15) & ~0xf);
+ p_selftest[0] = p_selftest[1] = -1;
+
+ OUTL( (VIRT_TO_BUS(p_selftest)) | I82559_SELFTEST, ioaddr + SCBPort);
+ count = 0x7FFFF; // Timeout for self-test.
+ do {
+ udelay(10);
+ } while ( (p_selftest[1] == -1) && (--count >= 0) );
+
+ // Reset device again after selftest
+ i82559_reset(p_i82559);
+
+ Acknowledge82559Interrupt(p_i82559);
+ UnMask82559Interrupt(p_i82559, ints );
+
+ if (count < 0) {
+ // Test timed out.
+#ifdef DEBUG
+ os_printf("Self test failed\n");
+#endif
+ return (0);
+ }
+#ifdef DEBUG
+ os_printf(" General self-test: %s.\n"
+ " Serial sub-system self-test: %s.\n"
+ " Internal registers self-test: %s.\n"
+ " ROM checksum self-test: %s (%08X).\n",
+ HAL_LE32TOC(p_selftest[1]) & 0x1000 ? "failed" : "passed",
+ HAL_LE32TOC(p_selftest[1]) & 0x0020 ? "failed" : "passed",
+ HAL_LE32TOC(p_selftest[1]) & 0x0008 ? "failed" : "passed",
+ HAL_LE32TOC(p_selftest[1]) & 0x0004 ? "failed" : "passed",
+ HAL_LE32TOC(p_selftest[0]));
+#endif
+
+ // free self-test memory?
+ // No, there's no point: this "heap" does not support free.
+
+ if (p_i82559->hardwired_esa) {
+ // Hardwire the address without consulting the EEPROM.
+ // When this flag is set, the p_i82559 will already contain
+ // the ESA. Copy it to a mac_address for call to set_mac_addr
+ mac_address[0] = p_i82559->mac_address[0];
+ mac_address[1] = p_i82559->mac_address[1];
+ mac_address[2] = p_i82559->mac_address[2];
+ mac_address[3] = p_i82559->mac_address[3];
+ mac_address[4] = p_i82559->mac_address[4];
+ mac_address[5] = p_i82559->mac_address[5];
+
+ eth_set_mac_address(p_i82559, mac_address, 0);
+
+ } else {
+
+ // Acquire the ESA either from extenal means (probably RedBoot
+ // variables) or from the attached EEPROM - if there is one.
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA
+ int ok = false;
+ int wflag = 0;
+ CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA( p_i82559, mac_address, ok );
+ if ( ok ) {
+#ifndef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM
+ if ( CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM == p_i82559->index )
+#endif // CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM
+ {
+ cyg_uint8 tmp_addr[ETHER_ADDR_LEN];
+
+ // write eeprom address unless it is already there
+ wflag = 1;
+ if (read_eeprom_esa(p_i82559, tmp_addr)) {
+ int i;
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ if (tmp_addr[i] != mac_address[i])
+ break;
+ if (i >= ETHER_ADDR_LEN)
+ wflag = 0;
+ }
+ }
+#endif // ! CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+ eth_set_mac_address(p_i82559, mac_address, wflag);
+ }
+#else // ! CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA
+
+#ifndef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM
+ if ( CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM == p_i82559->index ) {
+#endif // CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM
+
+ if (read_eeprom_esa(p_i82559, mac_address)) {
+ // record the MAC address in the device structure
+ p_i82559->mac_address[0] = mac_address[0];
+ p_i82559->mac_address[1] = mac_address[1];
+ p_i82559->mac_address[2] = mac_address[2];
+ p_i82559->mac_address[3] = mac_address[3];
+ p_i82559->mac_address[4] = mac_address[4];
+ p_i82559->mac_address[5] = mac_address[5];
+
+ p_i82559->mac_addr_ok = 1;
+
+ eth_set_mac_address(p_i82559, mac_address, 0);
+ }
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM
+ }
+ else { // We are now "in" another device
+#if 1 < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT
+ struct i82559 *other; // The one that *is* set up from EEPROM
+ other = i82559_priv_array[CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM];
+ if ( other->mac_addr_ok ) {
+ mac_address[0] = other->mac_address[0];
+ mac_address[1] = other->mac_address[1];
+ mac_address[2] = other->mac_address[2];
+ mac_address[3] = other->mac_address[3];
+ mac_address[4] = other->mac_address[4];
+ mac_address[5] = other->mac_address[5];
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_MAC_ADJUST
+ mac_address[5] += CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_MAC_ADJUST;
+#endif
+ eth_set_mac_address(p_i82559, mac_address, 0);
+ }
+#endif // 1 < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT
+ }
+#endif // CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM
+
+#endif // ! CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+#endif // ! CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA
+ }
+
+#ifdef DEBUG
+ os_printf("i82559_init: MAC Address = %02X %02X %02X %02X %02X %02X\n",
+ p_i82559->mac_address[0], p_i82559->mac_address[1],
+ p_i82559->mac_address[2], p_i82559->mac_address[3],
+ p_i82559->mac_address[4], p_i82559->mac_address[5]);
+#endif
+
+ // and record the net dev pointer
+ p_i82559->ndp = (void *)ndp;
+
+ p_i82559->within_send = 0; // init recursion level
+
+ p_i82559->promisc = 0; // None of these initially
+ p_i82559->multicast_all = 0;
+ p_i82559->oversized = 1; // Enable this for VLAN mode by default
+
+ InitRxRing(p_i82559);
+ InitTxRing(p_i82559);
+
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+
+ // Initialize upper level driver
+ if ( p_i82559->mac_addr_ok )
+ (sc->funs->eth_drv->init)(sc, &(p_i82559->mac_address[0]) );
+ else
+ (sc->funs->eth_drv->init)(sc, NULL );
+
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+
+ return (1);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82559_start
+//
+// ------------------------------------------------------------------------
+static void
+i82559_start( struct eth_drv_sc *sc, unsigned char *enaddr, int flags )
+{
+ struct i82559 *p_i82559;
+ cyg_uint32 ioaddr;
+#ifdef KEEP_STATISTICS
+ void *p_statistics;
+#endif
+#ifdef CYGPKG_NET
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+
+ p_i82559 = (struct i82559 *)sc->driver_private;
+ ioaddr = p_i82559->io_address; // get 82559's I/O address
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "i82559_start: Bad device pointer %x\n", p_i82559 );
+#endif
+ return;
+ }
+
+ if ( ! p_i82559->mac_addr_ok ) {
+#ifdef DEBUG
+ os_printf("i82559_start %d: invalid MAC address, "
+ "can't bring up interface\n",
+ p_i82559->index );
+#endif
+ return;
+ }
+
+ if ( p_i82559->active )
+ i82559_stop( sc );
+
+#ifdef KEEP_STATISTICS
+#ifdef CYGDBG_DEVS_ETH_INTEL_I82559_KEEP_STATISTICS
+ p_statistics = p_i82559->p_statistics;
+ memset(p_statistics, 0xFFFFFFFF, sizeof(I82559_COUNTERS));
+ // set statistics dump address
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+ OUTL(VIRT_TO_BUS(p_statistics), ioaddr + SCBPointer);
+ OUTW(SCB_M | CU_STATSADDR, ioaddr + SCBCmd);
+ // Start dump command
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+ OUTW(SCB_M | CU_DUMPSTATS, ioaddr + SCBCmd); // start register dump
+ // ...and wait for it to complete operation
+
+ // The code to wait was bogus; it was looking at the structure in the
+ // wrong way. In any case, there is no need to wait, the
+ // wait_for_cmd_done() in any following activity is good enough.
+
+#endif
+#endif
+
+ // Enable device
+ p_i82559->active = 1;
+
+ /* Enable promiscuous mode if requested, reception of oversized frames always.
+ * The latter is needed for VLAN support and shouldn't hurt even if we're not
+ * using VLANs. Reset multicastALL reception choice.
+ */
+
+ p_i82559->promisc = 0
+#ifdef CYGPKG_NET
+ || !!(ifp->if_flags & IFF_PROMISC)
+#endif
+#ifdef ETH_DRV_FLAGS_PROMISC_MODE
+ || !!(flags & ETH_DRV_FLAGS_PROMISC_MODE)
+#endif
+ ;
+
+ p_i82559->multicast_all = 0;
+
+ i82559_configure(p_i82559,
+ p_i82559->promisc,
+ p_i82559->oversized,
+ p_i82559->multicast_all );
+
+#ifdef DEBUG
+ {
+ int status = i82559_status( sc );
+ os_printf("i82559_start %d flg %x Link = %s, %s Mbps, %s Duplex\n",
+ p_i82559->index,
+ *(int *)p_i82559,
+ status & GEN_STATUS_LINK ? "Up" : "Down",
+ status & GEN_STATUS_100MBPS ? "100" : "10",
+ status & GEN_STATUS_FDX ? "Full" : "Half");
+ }
+#endif
+
+ i82559_restart(p_i82559);
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+}
+
+static void i82559_restart(struct i82559 *p_i82559)
+{
+ cyg_uint32 ioaddr;
+ ioaddr = p_i82559->io_address; // get 82559's I/O address
+
+ // Load pointer to Rx Ring and enable receiver
+ wait_for_cmd_done(ioaddr, WAIT_RU);
+ OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]), ioaddr + SCBPointer);
+ OUTW(RUC_START, ioaddr + SCBCmd);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82559_status
+//
+// ------------------------------------------------------------------------
+int
+i82559_status( struct eth_drv_sc *sc )
+{
+ int status;
+ struct i82559 *p_i82559;
+ cyg_uint32 ioaddr;
+ p_i82559 = (struct i82559 *)sc->driver_private;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "i82559_status: Bad device pointer %x\n", p_i82559 );
+#endif
+ return 0;
+ }
+
+ ioaddr = p_i82559->io_address; // get 82559's I/O address
+
+ status = INB(ioaddr + SCBGenStatus);
+
+ return status;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : BringDown82559
+//
+// ------------------------------------------------------------------------
+
+static void
+i82559_stop( struct eth_drv_sc *sc )
+{
+ struct i82559 *p_i82559;
+
+ p_i82559 = (struct i82559 *)sc->driver_private;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "i82559_stop: Bad device pointer %x\n", p_i82559 );
+#endif
+ return;
+ }
+
+#ifdef DEBUG
+ os_printf("i82559_stop %d flg %x\n", p_i82559->index, *(int *)p_i82559 );
+#endif
+
+ p_i82559->active = 0; // stop people tormenting it
+ i82559_reset(p_i82559); // that should stop it
+
+ // Now that it's inactive, return all pending tx status to the higher
+ // layers:
+ // "Done" txen are from here to active, OR
+ // the remove one if the queue is full AND its status is nonzero:
+ while ( 1 ) {
+ int tx_descriptor_remove = p_i82559->tx_descriptor_remove;
+ unsigned long key = p_i82559->tx_keys[ tx_descriptor_remove ];
+
+ // Break out if "remove" is the active slot
+ // (AND the Q is not full, or the Tx is not complete yet)
+ if ( (tx_descriptor_remove == p_i82559->tx_descriptor_active) &&
+ ( ! p_i82559->tx_queue_full) )
+ break;
+
+ // Zero the key in global state before the callback:
+ p_i82559->tx_keys[ tx_descriptor_remove ] = 0;
+
+#ifdef DEBUG_82559
+ os_printf("Stop: TxDone %d %x: KEY %x TxCB %x\n",
+ p_i82559->index, (int)p_i82559, key,
+ p_i82559->tx_ring[ tx_descriptor_remove ]);
+#endif
+ // tx_done() can now cope with a NULL key, no guard needed here
+ (sc->funs->eth_drv->tx_done)( sc, key, 1 /* status */ );
+
+ if ( ++tx_descriptor_remove >= MAX_TX_DESCRIPTORS )
+ tx_descriptor_remove = 0;
+ p_i82559->tx_descriptor_remove = tx_descriptor_remove;
+ p_i82559->tx_queue_full = 0;
+ }
+
+ ResetRxRing( p_i82559 );
+ ResetTxRing( p_i82559 );
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : InitRxRing
+//
+// ------------------------------------------------------------------------
+static void
+InitRxRing(struct i82559* p_i82559)
+{
+ int i;
+ RFD *rfd;
+ RFD *p_rfd = 0;
+#ifdef DEBUG_82559
+ os_printf("InitRxRing %d\n", p_i82559->index);
+#endif
+ for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ ) {
+ rfd = (RFD *)pciwindow_mem_alloc(RFD_SIZEOF + MAX_RX_PACKET_SIZE);
+ p_i82559->rx_ring[i] = rfd;
+ if ( i )
+ WRITEMEM32(p_rfd+RFD_LINK, HAL_CTOLE32(VIRT_TO_BUS(rfd)));
+ p_rfd = (RFD *)rfd;
+ }
+ // link last RFD to first:
+ WRITEMEM32(p_rfd+RFD_LINK,
+ HAL_CTOLE32(VIRT_TO_BUS(p_i82559->rx_ring[0])));
+
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+ ResetRxRing( p_i82559 );
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : ResetRxRing
+//
+// ------------------------------------------------------------------------
+static void
+ResetRxRing(struct i82559* p_i82559)
+{
+ RFD *p_rfd;
+ int i;
+#ifdef DEBUG_82559
+ os_printf("ResetRxRing %d\n", p_i82559->index);
+#endif
+ for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ ) {
+ p_rfd = p_i82559->rx_ring[i];
+ CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
+ CYG_ASSERT( (cyg_uint8 *)p_rfd < i82559_heap_free, "rfd over" );
+#ifdef CYGDBG_USE_ASSERTS
+ {
+ RFD *p_rfd2;
+ cyg_uint32 link;
+ p_rfd2 = p_i82559->rx_ring[ ( i ? (i-1) : (MAX_RX_DESCRIPTORS-1) ) ];
+ READMEM32(p_rfd2 + RFD_LINK, link);
+ if (!(HAL_LE32TOC(link) == VIRT_TO_BUS(p_rfd))) {
+ START_CONSOLE();
+ diag_printf("Bad link eth%d %p %p %d %p\n",
+ p_i82559->index,
+ HAL_LE32TOC(link), VIRT_TO_BUS(p_rfd),
+ i, __builtin_return_address(0));
+ END_CONSOLE();
+ }
+ CYG_ASSERT( HAL_LE32TOC(link) == VIRT_TO_BUS(p_rfd),
+ "rfd linked list broken" );
+ }
+#endif
+ WRITEMEM32(p_rfd + RFD_STATUS, 0 ); // do NOT suspend after just one rx
+ WRITEMEM16(p_rfd + RFD_COUNT, 0);
+ WRITEMEM32(p_rfd + RFD_RDB_ADDR, HAL_CTOLE32(0xFFFFFFFF));
+ WRITEMEM16(p_rfd + RFD_SIZE, HAL_CTOLE16(MAX_RX_PACKET_SIZE));
+ }
+ p_i82559->next_rx_descriptor = 0;
+ // And set an end-of-list marker in the previous one.
+ WRITEMEM32(p_rfd + RFD_STATUS, RFD_STATUS_EL);
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : CheckRxRing
+//
+// ------------------------------------------------------------------------
+void
+CheckRxRing(struct i82559* p_i82559, const char * func, int line)
+{
+ RFD *p_rfd;
+ int i;
+ RFD *p_rfd2;
+ cyg_uint32 link;
+
+ // console_printf("%s:%d(eth%d)\n",func,line,p_i82559->index);
+
+ for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ ) {
+ p_rfd = p_i82559->rx_ring[i];
+ if (! ((cyg_uint8 *)p_rfd >= i82559_heap_base))
+ console_printf("rfd under: %s:%d\n", func, line);
+ if (! ((cyg_uint8 *)p_rfd < i82559_heap_free))
+ console_printf("rfd over: %s:%d\n", func, line );
+
+ p_rfd2 = p_i82559->rx_ring[ ( i ? (i-1) : (MAX_RX_DESCRIPTORS-1) ) ];
+ READMEM32(p_rfd2 + RFD_LINK, link);
+ if (!(HAL_LE32TOC(link) == VIRT_TO_BUS(p_rfd))) {
+ console_printf("Bad link eth%d %p %p %d %p: %s:%d\n",
+ p_i82559->index,
+ HAL_LE32TOC(link), VIRT_TO_BUS(p_rfd),
+ i, __builtin_return_address(0),
+ func,line);
+ CYG_ASSERT(HAL_LE32TOC(link) == VIRT_TO_BUS(p_rfd),"Bad Link");
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : PacketRxReady (Called from delivery thread & foreground)
+//
+// ------------------------------------------------------------------------
+static void
+PacketRxReady(struct i82559* p_i82559)
+{
+ RFD *p_rfd;
+ int next_descriptor;
+ int length, ints;
+ struct cyg_netdevtab_entry *ndp;
+ struct eth_drv_sc *sc;
+ cyg_uint32 ioaddr;
+ cyg_uint16 status;
+
+ ndp = (struct cyg_netdevtab_entry *)(p_i82559->ndp);
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+
+ CHECK_NDP_SC_LINK();
+
+ ioaddr = p_i82559->io_address;
+
+ next_descriptor = p_i82559->next_rx_descriptor;
+ p_rfd = p_i82559->rx_ring[next_descriptor];
+
+ CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
+ CYG_ASSERT( (cyg_uint8 *)p_rfd < i82559_heap_free, "rfd over" );
+
+ while ( 1 ) {
+ cyg_uint32 rxstatus;
+ cyg_uint16 rxstatus_hi;
+ READMEM32(p_rfd + RFD_STATUS, rxstatus);
+ if (0 == (rxstatus & RFD_STATUS_C))
+ break;
+
+ READMEM16(p_rfd + RFD_STATUS_HI, rxstatus_hi);
+ rxstatus_hi |= RFD_STATUS_HI_EL;
+ WRITEMEM16(p_rfd + RFD_STATUS_HI, rxstatus_hi);
+
+ READMEM16(p_rfd + RFD_COUNT, length);
+ length = HAL_LE16TOC(length);
+ length &= RFD_COUNT_MASK;
+
+#ifdef DEBUG_82559
+ os_printf( "Device %d (eth%d), rx descriptor %d:\n",
+ p_i82559->index, p_i82559->index, next_descriptor );
+// dump_rfd( p_rfd, 1 );
+#endif
+
+ p_i82559->next_rx_descriptor = next_descriptor;
+ // Check for bogusly short packets; can happen in promisc mode:
+ // Asserted against and checked by upper layer driver.
+#ifdef CYGPKG_NET
+ if ( length > sizeof( struct ether_header ) )
+ // then it is acceptable; offer the data to the network stack
+#endif
+ (sc->funs->eth_drv->recv)( sc, length );
+
+ WRITEMEM16(p_rfd + RFD_COUNT, 0);
+ WRITEMEM16(p_rfd + RFD_STATUS_LO, 0);
+
+ // The just-emptied slot is now ready for re-use and already marked EL;
+ // we can now remove the EL marker from the previous one.
+ if ( 0 == next_descriptor )
+ p_rfd = p_i82559->rx_ring[ MAX_RX_DESCRIPTORS-1 ];
+ else
+ p_rfd = p_i82559->rx_ring[ next_descriptor-1 ];
+ // The previous one: check it *was* marked before clearing.
+ READMEM16(p_rfd + RFD_STATUS_HI, rxstatus_hi);
+ CYG_ASSERT( rxstatus_hi & RFD_STATUS_HI_EL, "No prev EL" );
+ // that word is not written by the device.
+ WRITEMEM16(p_rfd + RFD_STATUS_HI, 0);
+
+#ifdef KEEP_STATISTICS
+ statistics[p_i82559->index].rx_deliver++;
+#endif
+ if (++next_descriptor >= MAX_RX_DESCRIPTORS)
+ next_descriptor = 0;
+ p_rfd = p_i82559->rx_ring[next_descriptor];
+
+ CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
+ CYG_ASSERT( (cyg_uint8 *)p_rfd < i82559_heap_free, "rfd over" );
+
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+
+#ifdef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ // Can't deliver more than one packet in polled standalone mode
+ break;
+#endif
+ }
+
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+
+ // See if the RU has gone idle (usually because of out of resource
+ // condition) and restart it if needs be.
+ ints = Mask82559Interrupt(p_i82559);
+ status = INW(ioaddr + SCBStatus);
+ if ( RU_STATUS_READY != (status & RU_STATUS_MASK) ) {
+ // Acknowledge the RX INT sources
+ OUTW( SCB_INTACK_RX, ioaddr + SCBStatus);
+ // (see pages 6-10 & 6-90)
+
+#ifdef KEEP_STATISTICS
+ statistics[p_i82559->index].rx_restart++;
+#endif
+ // There's an end-of-list marker out there somewhere...
+ // So mop it up; it takes a little time but this is infrequent.
+ ResetRxRing( p_i82559 );
+ next_descriptor = 0; // re-initialize next desc.
+ // load pointer to Rx Ring
+ wait_for_cmd_done(ioaddr, WAIT_RU);
+ OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]),
+ ioaddr + SCBPointer);
+ OUTW(RUC_START, ioaddr + SCBCmd);
+ Acknowledge82559Interrupt(p_i82559);
+ }
+ UnMask82559Interrupt(p_i82559, ints);
+
+ p_i82559->next_rx_descriptor = next_descriptor;
+}
+
+// and the callback function
+
+static void
+i82559_recv( struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len )
+{
+ struct i82559 *p_i82559;
+ RFD *p_rfd;
+ int next_descriptor;
+ int total_len;
+ struct eth_drv_sg *last_sg;
+ volatile cyg_uint8 *from_p;
+ cyg_uint32 rxstatus;
+ cyg_uint16 rxstatus16;
+
+ p_i82559 = (struct i82559 *)sc->driver_private;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "i82559_recv: Bad device pointer %x\n", p_i82559 );
+#endif
+ return;
+ }
+
+ next_descriptor = p_i82559->next_rx_descriptor;
+ p_rfd = p_i82559->rx_ring[next_descriptor];
+
+ CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" );
+ CYG_ASSERT( (cyg_uint8 *)p_rfd < i82559_heap_free, "rfd over" );
+
+ READMEM32(p_rfd + RFD_STATUS, rxstatus);
+ CYG_ASSERT( rxstatus & RFD_STATUS_C, "No complete frame" );
+ CYG_ASSERT( rxstatus & RFD_STATUS_EL, "No marked frame" );
+ READMEM16(p_rfd + RFD_STATUS_LO, rxstatus16 );
+ CYG_ASSERT( rxstatus16 & RFD_STATUS_LO_C, "No complete frame 2" );
+ READMEM16(p_rfd + RFD_STATUS_HI, rxstatus16 );
+ CYG_ASSERT( rxstatus16 & RFD_STATUS_HI_EL, "No marked frame 2" );
+
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+
+ if ( 0 == (rxstatus & RFD_STATUS_C) )
+ return;
+
+ READMEM16(p_rfd + RFD_COUNT, total_len);
+ total_len = HAL_LE16TOC(total_len);
+ total_len &= RFD_COUNT_MASK;
+
+#ifdef DEBUG_82559
+ os_printf("Rx %d %x (status %x): %d sg's, %d bytes\n",
+ p_i82559->index, (int)p_i82559,
+ HAL_LE32TOC(rxstatus), sg_len, total_len);
+#endif
+
+ // Copy the data to the network stack
+ from_p = p_rfd + RFD_BUFFER;
+
+ // check we have memory to copy into; we would be called even if
+ // caller was out of memory in order to maintain our state.
+ if ( 0 == sg_len || 0 == sg_list )
+ return; // caller was out of mbufs
+
+ CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
+ CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
+
+ for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
+ cyg_uint8 *to_p;
+ int l;
+
+ to_p = (cyg_uint8 *)(sg_list->buf);
+ l = sg_list->len;
+
+ CYG_ASSERT( 0 <= l, "sg length -ve" );
+
+ if ( 0 >= l || 0 == to_p )
+ return; // caller was out of mbufs
+
+ if ( l > total_len )
+ l = total_len;
+
+ memcpy( to_p, (unsigned char *)from_p, l );
+ from_p += l;
+ total_len -= l;
+ }
+
+ CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" );
+ CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" );
+ CYG_ASSERT( p_rfd + RFD_BUFFER < from_p, "from_p wild in rx" );
+ CYG_ASSERT( p_rfd + RFD_BUFFER + MAX_RX_PACKET_SIZE >= from_p,
+ "from_p overflow in rx" );
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : InitTxRing
+//
+// ------------------------------------------------------------------------
+static void
+InitTxRing(struct i82559* p_i82559)
+{
+ int i;
+ cyg_uint32 ioaddr;
+
+#ifdef DEBUG_82559
+ os_printf("InitTxRing %d\n", p_i82559->index);
+#endif
+ ioaddr = p_i82559->io_address;
+ for ( i = 0; i < MAX_TX_DESCRIPTORS; i++) {
+ p_i82559->tx_ring[i] = (TxCB *)pciwindow_mem_alloc(
+ TxCB_SIZEOF + MAX_TX_PACKET_SIZE);
+ }
+
+ ResetTxRing(p_i82559);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : ResetTxRing
+//
+// ------------------------------------------------------------------------
+static void
+ResetTxRing(struct i82559* p_i82559)
+{
+ int i;
+ cyg_uint32 ioaddr;
+
+#ifdef DEBUG_82559
+ os_printf("ResetTxRing %d\n", p_i82559->index);
+#endif
+ ioaddr = p_i82559->io_address;
+ p_i82559->tx_descriptor_add =
+ p_i82559->tx_descriptor_active =
+ p_i82559->tx_descriptor_remove = 0;
+ p_i82559->tx_in_progress =
+ p_i82559->tx_queue_full = 0;
+
+ for ( i = 0; i < MAX_TX_DESCRIPTORS; i++) {
+ TxCB *p_txcb = p_i82559->tx_ring[i];
+ CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" );
+ CYG_ASSERT( (cyg_uint8 *)p_txcb < i82559_heap_free, "txcb over" );
+
+ WRITEMEM16(p_txcb + TxCB_STATUS, 0);
+ WRITEMEM16(p_txcb + TxCB_CMD, 0);
+ WRITEMEM32(p_txcb + TxCB_LINK,
+ HAL_CTOLE32(VIRT_TO_BUS((cyg_uint32)p_txcb)));
+ WRITEMEM32(p_txcb + TxCB_TBD_ADDR, HAL_CTOLE32(0xFFFFFFFF));
+ WRITEMEM8(p_txcb + TxCB_TBD_NUMBER, 0);
+ WRITEMEM8(p_txcb + TxCB_TX_THRESHOLD, 16);
+ WRITEMEM16(p_txcb + TxCB_COUNT,
+ HAL_CTOLE16(TxCB_COUNT_EOF | 0));
+ p_i82559->tx_keys[i] = 0;
+ }
+
+ wait_for_cmd_done(ioaddr,WAIT_CU);
+ OUTL(0, ioaddr + SCBPointer);
+ OUTW(SCB_M | CU_ADDR_LOAD, ioaddr + SCBCmd);
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : TxMachine (Called from FG & ISR)
+//
+// This steps the Tx Machine onto the next record if necessary - allowing
+// for missed interrupts, and so on.
+// ------------------------------------------------------------------------
+
+static void
+TxMachine(struct i82559* p_i82559)
+{
+ int tx_descriptor_active;
+ cyg_uint32 ioaddr;
+
+ tx_descriptor_active = p_i82559->tx_descriptor_active;
+ ioaddr = p_i82559->io_address;
+
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+ // See if the CU is idle when we think it isn't; this is the only place
+ // tx_descriptor_active is advanced. (Also recovers from a dropped intr)
+ if ( p_i82559->tx_in_progress ) {
+ cyg_uint16 status;
+ status = INW(ioaddr + SCBStatus);
+ if ( 0 == (status & CU_STATUS_MASK) ) {
+ // It is idle. So ack the TX interrupts
+ OUTW( SCB_INTACK_TX, ioaddr + SCBStatus);
+ // (see pages 6-10 & 6-90)
+
+ // and step on to the next queued tx.
+ p_i82559->tx_in_progress = 0;
+ if ( ++tx_descriptor_active >= MAX_TX_DESCRIPTORS )
+ tx_descriptor_active = 0;
+ p_i82559->tx_descriptor_active = tx_descriptor_active;
+ }
+ }
+
+ // is the CU idle, and there a next tx to set going?
+ if ( ( ! p_i82559->tx_in_progress )
+ && (( p_i82559->tx_descriptor_add != tx_descriptor_active )
+ || p_i82559->tx_queue_full ) ) {
+ TxCB *p_txcb = p_i82559->tx_ring[tx_descriptor_active];
+ cyg_uint16 status;
+
+ // start Tx operation
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+ status = INW(ioaddr + SCBStatus);
+ // The following assert sometimes fires here, apparantly harmless!
+ // So check a second time to let the cursed thing settle and not
+ // tell us lies.
+ if ( 0 != (status & CU_STATUS_MASK) ) {
+#ifdef CYGDBG_USE_ASSERTS
+ missed_interrupt.bad_cu_idles++;
+#endif
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+ status = INW(ioaddr + SCBStatus);
+ }
+ CYG_ASSERT( ( 0 == (status & CU_STATUS_MASK)), "CU not idle");
+ CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" );
+ CYG_ASSERT( (cyg_uint8 *)p_txcb < i82559_heap_free, "txcb over" );
+#ifdef DEBUG_82559
+ {
+ unsigned long key = p_i82559->tx_keys[ tx_descriptor_active ];
+ os_printf("Tx %d %x: Starting Engines: KEY %x TxCB %x\n",
+ p_i82559->index, (int)p_i82559, key, p_txcb);
+ }
+#endif
+
+ OUTL(VIRT_TO_BUS(p_txcb), ioaddr + SCBPointer);
+ OUTW(CU_START, ioaddr + SCBCmd);
+ p_i82559->tx_in_progress = 1;
+ }
+ CheckRxRing(p_i82559,__FUNCTION__,__LINE__);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : TxDone (Called from delivery thread)
+//
+// This returns Tx's from the Tx Machine to the stack (ie. reports
+// completion) - allowing for missed interrupts, and so on.
+// ------------------------------------------------------------------------
+
+static void
+TxDone(struct i82559* p_i82559)
+{
+ struct cyg_netdevtab_entry *ndp;
+ struct eth_drv_sc *sc;
+ int tx_descriptor_remove = p_i82559->tx_descriptor_remove;
+
+ ndp = (struct cyg_netdevtab_entry *)(p_i82559->ndp);
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ CHECK_NDP_SC_LINK();
+
+ // "Done" txen are from here to active, OR
+ // the remove one if the queue is full AND its status is nonzero:
+ while ( 1 ) {
+ cyg_uint16 txstatus;
+ TxCB *p_txcb = p_i82559->tx_ring[ tx_descriptor_remove ];
+ unsigned long key = p_i82559->tx_keys[ tx_descriptor_remove ];
+
+ READMEM16(p_txcb + TxCB_STATUS, txstatus);
+
+ // Break out if "remove" is the active slot
+ // (AND the Q is not full, or the Tx is not complete yet)
+ if ( (tx_descriptor_remove == p_i82559->tx_descriptor_active) &&
+ ( ( ! p_i82559->tx_queue_full) || (0 == txstatus) ) )
+ break;
+
+ // Zero the key in global state before the callback:
+ p_i82559->tx_keys[ tx_descriptor_remove ] = 0;
+
+#ifdef DEBUG_82559
+ os_printf("TxDone %d %x: KEY %x TxCB %x\n",
+ p_i82559->index, (int)p_i82559, key, p_txcb );
+#endif
+ // tx_done() can now cope with a NULL key, no guard needed here
+ (sc->funs->eth_drv->tx_done)( sc, key, 1 /* status */ );
+
+ if ( ++tx_descriptor_remove >= MAX_TX_DESCRIPTORS )
+ tx_descriptor_remove = 0;
+ p_i82559->tx_descriptor_remove = tx_descriptor_remove;
+ p_i82559->tx_queue_full = 0;
+ }
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : i82559_can_send
+//
+// ------------------------------------------------------------------------
+
+static int
+i82559_can_send(struct eth_drv_sc *sc)
+{
+ struct i82559 *p_i82559;
+ int ints;
+
+ p_i82559 = (struct i82559 *)sc->driver_private;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "i82559_send: Bad device pointer %x\n", p_i82559 );
+#endif
+ return 0;
+ }
+
+ // Advance TxMachine atomically
+ ints = Mask82559Interrupt(p_i82559);
+
+ // This helps unstick deadly embraces.
+ CYG_ASSERT( p_i82559->within_send < 10, "send: Excess send recursions" );
+ p_i82559->within_send++;
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+ {
+ int i;
+ // The problem is, if DEMUX_ALL, either device can eat the other's
+ // interrupts; so we must poll them *both*:
+ for (i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT; i++) {
+ p_i82559 = i82559_priv_array[i];
+ if ( p_i82559->active ) {
+ // See if the Tx machine is wedged - reset if so:
+ Check82559TxLockupTimeout(p_i82559);
+ TxMachine(p_i82559);
+ Acknowledge82559Interrupt(p_i82559);
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ // We are not prepared to receive a packet now if we are in a polled
+ // standalone configuration.
+ PacketRxReady(p_i82559);
+#endif
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT
+ if ( CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT(p_i82559) ) {
+#ifdef CYGDBG_USE_ASSERTS
+ missed_interrupt.can_send++;
+#endif
+ eth_isr( p_i82559->vector, (cyg_addrword_t)p_i82559 );
+ eth_dsr( p_i82559->vector, 1, (cyg_addrword_t)p_i82559 );
+ }
+#endif
+ }
+ }
+ }
+ // ensure we look at the correct device at the end
+ p_i82559 = (struct i82559 *)sc->driver_private;
+#else // no CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+
+ // See if the Tx machine is wedged - reset if so:
+ Check82559TxLockupTimeout(p_i82559);
+ TxMachine(p_i82559);
+ Acknowledge82559Interrupt(p_i82559); // This can eat an Rx interrupt, so
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ // We are not prepared to receive a packet now if we are in a polled
+ // standalone configuration.
+ PacketRxReady(p_i82559);
+#endif
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT
+ if ( CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT(p_i82559) ) {
+#ifdef CYGDBG_USE_ASSERTS
+ missed_interrupt.can_send++;
+#endif
+ eth_isr( p_i82559->vector, (cyg_addrword_t)p_i82559 );
+ eth_dsr( p_i82559->vector, 1, (cyg_addrword_t)p_i82559 );
+ }
+#endif
+#endif // no CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+
+ p_i82559->within_send--;
+ UnMask82559Interrupt(p_i82559,ints);
+
+ return (0 == p_i82559->within_send) && ! p_i82559->tx_queue_full;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82559_send
+//
+// ------------------------------------------------------------------------
+
+static void
+i82559_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list, int sg_len, int total_len,
+ unsigned long key)
+{
+ struct i82559 *p_i82559;
+ int tx_descriptor_add, ints;
+ TxCB *p_txcb;
+ cyg_uint32 ioaddr;
+
+ p_i82559 = (struct i82559 *)sc->driver_private;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "i82559_send: Bad device pointer %x\n", p_i82559 );
+#endif
+ return;
+ }
+
+#ifdef DEBUG_82559
+ os_printf("Tx %d %x: %d sg's, %d bytes, KEY %x\n",
+ p_i82559->index, (int)p_i82559, sg_len, total_len, key );
+#endif
+
+ if ( ! p_i82559->active )
+ return; // device inactive, no return
+#ifdef KEEP_STATISTICS
+ statistics[p_i82559->index].tx_count++;
+#endif
+ ioaddr = p_i82559->io_address; // get device I/O address
+
+ // See if the Tx machine is wedged - reset if so:
+ Check82559TxLockupTimeout(p_i82559);
+
+ if ( p_i82559->tx_queue_full ) {
+#ifdef KEEP_STATISTICS
+ statistics[p_i82559->index].tx_dropped++;
+#endif
+#ifdef DEBUG_82559
+ os_printf( "i82559_send: Queue full, device %x, key %x\n",
+ p_i82559, key );
+#endif
+ }
+ else {
+ struct eth_drv_sg *last_sg;
+ volatile cyg_uint8 *to_p;
+
+ tx_descriptor_add = p_i82559->tx_descriptor_add;
+
+ p_i82559->tx_keys[tx_descriptor_add] = key;
+
+ p_txcb = p_i82559->tx_ring[tx_descriptor_add];
+
+ CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" );
+ CYG_ASSERT( (cyg_uint8 *)p_txcb < i82559_heap_free, "txcb over" );
+
+ WRITEMEM16(p_txcb + TxCB_STATUS, 0);
+ WRITEMEM16(p_txcb + TxCB_CMD,
+ (TxCB_CMD_TRANSMIT | TxCB_CMD_S
+ | TxCB_CMD_I | TxCB_CMD_EL));
+ WRITEMEM32(p_txcb + TxCB_LINK,
+ HAL_CTOLE32(VIRT_TO_BUS((cyg_uint32)p_txcb)));
+ WRITEMEM32(p_txcb + TxCB_TBD_ADDR,
+ HAL_CTOLE32(0xFFFFFFFF));
+ WRITEMEM8(p_txcb + TxCB_TBD_NUMBER, 0);
+ WRITEMEM8(p_txcb + TxCB_TX_THRESHOLD, 16);
+ WRITEMEM16(p_txcb + TxCB_COUNT,
+ HAL_CTOLE16(TxCB_COUNT_EOF | total_len));
+
+ // Copy from the sglist into the txcb
+ to_p = p_txcb + TxCB_BUFFER;
+
+ CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
+ CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
+
+ for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
+ cyg_uint8 *from_p;
+ int l;
+
+ from_p = (cyg_uint8 *)(sg_list->buf);
+ l = sg_list->len;
+
+ if ( l > total_len )
+ l = total_len;
+
+ memcpy( (unsigned char *)to_p, from_p, l );
+ to_p += l;
+ total_len -= l;
+
+ if ( 0 > total_len )
+ break; // Should exit via sg_last normally
+ }
+
+ CYG_ASSERT( 0 == total_len, "length mismatch in tx" );
+ CYG_ASSERT( last_sg == sg_list, "sg count mismatch in tx" );
+ CYG_ASSERT( p_txcb + TxCB_BUFFER < to_p, "to_p wild in tx" );
+ CYG_ASSERT( p_txcb + TxCB_BUFFER + MAX_TX_PACKET_SIZE >= to_p,
+ "to_p overflow in tx" );
+
+ // Next descriptor
+ if ( ++tx_descriptor_add >= MAX_TX_DESCRIPTORS)
+ tx_descriptor_add = 0;
+ p_i82559->tx_descriptor_add = tx_descriptor_add;
+
+ // From this instant, interrupts can advance the world and start,
+ // even complete, this tx request...
+
+ if ( p_i82559->tx_descriptor_remove == tx_descriptor_add )
+ p_i82559->tx_queue_full = 1;
+ }
+
+ // Try advancing the Tx Machine regardless
+
+ // no more interrupts until started
+ ints = Mask82559Interrupt(p_i82559);
+
+ // This helps unstick deadly embraces.
+ CYG_ASSERT( p_i82559->within_send < 10, "send: Excess send recursions" );
+ p_i82559->within_send++;
+
+ // Check that either:
+ // tx is already active, there is other stuff queued,
+ // OR this tx just added is the current active one
+ // OR this tx just added is already complete
+ CYG_ASSERT(
+ // The machine is busy:
+ (p_i82559->tx_in_progress == 1) ||
+ // or: The machine is idle and this just added is the next one
+ (((p_i82559->tx_descriptor_add-1) == p_i82559->tx_descriptor_active)
+ || ((0 == p_i82559->tx_descriptor_add) &&
+ ((MAX_TX_DESCRIPTORS-1) == p_i82559->tx_descriptor_active))) ||
+ // or: This tx is already complete
+ (p_i82559->tx_descriptor_add == p_i82559->tx_descriptor_active),
+ "Active/add mismatch" );
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+ {
+ int i;
+ // The problem is, if DEMUX_ALL, either device can eat the other's
+ // interrupts; so we must poll them *both*:
+ for (i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT; i++) {
+ p_i82559 = i82559_priv_array[i];
+ if ( p_i82559->active ) {
+ TxMachine(p_i82559);
+ Acknowledge82559Interrupt(p_i82559);
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ // We are not prepared to receive a packet now if we are in a polled
+ // standalone configuration.
+ PacketRxReady(p_i82559);
+#endif
+ }
+ }
+ }
+ // ensure we look at the correct device at the end
+ p_i82559 = (struct i82559 *)sc->driver_private;
+#else // no CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+ // Advance TxMachine atomically
+ TxMachine(p_i82559);
+ Acknowledge82559Interrupt(p_i82559); // This can eat an Rx interrupt, so
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ // We are not prepared to receive a packet now if we are in a polled
+ // standalone configuration.
+ PacketRxReady(p_i82559);
+#endif
+#endif // no CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+
+ p_i82559->within_send--;
+ UnMask82559Interrupt(p_i82559, ints);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82559_reset
+//
+// ------------------------------------------------------------------------
+static void
+i82559_reset(struct i82559* p_i82559)
+{
+ cyg_uint32 ioaddr = p_i82559->io_address;
+
+ // First do soft reset. This must be done before the hard reset,
+ // otherwise we may create havoc on the PCI bus.
+ // Wait 20 uSecs afterwards for chip to settle.
+ OUTL(I82559_SELECTIVE_RESET, ioaddr + SCBPort);
+ udelay(20);
+
+ // Do hard reset now that the controller is off the PCI bus.
+ // Wait 20 uSecs afterwards for chip to settle.
+ OUTL(I82559_RESET, ioaddr + SCBPort);
+ udelay(20);
+
+ // Set the base addresses
+ wait_for_cmd_done(ioaddr, WAIT_RU);
+ OUTL(0, ioaddr + SCBPointer);
+ OUTW(SCB_M | RUC_ADDR_LOAD, ioaddr + SCBCmd);
+
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+ OUTL(0, ioaddr + SCBPointer);
+ OUTW(SCB_M | CU_ADDR_LOAD, ioaddr + SCBCmd);
+}
+
+// ------------------------------------------------------------------------
+//
+// INTERRUPT HANDLERS
+//
+// ------------------------------------------------------------------------
+
+static cyg_uint32
+eth_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct i82559* p_i82559 = (struct i82559 *)data;
+ cyg_uint16 status;
+ cyg_uint32 ioaddr;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "i82559_isr: Bad device pointer %x\n", p_i82559 );
+#endif
+ return 0;
+ }
+
+ ioaddr = p_i82559->io_address;
+ status = INW(ioaddr + SCBStatus);
+
+ // Acknowledge all INT sources that were active
+ OUTW( status & SCB_INTACK_MASK, ioaddr + SCBStatus);
+ // (see pages 6-10 & 6-90)
+
+#ifdef KEEP_STATISTICS
+ statistics[p_i82559->index].interrupts++;
+
+ // receiver left ready state ?
+ if ( status & SCB_STATUS_RNR )
+ statistics[p_i82559->index].rx_resource++;
+
+ // frame receive interrupt ?
+ if ( status & SCB_STATUS_FR )
+ statistics[p_i82559->index].rx_count++;
+
+ // transmit interrupt ?
+ if ( status & SCB_STATUS_CX )
+ statistics[p_i82559->index].tx_complete++;
+#endif
+
+ // Advance the Tx Machine regardless
+ TxMachine(p_i82559);
+
+ // it should have settled down now...
+ Acknowledge82559Interrupt(p_i82559);
+
+ return CYG_ISR_CALL_DSR; // schedule DSR
+}
+
+
+// ------------------------------------------------------------------------
+#if defined( CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT ) || \
+ defined( CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL )
+static cyg_uint32
+eth_mux_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ int i;
+ struct i82559* p_i82559;
+
+ for (i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT; i++) {
+ p_i82559 = i82559_priv_array[i];
+ if ( p_i82559->active )
+ (void)eth_isr( vector, (cyg_addrword_t)p_i82559 );
+ }
+
+ return CYG_ISR_CALL_DSR;
+}
+#endif
+
+// ------------------------------------------------------------------------
+
+#if defined(CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT) || \
+ defined(CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT) || \
+ !defined(CYGPKG_IO_ETH_DRIVERS_STAND_ALONE)
+static void
+eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ // This conditioning out is necessary because of explicit calls to this
+ // DSR - which would not ever be called in the case of a polled mode
+ // usage ie. in RedBoot.
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ struct i82559* p_i82559 = (struct i82559 *)data;
+ struct cyg_netdevtab_entry *ndp =
+ (struct cyg_netdevtab_entry *)(p_i82559->ndp);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ // but here, it must be a *sc:
+ eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+#else
+# ifndef CYGPKG_REDBOOT
+# error Empty i82559 ethernet DSR is compiled. Is this what you want?
+# endif
+#endif
+}
+#endif
+
+// ------------------------------------------------------------------------
+// Deliver routine:
+#if defined( CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT ) || \
+ defined( CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL )
+
+void
+i82559_deliver(struct eth_drv_sc *sc)
+{
+ int i;
+ struct i82559* p_i82559;
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT
+ again:
+#endif
+
+ // Since this must mux all devices, the incoming arg is ignored.
+ for (i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT; i++) {
+ p_i82559 = i82559_priv_array[i];
+ if ( p_i82559->active ) {
+
+ // See if the Tx machine is wedged - reset if so:
+ Check82559TxLockupTimeout(p_i82559);
+
+ // First pass any rx data up the stack
+ PacketRxReady(p_i82559);
+
+ // Then scan for completed Txen and inform the stack
+ TxDone(p_i82559);
+ }
+ }
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT
+ {
+ int retry = 0;
+ for (i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT; i++) {
+ p_i82559 = i82559_priv_array[i];
+ if ( p_i82559->active ) {
+ if ( CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT(p_i82559) ) {
+ int ints = Mask82559Interrupt(p_i82559);
+ retry++;
+#ifdef CYGDBG_USE_ASSERTS
+ missed_interrupt.deliver++;
+#endif
+ eth_isr( p_i82559->vector, (cyg_addrword_t)p_i82559 );
+ UnMask82559Interrupt(p_i82559,ints);
+ }
+ }
+
+ }
+ if ( retry )
+ goto again;
+ }
+#endif
+}
+
+#else // no CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL : Simplex version:
+
+void
+i82559_deliver(struct eth_drv_sc *sc)
+{
+ struct i82559* p_i82559 = (struct i82559 *)(sc->driver_private);
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT
+ again:
+#endif
+ // See if the Tx machine is wedged - reset if so:
+ Check82559TxLockupTimeout(p_i82559);
+
+ // First pass any rx data up the stack
+ PacketRxReady(p_i82559);
+
+ // Then scan for completed Txen and inform the stack
+ TxDone(p_i82559);
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT
+ if ( CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT(p_i82559) ) {
+ int ints = Mask82559Interrupt(p_i82559);
+#ifdef CYGDBG_USE_ASSERTS
+ missed_interrupt.deliver++;
+#endif
+ eth_isr( p_i82559->vector, (cyg_addrword_t)p_i82559 );
+ UnMask82559Interrupt(p_i82559,ints);
+ goto again;
+ }
+#endif
+}
+
+#endif // no CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+
+// ------------------------------------------------------------------------
+// Device table entry to operate the chip in a polled mode.
+// Only diddle the interface we were asked to!
+
+void
+i82559_poll(struct eth_drv_sc *sc)
+{
+ struct i82559 *p_i82559;
+ int ints;
+ p_i82559 = (struct i82559 *)sc->driver_private;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "i82559_poll: Bad device pointer %x\n", p_i82559 );
+#endif
+ return;
+ }
+
+ // Do these atomically
+ ints = Mask82559Interrupt(p_i82559);
+
+ // As it happens, this driver always requests the DSR to be called:
+ (void)eth_isr( p_i82559->vector, (cyg_addrword_t)p_i82559 );
+
+ // (no harm in calling this ints-off also, when polled)
+ i82559_deliver( sc );
+
+ Acknowledge82559Interrupt(p_i82559);
+ UnMask82559Interrupt(p_i82559, ints);
+}
+
+// ------------------------------------------------------------------------
+// Determine interrupt vector used by a device - for attaching GDB stubs
+// packet handler.
+int
+i82559_int_vector(struct eth_drv_sc *sc)
+{
+ struct i82559 *p_i82559;
+ p_i82559 = (struct i82559 *)sc->driver_private;
+ return (p_i82559->vector);
+}
+
+#if 0
+int
+i82559_int_op( struct eth_drv_sc *sc, int mask)
+{
+ struct i82559 *p_i82559;
+ p_i82559 = (struct i82559 *)sc->driver_private;
+
+ if ( 1 == mask )
+ return Mask82559Interrupt( p_i82559 );
+
+ if ( 0 == mask )
+ UnMask82559Interrupt( p_i82559, 0x0fffffff ); // enable all
+
+ return 0;
+}
+#endif
+
+
+// ------------------------------------------------------------------------
+//
+// Function : pci_init_find_82559s
+//
+// This is called exactly once at the start of time to:
+// o scan the PCI bus for objects
+// o record them in the device table
+// o acquire all the info needed for the driver to access them
+// o instantiate interrupts for them
+// o attach those interrupts appropriately
+// ------------------------------------------------------------------------
+static cyg_pci_match_func find_82559s_match_func;
+
+// Intel 82559 and 82557 are virtually identical, with different
+// dev codes; also 82559ER (cutdown) = 0x1209.
+static cyg_bool
+find_82559s_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+{
+ return
+ (0x8086 == v) &&
+ ((0x1030 == d) ||
+ (0x1229 == d) ||
+ (0x1209 == d) ||
+ (0x1029 == d) ||
+ (0x2449 == d));
+}
+
+static int
+pci_init_find_82559s( void )
+{
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+ cyg_uint16 cmd;
+ int device_index;
+ int found_devices = 0;
+
+#ifdef CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT
+ static cyg_handle_t mux_interrupt_handle = 0;
+ #endif
+
+#ifdef DEBUG
+ db_printf("pci_init_find_82559s()\n");
+#endif
+
+ // allocate memory to be used in ioctls later
+ if (mem_reserved_ioctl != (void*)0) {
+#ifdef DEBUG
+ db_printf("pci_init_find_82559s() called > once\n");
+#endif
+ return 0;
+ }
+
+ // First initialize the heap in PCI window'd memory
+ i82559_heap_size = CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE;
+ i82559_heap_base = (cyg_uint8 *)CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE;
+ i82559_heap_free = i82559_heap_base;
+
+ mem_reserved_ioctl = pciwindow_mem_alloc(MAX_MEM_RESERVED_IOCTL);
+
+ cyg_pci_init();
+#ifdef DEBUG
+ db_printf("Finished cyg_pci_init();\n");
+#endif
+
+ devid = CYG_PCI_NULL_DEVID;
+
+ for (device_index = 0;
+ device_index < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT;
+ device_index++) {
+ struct i82559 *p_i82559 = i82559_priv_array[device_index];
+
+ p_i82559->index = device_index;
+
+ // See above for find_82559s_match_func - it selects any of several
+ // variants. This is necessary in case we have multiple mixed-type
+ // devices on one board in arbitrary orders.
+ if (cyg_pci_find_matching( &find_82559s_match_func, NULL, &devid )) {
+#ifdef DEBUG
+ db_printf("eth%d = 82559\n", device_index);
+#endif
+ // Allocate it a stats window:
+ p_i82559->p_statistics = pciwindow_mem_alloc(sizeof(I82559_COUNTERS));
+
+ cyg_pci_get_device_info(devid, &dev_info);
+
+ p_i82559->interrupt_handle = 0; // Flag not attached.
+ if (cyg_pci_translate_interrupt(&dev_info, &p_i82559->vector)) {
+#ifdef DEBUG
+ db_printf(" Wired to HAL vector %d\n", p_i82559->vector);
+#endif
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ cyg_drv_interrupt_create(
+ p_i82559->vector,
+ 0, // Priority - unused
+ (CYG_ADDRWORD)p_i82559, // Data item passed to ISR & DSR
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+ eth_mux_isr, // ISR
+#else
+ eth_isr, // ISR
+#endif
+ eth_dsr, // DSR
+ &p_i82559->interrupt_handle, // handle to intr obj
+ &p_i82559->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(p_i82559->interrupt_handle);
+
+ // Don't unmask the interrupt yet, that could get us into a
+ // race.
+#ifdef CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT
+ // ALSO attach it to MUX interrupt for multiplexed
+ // interrupts. This is for certain boards where the
+ // PCI backplane is wired "straight through" instead of
+ // with a rotation of interrupt lines in the different
+ // slots.
+ {
+ static cyg_interrupt mux_interrupt_object;
+
+ if ( ! mux_interrupt_handle ) {
+#ifdef DEBUG
+ db_printf(" Also attaching to HAL vector %d\n",
+ CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT);
+#endif
+ cyg_drv_interrupt_create(
+ CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT,
+ 0, // Priority - unused
+ (CYG_ADDRWORD)p_i82559,// Data item passed to ISR and DSR
+ eth_mux_isr, // ISR
+ eth_dsr, // DSR
+ &mux_interrupt_handle,
+ &mux_interrupt_object );
+
+ cyg_drv_interrupt_attach(mux_interrupt_handle);
+ }
+ }
+#endif // CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ }
+ else {
+ p_i82559->vector=0;
+#ifdef DEBUG
+ db_printf(" Does not generate interrupts.\n");
+#endif
+ }
+
+ if (cyg_pci_configure_device(&dev_info)) {
+#ifdef DEBUG
+ int i;
+ db_printf("Found device on bus %d, devfn 0x%02x:\n",
+ CYG_PCI_DEV_GET_BUS(devid),
+ CYG_PCI_DEV_GET_DEVFN(devid));
+
+ if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
+ db_printf(" Note that board is active. Probed"
+ " sizes and CPU addresses invalid!\n");
+ }
+ db_printf(" Vendor 0x%04x", dev_info.vendor);
+ db_printf("\n Device 0x%04x", dev_info.device);
+ db_printf("\n Command 0x%04x, Status 0x%04x\n",
+ dev_info.command, dev_info.status);
+
+ db_printf(" Class/Rev 0x%08x", dev_info.class_rev);
+ db_printf("\n Header 0x%02x\n", dev_info.header_type);
+
+ db_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+ dev_info.header.normal.sub_vendor,
+ dev_info.header.normal.sub_id);
+
+ for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
+ db_printf(" BAR[%d] 0x%08x /", i, dev_info.base_address[i]);
+ db_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
+ dev_info.base_size[i], dev_info.base_map[i]);
+ }
+ db_printf(" eth%d configured\n", device_index);
+#endif
+ found_devices++;
+ p_i82559->found = 1;
+ p_i82559->active = 0;
+ p_i82559->devid = devid;
+ p_i82559->memory_address = dev_info.base_map[0];
+ p_i82559->io_address = dev_info.base_map[1];
+#ifdef DEBUG
+ db_printf(" memory address = 0x%08x\n", dev_info.base_map[0]);
+ db_printf(" I/O address = 0x%08x\n", dev_info.base_map[1]);
+#endif
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_USE_MEMORY
+ // Use the memory address instead of I/O. Some devices just
+ // don't want to talk using the I/O registers :-(
+ p_i82559->io_address = dev_info.base_map[0];
+#endif
+
+ // Don't use cyg_pci_set_device_info since it clears
+ // some of the fields we want to print out below.
+ cyg_pci_read_config_uint16(dev_info.devid,
+ CYG_PCI_CFG_COMMAND, &cmd);
+ cmd |= (CYG_PCI_CFG_COMMAND_IO // enable I/O space
+ | CYG_PCI_CFG_COMMAND_MEMORY // enable memory space
+ | CYG_PCI_CFG_COMMAND_MASTER); // enable bus master
+ cyg_pci_write_config_uint16(dev_info.devid,
+ CYG_PCI_CFG_COMMAND, cmd);
+
+ // Now the PCI part of the device is configured, reset
+ // it. This should make it safe to enable the
+ // interrupt
+ i82559_reset(p_i82559);
+
+ // This is the indicator for "uses an interrupt"
+ if (p_i82559->interrupt_handle != 0) {
+ cyg_drv_interrupt_acknowledge(p_i82559->vector);
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ cyg_drv_interrupt_unmask(p_i82559->vector);
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ }
+#ifdef DEBUG
+ db_printf(" **** Device enabled for I/O and Memory "
+ "and Bus Master\n");
+#endif
+ }
+ else {
+ p_i82559->found = 0;
+ p_i82559->active = 0;
+#ifdef DEBUG
+ db_printf("Failed to configure device %d\n",device_index);
+#endif
+ }
+ }
+ else {
+ p_i82559->found = 0;
+ p_i82559->active = 0;
+#ifdef DEBUG
+ db_printf("eth%d not found\n", device_index);
+#endif
+ }
+ }
+
+ if (0 == found_devices)
+ return 0;
+
+#ifdef CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT
+ // Now enable the mux shared interrupt if it is in use
+ if (mux_interrupt_handle) {
+ cyg_drv_interrupt_acknowledge(CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT);
+ cyg_drv_interrupt_unmask(CYGNUM_DEVS_ETH_INTEL_I82559_SEPARATE_MUX_INTERRUPT);
+ }
+#endif
+
+ // Now a delay to ensure the hardware has "come up" before you try to
+ // use it. Yes, really, the full 2 seconds. It's only really
+ // necessary if DEBUG is off - otherwise all that printout wastes
+ // enough time. No kidding.
+ udelay( 2000000 );
+ return 1;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : i82559_set_multicast
+//
+// ------------------------------------------------------------------------
+#ifdef ETH_DRV_SET_MC_LIST
+static int i82559_set_multicast(struct i82559* p_i82559,
+ int num_addrs,
+ cyg_uint8 *address_list )
+{
+ cyg_uint32 ioaddr;
+ volatile CFG *ccs;
+ volatile cyg_uint8* config_bytes;
+ cyg_uint16 status;
+ int count;
+ int i;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "eth_set_promiscuos_mode: Bad device pointer %x\n",
+ p_i82559 );
+#endif
+ return -1;
+ }
+
+ ioaddr = p_i82559->io_address;
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+ // load cu base address = 0 */
+ OUTL(0, ioaddr + SCBPointer);
+ // 32 bit linear addressing used
+ OUTW(SCB_M | CU_ADDR_LOAD, ioaddr + SCBCmd);
+ // wait for SCB command complete
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+
+ // Check the malloc we did earlier worked
+ ccs = (CFG *)mem_reserved_ioctl;
+ if (ccs == (void*)0)
+ return 2; // Failed
+
+ // Prepare header
+ WRITEMEM16(ccs + CFG_CMD,
+ (CFG_CMD_EL | CFG_CMD_SUSPEND | CFG_CMD_MULTICAST));
+ WRITEMEM16(ccs + CFG_STATUS, 0);
+ WRITEMEM32(ccs + CFG_CB_LINK_OFFSET,
+ HAL_CTOLE32(VIRT_TO_BUS((cyg_uint32)ccs)));
+
+ count = 6 * num_addrs; // byte count
+
+ WRITEMEM16(ccs + CFG_MC_LIST_BYTES,
+ HAL_CTOLE16( count ) );
+
+ config_bytes = ccs + CFG_MC_LIST_DATA;
+
+ for ( i = 0; i < count; i++ )
+ config_bytes[i] = address_list[i];
+
+ // Let chip read configuration
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+
+ OUTL(VIRT_TO_BUS(ccs), ioaddr + SCBPointer);
+ OUTW(SCB_M | CU_START, ioaddr + SCBCmd);
+
+ // ...and wait for it to complete operation
+ count = 10000;
+ do {
+ udelay(1);
+ READMEM16(ccs + CFG_STATUS, status);
+ } while (0 == (status & CFG_STATUS_C) && (count-- > 0));
+
+ // Check status
+ if ((status & (CFG_STATUS_C | CFG_STATUS_OK))
+ != (CFG_STATUS_C | CFG_STATUS_OK)) {
+ // Failed!
+#ifdef DEBUG
+ os_printf("%s:%d Multicast setup failed\n", __FUNCTION__, __LINE__);
+#endif
+ return 1;
+ }
+
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+ /* load pointer to Rx Ring */
+
+ OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]), ioaddr + SCBPointer);
+ OUTW(RUC_START, ioaddr + SCBCmd);
+
+ return 0;
+}
+#endif // ETH_DRV_SET_MC_ALL
+
+// ------------------------------------------------------------------------
+//
+// Function : i82559_configure
+//
+// Return : 0 = It worked.
+// non0 = It failed.
+// ------------------------------------------------------------------------
+
+static int i82559_configure(struct i82559* p_i82559, int promisc,
+ int oversized, int multicast_all)
+{
+ cyg_uint32 ioaddr;
+ volatile CFG *ccs;
+ volatile cyg_uint8* config_bytes;
+ cyg_uint16 status;
+ int count;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "eth_set_promiscuos_mode: Bad device pointer %x\n",
+ p_i82559 );
+#endif
+ return -1;
+ }
+
+ ioaddr = p_i82559->io_address;
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+ // load cu base address = 0 */
+ OUTL(0, ioaddr + SCBPointer);
+ // 32 bit linear addressing used
+ OUTW(SCB_M | CU_ADDR_LOAD, ioaddr + SCBCmd);
+ // wait for SCB command complete
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+
+ // Check the malloc we did earlier worked
+ ccs = (CFG *)mem_reserved_ioctl;
+ if (ccs == (void*)0)
+ return 2; // Failed
+
+ // Prepare header
+ WRITEMEM16(ccs + CFG_CMD,
+ (CFG_CMD_EL | CFG_CMD_SUSPEND | CFG_CMD_CONFIGURE));
+ WRITEMEM16(ccs + CFG_STATUS, 0);
+ WRITEMEM32(ccs + CFG_CB_LINK_OFFSET,
+ HAL_CTOLE32(VIRT_TO_BUS((cyg_uint32)ccs)));
+
+ // Default values from the Intel Manual
+ config_bytes = ccs + CFG_BYTES;
+
+ config_bytes[0]= 22; // All 22 bytes
+ config_bytes[1]=0xc;
+ config_bytes[2]=0x0;
+ config_bytes[3]=0x0;
+ config_bytes[4]=0x0;
+ config_bytes[5]=0x0;
+ config_bytes[6]=0x32 | (promisc ? 0x80 : 0x00); // | 0x32 for small stats,
+ config_bytes[7]=0x00 | (promisc ? 0x00 : 0x01); //\ | 0x12 for stats with PAUSE stats
+ config_bytes[8]=0x01; // [7]:discard short frames \ | 0x16 for PAUSE + TCO stats
+ config_bytes[9]=0x0;
+ config_bytes[10]=0x28;
+ config_bytes[11]=0x0;
+ config_bytes[12]=0x60;
+ config_bytes[13]=0x0; // arp
+ config_bytes[14]=0x0; // arp
+
+ config_bytes[15]=0x80 | (promisc ? 1 : 0); // 0x81: promiscuous mode set
+ // 0x80: normal mode
+ config_bytes[16]=0x0;
+ config_bytes[17]=0x40;
+ config_bytes[18]=0x72 | (oversized ? 8 : 0); // Keep the Padding Enable bit
+
+ config_bytes[19]=0x80; // FDX pin enable is the default
+ config_bytes[20]=0x3f; // the default
+ config_bytes[21]=0x05 | (multicast_all ? 8 : 0); // Bit 3 is MultiCastALL enable
+
+ // Let chip read configuration
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+
+ OUTL(VIRT_TO_BUS(ccs), ioaddr + SCBPointer);
+ OUTW(SCB_M | CU_START, ioaddr + SCBCmd);
+
+ // ...and wait for it to complete operation
+ count = 10000;
+ do {
+ udelay(1);
+ READMEM16(ccs + CFG_STATUS, status);
+ } while (0 == (status & CFG_STATUS_C) && (count-- > 0));
+
+ // Check status
+ if ((status & (CFG_STATUS_C | CFG_STATUS_OK))
+ != (CFG_STATUS_C | CFG_STATUS_OK)) {
+ // Failed!
+#ifdef DEBUG
+ os_printf("%s:%d Config update failed\n", __FUNCTION__, __LINE__);
+#endif
+ return 1;
+ }
+
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+ /* load pointer to Rx Ring */
+
+ OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]), ioaddr + SCBPointer);
+ OUTW(RUC_START, ioaddr + SCBCmd);
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------
+#if 0
+// The following table below doesn't really work with all cards.
+// The safest way to proceed is to do a read-modify-write of the
+// EEPROM contents rather than relying on a static table.
+
+#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_WRITE_EEPROM
+// We use this as a templete when writing a new MAC address into the
+// eeproms. The MAC address in the first few bytes is over written
+// with the correct MAC address and then the whole lot is programmed
+// into the serial EEPROM. The checksum is calculated on the fly and
+// sent instead of the last two bytes.
+// The values are copied from the Intel EtherPro10/100+ &c devices
+// in the EBSA boards.
+static cyg_uint16 eeprom_burn[64] = {
+/* halfword addresses! */
+/* 0: */ 0x9000, 0x8c27, 0x8257, 0x0203,
+/* 4: */ 0x0000, 0x0201, 0x4701, 0x0000,
+/* 8: */ 0x7213, 0x8306, 0x40A2, 0x000c,
+/* C: */ 0x8086, 0x0000, 0x0000, 0x0000,
+/* 10: */ 0x0000, 0x0000, 0x0000, 0x0000,
+/* 14: */ 0x0000, 0x0000, 0x0000, 0x0000,
+/* 18: */ 0x0000, 0x0000, 0x0000, 0x0000,
+/* 1C: */ 0x0000, 0x0000, 0x0000, 0x0000,
+/* 20: */ 0x0000, 0x0000, 0x0000, 0x0000,
+/* 24: */ 0x0000, 0x0000, 0x0000, 0x0000,
+/* 28: */ 0x0000, 0x0000, 0x0000, 0x0000,
+/* 2C: */ 0x0000, 0x0000, 0x0000, 0x0000,
+/* 30: */ 0x0128, 0x0000, 0x0000, 0x0000,
+/* 34: */ 0x0000, 0x0000, 0x0000, 0x0000,
+/* 38: */ 0x0000, 0x0000, 0x0000, 0x0000,
+/* 3C: */ 0x0000, 0x0000, 0x0000, 0x0000,
+};
+#endif
+#endif
+
+// ------------------------------------------------------------------------
+//
+// Function : eth_set_mac_address
+//
+// Return : 0 = It worked.
+// non0 = It failed.
+// ------------------------------------------------------------------------
+static int
+eth_set_mac_address(struct i82559* p_i82559, cyg_uint8 *addr, int eeprom)
+{
+ cyg_uint32 ioaddr;
+ cyg_uint16 status;
+ volatile CFG *ccs;
+ volatile cyg_uint8* config_bytes;
+ int count;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "eth_set_mac_address : Bad device pointer %x\n",
+ p_i82559 );
+#endif
+ return -1;
+ }
+
+ ioaddr = p_i82559->io_address;
+
+ ccs = (CFG *)mem_reserved_ioctl;
+ if (ccs == (void*)0)
+ return 2;
+
+ WRITEMEM16(ccs + CFG_CMD,
+ (CFG_CMD_EL | CFG_CMD_SUSPEND | CFG_CMD_IAS));
+ WRITEMEM16(ccs + CFG_STATUS, 0);
+ WRITEMEM32(ccs + CFG_CB_LINK_OFFSET,
+ HAL_CTOLE32(VIRT_TO_BUS((cyg_uint32)ccs)));
+
+ config_bytes = ccs + CFG_BYTES;
+ memcpy((char *)(config_bytes),addr,6);
+ config_bytes[6]=0x0;
+ config_bytes[7]=0x0;
+
+ // Let chip read new ESA
+ wait_for_cmd_done(ioaddr, WAIT_CU);
+ OUTL(VIRT_TO_BUS(ccs), ioaddr + SCBPointer);
+ OUTW(SCB_M | CU_START, ioaddr + SCBCmd);
+
+ // ...and wait for it to complete operation
+ count = 1000;
+ do {
+ READMEM16(ccs + CFG_STATUS, status);
+ udelay(1);
+ } while (0 == (status & CFG_STATUS_C) && (count-- > 0));
+
+ // Check status
+ READMEM16(ccs + CFG_STATUS, status);
+ if ((status & (CFG_STATUS_C | CFG_STATUS_OK))
+ != (CFG_STATUS_C | CFG_STATUS_OK)) {
+#ifdef DEBUG
+ os_printf("%s:%d ESA update failed\n", __FUNCTION__, __LINE__);
+#endif
+ return 3;
+ }
+
+#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_WRITE_EEPROM
+ if ( 0 == eeprom
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM
+ || CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM != p_i82559->index
+#endif
+ ) {
+ // record the MAC address in the device structure
+ p_i82559->mac_address[0] = addr[0];
+ p_i82559->mac_address[1] = addr[1];
+ p_i82559->mac_address[2] = addr[2];
+ p_i82559->mac_address[3] = addr[3];
+ p_i82559->mac_address[4] = addr[4];
+ p_i82559->mac_address[5] = addr[5];
+ p_i82559->mac_addr_ok = 1;
+
+#ifdef DEBUG
+ os_printf( "No EEPROM write: MAC Address = %02X %02X %02X %02X %02X %02X (ok %d)\n",
+ p_i82559->mac_address[0],
+ p_i82559->mac_address[1],
+ p_i82559->mac_address[2],
+ p_i82559->mac_address[3],
+ p_i82559->mac_address[4],
+ p_i82559->mac_address[5],
+ p_i82559->mac_addr_ok );
+#endif
+ } else {
+ int checksum, i, count;
+ // (this is the length of the *EEPROM*s address, not MAC address)
+ int addr_length;
+ cyg_uint16 eeprom_burn[64];
+
+ addr_length = get_eeprom_size( ioaddr );
+
+ for (i = 0; i < (1 << addr_length); i++)
+ eeprom_burn[i] = read_eeprom( ioaddr, i, addr_length );
+
+ // now set this address in the device eeprom ....
+ eeprom_burn[0] = addr[0] | (addr[1] << 8);
+ eeprom_burn[1] = addr[2] | (addr[3] << 8);
+ eeprom_burn[2] = addr[4] | (addr[5] << 8);
+
+ // No idea what these were for...
+ // eeprom_burn[20] &= 0xfe;
+ // eeprom_burn[20] |= p_i82559->index;
+
+ program_eeprom( ioaddr, addr_length, eeprom_burn );
+
+ // update 82559 driver data structure ...
+ udelay( 100000 );
+
+ // by reading EEPROM to get the mac address back
+ for (checksum = 0, i = 0, count = 0; count < (1 << addr_length); count++) {
+ cyg_uint16 value;
+ // read word from eeprom
+ value = read_eeprom(ioaddr, count, addr_length);
+ checksum += value;
+ if (count < 3) {
+ p_i82559->mac_address[i++] = value & 0xFF;
+ p_i82559->mac_address[i++] = (value >> 8) & 0xFF;
+ }
+ }
+
+#ifdef DEBUG
+ os_printf("eth_set_mac_address[WRITE_EEPROM]: MAC Address = %02X %02X %02X %02X %02X %02X\n",
+ p_i82559->mac_address[0], p_i82559->mac_address[1],
+ p_i82559->mac_address[2], p_i82559->mac_address[3],
+ p_i82559->mac_address[4], p_i82559->mac_address[5]);
+#endif
+
+ p_i82559->mac_addr_ok = 1;
+
+ for ( i = 0, count = 0; i < 6; i++ )
+ if ( p_i82559->mac_address[i] != addr[i] )
+ count++;
+
+ if ( count ) {
+#ifdef DEBUG
+ os_printf( "Warning: MAC Address read back wrong! %d bytes differ.\n",
+ count );
+#endif
+ p_i82559->mac_addr_ok = 0;
+ }
+
+ // If the EEPROM checksum is wrong, the MAC address read from
+ // the EEPROM is probably wrong as well. In that case, we
+ // don't set mac_addr_ok.
+ if ((checksum & 0xFFFF) != 0xBABA) {
+#ifdef DEBUG
+ os_printf( "Warning: Invalid EEPROM checksum %04X for device %d\n",
+ checksum, p_i82559->index);
+#endif
+ p_i82559->mac_addr_ok = 0;
+ }
+ }
+#else // CYGPKG_DEVS_ETH_INTEL_I82559_WRITE_EEPROM
+
+ // record the MAC address in the device structure
+ p_i82559->mac_address[0] = addr[0];
+ p_i82559->mac_address[1] = addr[1];
+ p_i82559->mac_address[2] = addr[2];
+ p_i82559->mac_address[3] = addr[3];
+ p_i82559->mac_address[4] = addr[4];
+ p_i82559->mac_address[5] = addr[5];
+ p_i82559->mac_addr_ok = 1;
+
+#ifdef DEBUG
+ os_printf( "Set MAC Address = %02X %02X %02X %02X %02X %02X (ok %d)\n",
+ p_i82559->mac_address[0],
+ p_i82559->mac_address[1],
+ p_i82559->mac_address[2],
+ p_i82559->mac_address[3],
+ p_i82559->mac_address[4],
+ p_i82559->mac_address[5],
+ p_i82559->mac_addr_ok );
+#endif
+
+#endif // ! CYGPKG_DEVS_ETH_INTEL_I82559_WRITE_EEPROM
+
+ return p_i82559->mac_addr_ok ? 0 : 1;
+}
+
+#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_WRITE_EEPROM
+// ------------------------------------------------------------------------
+static void
+write_eeprom(long ioaddr, int location, int addr_len, unsigned short value)
+{
+ int ee_addr = ioaddr + SCBeeprom;
+ int write_cmd = location | EE_WRITE_CMD(addr_len);
+ int i;
+
+ OUTW(EE_ENB & ~EE_CS, ee_addr);
+ eeprom_delay( 100 );
+ OUTW(EE_ENB, ee_addr);
+ eeprom_delay( 100 );
+
+// os_printf("\n write_eeprom : write_cmd : %x",write_cmd);
+// os_printf("\n addr_len : %x value : %x ",addr_len,value);
+
+ /* Shift the write command bits out. */
+ for (i = (addr_len+2); i >= 0; i--) {
+ short dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+ OUTW(EE_ENB | dataval, ee_addr);
+ eeprom_delay(100);
+ OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+ eeprom_delay(150);
+ }
+ OUTW(EE_ENB, ee_addr);
+
+ for (i = 15; i >= 0; i--) {
+ short dataval = (value & (1 << i)) ? EE_DATA_WRITE : 0;
+ OUTW(EE_ENB | dataval, ee_addr);
+ eeprom_delay(100);
+ OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+ eeprom_delay(150);
+ }
+
+ /* Terminate the EEPROM access. */
+ OUTW(EE_ENB & ~EE_CS, ee_addr);
+ eeprom_delay(150000); // let the write take effect
+}
+
+// ------------------------------------------------------------------------
+static int
+write_enable_eeprom(long ioaddr, int addr_len)
+{
+ int ee_addr = ioaddr + SCBeeprom;
+ int write_en_cmd = EE_WRITE_EN_CMD(addr_len);
+ int i;
+
+ OUTW(EE_ENB & ~EE_CS, ee_addr);
+ OUTW(EE_ENB, ee_addr);
+
+#ifdef DEBUG_82559
+ os_printf("write_en_cmd : %x",write_en_cmd);
+#endif
+
+ // Shift the wr/er enable command bits out.
+ for (i = (addr_len+2); i >= 0; i--) {
+ short dataval = (write_en_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+ OUTW(EE_ENB | dataval, ee_addr);
+ eeprom_delay(100);
+ OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+ eeprom_delay(150);
+ }
+
+ // Terminate the EEPROM access.
+ OUTW(EE_ENB & ~EE_CS, ee_addr);
+ eeprom_delay(EEPROM_DONE_DELAY);
+}
+
+
+// ------------------------------------------------------------------------
+static void
+program_eeprom(cyg_uint32 ioaddr, cyg_uint32 eeprom_size, cyg_uint8 *data)
+{
+ cyg_uint32 i;
+ cyg_uint16 checksum = 0;
+ cyg_uint16 value;
+
+ // First enable erase/write operations on the eeprom.
+ // This is done through the EWEN instruction.
+ write_enable_eeprom( ioaddr, eeprom_size );
+
+ for (i=0 ; i< (1 << eeprom_size) ; i++) {
+ value = ((unsigned short *)data)[i];
+ checksum += value;
+#ifdef DEBUG_82559
+ os_printf("\n i : %x ... value to be written : %x",i,value);
+#endif
+ write_eeprom( ioaddr, i, eeprom_size, value);
+#ifdef DEBUG_82559
+ os_printf("\n val read : %x ",read_eeprom(ioaddr,i,eeprom_size));
+#endif
+ }
+ value = 0xBABA - checksum;
+#ifdef DEBUG_82559
+ os_printf("\n i : %x ... checksum adjustment val to be written : %x",i,value);
+#endif
+ write_eeprom( ioaddr, i, eeprom_size, value );
+}
+
+// ------------------------------------------------------------------------
+#endif // ! CYGPKG_DEVS_ETH_INTEL_I82559_WRITE_EEPROM
+
+
+// ------------------------------------------------------------------------
+//
+// Function : eth_get_mac_address
+//
+// ------------------------------------------------------------------------
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+static int
+eth_get_mac_address(struct i82559* p_i82559, char *addr)
+{
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "eth_get_mac_address : Bad device pointer %x\n",
+ p_i82559 );
+#endif
+ return -1;
+ }
+
+ memcpy( addr, (char *)(&p_i82559->mac_address[0]), 6 );
+ return 0;
+}
+#endif
+// ------------------------------------------------------------------------
+//
+// Function : i82559_ioctl
+//
+// ------------------------------------------------------------------------
+static int
+i82559_ioctl(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ struct i82559 *p_i82559;
+
+ p_i82559 = (struct i82559 *)sc->driver_private;
+
+ IF_BAD_82559( p_i82559 ) {
+#ifdef DEBUG
+ os_printf( "i82559_ioctl/control: Bad device pointer %x\n", p_i82559 );
+#endif
+ return -1;
+ }
+
+#ifdef ioctlDEBUG
+ db_printf( "i82559_ioctl: device eth%d at %x; key is 0x%x, data at %x[%d]\n",
+ p_i82559->index, p_i82559, key, data, data_length );
+#endif
+
+ switch ( key ) {
+
+#ifdef ETH_DRV_SET_MAC_ADDRESS
+ case ETH_DRV_SET_MAC_ADDRESS:
+ if ( 6 != data_length )
+ return -2;
+ return eth_set_mac_address( p_i82559, data, 1 /* do write eeprom */ );
+#endif
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ return eth_get_mac_address( p_i82559, data );
+#endif
+
+#ifdef ETH_DRV_GET_IF_STATS_UD
+ case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+ ETH_STATS_INIT( sc ); // so UPDATE the statistics structure
+#endif
+ // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+ case ETH_DRV_GET_IF_STATS:
+#endif
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+ {
+ struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+ int i;
+ static unsigned char my_chipset[]
+ = { ETH_DEV_DOT3STATSETHERCHIPSET };
+
+ strcpy( p->description, CYGDAT_DEVS_ETH_DESCRIPTION );
+ CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+ for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+ if ( 0 == (p->snmp_chipset[i] = my_chipset[i]) )
+ break;
+
+ i = i82559_status( sc );
+
+ if ( !( i & GEN_STATUS_LINK) ) {
+ p->operational = 2; // LINK DOWN
+ p->duplex = 1; // UNKNOWN
+ p->speed = 0;
+ }
+ else {
+ p->operational = 3; // LINK UP
+ p->duplex = (i & GEN_STATUS_FDX) ? 3 : 2; // 2 = SIMPLEX, 3 = DUPLEX
+ p->speed = ((i & GEN_STATUS_100MBPS) ? 100 : 10) * 1000000;
+ }
+
+#ifdef KEEP_STATISTICS
+ {
+ I82559_COUNTERS *pc = &i82559_counters[ p_i82559->index ];
+ STATISTICS *ps = &statistics[ p_i82559->index ];
+
+ // Admit to it...
+ p->supports_dot3 = true;
+
+ // Those commented out are not available on this chip.
+
+ p->tx_good = pc->tx_good ;
+ p->tx_max_collisions = pc->tx_max_collisions ;
+ p->tx_late_collisions = pc->tx_late_collisions ;
+ p->tx_underrun = pc->tx_underrun ;
+ p->tx_carrier_loss = pc->tx_carrier_loss ;
+ p->tx_deferred = pc->tx_deferred ;
+ //p->tx_sqetesterrors = pc->tx_sqetesterrors ;
+ p->tx_single_collisions = pc->tx_single_collisions;
+ p->tx_mult_collisions = pc->tx_mult_collisions ;
+ p->tx_total_collisions = pc->tx_total_collisions ;
+ p->rx_good = pc->rx_good ;
+ p->rx_crc_errors = pc->rx_crc_errors ;
+ p->rx_align_errors = pc->rx_align_errors ;
+ p->rx_resource_errors = pc->rx_resource_errors ;
+ p->rx_overrun_errors = pc->rx_overrun_errors ;
+ p->rx_collisions = pc->rx_collisions ;
+ p->rx_short_frames = pc->rx_short_frames ;
+ //p->rx_too_long_frames = pc->rx_too_long_frames ;
+ //p->rx_symbol_errors = pc->rx_symbol_errors ;
+
+ p->interrupts = ps->interrupts ;
+ p->rx_count = ps->rx_count ;
+ p->rx_deliver = ps->rx_deliver ;
+ p->rx_resource = ps->rx_resource ;
+ p->rx_restart = ps->rx_restart ;
+ p->tx_count = ps->tx_count ;
+ p->tx_complete = ps->tx_complete ;
+ p->tx_dropped = ps->tx_dropped ;
+ }
+#endif // KEEP_STATISTICS
+
+ p->tx_queue_len = MAX_TX_DESCRIPTORS;
+
+ return 0; // OK
+ }
+#endif
+
+#ifdef ETH_DRV_SET_MC_LIST
+ case ETH_DRV_SET_MC_LIST: {
+ struct eth_drv_mc_list *mcl = (struct eth_drv_mc_list *)data;
+
+ i82559_reset(p_i82559);
+ ResetRxRing( p_i82559 );
+ ResetTxRing( p_i82559 );
+
+ p_i82559->multicast_all = 0;
+
+ i82559_configure(p_i82559,
+ p_i82559->promisc,
+ p_i82559->oversized,
+ p_i82559->multicast_all );
+
+ i82559_set_multicast( p_i82559,
+ mcl->len,
+ &(mcl->addrs[0][0]) );
+
+ i82559_restart(p_i82559);
+ return 0;
+ }
+#endif // ETH_DRV_SET_MC_LIST
+
+#ifdef ETH_DRV_SET_MC_ALL
+ case ETH_DRV_SET_MC_ALL:
+ i82559_reset(p_i82559);
+ ResetRxRing( p_i82559 );
+ ResetTxRing( p_i82559 );
+
+ p_i82559->multicast_all = 1;
+
+ i82559_configure(p_i82559,
+ p_i82559->promisc,
+ p_i82559->oversized,
+ p_i82559->multicast_all );
+
+ i82559_restart(p_i82559);
+ return 0;
+#endif // ETH_DRV_SET_MC_ALL
+
+ default:
+ break;
+ }
+ return -1;
+}
+
+// ------------------------------------------------------------------------
+//
+// Statistics update...
+//
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+#ifdef CYGDBG_DEVS_ETH_INTEL_I82559_KEEP_82559_STATISTICS
+void
+update_statistics(struct i82559* p_i82559)
+{
+ I82559_COUNTERS *p_statistics;
+ cyg_uint32 *p_counter;
+ cyg_uint32 *p_register;
+ int reg_count, ints;
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+ struct i82559* op_i82559 = p_i82559;
+#endif
+
+ ints = Mask82559Interrupt(p_i82559);
+
+ // This points to the shared memory stats area/command block
+ p_statistics = (I82559_COUNTERS *)(p_i82559->p_statistics);
+
+ if ( (p_statistics->done & 0xFFFF) == 0xA007 ) {
+ p_counter = (cyg_uint32 *)&i82559_counters[ p_i82559->index ];
+ p_register = (cyg_uint32 *)p_statistics;
+ for ( reg_count = 0;
+ reg_count < sizeof( I82559_COUNTERS ) / sizeof( cyg_uint32 ) - 1;
+ reg_count++ ) {
+ *p_counter += *p_register;
+ p_counter++;
+ p_register++;
+ }
+ p_statistics->done = 0;
+ // start register dump
+ wait_for_cmd_done(p_i82559->io_address, WAIT_CU);
+ OUTW(CU_DUMPSTATS, p_i82559->io_address + SCBCmd);
+ }
+
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+ {
+ int i;
+ // The problem is, if DEMUX_ALL, either device can eat the other's
+ // interrupts; so we must poll them *both*:
+ for (i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT; i++) {
+ p_i82559 = i82559_priv_array[i];
+ if ( p_i82559->active ) {
+ // See if the Tx machine is wedged - reset if so:
+ Check82559TxLockupTimeout(p_i82559);
+ TxMachine(p_i82559);
+ Acknowledge82559Interrupt(p_i82559);
+ PacketRxReady(p_i82559);
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT
+ if ( CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT(p_i82559) ) {
+#ifdef CYGDBG_USE_ASSERTS
+ missed_interrupt.stats++;
+#endif
+ eth_isr( p_i82559->vector, (cyg_addrword_t)p_i82559 );
+ eth_dsr( p_i82559->vector, 1, (cyg_addrword_t)p_i82559 );
+ }
+#endif
+ }
+ }
+ }
+ // ensure we look at the correct device at the end
+ p_i82559 = op_i82559;
+#else // no CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+ // See if the Tx machine is wedged - reset if so:
+ Check82559TxLockupTimeout(p_i82559);
+ TxMachine(p_i82559);
+ Acknowledge82559Interrupt(p_i82559); // This can eat an Rx interrupt, so
+ PacketRxReady(p_i82559);
+#ifdef CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT
+ if ( CYGHWR_DEVS_ETH_INTEL_I82559_MISSED_INTERRUPT(p_i82559) ) {
+#ifdef CYGDBG_USE_ASSERTS
+ missed_interrupt.stats++;
+#endif
+ eth_isr( p_i82559->vector, (cyg_addrword_t)p_i82559 );
+ eth_dsr( p_i82559->vector, 1, (cyg_addrword_t)p_i82559 );
+ }
+#endif
+#endif // no CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+
+ UnMask82559Interrupt(p_i82559, ints);
+}
+#endif
+#endif // KEEP_STATISTICS
+
+// ------------------------------------------------------------------------
+
+// EOF if_i82559.c
diff --git a/ecos/packages/devs/eth/m68k/mcf5272/current/ChangeLog b/ecos/packages/devs/eth/m68k/mcf5272/current/ChangeLog
new file mode 100644
index 0000000..1d9e564
--- /dev/null
+++ b/ecos/packages/devs/eth/m68k/mcf5272/current/ChangeLog
@@ -0,0 +1,182 @@
+2009-04-21 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c: fix a couple of typos
+
+2008-11-17 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/mcf5272.cdl, doc/mcf5272_eth.sgml, src/if_mcf5272.c: minor
+ clean-ups.
+
+2008-09-22 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c (mcf52xx_eth_deliver): avoid cpp warning when
+ building for processors without a data cache.
+
+2008-09-02 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c, (mcf52xx_eth_init): add
+ support for run-time device dection.
+
+2008-06-02 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/mcf5272_eth.cdl: add constraints so net tests run with
+ sensible performance.
+
+2008-03-18 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c: rearrange RX interrupt masking to avoid
+ spurious interrupt exceptions.
+
+2008-03-03 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c: encapsulate stats gathering in a macro.
+
+2008-02-28 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c: cleanup and more coping with unified and
+ copyback caches.
+
+ * cdl/mcf5272_eth.cdl: the ethernet driver must be built with at
+ least -O1 to ensure some data stays in registers when manipulating
+ the cache.
+
+2008-02-14 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c: cope with unified and copyback caches.
+
+2007-04-25 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/mcf5272_eth.cdl: memset/memcpy are part of infra and always
+ declared in isoinfra, so don't need to require CYGPKG_LIBC_STRING.
+ Require CYGPKG_ISOINFRA instead, although that's in every template
+ anyway.
+
+2006-09-25 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c: remove unnecessary #error
+
+ * cdl/mcf5272_eth.cdl, src/if_mcf5272, doc/mcf5272_eth.sgml:
+ Motorola -> Freescale.
+
+2006-09-08 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c: more/enhanced diagnostics. Update to use
+ current var_io.h definitions. Add partial support for multiple
+ devices.
+
+2006-03-10 John Dallaway <jld@ecoscentric.com>
+
+ * cdl/mcf5272_eth.cdl: Add reference to package documentation.
+
+2004-10-07 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c (mcf52xx_eth_init): add optional platform init
+ function
+
+2004-06-25 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c (DEBUG): add some debug/tracing support
+
+2004-05-20 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c, cdl/mcf5272_eth.cdl: add a dependency
+ on CYGPKG_LIBC_STRING to get memcpy()
+
+2004-04-21 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c (mcf52xx_eth_init): use the right macro if the
+ platform has its own way of supplying a MAC address.
+
+2004-03-25 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c (mcf52xx_eth_deliver): make the rx ring scan
+ more robust. The mcf5282 appears to occasionally place incoming
+ frames in unexpected slots.
+
+2004-03-17 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/mcf5272_eth.sgml: update documentation following port to an
+ mcf5282
+
+2004-03-10 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c (mcf52xx_eth_poll): update tx poll code to
+ match previous changes. Ignore the MAC address passed to _start(),
+ it is not needed. During _init(), if running on top of RedBoot,
+ check for an outgoing transmit before resetting and wait a bit if
+ necessary.
+
+2004-03-08 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c: cope with processor variants where tx buffers
+ need to be more aligned than is guaranteed by higher-level code.
+ Provide a MAC address even if virtual vectors are not available,
+ e.g. when debugging via BDM. Reorganize the init code as per the
+ recommendations in the mcf5282 manual. Add statistics counting for
+ the mcf5282. Disable RX interrupts between the ISR and the
+ received packet(s) being processed, since those just add to the
+ load. Use separate ISR priorities for RX and TX.
+
+ * cdl/mcf5272_eth.cdl: At least two rx buffers are needed to cope
+ with oversized incoming frames. ISR priorities now have to be
+ configured separately for RX and TX.
+
+2004-02-11 Bart Veer <bartv@ecoscentric.com>
+
+ * src/if_mcf5272.c: The driver now works on coldfire processors
+ other than just the 5272. Use new per-processor initialization
+ macro to set up GPIO pins. Also cope with incompatible renaming
+ of flash configury within hal/common.
+
+ * cdl/mcf5272_eth.cdl: update descriptions to reflect that the
+ driver now works on other coldfire processors as well.
+
+2003-07-22 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/mcf5272_eth.sgml: fix various typos etc
+
+ * src/if_mcf5272.c (mcf5272_eth_deliver): eliminate warning
+
+ * cdl/mcf5272_eth.cdl: RedBoot now needs more than one buffer.
+
+2003-07-18 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/mcf5272_eth.sgml: add documentation
+
+2003-07-13 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/mcf5272_eth.cdl:
+ Increase default number of receive buffers.
+
+ * src/if_mcf5272.c:
+ Implement SNMP statistics
+ Improve handling of overrun conditions
+ Preserve order of incoming packets
+
+2003-06-04 Bart Veer <bartv@ecoscentric.com>
+
+ * New version of the M68K support
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/m68k/mcf5272/current/cdl/mcf5272_eth.cdl b/ecos/packages/devs/eth/m68k/mcf5272/current/cdl/mcf5272_eth.cdl
new file mode 100644
index 0000000..91dbf91
--- /dev/null
+++ b/ecos/packages/devs/eth/m68k/mcf5272/current/cdl/mcf5272_eth.cdl
@@ -0,0 +1,194 @@
+# ====================================================================
+#
+# mcfxxxx_eth.cdl
+#
+# Ethernet driver for Freescale MCFxxxx ColdFires
+#
+# ====================================================================
+# ####ECOSGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
+#
+# eCos is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 or (at your option) any later
+# version.
+#
+# eCos is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with eCos; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered by
+# the GNU General Public License. However the source code for this file
+# must still be made available in accordance with section (3) of the GNU
+# General Public License v2.
+#
+# This exception does not invalidate any other reasons why a work based
+# on this file might be covered by the GNU General Public License.
+# -------------------------------------------
+# ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Date: 2003-06-04
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_MCFxxxx {
+ display "MCFxxxx ethernet driver"
+ doc ref/devs-eth-m68k-mcfxxxx-part.html
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_M68K_MCFxxxx
+ include_dir cyg/io/eth
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_IO_ETH_MULTICAST
+ requires CYGPKG_INFRA CYGPKG_HAL CYGPKG_ISOINFRA
+ compile -library=libextras.a if_mcf5272.c
+
+ description "
+ This driver supports the on-chip ethernet provided by some
+ Freescale MCFxxxx coldfire processors."
+
+
+ cdl_option CYGDAT_DEVS_ETH_MCFxxxx_NAME {
+ display "Device name for this ethernet device"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option controls the name of the on-chip ethernet device.
+ By default the on-chip device is labelled eth0, and any
+ additional devices can be named eth1 onwards."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS {
+ display "Number of receive buffers"
+ flavor data
+ default_value 4
+ legal_values 2 to 16
+ description "
+ This ethernet driver statically allocates a number of buffers
+ for incoming packets. Usually each buffer requires 1528 bytes.
+ Increasing the number of buffers reduces the probability of packets getting
+ lost under heavy processor or network load. Reducing the number
+ of buffers makes lost packets more likely, potentially causing
+ significant TCP/IP delays."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_MCFxxxx_ISR_RX_PRIORITY {
+ display "Interrupt priority for incoming packets"
+ flavor data
+ default_value { is_loaded(CYGNUM_HAL_M68K_MCFxxxx_ISR_DEFAULT_PRIORITY_ETH_RX) ?
+ CYGNUM_HAL_M68K_MCFxxxx_ISR_DEFAULT_PRIORITY_ETH_RX :
+ CYGNUM_HAL_M68K_MCFxxxx_ISR_PRIORITY_MIN }
+ legal_values CYGNUM_HAL_M68K_MCFxxxx_ISR_PRIORITY_MIN to CYGNUM_HAL_M68K_MCFxxxx_ISR_PRIORITY_MAX
+ description "
+ By default the ethernet is given an interrupt priority of 1,
+ in other words it will interrupt at IPL level 1. The device can
+ be made to interrupt at a higher priority but this is rarely
+ useful since nearly all processing happens at thread level
+ or DSR level rather than ISR level."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_MCFxxxx_ISR_TX_PRIORITY {
+ display "Interrupt priority for packet transmits"
+ flavor data
+ default_value { is_loaded(CYGNUM_HAL_M68K_MCFxxxx_ISR_DEFAULT_PRIORITY_ETH_TX) ?
+ CYGNUM_HAL_M68K_MCFxxxx_ISR_DEFAULT_PRIORITY_ETH_TX :
+ CYGNUM_HAL_M68K_MCFxxxx_ISR_PRIORITY_MIN }
+ legal_values CYGNUM_HAL_M68K_MCFxxxx_ISR_PRIORITY_MIN to CYGNUM_HAL_M68K_MCFxxxx_ISR_PRIORITY_MAX
+ description "
+ By default the ethernet is given an interrupt priority of 1,
+ in other words it will interrupt at IPL level 1. The device can
+ be made to interrupt at a higher priority but this is rarely
+ useful since nearly all processing happens at thread level
+ or DSR level rather than ISR level."
+ }
+
+ cdl_interface CYGINT_DEVS_ETH_MCFxxxx_PLATFORM_MAC {
+ display "Platform provides network MAC address"
+ flavor bool
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_MCFxxxx_PLATFORM_MAC {
+ display "Default MAC address"
+ active_if !CYGINT_DEVS_ETH_MCFxxxx_PLATFORM_MAC
+ flavor data
+ default_value { "0x00, 0xFF, 0x12, 0x34, 0x56, 0x78" }
+ description "
+ If the target board does not provide a fixed unique ethernet
+ MAC address assigned by the IEEE then it is necessary to invent one.
+ If RedBoot is in use and provides configuration data held in
+ flash then that will be used. If RedBoot is not in use or if the
+ fconfig flash block does not contain an entry for the MAC address
+ then the code will use a default value, determined by this option.
+ If the local network has multiple boards attached then it is
+ essential that each one has a unique MAC address."
+ }
+
+ cdl_option CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS {
+ display "Maintain traffic statistics"
+ flavor bool
+ default_value CYGPKG_SNMPAGENT
+ description "
+ The MCFxxxx ethernet driver can maintain some statistics
+ about traffic, for example the number of incoming and
+ outgoing packets. These statistics are intended mainly
+ for SNMP agent software."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MCFxxxx_OPTIONS {
+ display "Build options"
+ flavor none
+ description "
+ Package-specific build options including control over compiler
+ flags used only in building this package."
+
+ cdl_option CYGPKG_DEVS_ETH_MCFxxxx_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ requires {
+ is_substr(CYGBLD_GLOBAL_CFLAGS, "-O1") || is_substr(CYGBLD_GLOBAL_CFLAGS, "-O2") ||
+ is_substr(CYGBLD_GLOBAL_CFLAGS, "-O3") || is_substr(CYGBLD_GLOBAL_CFLAGS, "-Os") ||
+ is_substr(CYGPKG_DEVS_ETH_MCFxxxx_CFLAGS_ADD, "-O1") ||
+ is_substr(CYGPKG_DEVS_ETH_MCFxxxx_CFLAGS_ADD, "-O2") ||
+ is_substr(CYGPKG_DEVS_ETH_MCFxxxx_CFLAGS_ADD, "-O3") ||
+ is_substr(CYGPKG_DEVS_ETH_MCFxxxx_CFLAGS_ADD, "-Os")
+ }
+ default_value { ((is_substr(CYGBLD_GLOBAL_CFLAGS, "-O1") || is_substr(CYGBLD_GLOBAL_CFLAGS, "-O2") ||
+ is_substr(CYGBLD_GLOBAL_CFLAGS, "-O3") || is_substr(CYGBLD_GLOBAL_CFLAGS, "-Os")) ? "" : "-O2 ") .
+ "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building this package. These flags are used in addition
+ to the set of global flags. Note that the package cannot
+ be built with -O0: some of the cache-related code depends
+ on certain values being held in registers instead of
+ memory."
+ }
+ cdl_option CYGPKG_DEVS_ETH_MCFxxxx_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building this package. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/m68k/mcf5272/current/doc/mcf5272_eth.sgml b/ecos/packages/devs/eth/m68k/mcf5272/current/doc/mcf5272_eth.sgml
new file mode 100644
index 0000000..83ddcef
--- /dev/null
+++ b/ecos/packages/devs/eth/m68k/mcf5272/current/doc/mcf5272_eth.sgml
@@ -0,0 +1,206 @@
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- mcfxxxxeth.sgml -->
+<!-- -->
+<!-- mcfxxxx ethernet driver documentation. -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2003, 2004, 2006, 2008 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2003/07/15 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-eth-m68k-mcfxxxx-part"><title>Freescale ColdFire Ethernet Driver</title>
+
+<refentry id="devs-eth-m68k-mcfxxxx">
+ <refmeta>
+ <refentrytitle>Freescale ColdFire Ethernet Driver</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname><varname>CYGPKG_DEVS_ETH_MCFxxxx</varname></refname>
+ <refpurpose>eCos Support for Freescale ColdFire On-chip Ethernet Devices</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="devs-eth-m68k-mcfxxxx-description"><title>Description</title>
+ <para>
+Some members of the Freescale ColdFire family of processors come with
+an on-chip ethernet device. This package provides an eCos driver for
+that device. The driver supports both polled mode for use by RedBoot
+and interrupt-driven mode for use by a full TCP/IP stack.
+ </para>
+ <para>
+The original version of the driver was written specifically for the
+MCF5272 processor. It has since been made to work on other members of
+the ColdFire family.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-m68k-mcfxxxx-config"><title>Configuration Options</title>
+ <para>
+This ethernet package should be loaded automatically when
+selecting a target containing a ColdFire processor with on-chip
+ethernet, and it should never be necessary to load it explicitly. If
+the application does not actually require ethernet functionality then
+the package is inactive and the final executable will not suffer any
+overheads from unused functionality. This is determined by the
+presence of the generic ethernet I/O package
+<varname>CYGPKG_IO_ETH_DRIVERS</varname>. Typically the choice of eCos
+template causes the right thing to happen. For example the default
+template does not include any TCP/IP stack so
+<varname>CYGPKG_IO_ETH_DRIVERS</varname> is not included, but the
+net, redboot and lwip_eth templates do include a TCP/IP stack so will
+specify that package and hence enable the ethernet driver.
+ </para>
+ <para>
+All eCos network devices need a unique name. By default the on-chip
+ethernet device is assigned the name <literal>eth0</literal> but
+can be changed through the configuration option
+<varname>CYGDAT_DEVS_ETH_MCFxxxx_NAME</varname>. This is useful if for
+example the target hardware includes a number of additional off-chip
+ethernet devices.
+ </para>
+ <para>
+The hardware requires that incoming ethernet frames are received
+into one of a small number of buffers, arranged in a ring. Once a
+frame has been received and its size is known the driver will pass it
+up to higher-level code for further processing. The number of these
+buffers is configurable via the option
+<varname>CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS</varname>. Each receive
+buffer requires 1528 bytes of memory. A smaller number of buffers
+increases the probability that incoming ethernet frames have to be
+discarded. TCP/IP stacks are designed to cope with the occasional lost
+packet, but if too many frames are discarded then this will greatly
+affect performance. A key issue here is that passing the incoming
+frames up to higher-level code typically happens at thread level and
+hence the system behaviour is defined in large part by the priority of
+various threads running in the TCP/IP stack. If application code has
+high-priority threads that take up much of the available cpu time and
+the TCP/IP stack gets little chance to run then there will be little
+opportunity to pass received frames up the stack. Balancing out the
+various thread priorities and the number of receive buffers is the
+responsibility of the application developer.
+ </para>
+ <para>
+By default the ethernet driver will raise interrupts using a low
+priority level. The exact value will depend on the processor being
+used, for example the MCF5282 interrupt controllers impose specific
+constraints on interrupt priorities. The driver does very little at
+interrupt level, instead the real work is done via threads inside the
+TCP/IP stack. Hence the interrupt priority has little or no effect on
+the system's behaviour. If the default priorities are inappropriate for
+some reason then they can be changed through the configuration options
+<varname>CYGNUM_DEVS_ETH_MCFxxxx_ISR_RX_PRIORITY</varname> and
+<varname>CYGNUM_DEVS_ETH_MCFxxxx_ISR_TX_PRIORITY</varname>.
+ </para>
+ <para>
+There is an option related to the default network MAC address,
+<varname>CYGDAT_DEVS_ETH_MCFxxxx_PLATFORM_MAC</varname>. This is
+discussed in more detail <link
+linkend="devs-eth-m68k-mcfxxxx-mac">below</link>.
+ </para>
+ <para>
+Optionally the ethernet driver can maintain statistics about the
+number of incoming and transmitted ethernet frames, receive overruns,
+collisions, and other conditions. Maintaining and providing these
+statistics involves some overhead, and is controlled by the
+configuration option
+<varname>CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS</varname>. Typically these
+statistics are only accessed through SNMP, so by default statistics
+gathering is enabled if the configuration includes
+<varname>CYGPKG_SNMPAGENT</varname> and disabled otherwise.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-m68k-mcfxxxx-mac"><title>MAC Address</title>
+ <para>
+The ColdFire processors do not have a built-in unique network MAC
+address since that would require slightly different manufacturing for
+each chip. All ethernet devices should have a unique address so this
+has to come from elsewhere. There are a number of possibilities:
+ </para>
+ <orderedlist>
+ <listitem><para>
+The platform HAL can provide the address. For example the target board
+may have a small serial EPROM or similar which is initialized during
+board manufacture. The platform HAL can read the serial EPROM during
+system startup and provide the information to the ethernet driver. If
+this is the case then the platform HAL should implement the CDL
+interface <varname>CYGINT_DEVS_ETH_MCFxxxx_PLATFORM_MAC</varname> and
+provide a macro <function>HAL_MCFxxxx_ETH_GET_MAC_ADDRESS</function>
+in the exported header <filename
+class="headerfile">cyg/hal/plf_arch.h</filename>.
+ </para></listitem>
+ <listitem><para>
+There is a configuration option
+<varname>CYGDAT_DEVS_ETH_MCFxxxx_PLATFORM_MAC</varname> which
+specifies the default MAC address. Manipulating this option is fine if
+the configuration will only be used on a single board. However if
+multiple boards run applications with the same configuration then they
+would all have the same MAC address, and the resulting behaviour is
+undefined.
+ </para></listitem>
+ <listitem><para>
+If the target hardware boots via RedBoot and uses a block of flash to
+hold configuration variables then one of these variables will be the
+MAC address. It can be manipulated at the RedBoot prompt using the
+<command>fconfig</command> command, thus giving each board a unique
+address. An eCos application containing the ethernet driver will
+automatically pick up this address.
+ </para></listitem>
+ </orderedlist>
+ <para>
+When designing a new target board it is recommended that the board
+comes with a unique network address supported by the platform HAL,
+rather than relying on users to change the address. The latter
+approach can be error-prone and will lead to failures that are
+difficult to track down.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-m68k-mcfxxxx-phy"><title>Platform-specific PHY</title>
+ <para>
+The on-chip ethernet hardware relies on an external media independent
+interface (MII), also known as a PHY chip. This separate chip handles
+the low-level details of ethernet communication, for example
+negotiating a link speed with the hub. In most scenarios the PHY chip
+simply does the right thing and needs no support from the ethernet
+driver. If there are special requirements, for example if the board
+has to be hardwired to communicate at 10Mbps rather than autonegotiate
+the link speed, then usually this is handled by fixed logic levels on
+some of the PHY pins or by using jumpers.
+ </para>
+ <para>
+The eCos ethernet driver assumes that the PHY is already fully
+operational and does not interact with it in any way. If the target
+hardware does require software initialization of the PHY chip then
+usually this will be done in the platform HAL, because the choice of
+PHY chip is a characteristic of the platform.
+ </para>
+ </refsect1>
+
+</refentry>
+</part>
diff --git a/ecos/packages/devs/eth/m68k/mcf5272/current/src/if_mcf5272.c b/ecos/packages/devs/eth/m68k/mcf5272/current/src/if_mcf5272.c
new file mode 100644
index 0000000..67019e4
--- /dev/null
+++ b/ecos/packages/devs/eth/m68k/mcf5272/current/src/if_mcf5272.c
@@ -0,0 +1,1354 @@
+//==========================================================================
+//
+// if_mcfxxxx.c
+//
+// Ethernet driver for Freescale MCFxxxx coldfires
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors:
+// Date: 2003-06-04
+// Description: hardware driver for MCFxxxx ethernet devices.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include CYGBLD_HAL_PLATFORM_H
+#include <pkgconf/devs_eth_mcfxxxx.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <string.h>
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <net/if.h> /* Needed for struct ifnet */
+#endif
+#include <cyg/io/eth/eth_drv_stats.h>
+
+// ----------------------------------------------------------------------------
+// Support for multiple devices - still incomplete.
+# define EIR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_EIR)
+# define EIMR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_EIMR)
+# define RDAR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_RDAR)
+# define TDAR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_TDAR)
+# define ECR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_ECR)
+# define MMFR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_MMFR)
+# define MSCR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_MSCR)
+# define MIBC(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_MIBC)
+# define RCR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_RCR)
+# define TCR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_TCR)
+# define PALR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_PALR)
+# define PAUR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_PAUR)
+# define OPD(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_OPD)
+# define IAUR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_IAUR)
+# define IALR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_IALR)
+# define GAUR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_GAUR)
+# define GALR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_GALR)
+# define TFWR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_TFWR)
+# define FRBR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_FRBR)
+# define FRSR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_FRSR)
+# define ERDSR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_ERDSR)
+# define ETDSR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_ETDSR)
+# define EMRBR(_eth_) (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_EMRBR)
+
+// ----------------------------------------------------------------------------
+// Debug support, in the form of diagnostics and a simple trace
+// buffer. Also make it easy to enable stats without messing about
+// with the configuration.
+
+#define DIAG_LEVEL 0
+#define DIAG_BUFFERED 0
+#define DIAG_WRAP 1
+#ifndef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
+//# define CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS 1
+#endif
+
+#if (DIAG_LEVEL <= 0)
+
+# define DIAG(_level_, _fmt_, ...) \
+ CYG_MACRO_START \
+ CYG_MACRO_END
+
+# define DIAGPKT(_level_, _msg_, _pkt_, _len_) \
+ CYG_MACRO_START \
+ CYG_MACRO_END
+
+#elif (! DIAG_BUFFERED)
+
+# define DIAG(_level_, _fmt_, ...) \
+ CYG_MACRO_START \
+ if ((_level_) <= DIAG_LEVEL) { \
+ diag_printf("mcfxxxx_eth %s : " _fmt_ "\n", __func__, ## __VA_ARGS__); \
+ } \
+ CYG_MACRO_END
+
+# define DIAGPKT(_level_, _msg_, _pkt_, _len_) \
+ CYG_MACRO_START \
+ if ((_level_) <= DIAG_LEVEL) { \
+ diag_printf("mcfxxxx_eth %s : pkt %p, len %d\n", __func__, \
+ (cyg_uint8*)_pkt_, _len_); \
+ } \
+ CYG_MACRO_END
+
+#else
+// Trace buffer size. This has to be kept smallish or RedBoot will overrun
+// its RAM allocation. With 24 bytes per entry, 300 entries require a bit
+// under 8K.
+# define DIAG_BUFFER_SIZE 300
+typedef struct mcfxxxx_eth_trace {
+ const char* fn;
+ const char* msg;
+ cyg_uint32 len;
+ cyg_uint8 packet[14];
+} mcfxxxx_eth_trace_entry;
+static mcfxxxx_eth_trace_entry mcfxxxx_eth_trace_data[DIAG_BUFFER_SIZE];
+static int mcfxxxx_eth_trace_next = DIAG_BUFFER_SIZE - 1;
+static cyg_bool mcfxxxx_eth_trace_wrapped = false;
+
+static void
+mcfxxxx_eth_trace(const char* fn, const char* msg, cyg_uint8* packet, cyg_uint32 len)
+{
+ mcfxxxx_eth_trace_entry* entry = &(mcfxxxx_eth_trace_data[mcfxxxx_eth_trace_next]);
+
+# ifdef DIAG_WRAP
+ if (0 == mcfxxxx_eth_trace_next) {
+ mcfxxxx_eth_trace_next = DIAG_BUFFER_SIZE - 1;
+ mcfxxxx_eth_trace_wrapped = true;
+ } else {
+ mcfxxxx_eth_trace_next -= 1;
+ }
+# else
+ if (mcfxxxx_eth_trace_next < 0) {
+ return;
+ }
+ mcfxxxx_eth_trace_next -= 1;
+# endif
+
+ entry->fn = fn;
+ entry->msg = msg;
+ entry->len = len;
+ if ((cyg_uint8*)0 == packet) {
+ memset(entry->packet, 0, 14);
+ } else {
+ memcpy(entry->packet, packet, 14);
+ }
+}
+
+# define DIAG(_level_, _fmt_, ...) \
+ CYG_MACRO_START \
+ if ((_level_) <= DIAG_LEVEL) { \
+ mcfxxxx_eth_trace(__func__, _fmt_, (cyg_uint8*)0, 0); \
+ } \
+ CYG_MACRO_END
+
+# define DIAGPKT(_level_, _msg_, _pkt_, _len_) \
+ CYG_MACRO_START \
+ if ((_level_) <= DIAG_LEVEL) { \
+ mcfxxxx_eth_trace(__func__, _msg_, (cyg_uint8*)_pkt_, _len_); \
+ } \
+ CYG_MACRO_END
+
+#endif
+
+#if (DIAG_LEVEL < 3)
+# define WRITE32(_addr_, _val_) HAL_WRITE_UINT32(_addr_, _val_)
+# define READ32( _addr_, _var_) HAL_READ_UINT32(_addr_, _var_)
+#else
+
+# define WRITE32(_addr_, _val_) \
+ CYG_MACRO_START \
+ DIAG(DIAG_LEVEL, "WRITE %s %08x <= 0x%08x", # _addr_, _addr_, _val_) ; \
+ HAL_WRITE_UINT32(_addr_, _val_); \
+ CYG_MACRO_END
+
+#define READ32(_addr_, _var_) \
+ CYG_MACRO_START \
+ HAL_READ_UINT32(_addr_, _var_); \
+ DIAG(DIAG_LEVEL, "READ %s %08x == 0x%08x", # _addr_, _addr_, _var_) ; \
+ CYG_MACRO_END
+
+#endif
+
+#if 0
+// A function that gets placed in RAM. This can be called by flash-resident
+// code, e.g. RedBoot, when I need a breakpoint on a specific condition.
+static void mcfxxxx_eth_ramfn(void) __attribute__((section (".2ram.mcfxxxx_eth_ramfn")));
+static int mcfxxxx_eth_ramfn_calls;
+static void
+mcfxxxx_eth_ramfn(void)
+{
+ mcfxxxx_eth_ramfn_calls += 1;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+#ifdef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
+# define INCR_STAT(_a_) \
+ CYG_MACRO_START \
+ _a_ += 1; \
+ CYG_MACRO_END
+#else
+# define INCR_STAT(_a_)
+#endif
+
+// ----------------------------------------------------------------------------
+// Most existing MCFxxxx chips have a single on-chip ethernet device,
+// so all device-specific data could be held in statics. However, in
+// case this driver ever gets re-used for a chip with multiple
+// ethernet devices that data is held in a driver-specific structure.
+//
+// The driver currently supports n rx buffers, configurable, each of
+// maximum size. Incoming frames are then copied to higher-level's code
+// sg lists.
+//
+// For tx the current code supports a single outgoing transmission at a
+// time. This does limit outgoing bandwidth a bit, but only a bit, and
+// saves memory and complexity.
+//
+// There are actually two implementations of the TX code. The MCF5272
+// has no alignment restrictions for the data being transmitted, so it
+// is possible to avoid a copy and put the higher-level sg_list entries
+// directly into the device's ring buffer. The MCF5282 does have
+// alignment restrictions and the sg_list entries may not be suitably
+// aligned, so a copy operation is necessary.
+// NOTE: a possible optimization is to detect aligned vs. misaligned
+// data and only copy the bits that need aligning. This would significantly
+// complicate the code and it is not clear that data would be aligned
+// sufficiently often to make it worthwhile, at least not without work
+// inside the TCP/IP stack.
+//
+// With only one outgoing transmission at a time a full ring buffer seems
+// overkill. However it appears that the hardware can get confused if the
+// ring buffer consists of only a single entry, so the code has to
+// implement a full ring buffer anyway
+
+#if defined(HAL_DCACHE_LINE_SIZE) && (HAL_DCACHE_LINE_SIZE != 16)
+# error Driver code needs adjusting for cache line sizes other than 16 bytes.
+#endif
+
+#if defined(CYGPKG_HAL_M68K_MCF5272)
+
+# undef TX_NEEDS_ALIGNMENT
+# define TX_BUFFER_SIZE 0
+
+// Always use an even number of buffer descriptors, to preserve
+// alignment to a 16-byte boundary. We need one more entry in the
+// ring buffer than SG_LIST_SIZE.
+# if (0 == (CYGNUM_IO_ETH_DRIVERS_SG_LIST_SIZE & 0x01))
+# define TX_BUFFER_DESCRIPTOR_COUNT (CYGNUM_IO_ETH_DRIVERS_SG_LIST_SIZE + 2)
+# else
+# define TX_BUFFER_DESCRIPTOR_COUNT (CYGNUM_IO_ETH_DRIVERS_SG_LIST_SIZE + 1)
+# endif
+
+// This #elif should probably become a #else
+#elif defined(CYGPKG_HAL_M68K_MCF5282) || defined(CYGPKG_HAL_M68K_MCF532x)
+
+# define TX_NEEDS_ALIGNMENT 1
+# define TX_BUFFER_SIZE 1520
+# define TX_BUFFER_DESCRIPTOR_COUNT 2
+
+#else
+
+# error Current processor unsupported
+
+#endif
+
+#if (0 == (CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS & 0x01)) || (0 == HAL_DCACHE_SIZE)
+# define RX_BUFFER_DESCRIPTOR_PADDING 0
+#else
+# define RX_BUFFER_DESCRIPTOR_PADDING 16
+#endif
+
+typedef struct mcfxxxx_eth {
+
+ // There are two separate interrupt vectors to worry about, RXF
+ // and TXF. Other interrupt sources such as error conditions are
+ // handled by the main tx/rx code, not by separate interrupt
+ // handlers.
+ cyg_handle_t interrupt_handle_rx;
+ cyg_interrupt interrupt_data_rx;
+ cyg_handle_t interrupt_handle_tx;
+ cyg_interrupt interrupt_data_tx;
+
+ // Pointers to the buffer descriptors. These index the data[] array
+ // below.
+ hal_mcfxxxx_eth_buffer_descriptor* txbds;
+ hal_mcfxxxx_eth_buffer_descriptor* rxbds;
+
+#ifdef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
+ cyg_uint32 interrupts;
+ cyg_uint32 tx_count;
+ cyg_uint32 tx_good;
+ cyg_uint32 tx_max_collisions;
+ cyg_uint32 tx_late_collisions;
+ cyg_uint32 tx_underrun;
+ cyg_uint32 tx_carrier_loss;
+ cyg_uint32 tx_deferred;
+ cyg_uint32 tx_single_collisions;
+ cyg_uint32 tx_mult_collisions;
+ cyg_uint32 tx_total_collisions;
+
+ cyg_uint32 rx_count;
+ cyg_uint32 rx_good;
+ cyg_uint32 rx_crc_errors;
+ cyg_uint32 rx_align_errors;
+ cyg_uint32 rx_overrun_errors;
+ cyg_uint32 rx_short_frames;
+ cyg_uint32 rx_too_long_frames;
+#endif
+
+ unsigned long tx_key;
+
+ cyg_uint8 tx_index;
+ cyg_uint8 started;
+ cyg_uint8 tx_can_send;
+ cyg_uint8 tx_done;
+ cyg_uint8 rx_rdy;
+ cyg_uint8 rx_next_buffer;
+ cyg_uint16 rx_len;
+ cyg_uint8 mac[6];
+
+ // We need:
+ // 1) padding to get the data aligned to a 16-byte boundary. A
+ // 16 byte alignment for the rx and tx buffer descriptors is
+ // recommended, and should also help with flushing/invalidating
+ // cache lines when necessary.
+ // 2) n 1520 byte rx buffers. 1520 is a multiple of 16 so maintains
+ // alignment.
+ // 3) possibly a 1520 byte tx buffer, as per TX_ALIGNED_BUF_SIZE.
+ // 4) some number of tx buffer descriptors, as per TX_BUFFER_COUNT.
+ // This number will be even, maintaining alignment to 16 bytes.
+ // 5) some number of rx buffer descriptors. The number of RX buffers
+ // need not be even since each buffer is large.
+ // 6) padding for the RXBUFFERS to ensure that cache lines are not
+ // shared between buffer descriptors and other data.
+ cyg_uint8 data[15 +
+ (1520 * CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS) +
+ TX_BUFFER_SIZE +
+ (TX_BUFFER_DESCRIPTOR_COUNT * sizeof(hal_mcfxxxx_eth_buffer_descriptor)) +
+ (CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS * sizeof(hal_mcfxxxx_eth_buffer_descriptor)) +
+ RX_BUFFER_DESCRIPTOR_PADDING
+ ];
+} mcfxxxx_eth;
+
+// This structure is held in bss so all stats etc. are automatically zeroed.
+static mcfxxxx_eth mcfxxxx_eth_info;
+
+ETH_DRV_SC(mcfxxxx_eth_sc0,
+ (void*) &mcfxxxx_eth_info,
+ CYGDAT_DEVS_ETH_MCFxxxx_NAME,
+ mcfxxxx_eth_start,
+ mcfxxxx_eth_stop,
+ mcfxxxx_eth_ioctl,
+ mcfxxxx_eth_can_send,
+ mcfxxxx_eth_send,
+ mcfxxxx_eth_recv,
+ mcfxxxx_eth_deliver,
+ mcfxxxx_eth_poll,
+ mcfxxxx_eth_int_vector
+ );
+
+NETDEVTAB_ENTRY(mcfxxxx_eth_netdev0,
+ "mcfxxxx-" CYGDAT_DEVS_ETH_MCFxxxx_NAME,
+ mcfxxxx_eth_init,
+ &mcfxxxx_eth_sc0);
+
+static cyg_uint32 mcfxxxx_eth_isr_rx(cyg_vector_t, cyg_addrword_t);
+static void mcfxxxx_eth_dsr_rx(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
+static cyg_uint32 mcfxxxx_eth_isr_tx(cyg_vector_t, cyg_addrword_t);
+static void mcfxxxx_eth_dsr_tx(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
+
+// ----------------------------------------------------------------------------
+// The MAC address. Usually this will be supplied by the platform HAL, but some
+// platforms may not have appropriate hardware. In that case the address will
+// normally come from RedBoot's config info, with a fallback configurable
+// value.
+#ifdef CYGINT_DEVS_ETH_MCFxxxx_PLATFORM_MAC
+
+# if !defined(HAL_MCFxxxx_ETH_GET_MAC_ADDRESS)
+# error Platform HAL should have provided a MAC address macro
+# endif
+
+#else
+
+static cyg_uint8 mcfxxxx_eth_default_mac[6] = { CYGDAT_DEVS_ETH_MCFxxxx_PLATFORM_MAC } ;
+
+# ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+RedBoot_config_option("Network hardware address [MAC]",
+ mcfxxxx_mac,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+# endif
+# endif
+
+static void
+mcfxxxx_eth_get_config_mac_address(cyg_uint8* mac)
+{
+ int mac_ok = 0;
+#ifdef CYGPKG_REDBOOT
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+ mac_ok = flash_get_config("mcfxxxx_mac", mac, CONFIG_ESA);
+# endif
+#else
+ // Not in RedBoot. Do we have virtual vectors?
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ mac_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET, "mcfxxxx_mac", mac, CYGNUM_FLASH_CFG_TYPE_CONFIG_ESA);
+# endif
+#endif
+ if (! mac_ok) {
+ memcpy(mac, mcfxxxx_eth_default_mac, 6);
+ }
+}
+
+#endif // CYGINT_DEVS_ETH_MCFxxxx_PLATFORM_MAC
+
+// ----------------------------------------------------------------------------
+
+static bool
+mcfxxxx_eth_init(struct cyg_netdevtab_entry* ndp)
+{
+ struct eth_drv_sc* sc = (struct eth_drv_sc*) ndp->device_instance;
+ struct mcfxxxx_eth* eth = (struct mcfxxxx_eth*) sc->driver_private;
+ CYG_ADDRWORD ptr;
+ cyg_uint8* rxbuffers;
+ cyg_uint8* txbuffer;
+ cyg_uint32 i;
+
+ DIAG(1, "entry");
+
+#ifdef HAL_MCFxxxx_ETH_DETECT_DEVICE
+ if (! HAL_MCFxxxx_ETH_DETECT_DEVICE(HAL_MCFxxxx_ETH0_BASE) ) {
+ DIAG(1, "device disabled by HAL");
+ return 0;
+ }
+#endif
+
+#ifdef CYGSEM_HAL_USE_ROM_MONITOR
+ // If we are debugging over RedBoot, it is possible that there is an
+ // outgoing packet still queued up. Give it a chance to get out, a
+ // couple of milliseconds should suffice.
+ for (i = 0; i < 20; i++) {
+ cyg_uint32 x_des_active;
+ READ32(TDAR(eth), x_des_active);
+ if (0 == (x_des_active & HAL_MCFxxxx_ETHx_TDAR_X_DES_ACTIVE)) {
+ break;
+ }
+ HAL_DELAY_US(100);
+ }
+#endif
+
+ // Set the whole ethernet device to disabled. Then the other registers
+ // can be manipulated safely. The device gets activated in the start
+ // function. The reset also sets all registers to their default values.
+ WRITE32(ECR(eth), HAL_MCFxxxx_ETHx_ECR_RESET);
+
+ eth->started = 0;
+ // While the reset is going on, sort out the buffers and buffer descriptors.
+ // These should be aligned to a 16-byte boundary.
+ ptr = (CYG_ADDRWORD) eth->data;
+ ptr = (ptr + 15) & ~15;
+ // First the rx buffers, n * 1520 bytes.
+ rxbuffers = (cyg_uint8*) ptr;
+ ptr += (CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS * 1520);
+ // We are still aligned to a 16-byte boundary. Now for the tx buffer if necessary.
+ txbuffer = (cyg_uint8*) ptr;
+ ptr += TX_BUFFER_SIZE;
+ // Still aligned. The tx buffer descriptors. This will be an even number
+ // so alignment is maintained.
+ eth->txbds = (hal_mcfxxxx_eth_buffer_descriptor*) ptr;
+ ptr += (TX_BUFFER_DESCRIPTOR_COUNT * sizeof(hal_mcfxxxx_eth_buffer_descriptor));
+ // And finally the rx buffer descriptors.
+ eth->rxbds = (hal_mcfxxxx_eth_buffer_descriptor*) ptr;
+
+ // We can fill in the buffer fields in the various rx buffer descriptors.
+ // The length and flag fields are handled by _start().
+ for (i = 0; i < CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS; i++) {
+ eth->rxbds[i].ethbd_buffer = rxbuffers;
+ rxbuffers += 1520;
+ }
+
+ // Ditto for the tx buffers, if tx involves copying into an
+ // aligned buffer. Only one entry in the ring buffer will be used
+ // at a time, so the two buffer descriptors can share the same
+ // buffer.
+#ifdef TX_NEEDS_ALIGNMENT
+ eth->txbds[0].ethbd_buffer = txbuffer;
+ eth->txbds[1].ethbd_buffer = txbuffer;
+#endif
+
+ // rx_next_buffer tracks the next rx buffer descriptor which the
+ // hardware may process.
+ eth->rx_next_buffer = 0;
+
+ // Determine the MAC address. This has to be done by the platform HAL if possible
+#ifdef CYGINT_DEVS_ETH_MCFxxxx_PLATFORM_MAC
+ HAL_MCFxxxx_ETH_GET_MAC_ADDRESS(eth->mac);
+#else
+ mcfxxxx_eth_get_config_mac_address(eth->mac);
+#endif
+
+ // The interrupt handlers can also be installed here. All
+ // interrupts are masked after the reset so nothing will
+ // actually happen. Separate ISR's and DSR's are used for
+ // the various interrupt sources.
+ cyg_drv_interrupt_create(CYGNUM_HAL_ISR_ERX,
+ CYGNUM_DEVS_ETH_MCFxxxx_ISR_RX_PRIORITY,
+ (CYG_ADDRWORD) sc,
+ &mcfxxxx_eth_isr_rx,
+ &mcfxxxx_eth_dsr_rx,
+ &(eth->interrupt_handle_rx),
+ &(eth->interrupt_data_rx));
+ cyg_drv_interrupt_attach(eth->interrupt_handle_rx);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_ISR_ERX);
+
+ cyg_drv_interrupt_create(CYGNUM_HAL_ISR_ETX,
+ CYGNUM_DEVS_ETH_MCFxxxx_ISR_TX_PRIORITY,
+ (CYG_ADDRWORD) sc,
+ &mcfxxxx_eth_isr_tx,
+ &mcfxxxx_eth_dsr_tx,
+ &(eth->interrupt_handle_tx),
+ &(eth->interrupt_data_tx));
+ cyg_drv_interrupt_attach(eth->interrupt_handle_tx);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_ISR_ETX);
+
+ // An EBERR bus error will halt the ethernet device and raise an
+ // interrupt. Arguably this should be handled here, but the assumption
+ // is that the interrupt will never be raised because the driver will
+ // never be given a bogus pointer.
+
+ // Now the rest of the hardware can be initialized. First control
+ // the GPIO pins, or whatever else needs doing on a per-processor
+ // basis. For now the PHY is enabled unconditionally.
+ // NOTE: much of this initialization code should be moved to a
+ // separate reset function which can be called during start-up or
+ // after an internal bus error.
+#ifdef HAL_MCFxxxx_ETH0_PROC_INIT
+ HAL_MCFxxxx_ETH0_PROC_INIT(1);
+#endif
+#ifdef HAL_MCFxxxx_ETH0_PLATFORM_INIT
+ HAL_MCFxxxx_ETH0_PLATFORM_INIT();
+#endif
+
+ // Now for the ethernet device itself. The order used here is as
+ // per the MCF5282 User's Manual.
+ //
+ // EIMR: We want interrupts for complete frame transfers only
+ WRITE32(EIMR(eth), HAL_MCFxxxx_ETHx_EIMR_TXF | HAL_MCFxxxx_ETHx_EIMR_RXF);
+
+ // EIR: Cleared by the reset, but just in case.
+ WRITE32(EIR(eth), 0xFFF80000);
+ // TFWR: Leave to its default value
+#if defined(HAL_MCFxxxx_ETHx_IAUR)
+ // IAUR & IALR. The MCF5282 also has a unicast hash table, allowing the
+ // device to accept frames sent to several different addresses.
+ // This is not supported, only an exact match is used.
+ WRITE32(IAUR(eth), 0x0);
+ WRITE32(IALR(eth), 0x0);
+#endif
+ // Multicast hash table (GAUR & GALR). All 1's should be equivalent
+ // to multi-all. All 0's should be equivalent to no-multi.
+ WRITE32(GAUR(eth), 0x0);
+ WRITE32(GALR(eth), 0x0);
+ // MAC address (PAUR & PALR)
+ i = (eth->mac[4] << 24) | (eth->mac[5] << 16);
+ WRITE32(PAUR(eth), i);
+ i = (eth->mac[0] << 24) | (eth->mac[1] << 16) | (eth->mac[2] << 8) | (eth->mac[3] << 0);
+ WRITE32(PALR(eth), i);
+#if defined(HAL_MCFxxxx_ETHx_OPD)
+ // OPD: not actually used, but reset it to its default anyway
+ WRITE32(OPD(eth), 0x00010000);
+#endif
+ // RCR: Default to half-duplex mode. Promiscuous mode may get
+ // set by start().
+ // MII mode should be platform-specific, 7-wire mode is possible.
+ // On an mcf5282 the register also contains the max frame length
+#if defined(HAL_MCFxxxx_ETHx_RCR_MAX_FL_VALUE)
+ WRITE32(RCR(eth), HAL_MCFxxxx_ETHx_RCR_MAX_FL_VALUE | HAL_MCFxxxx_ETHx_RCR_MII_MODE | HAL_MCFxxxx_ETHx_RCR_DRT);
+#else
+ WRITE32(RCR(eth), HAL_MCFxxxx_ETHx_RCR_MII_MODE | HAL_MCFxxxx_ETHx_RCR_DRT);
+#endif
+ // TCR: default to half-duplex
+ WRITE32(TCR(eth), 0);
+
+ // MSCR/MII_SPEED.
+ // MDC_FREQUENCY == HZ / (4 * reg value)
+ // MDC_FREQUENCY should be <= 2.5MHz
+ WRITE32(MSCR(eth), ((CYGHWR_HAL_SYSTEM_CLOCK_HZ - 1) / (4 * 2500000)) + 1);
+
+ // FRSR: Leave to its default value
+ // EMRBR: The receiver buffer size is 1520 (must be a multiple of 16 and > frame size)
+ WRITE32(EMRBR(eth), 1520);
+ // The buffer descriptor rings, ERDSR & ETDSR
+ WRITE32(ERDSR(eth), (cyg_uint32)eth->rxbds);
+ WRITE32(ETDSR(eth), (cyg_uint32)eth->txbds);
+
+ // Other registers:
+ // IVEC: readonly
+ // RDAR: Set by start() and by the receive code
+ // TDAR: Set by start() and by the transmit code
+ // MMFR: There is no need to access the phy
+ // R_BOUND: Read-only
+ // MFLR: The default length is already 1518 bytes, so leave it.
+ // (This register does not exist on the 5282)
+
+ // The ethernet device gets enabled in _start()
+
+ DIAG(1, "calling higher-level");
+
+ // Initialize the upper level driver
+ (sc->funs->eth_drv->init)(sc, eth->mac);
+
+ DIAG(1, "done");
+
+ return 1;
+}
+
+// ----------------------------------------------------------------------------
+
+// The driver only supports one transmit at a time, and a global is used
+// to keep track of whether or not a transmit is in progress.
+static int
+mcfxxxx_eth_can_send(struct eth_drv_sc* sc)
+{
+ struct mcfxxxx_eth* eth = (struct mcfxxxx_eth*) sc->driver_private;
+ if (eth->tx_can_send) {
+ DIAG(1, "yes");
+ } else {
+ DIAG(3, "no");
+ }
+ return eth->tx_can_send;
+}
+
+// There are two implementations of the transmit code, one for the case
+// where the data needs to be copied into an aligned buffer, the other
+// for when the data can be used in place.
+
+static void
+mcfxxxx_eth_send(struct eth_drv_sc* sc,
+ struct eth_drv_sg* sg_list, int sg_len, int total_len,
+ unsigned long key)
+{
+ struct mcfxxxx_eth* eth = (struct mcfxxxx_eth*) sc->driver_private;
+ cyg_uint32 index = eth->tx_index;
+ int i;
+
+ DIAG(1, " total_len %d", total_len);
+ eth->tx_can_send = 0;
+ eth->tx_key = key;
+
+#ifdef TX_NEEDS_ALIGNMENT
+ {
+ // The aligned buffer is permanently held in the buffer descriptor.
+ cyg_uint8* buf = eth->txbds[index].ethbd_buffer;
+ for (i = 0; i < sg_len; i++) {
+ memcpy(buf, (cyg_uint8*) sg_list[i].buf, sg_list[i].len);
+ buf += sg_list[i].len;
+ }
+ eth->txbds[index].ethbd_length = total_len;
+ eth->txbds[index].ethbd_flags |= HAL_MCFxxxx_ETHx_TXBD_R + HAL_MCFxxxx_ETHx_TXBD_L + HAL_MCFxxxx_ETHx_TXBD_TC;
+ DIAGPKT(1, "start", buf, total_len);
+
+# ifdef HAL_DCACHE_STORE
+ // Make sure the data has been written to memory.
+ HAL_DCACHE_STORE(eth->txbds[index].ethbd_buffer, total_len);
+# endif
+ }
+#else
+ {
+ cyg_uint32 last_index = index;
+ for (i = 0; i < sg_len; i++) {
+ eth->txbds[index].ethbd_flags &= ~(HAL_MCFxxxx_ETHx_TXBD_L | HAL_MCFxxxx_ETHx_TXBD_TC);
+ // The R bit can be set immediately, rather than in the
+ // usual reverse order to prevent an underrun. This is
+ // because a new send is only initiated when the transmit
+ // engine is idle.
+ eth->txbds[index].ethbd_flags |= HAL_MCFxxxx_ETHx_TXBD_R;
+ eth->txbds[index].ethbd_length = sg_list[i].len;
+ eth->txbds[index].ethbd_buffer = (cyg_uint8*) sg_list[i].buf;
+# ifdef HAL_DCACHE_STORE
+ HAL_DCACHE_STORE(eth->txbds[index].ethbd_buffer, sg_list[i].len);
+# endif
+ last_index = index;
+ if (index == (TX_BUFFER_DESCRIPTOR_COUNT - 1)) {
+ index = 0;
+ } else {
+ index += 1;
+ }
+ }
+ eth->txbds[last_index].ethbd_flags |= HAL_MCFxxxx_ETHx_TXBD_L | HAL_MCFxxxx_ETHx_TXBD_TC;
+
+ eth->tx_index = last_index;
+ DIAGPKT(1, "start", sg_list[0].buf, total_len);
+ }
+#endif
+
+ // Make sure all the buffer descriptors have been written to memory.
+ // No need to invalidate the cache entries, the driver does not look
+ // for any bits changed by the hardware except on the 5272 which
+ // does not have a data cache at all.
+#ifdef HAL_DCACHE_STORE
+ HAL_DCACHE_STORE(&(eth->txbds[0]), TX_BUFFER_DESCRIPTOR_COUNT * sizeof(hal_mcfxxxx_eth_buffer_descriptor));
+#endif
+ WRITE32(TDAR(eth), HAL_MCFxxxx_ETHx_TDAR_X_DES_ACTIVE);
+}
+
+// The TX interrupt should only trigger when a whole frame has been
+// transmitted. There is no need to worry about nested tx interrupts,
+// at most one transmit can be in progress at any one time. Just
+// clear the interrupt pending bit and leave the rest to the DSR.
+static cyg_uint32
+mcfxxxx_eth_isr_tx(cyg_vector_t vector, cyg_addrword_t data)
+{
+ HAL_WRITE_UINT32(EIR(eth), HAL_MCFxxxx_ETHx_EIR_TXF | HAL_MCFxxxx_ETHx_EIR_TXB);
+ return CYG_ISR_CALL_DSR;
+}
+
+static void
+mcfxxxx_eth_dsr_tx(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct eth_drv_sc* sc = (struct eth_drv_sc*) data;
+ mcfxxxx_eth* eth = (mcfxxxx_eth*)(sc->driver_private);
+
+ INCR_STAT(eth->interrupts);
+#ifdef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
+
+# if defined(CYGPKG_HAL_M68K_MCF5272)
+ {
+ cyg_uint16 flags;
+ // The MCF5272 has all appropriate error flags in the tx buffer descriptor.
+ flags = eth->txbds[eth->tx_index].ethbd_flags & (HAL_MCFxxxx_ETHx_TXBD_DEF | HAL_MCFxxxx_ETHx_TXBD_LC | HAL_MCFxxxx_ETHx_TXBD_RL |
+ HAL_MCFxxxx_ETHx_TXBD_RC_MASK | HAL_MCFxxxx_ETHx_TXBD_UN | HAL_MCFxxxx_ETHx_TXBD_CSL);
+ if (0 == flags) {
+ INCR_STAT(eth->tx_good);
+ } else {
+ if (flags & HAL_MCFxxxx_ETHx_TXBD_RL) {
+ eth->tx_max_collisions = 16;
+ INCR_STAT(eth->tx_total_collisions);
+ } else {
+ int collisions = (flags & HAL_MCFxxxx_ETHx_TXBD_RC_MASK) >> HAL_MCFxxxx_ETHx_TXBD_RC_SHIFT;
+ if (collisions > 0) {
+ INCR_STAT(eth->tx_total_collisions);
+ if (collisions > eth->tx_max_collisions) {
+ eth->tx_max_collisions = collisions;
+ }
+ if (1 == collisions) {
+ INCR_STAT(eth->tx_single_collisions);
+ } else {
+ INCR_STAT(eth->tx_mult_collisions);
+ }
+ }
+ }
+ if (flags & HAL_MCFxxxx_ETHx_TXBD_LC) {
+ INCR_STAT(eth->tx_late_collisions);
+ }
+ if (flags & HAL_MCFxxxx_ETHx_TXBD_UN) {
+ INCR_STAT(eth->tx_underrun);
+ }
+ if (flags & HAL_MCFxxxx_ETHx_TXBD_CSL) {
+ INCR_STAT(eth->tx_carrier_loss);
+ }
+ if (flags & HAL_MCFxxxx_ETHx_TXBD_DEF) {
+ INCR_STAT(eth->tx_deferred);
+ }
+ }
+ }
+# else
+ {
+ // Assume MCF5282-compatible.
+ // There are no error bits in the tx buffer descriptor. Instead it is
+ // possible to check the interrupt status register, look for error
+ // flags, and clear them.
+ cyg_uint32 flags;
+ HAL_READ_UINT32(EIR(eth), flags);
+ flags &= (HAL_MCFxxxx_ETHx_EIR_LC | HAL_MCFxxxx_ETHx_EIR_RL | HAL_MCFxxxx_ETHx_EIR_UN);
+ if (0 == flags) {
+ INCR_STAT(eth->tx_good);
+ } else {
+ if (flags & HAL_MCFxxxx_ETHx_EIR_LC) {
+ INCR_STAT(eth->tx_late_collisions);
+ }
+ if (flags & HAL_MCFxxxx_ETHx_EIR_RL) {
+ INCR_STAT(eth->tx_total_collisions);
+ INCR_STAT(eth->tx_mult_collisions);
+ }
+ if (flags & HAL_MCFxxxx_ETHx_EIR_UN) {
+ INCR_STAT(eth->tx_underrun);
+ }
+ // Clear these interrupt flags
+ HAL_WRITE_UINT32(EIR(eth), flags);
+ }
+ }
+# endif
+#endif
+
+ eth->tx_done = 1;
+ eth->tx_index = eth->tx_index + 1;
+ if (TX_BUFFER_DESCRIPTOR_COUNT == eth->tx_index) {
+ eth->tx_index = 0;
+ }
+ // There is no need to worry about cleaning up the buffer descriptors.
+ // The hardware will have cleared the R bit, which is the only one that
+ // must be cleared.
+ DIAG(1, "packet sent");
+ eth_drv_dsr(vector, count, data);
+}
+
+// ----------------------------------------------------------------------------
+
+// A whole ethernet frame has been received and reported to higher-level
+// code, which has allocated an mbuf. The frame is identified by the
+// rx_next_buffer field of the mcfxxxx_eth structure, which gets set in
+// deliver(). The data must be copied into the mbuf, and then the
+// hardware needs to be told that this buffer is available again.
+// The hardware stores a 4-byte checksum in the receive buffer
+// which must be discarded.
+static void
+mcfxxxx_eth_recv(struct eth_drv_sc* sc, struct eth_drv_sg* sg_list, int sg_len)
+{
+ mcfxxxx_eth* eth = (mcfxxxx_eth*) sc->driver_private;
+ int index = eth->rx_next_buffer;
+ cyg_uint8* buf = eth->rxbds[index].ethbd_buffer;
+ int len = eth->rx_len - 4;
+ int i;
+
+ DIAGPKT(1, "packet received", buf, len);
+
+ for (i = 0; (i < sg_len) && (len > 0); i++) {
+ if (0 == sg_list[i].buf) {
+ break;
+ } else if (len <= sg_list[i].len) {
+ memcpy((void*) sg_list[i].buf, buf, len);
+ break;
+ } else {
+ memcpy((void*) sg_list[i].buf, buf, sg_list[i].len);
+ buf += sg_list[i].len;
+ len -= sg_list[i].len;
+ }
+ }
+
+ // Once the data has been copied out of the RX buffer, clear the
+ // cache lines ready for the next packet. Use an invalidate if
+ // available, otherwise a flush.
+#if defined(HAL_DCACHE_INVALIDATE)
+ HAL_DCACHE_INVALIDATE(eth->rxbds[index].ethbd_buffer, eth->rx_len);
+#elif defined(HAL_DCACHE_FLUSH)
+ HAL_DCACHE_FLUSH(eth->rxbds[index].ethbd_buffer, eth->rx_len);
+#endif
+}
+
+// The RX interrupt triggers whenever a whole frame has been received (or
+// when an error has occurred). The hardware may be busy receiving into the
+// next buffer.
+//
+// Because of the ring buffer several packets may arrive before the cpu gets
+// around to processing them. It is possible to save a little bit of load
+// by masking the rxf interrupt inside the ethernet device, then doing the
+// acknowledge and an unmask inside the deliver() code.
+static cyg_uint32
+mcfxxxx_eth_isr_rx(cyg_vector_t vector, cyg_addrword_t data)
+{
+ WRITE32(EIMR(eth), HAL_MCFxxxx_ETHx_EIMR_TXF);
+ return CYG_ISR_CALL_DSR;
+}
+
+static void
+mcfxxxx_eth_dsr_rx(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct eth_drv_sc* sc = (struct eth_drv_sc*) data;
+ mcfxxxx_eth* eth = (mcfxxxx_eth*)(sc->driver_private);
+
+ INCR_STAT(eth->interrupts);
+ eth->rx_rdy = 1;
+ eth_drv_dsr(vector, count, data);
+}
+
+// ----------------------------------------------------------------------------
+// deliver() is usually called from thread context, after the DSR has woken
+// up the packet handling thread. It needs to report completed transmits so
+// that higher-level code can release the mbuf, and report all received
+// frames.
+
+static void
+mcfxxxx_eth_deliver(struct eth_drv_sc* sc)
+{
+ mcfxxxx_eth* eth = (mcfxxxx_eth*) sc->driver_private;
+
+ DIAG(1, "entry");
+
+ if (eth->tx_done) {
+ DIAG(1, "tx_done");
+ INCR_STAT(eth->tx_count);
+ eth->tx_done = 0;
+ eth->tx_can_send = 1;
+ (*sc->funs->eth_drv->tx_done)(sc, eth->tx_key, 1);
+ }
+
+ if (eth->rx_rdy) {
+ int bd_emptied = 0;
+ int frame_found = 0;
+
+ DIAG(1, "rx_rdy");
+ eth->rx_rdy = 0;
+
+ // Acknowledge any packets that have been received and will be processed
+ // by the loop below. There is a small possibility of a packet arriving
+ // in the middle of this loop, causing an rxf interrupt to become pending
+ // even though the packet will get processed by the loop. This is harmless.
+ // The rxb interrupt is cleared as well because that comes for free, making
+ // debugging slightly easier.
+ WRITE32(EIR(eth), HAL_MCFxxxx_ETHx_EIR_RXF | HAL_MCFxxxx_ETHx_EIR_RXB);
+
+ DIAG(1, "updated eir");
+ // Loop while there are non-empty packets. This has to be done with a bit
+ // of care. Packets should be processed in the right order where possible,
+ // which means keeping track of the last packet received. However it is
+ // necessary to check all the buffers - for some reason the hardware does
+ // not always put the next frame in the expected buffer.
+ //
+ // This code interacts with any data cache in unpleasant ways. A buffer
+ // descriptor is only 8 bytes, i.e. half a cache line, and since
+ // typically the system is configured with several rx buffers some of
+ // these may get updated by the hardware at any time. The only safe
+ // way to handle this is to disable the data cache when accessing the
+ // rx buffer descriptors and thus make sure that there are never any
+ // modified cachelines for the tx buffer descriptors.
+ do {
+ int current;
+ int i;
+
+ current = eth->rx_next_buffer;
+ frame_found = 0;
+
+ for (i = 0; i < CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS; i++) {
+ // Note: these absolutely must be held in registers. The package's
+ // CDL imposes constraints to ensure the driver is built with
+ // sufficient optimization.
+ register cyg_uint16 flags;
+ register cyg_uint16 len;
+ register hal_mcfxxxx_eth_buffer_descriptor* rxbd = &(eth->rxbds[current]);
+#if defined(HAL_DCACHE_SIZE) && (HAL_DCACHE_SIZE > 0)
+ register int cache_enabled;
+ HAL_DCACHE_IS_ENABLED(cache_enabled);
+ if (cache_enabled) {
+ register int ints_enabled;
+ HAL_DISABLE_INTERRUPTS(ints_enabled);
+ HAL_DCACHE_DISABLE();
+ flags = rxbd->ethbd_flags;
+ len = rxbd->ethbd_length;
+ if (! (flags & HAL_MCFxxxx_ETHx_RXBD_E)) {
+ rxbd->ethbd_flags = (flags & HAL_MCFxxxx_ETHx_RXBD_W) | HAL_MCFxxxx_ETHx_RXBD_E;
+ rxbd->ethbd_length = 1518;
+ }
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(ints_enabled);
+ } else
+#endif
+ {
+ flags = rxbd->ethbd_flags;
+ len = rxbd->ethbd_length;
+ if (! (flags & HAL_MCFxxxx_ETHx_RXBD_E)) {
+ rxbd->ethbd_flags = (flags & HAL_MCFxxxx_ETHx_RXBD_W) | HAL_MCFxxxx_ETHx_RXBD_E;
+ rxbd->ethbd_length = 1518;
+ }
+ }
+
+ if (flags & HAL_MCFxxxx_ETHx_RXBD_E) {
+ current = (current == (CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS - 1)) ? 0 : (current + 1);
+ continue;
+ }
+
+ // Full frames should fill one buffer. However if an over-sized frame
+ // is received then the first 1520 bytes will go into one buffer, the
+ // remaining into the next. The LG flag will get set only in the last
+ // buffer descriptor. Just mark the first buffer as empty after the
+ // if.
+ if (flags & HAL_MCFxxxx_ETHx_RXBD_L) {
+ // We have the last frame in a packet.
+#ifdef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
+ INCR_STAT(eth->rx_count);
+ if (flags & HAL_MCFxxxx_ETHx_RXBD_OV) {
+ // An overrun does not invalidate the current frame
+ INCR_STAT(eth->rx_overrun_errors);
+ }
+#endif
+
+ if (flags & (HAL_MCFxxxx_ETHx_RXBD_LG | HAL_MCFxxxx_ETHx_RXBD_NO | HAL_MCFxxxx_ETHx_RXBD_CR | HAL_MCFxxxx_ETHx_RXBD_TR)) {
+ // The packet is invalid and should be discarded.
+#ifdef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
+ if (flags & (HAL_MCFxxxx_ETHx_RXBD_LG | HAL_MCFxxxx_ETHx_RXBD_TR)) {
+ INCR_STAT(eth->rx_too_long_frames);
+ }
+ if (flags & HAL_MCFxxxx_ETHx_RXBD_NO) {
+ INCR_STAT(eth->rx_align_errors);
+ }
+ if (flags & HAL_MCFxxxx_ETHx_RXBD_CR) {
+ INCR_STAT(eth->rx_crc_errors);
+ }
+#endif
+ } else {
+ // A valid packet
+ INCR_STAT(eth->rx_good);
+ eth->rx_len = len;
+ eth->rx_next_buffer = current;
+ (*sc->funs->eth_drv->recv)(sc, len - 4);
+ }
+ }
+
+ // Move on to the next buffer descriptor.
+ frame_found = 1;
+ bd_emptied = 1;
+ eth->rx_next_buffer = (current == (CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS - 1)) ? 0 : (current + 1);
+ break;
+ }
+ } while(frame_found);
+
+ // If at least one buffer was marked as now empty, inform the hardware.
+ if (bd_emptied) {
+ WRITE32(RDAR(eth), HAL_MCFxxxx_ETHx_RDAR_R_DES_ACTIVE);
+ }
+ }
+
+ // And make sure rx interrupts are unmasked again.
+ WRITE32(EIMR(eth), HAL_MCFxxxx_ETHx_EIMR_TXF | HAL_MCFxxxx_ETHx_EIMR_RXF);
+}
+
+// ----------------------------------------------------------------------------
+
+// Polling does not need any special action, just check for pending interrupts
+// and act as if an interrupt had occurred.
+static void
+mcfxxxx_eth_poll(struct eth_drv_sc* sc)
+{
+ struct mcfxxxx_eth* eth = (struct mcfxxxx_eth*) sc->driver_private;
+ cyg_uint32 eir;
+
+ DIAG(4, "entry");
+
+ READ32(EIR(eth), eir);
+
+ if (eir & HAL_MCFxxxx_ETHx_EIR_TXF) {
+ WRITE32(EIR(eth), HAL_MCFxxxx_ETHx_EIR_TXF | HAL_MCFxxxx_ETHx_EIR_TXB);
+ eth->tx_done = 1;
+ eth->tx_index = eth->tx_index + 1;
+ if (TX_BUFFER_DESCRIPTOR_COUNT == eth->tx_index) {
+ eth->tx_index = 0;
+ }
+ }
+ if (eir & HAL_MCFxxxx_ETHx_EIR_RXF) {
+ eth->rx_rdy = 1;
+ }
+ if (eth->tx_done || eth->rx_rdy) {
+ mcfxxxx_eth_deliver(sc);
+ }
+}
+
+// intvector() is used by RedBoot/stubs to ensure ctrl-C will get through
+// if ethernet is used for the debug channel.
+static int
+mcfxxxx_eth_int_vector(struct eth_drv_sc* sc)
+{
+ return CYGNUM_HAL_ISR_ERX;
+}
+
+// ----------------------------------------------------------------------------
+
+// SET_MAC_ADDRESS is straightforward, it just requires updating two registers.
+// SET_MC_ALL and SET_MC_LIST can be implemented by setting all bits in the
+// hash table. That should cause the hardware to match all multicast packets.
+
+static int
+mcfxxxx_eth_ioctl(struct eth_drv_sc* sc, unsigned long key, void* data, int data_length)
+{
+ mcfxxxx_eth* eth = (mcfxxxx_eth*) sc->driver_private;
+
+ DIAG(1, "entry");
+
+ switch(key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ {
+ cyg_uint32 reg;
+ memcpy(eth->mac, data, 6);
+ reg = (eth->mac[4] << 24) | (eth->mac[5] << 16);
+ WRITE32(PAUR(eth), reg);
+ reg = (eth->mac[0] << 24) | (eth->mac[1] << 16) | (eth->mac[2] << 8) | (eth->mac[3] << 0);
+ WRITE32(PALR(eth), reg);
+ return 0;
+ }
+
+ case ETH_DRV_SET_MC_ALL:
+ case ETH_DRV_SET_MC_LIST:
+ {
+ WRITE32(GAUR(eth), 0xFFFFFFFF);
+ WRITE32(GALR(eth), 0xFFFFFFFF);
+ return 0;
+ }
+#if defined(CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS) && defined(ETH_DRV_GET_IF_STATS_UD)
+ case ETH_DRV_GET_IF_STATS_UD:
+ case ETH_DRV_GET_IF_STATS:
+ {
+ struct ether_drv_stats* stats = (struct ether_drv_stats*) data;
+ cyg_uint32 tcr;
+
+ strcpy(stats->description, "Freescale MCFxxxx ethernet device");
+ stats->snmp_chipset[0] = '\0';
+ READ32(TCR(eth), tcr);
+ if (0 == (tcr & HAL_MCFxxxx_ETHx_TCR_FDEN)) {
+ stats->duplex = 2; // simplex
+ } else {
+ stats->duplex = 3; // full duplex
+ }
+ stats->operational = eth->started ? 3 : 2;
+ stats->speed = 10 * 1000000; // assume 10MHz. This would require querying the phy
+ stats->supports_dot3 = 1;
+ stats->tx_queue_len = 1; // fixed by the driver design
+ stats->tx_dropped = 0; // can_send() is robust
+
+ stats->interrupts = eth->interrupts;
+
+ stats->tx_count = eth->tx_count;
+ stats->tx_good = eth->tx_good;
+ stats->tx_max_collisions = eth->tx_max_collisions;
+ stats->tx_late_collisions = eth->tx_late_collisions;
+ stats->tx_underrun = eth->tx_underrun;
+ stats->tx_carrier_loss = eth->tx_carrier_loss;
+ stats->tx_deferred = eth->tx_deferred;
+ stats->tx_single_collisions = eth->tx_single_collisions;
+ stats->tx_mult_collisions = eth->tx_mult_collisions;
+ stats->tx_total_collisions = eth->tx_total_collisions;
+
+ stats->rx_count = eth->rx_count;
+ stats->rx_good = eth->rx_good;
+ stats->rx_crc_errors = eth->rx_crc_errors;
+ stats->rx_align_errors = eth->rx_align_errors;
+ stats->rx_overrun_errors = eth->rx_overrun_errors;
+ stats->rx_short_frames = eth->rx_short_frames;
+ stats->rx_too_long_frames = eth->rx_too_long_frames;
+
+ return 0;
+ }
+#endif
+
+ default:
+ return 1;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+// Starting involves setting up initial empty buffer descriptors, then
+// enabling the ethernet device. Optionally promiscuous mode needs to be
+// set as well.
+
+#if 0
+static int
+mcfxxxx_eth_read_phy(int addr, int reg)
+{
+ cyg_uint32 events;
+ int ints_state;
+ int i;
+ int result = -1;
+
+ HAL_DISABLE_INTERRUPTS(ints_state);
+ WRITE32(MMFR(eth),
+ HAL_MCFxxxx_ETHx_MMFR_ST_VALUE |
+ HAL_MCFxxxx_ETHx_MMFR_OP_READ |
+ (addr << HAL_MCFxxxx_ETHx_MMFR_PA_SHIFT) |
+ (reg << HAL_MCFxxxx_ETHx_MMFR_RA_SHIFT) |
+ HAL_MCFxxxx_ETHx_MMFR_TA_VALUE |
+ (0x00 << HAL_MCFxxxx_ETHx_MMFR_DATA_SHIFT));
+
+ // When the phy has responded the MII interrupt bit should be set.
+ for (i = 0; i < 10; i++) {
+ // 16 bits * both ways @ 2.5MHz, should just take a few microseconds.
+ // This happens in a loop, just in case.
+ HAL_DELAY_US(10);
+ READ32(EIR(eth), events);
+ if (events & HAL_MCFxxxx_ETHx_EIR_MII) {
+ WRITE32(EIR(eth), HAL_MCFxxxx_ETHx_EIR_MII);
+ READ32(MMFR(eth), result);
+ result &= 0x0000FFFF;
+ break;
+ }
+ }
+
+ HAL_RESTORE_INTERRUPTS(ints_state);
+ return result;
+}
+#endif
+
+static void
+mcfxxxx_eth_start(struct eth_drv_sc* sc, unsigned char* enaddr, int flags)
+{
+ mcfxxxx_eth* eth = (mcfxxxx_eth*) sc->driver_private;
+ cyg_uint32 rcr;
+ int i;
+
+ if (eth->started) {
+ return;
+ }
+
+ DIAG(1, "entry");
+
+ eth->tx_can_send = 1;
+ eth->tx_done = 0;
+ eth->rx_rdy = 0;
+
+ // Clear all tx buffer descriptors, setting the WRAP bit on the last one.
+ for (i = 0; i < TX_BUFFER_DESCRIPTOR_COUNT; i++) {
+ eth->txbds[i].ethbd_flags = 0;
+ }
+ eth->txbds[TX_BUFFER_DESCRIPTOR_COUNT - 1].ethbd_flags = HAL_MCFxxxx_ETHx_TXBD_W;
+ eth->tx_index = 0;
+
+ // Set all rx buffer descriptors to empty.
+ for (i = 0; i < CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS; i++) {
+ eth->rxbds[i].ethbd_flags = HAL_MCFxxxx_ETHx_RXBD_E;
+ eth->rxbds[i].ethbd_length = 1518;
+ }
+ eth->rxbds[CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS - 1].ethbd_flags = HAL_MCFxxxx_ETHx_RXBD_E | HAL_MCFxxxx_ETHx_RXBD_W;
+
+ // None of the rx buffers should be in the cache so no need to invalidate.
+ // The rxbds must be written to memory. The txbds will be taken care of
+ // by the transmit code when there are packets to transmit.
+#ifdef HAL_DCACHE_STORE
+ HAL_DCACHE_STORE(&(eth->rxbds[0]), CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS * sizeof(hal_mcfxxxx_eth_buffer_descriptor));
+#endif
+
+#if 0
+ // Interact with the phy to see if the RCR DRT and X_CTRNL FDEN
+ // bits should be set. Default to half-duplex.
+ // NOTE: this should be conditional on the presence of a phy, and the
+ // platform should be able to override the default phy settings. It
+ // is also necessary to search the phy address space.
+ {
+ int addr = -1;
+ int i;
+ int reg;
+
+ // Find the phy's address. If the phy is not present the id register
+ // will read as 0x00FFFF.
+ for (i = 0; i < 32; i++) {
+ reg = mcfxxxx_eth_read_phy(i, 2);
+ if ((-1 != reg) && (0x0000FFFF != reg)) {
+ addr = i;
+ break;
+ }
+ }
+
+ if (-1 != addr) {
+ // Read the status register, especially the link bit
+ reg = mcfxxxx_eth_read_phy(addr, 1);
+ if (reg & 0x04) {
+ // The link is up. What was negotiated with the partner?
+ reg = mcfxxxx_eth_read_phy(addr, 5);
+ if (reg & 0x0140) {
+ // Full duplex, either 100 or 10. Clear the RCR DRT bit, set
+ // the TCR FDEN bit
+ cyg_uint32 rcr;
+ READ32(RCR(eth), rcr);
+ WRITE32(RCR(eth), rcr & ~ HAL_MCFxxxx_ETHx_RCR_DRT);
+ WRITE32(TCR(eth), HAL_MCFxxxx_ETHx_TCR_FDEN);
+ }
+ }
+ }
+ }
+#endif
+
+ // The RCR register can have additional bits set on some processors,
+ // e.g. on the mcf5282 it contains the maximum frame length. Change it only
+ // by read/modify/write.
+ READ32(RCR(eth), rcr);
+#ifdef CYGPKG_NET
+ if (flags & IFF_PROMISC) {
+ rcr |= HAL_MCFxxxx_ETHx_RCR_PROM;
+ } else {
+ rcr &= ~HAL_MCFxxxx_ETHx_RCR_PROM;
+ }
+#else
+ rcr &= ~HAL_MCFxxxx_ETHx_RCR_PROM;
+#endif
+ WRITE32(RCR(eth), rcr);
+
+ // The hardware is now ready
+ // The documentation says that setting R_DES_ACTIVE could also be done before asserting
+ // ETHER_EN, but that appears incorrect: you'll never get any packets.
+ WRITE32(ECR(eth), HAL_MCFxxxx_ETHx_ECR_ETHER_EN);
+ WRITE32(RDAR(eth), HAL_MCFxxxx_ETHx_RDAR_R_DES_ACTIVE);
+ WRITE32(TDAR(eth), HAL_MCFxxxx_ETHx_TDAR_X_DES_ACTIVE);
+
+ eth->started = 1;
+
+ DIAG(1, "done");
+}
+
+// Stopping can be done simply by disabling the device, which causes
+// all transmits and receives to be aborted. There should be no further
+// interrupts.
+static void
+mcfxxxx_eth_stop(struct eth_drv_sc* sc)
+{
+ mcfxxxx_eth* eth = (mcfxxxx_eth*) sc->driver_private;
+
+ DIAG(1, "entry");
+
+ eth->started = 0;
+ WRITE32(ECR(eth), 0);
+ eth->tx_done = 0;
+ eth->rx_rdy = 0;
+ if (! eth->tx_can_send) {
+ (*sc->funs->eth_drv->tx_done)(sc, eth->tx_key, 1);
+ eth->tx_can_send = 1;
+ }
+
+ DIAG(1, "done");
+}
diff --git a/ecos/packages/devs/eth/mcf52xx/mcf5272/current/ChangeLog b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/ChangeLog
new file mode 100644
index 0000000..5f55155
--- /dev/null
+++ b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/ChangeLog
@@ -0,0 +1,28 @@
+2003-03-19 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/mcf5272_eth_driver.cdl: Fix mismatch between ecos.db and
+ package CDL.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/mcf52xx/mcf5272/current/cdl/mcf5272_eth_driver.cdl b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/cdl/mcf5272_eth_driver.cdl
new file mode 100644
index 0000000..f7801c0
--- /dev/null
+++ b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/cdl/mcf5272_eth_driver.cdl
@@ -0,0 +1,88 @@
+# ====================================================================
+#
+# mfc_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for MCF5272
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_MCF5272 {
+ display "MCF5272 ethernet driver"
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGHWR_NET_DRIVERS
+ include_dir cyg/devs/eth
+ description "MCF5272 Ethernet driver"
+ compile -library=libextras.a if_mcf5272.c nbuf.c
+
+ cdl_component CYGPKG_NET_MCF5272_ETH_DRIVERS_OPTIONS {
+ display "MCF5272 ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_NET_MCF5272_ETH_DRIVERS_RX_NUM_BDS {
+ display "The number of receive buffer descriptors"
+ flavor data
+ legal_values 2 to 2048
+ default_value 256
+ description "
+ This option specifies the number of buffer descriptors that
+ the driver should allocated for the receive side."
+ }
+
+ cdl_option CYGPKG_NET_MCF5272_ETH_DRIVERS_TX_NUM_BDS {
+ display "The number of transmit buffer descriptors"
+ flavor data
+ legal_values 2 to 2048
+ default_value 128
+ description "
+ This option specifies the number of buffer descriptors that
+ the driver should allocated for the transmit side."
+ }
+
+
+ cdl_option CYGPKG_NET_MCF5272_ETH_DRIVERS_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the MCF5272 ethernet driver package. These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/if_mcf5272.h b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/if_mcf5272.h
new file mode 100644
index 0000000..def2ad0
--- /dev/null
+++ b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/if_mcf5272.h
@@ -0,0 +1,329 @@
+#ifndef _IF_MCF5272_FEC
+#define _IF_MCF5272_FEC
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/eth_drv_stats.h>
+#include <cyg/devs/eth/nbuf.h>
+
+ /* Ethernet controller inetrrupt priority level. */
+#define MCF5272_INT_LEVEL 4
+
+/* Bit level definitions and macros */
+#define MCF5272_FEC_ECR_RESET (0x00000001)
+#define MCF5272_FEC_ECR_ETHER_EN (0x00000002)
+#define MCF5272_FEC_EIR_GRA (0x10000000)
+
+#define MCF5272_FEC_EIR_HBE (0x80000000)
+#define MCF5272_FEC_EIR_BR (0x40000000)
+#define MCF5272_FEC_EIR_BT (0x20000000)
+#define MCF5272_FEC_EIR_GRA (0x10000000)
+#define MCF5272_FEC_EIR_TXF (0x08000000)
+#define MCF5272_FEC_EIR_TXB (0x04000000)
+#define MCF5272_FEC_EIR_RXF (0x02000000)
+#define MCF5272_FEC_EIR_RXB (0x01000000)
+#define MCF5272_FEC_EIR_MII (0x00800000)
+#define MCF5272_FEC_EIR_EBERR (0x00400000)
+#define MCF5272_FEC_EIR_UMINT (1<<21)
+
+#define MCF5272_FEC_IMR_HBEEN (0x80000000)
+#define MCF5272_FEC_IMR_BREN (0x40000000)
+#define MCF5272_FEC_IMR_BTEN (0x20000000)
+#define MCF5272_FEC_IMR_GRAEN (0x10000000)
+#define MCF5272_FEC_IMR_TXFEN (0x08000000)
+#define MCF5272_FEC_IMR_TXBEN (0x04000000)
+#define MCF5272_FEC_IMR_RXFEN (0x02000000)
+#define MCF5272_FEC_IMR_RXBEN (0x01000000)
+#define MCF5272_FEC_IMR_MIIEN (0x00800000)
+#define MCF5272_FEC_IMR_EBERREN (0x00400000)
+#define MCF5272_FEC_RCR_PROM (0x00000008)
+#define MCF5272_FEC_RCR_MII_MODE (0x00000004)
+#define MCF5272_FEC_RCR_DRT (0x00000002)
+#define MCF5272_FEC_RCR_LOOP (0x00000001)
+#define MCF5272_FEC_TCR_GTS (0x00000001)
+#define MCF5272_FEC_TCR_HBC (0x00000002)
+#define MCF5272_FEC_TCR_FDEN (0x00000004)
+#define MCF5272_FEC_RDAR_DESTACT (0x01000000)
+#define MCF5272_FEC_MFLR_BRDCAST (0x80000000)
+#define MCF5272_FEC_MFLR_MLTCAST (0x40000000)
+#define MCF5272_FEC_XWMRK_64 (0x00000000)
+#define MCF5272_FEC_XWMRK_128 (0x00000002)
+#define MCF5272_FEC_XWMRK_192 (0x00000003)
+
+/* Define the PHY addresss. This address specifies which 32 attached */
+/* PHY devices. */
+
+//#define MCF5272_PHY_ADD (0)
+#define MCF5272_PHY_ADD (0 << 23)
+
+
+/* Start of frame delimter for valid MII management frame. */
+
+#define MCF5272_FEC_MII_ST (0x40000000)
+
+/* Operation code. This field bust be programmed to generate a valid */
+/* MII management frame. */
+
+#define MCF5272_FEC_MII_OP_READ (0x20000000)
+#define MCF5272_FEC_MII_OP_WRITE (0x10000000)
+
+/* Register address. Specifies one of the 32 attached PHY devices. */
+
+#define MCF5272_FEC_MII_RA_POS (18)
+#define MCF5272_FEC_MII_RA_MASK (0x1F)
+
+/* Turn around. Must be programmed to 10 to generate a valid MII */
+/* management frame. */
+
+#define MCF5272_FEC_MII_TA (0x00020000)
+
+
+/* The management frame data maske. Field for data to be written to */
+/* or read from PHY register. */
+
+#define MCF5272_FEC_MII_DATA_MASK (0x0000FFFF)
+
+
+/* This define the MII unchanged MII frame management bits. */
+
+#define MCF5272_FEC_MII_FIX_HDR (0 | \
+ MCF5272_FEC_MII_ST | \
+ MCF5272_PHY_ADD | \
+ MCF5272_FEC_MII_TA)
+
+
+/* The PHY address mask. */
+
+#define MCF5272_FEC_MII_PA (0x1F << 23)
+
+/* Define the interrupt mask. */
+
+#define MCF5272_FEC_INTERRUPT_MASK (MCF5272_FEC_IMR_TXFEN | \
+ MCF5272_FEC_IMR_RXFEN )
+
+
+/**************************************************
+ * FEC diagnostic counters
+ **************************************************/
+typedef struct MCF5272_FEC_DIAG
+{
+
+ /* We put all the receive statistics first. */
+
+ unsigned long rx_pk_cnt; /* The total number of */
+ /* received packets */
+
+ unsigned long rx_pk_cnt_sec;
+
+ unsigned long rx_bytes_cnt; /* The total number of */
+ /* received bytes */
+
+ unsigned long rx_bytes_cnt_sec;
+
+ unsigned long rx_err_cnt; /* The total number of bad */
+ /* packets received */
+
+ unsigned long rx_long_frm_err_cnt; /* The total number of long */
+ /* frame errors. */
+
+ unsigned long rx_short_frm_err_cnt; /* The total number of short */
+ /* frame errors. */
+
+ unsigned long rx_crc_err_cnt; /* The total number of CRC */
+ /* errors. */
+
+ unsigned long rx_overrun_err_cnt; /* The total number of */
+ /* overrun errors. */
+
+ unsigned long rx_trunc_error_cnt; /* The total numbers of */
+ /* receieve truncated packet */
+ /* errors. */
+
+ /* We put all the transmit statistics next. start_of_transmit */
+ /* doesn't take any space but only separates the receive statistics */
+ /* from the transmit statistics. */
+
+ char start_of_transmit[0];
+
+ unsigned long tx_pk_cnt; /* The total number of */
+ /* transmitted packet */
+
+ unsigned long tx_pk_cnt_sec;
+
+ unsigned long tx_bytes_cnt; /* The total number of */
+ /* transmitted bytes */
+
+ unsigned long tx_bytes_cnt_sec;
+
+ unsigned long tx_err_cnt; /* The total number of failed */
+ /* packet transmission */
+
+ unsigned long tx_def_cnt; /* The total number of tansmit */
+ /* defers. */
+
+ unsigned long tx_hb_err_cnt; /* The total number of heart */
+ /* beat errors. */
+
+ unsigned long tx_late_col_cnt; /* The total number of late */
+ /* collisions. */
+
+ unsigned long tx_exes_retry_cnt; /* Excessive rettry count. */
+
+ unsigned long tx_retry_cnt; /* The total number of transmit */
+ /* retries. */
+
+ unsigned long tx_underrun_cnt; /* The total number of transmit */
+ /* underruns. */
+
+ unsigned long tx_carrrier_loss_cnt; /* The total number of */
+ /* trasnmit carrier losses. */
+
+ unsigned long tx_free_bd_cnt; /* The total number of freed */
+ /* buffer descriptor. */
+
+ unsigned long tx_free_min_bd_cnt; /* The minimum number of free */
+ /* buffer descriptor count. */
+
+ unsigned long tx_full_cnt; /* The number of times when */
+ /* there is no transmit buffer. */
+
+ unsigned long tx_not_complete_cnt; /* The number of times the */
+ /* device driver discovered */
+ /* that the BD is still in use */
+ /* by the FEC. */
+
+ unsigned long internal_bus_error_cnt; /* FEC bus error count. A */
+ /* bus error occurred when */
+ /* the FEC was accessing an */
+ /* internal bus. */
+
+}MCF5272_FEC_DIAG __attribute__ ((aligned, packed));
+
+/* Ethernet driver status. */
+enum eth_drv_status_t
+{
+ ETH_DEV_UNKNOWN = 1,
+ ETH_DEV_DOWN = 2,
+ ETH_DEV_UP = 3
+};
+
+/* Ethernet duplex mode. */
+enum eth_drv_mode_t
+{
+ ETH_MODE_UNKNOWN = 1,
+ ETH_MODE_SIMPLEX = 2,
+ ETH_MODE_DUPLEX = 3
+};
+
+
+/* Ethernet speed values. */
+enum eth_speed_t
+{
+ ETH_SPEED_10MB = 10*1000*1000,
+ ETH_SPEED_100MB = 100*1000*1000
+};
+
+/* Ethernet driver statistics information structure. */
+
+struct mcf5272_ether_drv_stats
+{
+ struct ifreq ifreq; // tell ioctl() which interface.
+
+ char description[ DESC_LEN ]; // Textual description of hardware
+ unsigned char snmp_chipset[ SNMP_CHIPSET_LEN ];
+ // SNMP ID of chipset
+ enum eth_drv_mode_t duplex; // 1 = UNKNOWN, 2 = SIMPLEX, 3 = DUPLEX
+ enum eth_drv_status_t operational; // 1 = UNKNOWN, 2 = DOWN, 3 = UP
+ // These are general status information:
+ unsigned int speed; // 10,000,000 or 100,000,000
+ // to infinity and beyond?
+
+ MCF5272_FEC_DIAG stats;
+
+}__attribute__ ((aligned, packed));
+
+#ifndef FIELD_OFFSET
+#define FIELD_OFFSET(type,field) (cyg_uint32)(&(((type*)0)->field)
+#endif /* FIELD_OFFSET */
+
+/* The value of 1 second in nanosecond. */
+#define SEC_IN_NS 1000000000
+
+/* 48-bit Ethernet Addresses */
+typedef u8_t ETH_ADDR[6];
+
+/* 16-bit Ethernet Frame Type, ie. Protocol */
+typedef u16_t ETH_FTYPE;
+
+/* Maximum and Minimum Ethernet Frame Size (Data Field) */
+#define ETH_DATA_MAX_SIZE (1500)
+#define ETH_DATA_MIN_SIZE (46)
+
+/* Maximum and Minimum Ethernet Frame Size (Entire frame) */
+#define ETH_MAX_SIZE (ETH_DATA_MAX_SIZE+14)
+#define ETH_MIN_SIZE (ETH_DATA_MIN_SIZE+14)
+
+/* Common Ethernet Frame definition */
+typedef struct
+{
+ ETH_ADDR dest;
+ ETH_ADDR src;
+ ETH_FTYPE type;
+ u8_t data[ETH_DATA_MAX_SIZE];
+ u32_t fcs;
+} eth_frame_hdr __attribute__ ((aligned, packed));
+
+/* 802.1Q Ethernet Frame definition */
+typedef struct
+{
+ ETH_ADDR dest;
+ ETH_ADDR src;
+ u32_t header_802_1q;
+ ETH_FTYPE type;
+ u8_t data[ETH_DATA_MAX_SIZE];
+ u32_t fcs;
+} eth_802_1Q_frame_hdr __attribute__ ((aligned, packed));
+
+/* Definition of macros that access the FEC registers */
+#define put_reg(_addr_,_value_) \
+ *((volatile u32_t*)&(_addr_)) = (cyg_uint32)(_value_)
+
+#define get_reg(_addr_) \
+ *(((volatile u32_t*)&(_addr_)))
+
+
+#endif /* _IF_MCF5272_FEC */
+
+
diff --git a/ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/if_mcf5272_private_data.h b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/if_mcf5272_private_data.h
new file mode 100644
index 0000000..f3f1e7c
--- /dev/null
+++ b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/if_mcf5272_private_data.h
@@ -0,0 +1,95 @@
+#ifndef _IF_MCF5272_PRIVATE_DATA_H_
+#define _IF_MCF5272_PRIVATE_DATA_H_
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/devs/eth/if_mcf5272.h>
+#include <cyg/devs/eth/nbuf.h>
+
+/* Device driver private data. */
+
+struct MCF5272_fec_priv_data_t
+{
+
+ buf_info_t nbuffer;
+
+ /* Diagnositc supplement variables. */
+
+ struct
+ {
+ unsigned int old_tx_pk_cnt;
+ unsigned int old_rx_pk_cnt;
+ unsigned int old_tx_bytes_cnt;
+ unsigned int old_rx_bytes_cnt;
+ }diag_info_sup;
+
+ /* 1 second alarm variables */
+
+ cyg_handle_t alarm_h;
+ cyg_alarm alarm;
+ cyg_handle_t counter_h;
+
+ /* Diagnostic counters */
+
+ MCF5272_FEC_DIAG diag_counters;
+
+ /* This flag is set if the device is operational */
+
+ enum eth_drv_status_t operational;
+
+ /* Unknown, Half Duplex or Full duplex. */
+
+ enum eth_drv_mode_t duplex;
+
+ /* Ethernet bandwidth. */
+
+ u32_t speed;
+
+ /* Temporary packet buffer. */
+
+ eth_frame_hdr pkt_buf;
+
+};
+typedef struct MCF5272_fec_priv_data_t MCF5272_fec_priv_data_t;
+
+#define PMCF5272_FEC_DATA(_SC_) \
+ ((MCF5272_fec_priv_data_t*)(((struct eth_drv_sc*)(_SC_))->driver_private))
+#define PBUF_INFO(_SC_) \
+ (&(((MCF5272_fec_priv_data_t*)((_SC_)->driver_private))->nbuffer))
+
+#endif /* _IF_MCF5272_PRIVATE_DATA_H_ */
+
diff --git a/ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/nbuf.h b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/nbuf.h
new file mode 100644
index 0000000..a5e521a
--- /dev/null
+++ b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/include/nbuf.h
@@ -0,0 +1,647 @@
+#ifndef _NBUF_H
+#define _NBUF_H
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+/*
+ * File: nbuf.h
+ * Purpose: Definitions for Network Buffer Allocation.
+ *
+ * Notes: These routines implement a static buffer scheme.
+ * The buffer descriptors are as specified by the
+ * MPC860T/MCF5272 FEC.
+ *
+ * Modifications:
+ *
+ */
+
+#include <cyg/hal/drv_api.h>
+#include <pkgconf/net_mcf5272_eth_drivers.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/io/eth/eth_drv.h>
+
+
+
+/********************************************************************/
+
+
+typedef unsigned char uint8; /* 8 bits */
+typedef unsigned short int uint16; /* 16 bits */
+typedef unsigned long int uint32; /* 32 bits */
+
+typedef signed char int8; /* 8 bits */
+typedef signed short int int16; /* 16 bits */
+typedef signed long int int32; /* 32 bits */
+
+
+#define Rx 1
+#define Tx 0
+
+/*
+ * Buffer sizes in bytes -- The following values were chosen based
+ * on TFTP maximum packet sizes. These sizes may need to be
+ * increased to implement other protocols.
+ */
+#define RX_BUFFER_SIZE (576) /* must be divisible by 16 */
+/* #define TX_BUFFER_SIZE 576 */
+
+
+/* The this label is not defined, we define it and default it to 256. */
+#ifndef CYGPKG_NET_MCF5272_ETH_DRIVERS_RX_NUM_BDS
+#define CYGPKG_NET_MCF5272_ETH_DRIVERS_RX_NUM_BDS 256
+#endif
+
+/* The this label is not defined, we define it and default it to 256. */
+#ifndef CYGPKG_NET_MCF5272_ETH_DRIVERS_TX_NUM_BDS
+#define CYGPKG_NET_MCF5272_ETH_DRIVERS_TX_NUM_BDS 256
+#endif
+
+
+/* Number of Receive and Transmit Buffers and Buffer Descriptors */
+#define NUM_RXBDS (CYGPKG_NET_MCF5272_ETH_DRIVERS_RX_NUM_BDS)
+#define NUM_TXBDS (CYGPKG_NET_MCF5272_ETH_DRIVERS_TX_NUM_BDS)
+
+
+
+/*
+ * Buffer Descriptor Format -- must be aligned on 4-byte boundary
+ * but a 16-byte boundary is recommended. However, we cannot pack
+ * them on 16-byte boundaries as this will add 8-bytes of padding
+ * between structures and the FEC of the MPC860T/MCF5272 will choke.
+ */
+typedef struct NBUF
+{
+ uint16 status; /* control and status */
+ uint16 length; /* transfer length */
+ uint8 *data; /* buffer address */
+} __attribute__ ((packed, aligned))NBUF;
+
+
+/* Defines the tx key type. */
+typedef enum tx_key_type_t
+{
+ TX_KEY_ECOS, /* eCos key */
+ TX_KEY_USER /* user key */
+}tx_key_type_t;
+
+typedef struct tx_keys_t
+{
+ unsigned long tx_key; /* The transmit key that eCos gives us. */
+ uint_t tx_buf_index; /* Index to the TxNBUF where the last Buffer Descriptor of the frame. */
+ int num_dbufs; /* The number transmit buffer allocated for the frame. */
+ uint_t start_index; /* Index of the bd */
+ int_t pk_len;
+ tx_key_type_t key_type; /* The type of the key. */
+
+}tx_keys_t;
+
+typedef struct buf_info_t
+{
+
+ /* Buffer descriptor indexes */
+
+ uint_t iTxbd;
+ uint_t iRxbd;
+
+ /* Queue for the transmit keys */
+
+ #define TX_KEY_QUEUE_SIZE (NUM_TXBDS+1)
+ tx_keys_t tx_keys_queue[TX_KEY_QUEUE_SIZE];
+
+ /* Rear and front pointer for the keys queue. */
+
+ uint_t tq_rear;
+ uint_t tq_front;
+
+ /* Number transmit descriptor buffers busy. */
+
+ volatile int num_busy_bd;
+
+ /* The maximum number of buffer decriptor used. */
+
+ volatile int max_num_busy_bd;
+
+ /* Buffer Descriptors */
+ NBUF ntxbuf[NUM_TXBDS+2];
+ NBUF nrxbuf[NUM_RXBDS+2];
+
+ NBUF* RxNBUF;
+ NBUF* TxNBUF;
+
+ /* Buffers */
+ //TXB TxBuffer[NUM_TXBDS];
+ u8_t RxBuffer[(NUM_RXBDS+2)*RX_BUFFER_SIZE];
+
+
+}buf_info_t;
+
+
+/********************************************************************/
+
+/*
+ * Bit level Buffer Descriptor definitions
+ */
+
+#define TX_BD_R 0x8000
+#define TX_BD_TO1 0x4000
+#define TX_BD_INUSE TX_BD_TO1
+#define TX_BD_W 0x2000
+#define TX_BD_TO2 0x1000
+#define TX_BD_L 0x0800
+#define TX_BD_TC 0x0400
+#define TX_BD_DEF 0x0200
+#define TX_BD_HB 0x0100
+#define TX_BD_LC 0x0080
+#define TX_BD_RL 0x0040
+#define TX_BD_UN 0x0002
+#define TX_BD_CSL 0x0001
+
+#define RX_BD_E 0x8000
+#define RX_BD_R01 0x4000
+#define RX_BD_W 0x2000
+#define RX_BD_R02 0x1000
+#define RX_BD_L 0x0800
+#define RX_BD_M 0x0100
+#define RX_BD_BC 0x0080
+#define RX_BD_MC 0x0040
+#define RX_BD_LG 0x0020
+#define RX_BD_NO 0x0010
+#define RX_BD_SH 0x0008
+#define RX_BD_CR 0x0004
+#define RX_BD_OV 0x0002
+#define RX_BD_TR 0x0001
+
+/*******************************************************************/
+
+/*
+ * Functions to manipulate the network buffers.
+ */
+
+void nbuf_init (buf_info_t* pBuf);
+
+
+/********************************************************************/
+inline static
+uint32
+nbuf_get_start(buf_info_t* pBuf, uint8 direction)
+{
+ /*
+ * Return the address of the first buffer descriptor in the ring.
+ * This routine is needed by the FEC of the MPC860T and MCF5272
+ * in order to write the Rx/Tx descriptor ring start registers
+ */
+ switch (direction){
+ case Rx:
+ return (uint32)pBuf->RxNBUF;
+ default:
+ case Tx:
+ return (uint32)pBuf->TxNBUF;
+ }
+}
+
+
+
+
+
+
+/******************************************************************************
+ nbuf_rx_get_next() - Retrieve the next receive buffer descriptor.
+
+ INPUT:
+ pBuf - Pointer to the buffer info.
+
+RETURN:
+ Returns the pointer to the next receive buffer descriptor.
+*/
+
+inline static
+NBUF *
+nbuf_rx_get_next(buf_info_t* pBuf)
+{
+ NBUF* pBd = &pBuf->RxNBUF[pBuf->iRxbd];
+
+ /* Check to see if the ring of BDs is full */
+ if (pBd->status & RX_BD_E)
+ {
+ return NULL;
+ }
+
+ /* increment the circular index */
+ pBuf->iRxbd = (pBuf->iRxbd + 1) % NUM_RXBDS;
+
+ return pBd;
+}
+
+
+/* Return the pointer to the buffer descriptor based on the index */
+inline static
+NBUF*
+nbuf_rx_get(buf_info_t* pBuf, uint_t index)
+{
+ return(&pBuf->RxNBUF[index]);
+}
+
+/********************************************************************
+ Release the buffer descrip so that it can be use
+ to receive the enxt packet.
+
+ INPUT:
+ pNbuf - pointer to the buffer descriptor.
+*/
+
+inline static
+void
+nbuf_rx_release (NBUF* pNbuf)
+{
+
+ /* Mark the buffer as empty and not in use */
+ pNbuf->status |= RX_BD_E;
+
+}
+
+
+/* Return the current rx buffer descriptor index */
+inline static uint_t
+nbuf_rx_get_index(buf_info_t* pBuf)
+{
+ return pBuf->iRxbd;
+}
+
+/****************************************************************
+ This function checks the EMPTY bit of the next Rx buffer to be
+ allocated. If the EMPTY bit is cleared, then the next buffer in
+ the ring has been filled by the FEC and has not already been
+ allocated and passed up the stack. In this case, the next buffer
+ in the ring is ready to be allocated. Otherwise, the buffer is
+ either empty or not empty but still in use by a higher level
+ protocol. The FEC receive routine uses this function to determine
+ if multiple buffers where filled by the FEC during a single
+ interrupt event.
+ ****************************************************************/
+inline static
+uint_t
+nbuf_rx_next_ready(buf_info_t* pBuf)
+{
+
+ return ( !(pBuf->RxNBUF[pBuf->iRxbd].status & RX_BD_E));
+}
+
+
+
+
+/******************************************************************************
+ nbuf_rx_release_pkt() - Release the buffer descriptors of the next packet.
+
+ INPUT:
+ pointer to the buffer info.
+*/
+inline static
+void nbuf_rx_release_pkt(buf_info_t* pBuf)
+{
+
+ NBUF* pNbuf;
+
+ /* Indicates whether the last buffer descriptor is encountered. */
+ cyg_bool_t last = false;
+
+ do
+ {
+ /* Get the buffer descriptor. */
+ pNbuf = nbuf_rx_get_next(pBuf);
+
+ /* Stop when there is a packet truncated bit is set or it is the */
+ /* last buffer descriptor of the packet. */
+
+ if ((!(pNbuf->status & RX_BD_E) && pNbuf->status & RX_BD_TR) ||
+ pNbuf->status & RX_BD_L)
+ {
+ last = true;
+ }
+
+ /* Release the buffer descriptor. */
+ nbuf_rx_release(pNbuf);
+
+ }while(last == false);
+
+}
+
+
+
+/******************************************************************************
+ nbuf_rx_release_good_pkt() - Release the buffer descriptors for
+ good received packets.
+ Note call this function
+ only when there is valid received
+ buffer descriptors.
+
+ INPUT:
+ pBuf - pointer to the buffer info.
+*/
+inline static
+void nbuf_rx_release_good_pkt(buf_info_t* pBuf)
+{
+
+ u16_t status;
+
+ do
+ {
+
+ /* Read the status bits. If the RX_BD_L is set we terminate the */
+ /* loop. */
+
+ status = pBuf->RxNBUF[pBuf->iRxbd].status;
+
+ /* Release the buffer descriptor so that it could reused. */
+
+ nbuf_rx_release(&pBuf->RxNBUF[pBuf->iRxbd]);
+
+ /* Advance the index to the next buffer descriptor. */
+
+ pBuf->iRxbd = (pBuf->iRxbd + 1) % NUM_RXBDS;
+
+
+ }while(!(status & RX_BD_L));
+
+}
+
+
+/******************************************************************************
+ nbuf_tx_release() - Set the buffer descriptor ready for use to transmit
+ the next packet.
+
+ INPUT:
+ pNbuf - Pointer to the transmit buffer descriptor.
+*/
+inline static
+void
+nbuf_tx_release (NBUF* pNbuf)
+{
+
+ /* Clear the TX_BD_INUSE to indicate that we have read the */
+ /* transmitted buffer. */
+
+ pNbuf->status &= ~(TX_BD_INUSE | TX_BD_R | TX_BD_L | TX_BD_TC);
+
+}
+
+/* Return a nozero value if the buffer is full. Otherwise, it returns a
+ zero value.
+*/
+inline static
+int_t nbuf_tx_full(buf_info_t* pBuf)
+{
+ return (pBuf->TxNBUF[pBuf->iTxbd].status & TX_BD_R);
+}
+
+
+/* Return the pointer to the transmit buffer descriptor. */
+inline static
+NBUF*
+nbuf_tx_get(buf_info_t* pBuf, int_t index)
+{
+ return(&pBuf->TxNBUF[index]);
+}
+
+/******************************************************************************
+ nbuf_peek_tx_key() - Peek whether there is any
+ pending packets that are still in transmisison.
+
+ INPUT:
+ pBuf - Pointer to the buffer structure.
+
+ OUTPUT:
+ index - The index to the oldest pending packet in the queue.
+
+ RETURN:
+ Returns the index to the oldest pending packet in the queue. Otherwise,
+ it returns -1.
+
+*/
+inline static
+int_t nbuf_peek_tx_key(buf_info_t* pBuf)
+{
+ if (pBuf->tq_rear == pBuf->tq_front)
+ {
+ return -1; /* No pending transmit buffers. */
+ }
+ return pBuf->tx_keys_queue[pBuf->tq_front].tx_buf_index;
+}
+
+/******************************************************************************
+ nbuf_peek_bd_ahead() - Returns the pointer of the to the last buffer
+ descriptor of the 2nd. pending transmit frame.
+
+ INPUT:
+ pBuf - Pointer to the buffer structure.
+
+
+ RETURN:
+ Returns the pointer of the to the last buffer
+ descriptor of the 2nd. pending transmit frame. If there is not 2nd.
+ pending frame, it returns NULL.
+
+
+*/
+inline static
+NBUF* nbuf_peek_bd_ahead(buf_info_t* pBuf)
+{
+ uint_t ahead_front = (pBuf->tq_front + 1) % TX_KEY_QUEUE_SIZE;
+
+ if (pBuf->tq_rear == pBuf->tq_front ||
+ ahead_front == pBuf->tq_rear)
+ {
+ return NULL; /* No pending transmit buffers. */
+ }
+
+ return &pBuf->TxNBUF[pBuf->tx_keys_queue[ahead_front].tx_buf_index];
+}
+
+
+
+/******************************************************************************
+ nbuf_enq_tx_key() - Enqueue and deuque transmit key queue.
+ Enqueue the transmit key. The buf_index is the index to the transmit buffer deiscriptor
+ table of the last buffer descriptor for the frame and the transmit packet
+ type.
+*/
+inline static
+void nbuf_enq_tx_key(buf_info_t* pBuf,
+ uint_t buf_index,
+ unsigned long txkey,
+ uint_t start_index,
+ int num_bd,
+ int_t total_len,
+ tx_key_type_t key_type)
+{
+ tx_keys_t* p_keys = &pBuf->tx_keys_queue[pBuf->tq_rear];
+ /* Assign the transmit packet information to the transmit key queue. */
+
+ /* NOTE: We don't check for the full condition because the transmit */
+ /* key queue size is as big as the number of buffer descriptors. */
+
+ p_keys->tx_key = txkey;
+ p_keys->tx_buf_index = buf_index;
+ p_keys->num_dbufs = num_bd;
+ p_keys->pk_len = total_len;
+ p_keys->start_index = start_index;
+ p_keys->key_type = key_type;
+
+ /* Advance the transmit queue pointer to the next entry. */
+
+ pBuf->tq_rear = (pBuf->tq_rear + 1) % TX_KEY_QUEUE_SIZE;
+
+ }
+
+
+/******************************************************************************
+ nbuf_deq_tx_key() - Dequeue the transmit packet from the transmit key queue.
+ Assume that the queue is not empty.
+
+
+ INPUT:
+ pBuf - Pointer to the buffer structure.
+
+ OUTPUT:
+ key - The key the transmit information.
+*/
+inline static
+void nbuf_deq_tx_key(buf_info_t* pBuf, tx_keys_t* key)
+{
+
+ CYG_ASSERT(pBuf->tq_rear != pBuf->tq_front, "nbuf_deq_tx_key: empty");
+ *key = pBuf->tx_keys_queue[pBuf->tq_front];
+ pBuf->tq_front = (pBuf->tq_front + 1) % TX_KEY_QUEUE_SIZE;
+
+}
+
+/*******************************************************************************
+ nbuf_tx_dump() - Dump the transmit buffer information.
+
+ INPUT:
+ pBuf - pointer to the buffer info.
+*/
+inline static
+void nbuf_tx_dump(buf_info_t* pBuf)
+{
+
+ tx_keys_t key;
+
+ diag_printf("Current index to ring buffer: %d\n", pBuf->iTxbd);
+ diag_printf("Address to the BD: %08X\n",
+ &pBuf->TxNBUF[pBuf->iTxbd]);
+
+ diag_printf("BD status: %04X\n", pBuf->TxNBUF[pBuf->iTxbd].status);
+ diag_printf("TX Queue rear index: %d\n", pBuf->tq_rear);
+ diag_printf("TX Queue front index: %d\n", pBuf->tq_front);
+ diag_printf("Number of busy BDs: %d\n", pBuf->num_busy_bd);
+
+ diag_printf("Dump Transmit Queue\n");
+ diag_printf("===================\n");
+
+ while(nbuf_peek_tx_key(pBuf) != -1)
+ {
+ nbuf_deq_tx_key(pBuf, &key);
+ diag_printf("Number of BDs: %d\n", key.num_dbufs);
+ diag_printf("Frame length: %d\n", key.pk_len);
+ diag_printf("Begin index to ring bufer: %d\n", key.start_index);
+ diag_printf("BD address: %08X\n", &pBuf->TxNBUF[key.tx_buf_index]);
+ diag_printf("status: %04X\n", pBuf->TxNBUF[key.tx_buf_index].status);
+
+ diag_printf("End index to ring buffer: %d\n", key.tx_buf_index);
+ diag_printf("Key Info: %08X\n", key.tx_key);
+ diag_printf("Key type: %d\n", key.key_type);
+ diag_printf("\n");
+
+ }
+ diag_printf("===================\n");
+
+
+}
+
+
+/********************************************************************
+ nbuf_tx_allocate() - Alocate transmit buffer descriptor.
+
+ INPUT:
+ pBuf - pointer to the buffer info.
+
+ OUTPUT:
+ index - index to the buffer descriptor ring buffer that it returns. This
+ value is invalid if this funtion returns a NULL.
+
+ RETURN:
+ Returns the pointer to the buffer descriptor. If the ring buffer
+ descriptor is full, it returns NULL.
+
+ */
+inline static
+NBUF *
+nbuf_tx_allocate (buf_info_t* pBuf)
+{
+ NBUF* pBd = &pBuf->TxNBUF[pBuf->iTxbd];
+
+ /* If the ring buffer is full, then return a NULL. */
+
+ if (pBd->status & TX_BD_INUSE)
+ {
+ nbuf_tx_dump(pBuf);
+ return NULL;
+ }
+
+ /* Make sure that the buffer descriptor is still not in use by the */
+ /* FEC . */
+
+ CYG_ASSERT(!(pBd->status & TX_BD_R),
+ "Buffer descriptor allocated still in use");
+
+ /* Set the buffer to be in used so that we can check the status */
+ /* before we resuse it to send another packet. */
+
+ pBd->status |= TX_BD_INUSE;
+
+
+ /* increment the circular index */
+ pBuf->iTxbd = ((pBuf->iTxbd + 1) % NUM_TXBDS);
+
+ return pBd;
+}
+
+
+
+
+/*****************************************************************************/
+
+#endif /* _NBUF_H */
diff --git a/ecos/packages/devs/eth/mcf52xx/mcf5272/current/src/if_mcf5272.c b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/src/if_mcf5272.c
new file mode 100644
index 0000000..024b4e5
--- /dev/null
+++ b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/src/if_mcf5272.c
@@ -0,0 +1,1885 @@
+//==========================================================================
+//
+// dev/if_MCF5272_fec.c
+//
+// Ethernet device driver for MCF5272's Fast Ethernet Controller (FEC)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+
+// Ethernet device driver for Fast Ethernet MCF5272_fec
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#include <cyg/devs/eth/nbuf.h>
+#include <cyg/devs/eth/if_mcf5272.h>
+#include <cyg/devs/eth/if_mcf5272_private_data.h>
+
+#include <cyg/infra/cyg_ass.h>
+#include <sys/param.h>
+#include <net/if.h>
+
+
+/* Function to retrieve the Ethernet address of the device from the device's
+ database. We declare it weak so that other routines can overide it.
+ */
+
+externC const void*
+db_get_eth_address(void) __attribute__ ((weak));
+
+
+/*****************************************************************************
+
+ The following functions provide an interface directly to the
+ethernet driver for applications that wish to circumvent the IP stack.
+
+ Applications that wish to take advantage of this should override
+these routine with their own. Leaving these routines as default routes
+all data through the IP stack.
+
+*****************************************************************************/
+externC int_t
+eth_rx_pkt_filter(u8_t* pkt, uint_t pkt_len) __attribute__ ((weak));
+externC void
+eth_tx_check(struct eth_drv_sg * sg_list, unsigned int sg_len)
+ __attribute__ ((weak));
+externC void
+eth_send_done(unsigned long tag) __attribute__ ((weak));
+externC int_t
+eth_send(struct eth_drv_sg * sg_list, unsigned int sg_len, int total_len,
+ unsigned long tag);
+
+static MCF5272_fec_priv_data_t MCF5272_fec_priv_data;
+
+/* Interrupt strcture and handles. */
+static cyg_interrupt MCF5272_fec_rx_interrupt;
+static cyg_interrupt MCF5272_fec_tx_interrupt;
+
+static cyg_handle_t MCF5272_fec_rx_interrupt_handle;
+static cyg_handle_t MCF5272_fec_tx_interrupt_handle;
+
+
+// Interrupt handler
+static void MCF5272_fec_int(struct eth_drv_sc *sc);
+static int MCF5272_fec_int_vector(struct eth_drv_sc *sc);
+
+// This DSR handles the ethernet [logical] processing
+static void MCF5272_fec_deliver(struct eth_drv_sc * sc);
+static void MCF5272_fec_stop(struct eth_drv_sc *sc);
+
+static void
+MCF5272_fec_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key);
+
+static void
+MCF5272_fec_common_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list, int sg_len,
+ int total_len,
+ unsigned long key,
+ tx_key_type_t key_type);
+
+static int
+MCF5272_fec_isr(cyg_vector_t vector, cyg_addrword_t data,
+ HAL_SavedRegisters *regs);
+
+
+// One-second call back alarm
+static void one_second_alarm_func(cyg_handle_t alarm, cyg_addrword_t data);
+
+// Retrieve statistics
+static void MCF5272_get_stats(struct eth_drv_sc *sc, MCF5272_FEC_DIAG* stats);
+
+
+ETH_DRV_SC(MCF5272_fec_sc,
+ &MCF5272_fec_priv_data, // Driver specific data
+ "eth0", // Name for this interface
+ MCF5272_fec_start,
+ MCF5272_fec_stop,
+ MCF5272_fec_control,
+ MCF5272_fec_can_send,
+ MCF5272_fec_send,
+ MCF5272_fec_recv,
+ MCF5272_fec_deliver,
+ MCF5272_fec_int,
+ MCF5272_fec_int_vector);
+
+/* Device name */
+static const char ether_device_name[] = "MCF5272-eth";
+
+NETDEVTAB_ENTRY(MCF5272_fec_netdev,
+ ether_device_name,
+ MCF5272_fec_init,
+ &MCF5272_fec_sc);
+
+
+/*******************************************************************************
+ db_get_eth_address() - Returns the default Ethernet address.
+*/
+const void* db_get_eth_address(void)
+{
+
+ /* Just use an obviously invalid address until someone overrides this */
+ /* routine to provide their own address. */
+
+ static const unsigned char enaddr[] =
+ {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55
+ };
+ return (const void*)enaddr;
+}
+/*******************************************************************************
+ MCF5272_fec_init() - Routine that initializes the FEC.
+
+ INPUT:
+ tab - Pointer to the network device table.
+
+ */
+static bool MCF5272_fec_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ const u8_t *enaddr;
+
+ /* Indicate that the ethernet driver is down. */
+
+ PMCF5272_FEC_DATA(sc)->operational = ETH_DEV_DOWN;
+
+ /* Initialize the entire driver private area to zero. */
+
+ memset((char*)sc->driver_private, sizeof(MCF5272_fec_priv_data_t), 0);
+
+ /* Initialize the buffers structure. This strucre contains transmit */
+ /* and receive buffer descriptor managment information. */
+
+ nbuf_init(PBUF_INFO(sc));
+
+ /* Start a alarm that will trigger every second. This alarm will */
+ /* periodically update the recevie and transmit statistics. */
+
+ cyg_clock_to_counter(cyg_real_time_clock(),
+ &(((MCF5272_fec_priv_data_t*)sc->driver_private)->counter_h));
+ cyg_alarm_create(((MCF5272_fec_priv_data_t*)sc->driver_private)->counter_h,
+ one_second_alarm_func,
+ (cyg_addrword_t)(MCF5272_fec_priv_data_t*)sc->driver_private,
+ &(((MCF5272_fec_priv_data_t*)sc->driver_private)->alarm_h),
+ &(((MCF5272_fec_priv_data_t*)sc->driver_private)->alarm));
+ cyg_alarm_initialize(((MCF5272_fec_priv_data_t*)sc->driver_private)->alarm_h,
+ cyg_current_time()+
+ (1*SEC_IN_NS)/CYGNUM_KERNEL_COUNTERS_RTC_PERIOD,
+ (1*SEC_IN_NS)/CYGNUM_KERNEL_COUNTERS_RTC_PERIOD);
+
+ /* Initialize environment, setup receive, transmit and non-critical */
+ /* interrupt handlers. */
+
+ cyg_drv_interrupt_create(CYGNUM_HAL_VECTOR_ERX,
+ MCF5272_INT_LEVEL, // Priority
+ (cyg_addrword_t)sc, // Data item passed to interrupt handler
+ (cyg_ISR_t *)MCF5272_fec_isr,
+ (cyg_DSR_t *)eth_drv_dsr,
+ &MCF5272_fec_rx_interrupt_handle,
+ &MCF5272_fec_rx_interrupt);
+ cyg_drv_interrupt_create(CYGNUM_HAL_VECTOR_ETX,
+ MCF5272_INT_LEVEL, // Priority
+ (cyg_addrword_t)sc, // Data item passed to interrupt handler
+ (cyg_ISR_t *)MCF5272_fec_isr,
+ (cyg_DSR_t *)eth_drv_dsr,
+ &MCF5272_fec_tx_interrupt_handle,
+ &MCF5272_fec_tx_interrupt);
+
+ /* Attach interrupt here in order to start receiving interrupt from */
+ /* the FEC. */
+
+ cyg_drv_interrupt_attach(MCF5272_fec_rx_interrupt_handle);
+ cyg_drv_interrupt_attach(MCF5272_fec_tx_interrupt_handle);
+
+
+
+ put_reg(MCF5272_SIM->gpio.pbcnt, 0x55550000 |
+ (get_reg(MCF5272_SIM->gpio.pbcnt) & 0x0000FFFF));
+
+
+ /* Reset the FEC - equivalent to a hard reset. */
+
+ put_reg(MCF5272_SIM->enet.ecr, MCF5272_FEC_ECR_RESET);
+
+ /* Wait for the reset sequence to complete. */
+
+ while(get_reg(MCF5272_SIM->enet.ecr) & MCF5272_FEC_ECR_RESET);
+
+ /* Set the Ethernet control register to zero to disable the FEC. */
+
+ put_reg(MCF5272_SIM->enet.ecr, 0);
+
+ /* Set the source address for the controller. */
+
+ /* Initialize physical address register by copying our adapter */
+ /* address from the device's permanent storage. */
+
+ enaddr = (cyg_uint8*)db_get_eth_address();
+
+ put_reg(MCF5272_SIM->enet.malr,0
+ | (enaddr[0] <<24)
+ | (enaddr[1] <<16)
+ | (enaddr[2] <<8)
+ | (enaddr[3] <<0));
+ put_reg(MCF5272_SIM->enet.maur,0
+ | (enaddr[4] <<24)
+ | (enaddr[5] <<16));
+
+ /* Initialize the hash table registers to ignore hash checking to */
+ /* detect multicast Etherhet addresses. */
+
+ put_reg(MCF5272_SIM->enet.htur, 0);
+ put_reg(MCF5272_SIM->enet.htlr, 0);
+
+ /* Set Receive Buffer Size. This is the size for each receive */
+ /* buffer. */
+
+ put_reg(MCF5272_SIM->enet.emrbr, (uint16)RX_BUFFER_SIZE);
+
+ /* Point to the start of the circular Rx buffer descriptor queue. */
+
+ put_reg(MCF5272_SIM->enet.erdsr, nbuf_get_start(PBUF_INFO(sc), Rx));
+
+ /* Point to the start of the circular Tx buffer descriptor queue. */
+
+ put_reg(MCF5272_SIM->enet.etdsr, nbuf_get_start(PBUF_INFO(sc), Tx));
+
+ /* Set the FIFO transmit highwater mark to 128 bytes. Frame */
+ /* transmission begins when the number of bytes selected by this field */
+ /* are written into the transmit FIFO, if an end of frame has been */
+ /* written to the FIFIO, or if the FIFO is full before selected number */
+ /* of bytes are written. */
+
+ put_reg(MCF5272_SIM->enet.tfwr, MCF5272_FEC_XWMRK_128);
+
+ /* Clear any interrupts by setting all bits in the EIR register. */
+
+ put_reg(MCF5272_SIM->enet.eir, 0xFFFFFFFF);
+
+ /* Set the tranceiver interface to MII mode. */
+
+ put_reg(MCF5272_SIM->enet.rcr, 0 | MCF5272_FEC_RCR_MII_MODE);
+ // | MCF5272_FEC_RCR_DRT);
+
+ /* Set the mode is ETH_MODE_SIMPLEX. We are assuming the device is */
+ /* half-duplex mode. */
+
+ PMCF5272_FEC_DATA(sc)->duplex = ETH_MODE_SIMPLEX;
+
+ /* The default speed is 10 Mbs. */
+
+ PMCF5272_FEC_DATA(sc)->speed = ETH_SPEED_10MB;
+
+ /* Write the maximum frame length and setup so we can receive */
+ /* broadcast packets. */
+
+ put_reg(MCF5272_SIM->enet.mflr, MCF5272_FEC_MFLR_BRDCAST |
+ sizeof(eth_frame_hdr));
+
+ /* Check for heartbeat count and enable full-duplex transmit. The */
+ /* hearbeat check is performed following end of transmission and the HB */
+ /* bit in the status reguster is set if the collision input does not */
+ /* assert within the heartbeat window. */
+
+ /* NOTE: We disable full duplex mode because we notice that we're */
+ /* getting Receive CRC erors. */
+
+
+ put_reg(MCF5272_SIM->enet.tcr, 0 |MCF5272_FEC_TCR_HBC);
+ //| MCF5272_FEC_TCR_FDEN);
+
+ /* Set the MII frequency divider. The MII_SPEED controls the */
+ /* frequency of the MII management interface clock relative to the */
+ /* system clock. We set MII speed to 7 because the system clock */
+ /* frequency is 66 Mhz. */
+
+ put_reg(MCF5272_SIM->enet.mscr, 7<<1);
+
+ /* Initialize upper level driver. */
+
+ (sc->funs->eth_drv->init)(sc, (unsigned char *)enaddr);
+
+ /* Return true to indicate that the driver initialization has */
+ /* completed successfully. */
+
+ return true;
+
+}
+
+/* This function is called to "start up" the interface. It may be */
+/* called multiple times, even when the hardware is already running. It */
+/* will be called whenever something "hardware oriented" changes and should */
+/* leave the hardware ready to send/receive packets. */
+
+static void
+MCF5272_fec_start(struct eth_drv_sc *sc, cyg_uint8 *enaddr, int flags)
+{
+
+ /* Initialize the buffers structure. This strucre contains transmit */
+ /* and receive buffer descriptor managment information. We initialize */
+ /* again here becuase we don't know the internal state of the buffer */
+ /* descriptor pointer in the FEC if the FEC was disabled after calling */
+ /* MCF5272_fec_stop. */
+
+ if (PMCF5272_FEC_DATA(sc)->operational != ETH_DEV_UP)
+ {
+ nbuf_init(PBUF_INFO(sc));
+ }
+
+ /* Unmask the Transmit and Receive frame interrupt to handle the */
+ /* interrupts. */
+
+ /* Unmask the Internal Bus Errorso we can detect any internal bus */
+ /* error when the FEC tries to acess the internal bus. */
+
+ put_reg(MCF5272_SIM->enet.eimr,
+ get_reg(MCF5272_SIM->enet.eimr) | MCF5272_FEC_INTERRUPT_MASK);
+
+ /* Enable FEC. */
+
+ put_reg(MCF5272_SIM->enet.ecr, MCF5272_FEC_ECR_ETHER_EN);
+
+ /* Indicate that there have been empty receive buffers produced. */
+
+ put_reg(MCF5272_SIM->enet.rdar, MCF5272_FEC_RDAR_DESTACT);
+
+
+ /* Set the flag to indicate that the device is up and running. */
+
+ PMCF5272_FEC_DATA(sc)->operational = ETH_DEV_UP;
+
+}
+
+/* A routine to halt the FEC. */
+static void
+MCF5272_fec_stop(struct eth_drv_sc *sc)
+{
+
+ /* Stop the packet transmission gracefully. */
+
+ /* Set the Graceful Transmit Stop bit. */
+
+ put_reg(MCF5272_SIM->enet.tcr, get_reg(MCF5272_SIM->enet.tcr)
+ | MCF5272_FEC_TCR_GTS);
+
+ /* Wait for the current transmission to complete. */
+
+ while( !(get_reg(MCF5272_SIM->enet.eir) & MCF5272_FEC_EIR_GRA));
+
+ /* Clear the GRA event. */
+
+ put_reg(MCF5272_SIM->enet.eir, MCF5272_FEC_EIR_GRA);
+
+ /* Disable all FEC interrupts by clearing the IMR register. */
+
+ put_reg(MCF5272_SIM->enet.eimr, 0);
+
+ /* Clear the GTS bit so frames can be tranmitted when restarted */
+
+ put_reg(MCF5272_SIM->enet.tcr, get_reg(MCF5272_SIM->enet.tcr) &
+ ~MCF5272_FEC_TCR_GTS);
+
+ /* Set the Ethernet control register to zero to disable the FEC. */
+
+ put_reg(MCF5272_SIM->enet.ecr, 0);
+
+ /* Deliver any pending frames and acknowledge any transmitted frames. */
+
+ MCF5272_fec_deliver(sc);
+
+ /* Set the flag to indicate that the device is down. */
+
+ PMCF5272_FEC_DATA(sc)->operational = ETH_DEV_DOWN;
+
+}
+
+/* This routine is called to perform special "control" opertions. */
+
+static int
+MCF5272_fec_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ switch (key)
+ {
+
+ case ETH_DRV_SET_MAC_ADDRESS:
+
+ {
+ /* Set the hardware address of the Ethernet controller. */
+
+ struct ifreq* p_ifreq = data;
+
+ /* If the length of the strcutre is not equal to the size of */
+ /* ifreq, then exit with an error. */
+
+ if (data_length != sizeof(*p_ifreq))
+ {
+ return 0;
+ }
+
+ /* Set the lower 4-byte address. */
+
+ put_reg(MCF5272_SIM->enet.malr,0
+ | (p_ifreq->ifr_ifru.ifru_hwaddr.sa_data[0] <<24)
+ | (p_ifreq->ifr_ifru.ifru_hwaddr.sa_data[1] <<16)
+ | (p_ifreq->ifr_ifru.ifru_hwaddr.sa_data[2] <<8)
+ | (p_ifreq->ifr_ifru.ifru_hwaddr.sa_data[3] <<0));
+
+ /* Set the upper 2-byte address. */
+
+ put_reg(MCF5272_SIM->enet.maur,
+ 0
+ | (p_ifreq->ifr_ifru.ifru_hwaddr.sa_data[4] <<24)
+ | (p_ifreq->ifr_ifru.ifru_hwaddr.sa_data[5] <<16));
+
+
+ /* Return 1 to indicate that programming of the new MAC */
+ /* address is successful. */
+
+ return 1;
+ }
+
+
+ break;
+ #ifdef CYGPKG_NET
+
+ case ETH_DRV_GET_IF_STATS:
+ case ETH_DRV_GET_IF_STATS_UD:
+
+ #if 0
+ {
+
+ struct ether_drv_stats* pstats = (struct ether_drv_stats*)
+ data;
+ MCF5272_FEC_DIAG diag;
+
+ /* Retrieve the driver defined diagnostic structure. */
+ MCF5272_get_stats(sc, &diag);
+
+ strcpy(pstats->description, ether_device_name);
+ pstats->duplex = ETH_MODE_UNKNWON;
+ pstats->operational = (unsigned char )PMCF5272_FEC_DATA(sc)->operational;
+ pstats->speed = 0;
+
+ /* Translate the device specific diagnostic values to the */
+ /* generic ether_drv_stats values. */
+
+ /* Get the receive bytes count. */
+ pstats->rx_count = diag.rx_bytes_cnt;
+
+ /* Get the number of successful packet received. */
+ pstats->rx_good = diag.rx_pk_cnt;
+
+ /* Get the receive CRC error count. */
+ pstats->rx_crc_errors = diag.rx_crc_err_cnt;
+
+ /* Get the receive overrun error count. */
+ pstats->rx_overrun_errors = diag.rx_overrun_err_cnt;
+
+ /* Get the received short frame error count. */
+ pstats->rx_short_frames = diag.rx_short_frm_err_cnt;
+
+ /* Get the received long frame error count. */
+ pstats->rx_too_long_frames = diag.rx_long_frm_err_cnt;
+
+ /* Get the number of transmitted bytes. */
+ pstats->tx_count = diag.tx_bytes_cnt;
+
+ /* Get the number of defered packets. */
+ pstats->tx_deferred = diag.tx_def_cnt;
+
+ /* The number of successfully transmitted packets. */
+ pstats->tx_good = diag.tx_pk_cnt;
+
+ /* Get the transmit late collision count. */
+ pstats->tx_late_collisions = diag.tx_late_col_cnt;
+
+ /* Get the transmit underrun count. */
+ pstats->tx_underrun = diag.tx_underrun_cnt;
+
+ /* Get the transmit late collision count. */
+ pstats->tx_total_collisions = diag.tx_late_col_cnt;
+ return 1;
+ }
+ #else
+ {
+
+ /* Copy the ethernet name device over. */
+
+ strcpy(((struct mcf5272_ether_drv_stats*)data)->description,
+ ether_device_name);
+
+ /* Get the stats. */
+ MCF5272_get_stats(sc,
+ &((struct mcf5272_ether_drv_stats*)data)->stats);
+
+ /* Copy the mode over. */
+
+ ((struct mcf5272_ether_drv_stats*)data)->duplex =
+ PMCF5272_FEC_DATA(sc)->duplex;
+
+ /* The ethernet driver is operational. */
+
+ ((struct mcf5272_ether_drv_stats*)data)->operational =
+ PMCF5272_FEC_DATA(sc)->operational;
+
+ /* Copy the speed over. */
+
+ ((struct mcf5272_ether_drv_stats*)data)->speed =
+ PMCF5272_FEC_DATA(sc)->speed;
+
+ return 1;
+ }
+
+ #endif
+ break;
+
+ #endif /* CYGPKG_NET */
+ default:
+ return 1;
+ break;
+ }
+
+}
+
+
+/* This routine is called to see if it is possible to send another */
+/* packet. It will return non-zero if a transmit is possible, zero */
+/* otherwise. */
+
+static int
+MCF5272_fec_can_send(struct eth_drv_sc *sc)
+{
+ const int buffer_window = 5; /* Specifies the minimum empty buffer descrpitors */
+
+ if ((NUM_TXBDS - PBUF_INFO(sc)->num_busy_bd) > buffer_window)
+ {
+ return 1;
+ }
+ else
+ {
+ PMCF5272_FEC_DATA(sc)->diag_counters.tx_full_cnt++;
+ return 0;
+ }
+}
+
+
+/* This routine is called by eCos to send a frame to the ethernet */
+/* controller. */
+
+static void
+MCF5272_fec_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list,
+ int sg_len,
+ int total_len,
+ unsigned long key)
+{
+
+ /* Call eth_tx_check() routine for any packet transmitted by eCos. */
+
+ eth_tx_check(sg_list, sg_len);
+
+
+ /* If we do have enough buffer to send we call */
+ /* MCF5272_fec_common_send routine to send the packet. Otherwise, we */
+ /* throw away the packet and call eCos's tx_done rutine to notify that */
+ /* the packet has been sent. */
+
+ if (NUM_TXBDS - PBUF_INFO(sc)->num_busy_bd > sg_len)
+ {
+ MCF5272_fec_common_send(sc, sg_list, sg_len, total_len, key, TX_KEY_ECOS);
+
+
+ }
+ else
+ {
+
+ CYG_ASSERT(false, "ETH: Send buffer full");
+
+ /* Inform the upper layer of a completion of the packet. */
+
+ (sc->funs->eth_drv->tx_done)(sc,
+ key,
+ 0);
+ }
+
+}
+
+/* This routine is called to send a frame to the ethernet controller. */
+/* This is a generic send routine. */
+/*
+
+ INPUT:
+ sc - Ethernet driver sc.
+ sg_glist - scatter gather list.
+ sg_len - The number of scattter gather entries in the list.
+ total_len - The total length of the frame.
+
+*/
+
+
+static void
+MCF5272_fec_common_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list,
+ int sg_len,
+ int total_len,
+ unsigned long key,
+ tx_key_type_t key_type)
+{
+ int i = 0;
+ NBUF *pBD = NULL;
+ NBUF *first_bd;
+ buf_info_t* p_buf = PBUF_INFO(sc);
+
+
+ CYG_ASSERT(sg_len > 0, "ETH: sg_len cannot be zero");
+
+
+ /* Update the number of used transmitted buffer desciptors. */
+
+ p_buf->num_busy_bd += sg_len;
+
+ /* Keep track of the maximum number of busy transmit buffer */
+ /* descriptors. */
+
+ if (p_buf->num_busy_bd > p_buf->max_num_busy_bd)
+ {
+ p_buf->max_num_busy_bd = p_buf->num_busy_bd;
+ }
+
+ /* Enqueue the key, the index to first and last buffer desriptor, the */
+ /* number of buffer descriptors, the packet length and the type of */
+ /* packet to the transmit queue. */
+
+ nbuf_enq_tx_key(p_buf, (p_buf->iTxbd + sg_len - 1) % NUM_TXBDS,
+ key,
+ p_buf->iTxbd,
+ sg_len,
+ total_len,
+ key_type);
+
+ /* Get the pointer to the first buffer descriptor of the packet. We */
+ /* don't set the R bit for the first packet until we have allocated and */
+ /* initialized all the buffer descriptors. */
+
+ first_bd = pBD = nbuf_tx_allocate(p_buf);
+
+ do
+ {
+
+ CYG_ASSERT(pBD != NULL, "ETH: nbuf_tx_allocate() returned NULL");
+
+
+ /* Copy the address of the buffer and the length to the allocated */
+ /* buffer descriptor. Note that buf_index indexes to the buffer */
+ /* descriptor it returns. */
+
+ pBD->data = (uint8*)sg_list[i].buf;
+ pBD->length = sg_list[i].len;
+
+ if (i == sg_len - 1)
+ {
+
+ /* Set the the L, TC and R bit to indicate that the buffer */
+ /* descriptor is the last buffer descriptor, the CRC is */
+ /* appended by the FEC and the buffer descriptor is ready for */
+ /* transmission. */
+
+ pBD->status |= TX_BD_L | TX_BD_TC | TX_BD_R;
+
+ /* When we have reached the last buffer scatther list, we */
+ /* break from the loop. */
+
+ break;
+
+ }
+ else
+ {
+
+ if (i)
+ {
+
+ /* If the buffer descriptor is not the first buffer */
+ /* descriptor, then set the R bit to notify the FEC that */
+ /* the buffer descriptor is read for transmission. FEC */
+ /* must reset R bit after transmitted for buffer. */
+
+ pBD->status |= TX_BD_R;
+
+ }
+
+ /* Allocate the next buffer descriptor. */
+
+ pBD = nbuf_tx_allocate(p_buf);
+
+ }
+
+ /* Advance to the next index. */
+
+ i++;
+
+ }while(1);
+
+ /* Set the R bit in the first buffer descriptor to indicate that the */
+ /* buffer is ready for transmission if there are more than one buffer */
+ /* descriptors. */
+
+ if (sg_len > 1)
+ first_bd->status |= TX_BD_R;
+
+ /* Indicate that there is a transmit buffer ready. */
+
+ put_reg(MCF5272_SIM->enet.tdar, 1);
+
+}
+
+
+/* This function is called as a result of the "eth_drv_recv()" call */
+/* above. It's job is to actually fetch data for a packet from the */
+/* hardware once memory buffers have been allocated for the packet. Note */
+/* that the buffers may come in pieces, using a scatter-gather list. This */
+/* allows for more efficient processing in the upper layers of the stack. */
+
+/* Note that the total buffer allocated for the scatter-gather list */
+/* can be smaller than the packet or the buffer that in the scatter gather */
+/* list is invalid. This happens when the upper layer driver runs out of */
+/* buffers for the scatter-gather list. */
+
+static void
+MCF5272_fec_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ uint_t fill_count = 0, buf_count;
+ uint_t frame_length = 0, buf_len;
+ NBUF *pNbuf = NULL;
+ cyg_uint8* buf = NULL;
+ cyg_bool_t done = false;
+ uint_t sg_index = 0;
+
+ /* If the scatter-gather list is zero, set buf to NULL so that this */
+ /* routine would not copy the buffer to the scatter-gatther buffer. */
+
+ if (sg_len > 0)
+ {
+ buf = (cyg_uint8*)sg_list[0].buf;
+ }
+
+ do
+ {
+
+ /* Get the next buffer descriptor (bd). */
+
+ pNbuf = nbuf_rx_get_next(PBUF_INFO(sc));
+
+ CYG_ASSERT(pNbuf != NULL, "Cannot get the next bd");
+
+ if (pNbuf->status & TX_BD_L)
+ {
+
+ /* Calculate the remaining numer of bytes in the packet that */
+ /* needed to be copied out since the the length of the in the */
+ /* last BD contains the total length of the packet and not the */
+ /* length of the buffer. */
+
+ buf_len = (uint_t)pNbuf->length - frame_length;
+
+ /* Since the last bd, set done to true in order to exit the */
+ /* loop. */
+
+ done = true;
+ }
+ else
+ {
+ buf_len = RX_BUFFER_SIZE;
+
+ /* Update the frame length. */
+
+ frame_length += RX_BUFFER_SIZE;
+ }
+
+
+ /* Copy the packet to the scatter gather list if there is a buffer */
+ /* to copy the packet to. */
+
+ for (buf_count = 0; buf_count < buf_len && buf != NULL;)
+ {
+
+ uint_t copy_len;
+
+ /* Retrieve the minimum copy length. We basically copy based */
+ /* on the smaller size: the buffer from the scatther list or the */
+ /* from the buffer descriptor. */
+
+ copy_len = (((uint_t)sg_list[sg_index].len - fill_count) <
+ (buf_len - buf_count) ?
+ (uint_t)sg_list[sg_index].len - fill_count :
+ (buf_len - buf_count));
+
+ /* Copy the buffer to the upper layer driver buffer. */
+
+ memcpy(&buf[fill_count],
+ &pNbuf->data[buf_count],
+ copy_len);
+
+ /* Update the counts to reflect the number of bytes copied. */
+
+ fill_count += copy_len;
+ buf_count += copy_len;
+
+ /* If the buffer in the scatter-gather list is full, we */
+ /* attempt to retrieve the next buffer in the list. */
+
+ if (fill_count >= sg_list[sg_index].len)
+ {
+
+ /* If there is no more buffer, set the buf to NULL and */
+ /* exit the loop. */
+
+ if (++sg_index >= sg_len)
+ {
+ buf = NULL;
+ break;
+ }
+ else
+ {
+ buf = (cyg_uint8*)sg_list[sg_index].buf;
+ fill_count = 0;
+ }
+ }
+ }
+
+
+ /* Release the buffer scriotor so it cab be used to receive other */
+ /* packets. */
+
+ nbuf_rx_release(pNbuf);
+
+ }while(done == false);
+
+ /* Notify the FEC that there are receive buffer descriptors available */
+ /* for the FEC. */
+
+ put_reg(MCF5272_SIM->enet.rdar, MCF5272_FEC_RDAR_DESTACT);
+}
+
+/*******************************************************************************
+MCF5252_fec_recv_handler() - Receive handler to read the received
+buffer descriptors and inform the upper layer driver of the arrival
+of the packet.
+*/
+inline static
+bool MCF5252_fec_recv_handler(struct eth_drv_sc * sc)
+{
+
+ /* Receive interrupt has occurred informing driver that a frame has */
+ /* been written to the buffer. */
+
+ NBUF* pNBuf;
+ buf_info_t* p_buf_info = PBUF_INFO(sc);
+ MCF5272_fec_priv_data_t* eth_data = PMCF5272_FEC_DATA(sc);
+ uint_t len;
+
+ /* Pointer to the first buffer descriptor. */
+
+ NBUF* p_first_bd;
+
+ /* Check to see if the buffer descrpitor is not busy. */
+
+ if (nbuf_rx_next_ready(p_buf_info))
+ {
+
+ /* Flag that indicates whether the buffer is wrapped. */
+
+ cyg_bool_t wrap = false;
+
+ /* Get the index of the buffer desrciptor of the next frame. */
+
+ uint_t index = nbuf_rx_get_index(p_buf_info);
+ cyg_bool_t error = false;
+ len = 0;
+
+ /* Get the pointer to the first buffer descriptor. */
+
+ p_first_bd = nbuf_rx_get(p_buf_info, index);
+
+ do
+ {
+ pNBuf = nbuf_rx_get(p_buf_info, index);
+
+ if (pNBuf->status & RX_BD_E)
+ {
+
+ /* The buffer is empty or the FEC is stll writing to the */
+ /* buffer. then exit. */
+
+ return false;
+
+ }
+
+ /* Advance the index to the next buffer descriptor in the */
+ /* ring buffer. */
+
+ index = (index + 1) % NUM_RXBDS;
+
+ if ((pNBuf->status & (RX_BD_L | RX_BD_W)) == RX_BD_W)
+ {
+
+ /* If the buffer descriptor wraps, set the wrap flag and */
+ /* initalize the index pointer to the first buffer */
+ /* descriptor in the ring. */
+
+ wrap = true;
+
+ }
+
+ if (pNBuf->status & RX_BD_TR)
+ {
+
+ /* Packet truncate count. */
+
+ eth_data->diag_counters.rx_trunc_error_cnt++;
+
+ /* Release the bds. */
+
+ nbuf_rx_release_pkt(p_buf_info);
+
+ /* Update the receive error count. */
+
+ eth_data->diag_counters.rx_err_cnt++;
+
+ /* Notify the FEC that there are receive buffer */
+ /* descriptors available from the FEC. */
+
+ put_reg(MCF5272_SIM->enet.rdar, MCF5272_FEC_RDAR_DESTACT);
+
+ error = true;
+ break;
+ }
+
+ if (pNBuf->status & RX_BD_L)
+ {
+
+ /* Get the length of frame contain in the buffers. */
+
+ len = pNBuf->length;
+
+ /* If there is an error in receiving the packet, we */
+ /* proceed to update the counters. Otherwise, we just fall */
+ /* through. */
+
+ if (pNBuf->status & (RX_BD_LG | RX_BD_SH | RX_BD_CR |
+ RX_BD_OV))
+ {
+
+ /* Update the diagnostic counters. */
+
+ if (pNBuf->status & RX_BD_LG)
+ {
+ /* Larget frame error count. */
+ eth_data->diag_counters.rx_long_frm_err_cnt++;
+ }
+
+ if (pNBuf->status & RX_BD_SH)
+ {
+ /* Short frame error count. */
+ eth_data->diag_counters.rx_short_frm_err_cnt++;
+ }
+
+ if (pNBuf->status & RX_BD_CR)
+ {
+ /* CRC error count. */
+ eth_data->diag_counters.rx_crc_err_cnt++;
+ }
+
+ if (pNBuf->status & RX_BD_OV)
+ {
+ /* Overrun error count. */
+ eth_data->diag_counters.rx_overrun_err_cnt++;
+ }
+
+ /* Release the packet. */
+
+ nbuf_rx_release_pkt(p_buf_info);
+
+ /* Update the receive error count. */
+
+ eth_data->diag_counters.rx_err_cnt++;
+
+ /* Notify the FEC that there are receive buffer */
+ /* descriptors available for the FEC */
+
+ put_reg(MCF5272_SIM->enet.rdar, MCF5272_FEC_RDAR_DESTACT);
+
+ /* Set the error flag to true to indicate that there */
+ /* is an error. */
+
+ error = true;
+
+ }
+ }
+ }while(!(pNBuf->status & RX_BD_L));
+
+ if (error == false)
+ {
+ cyg_uint8* buf_ptr = p_first_bd->data;
+
+ /* Since there is no error, we update the good statistic */
+ /* counters. */
+
+ /* Update the number of frames received. */
+
+ eth_data->diag_counters.rx_pk_cnt++;
+
+ /* Update the number of bytes in the frame received. */
+
+ /* Subract 4 bytes from the length because the packet */
+ /* includes the 4-byte FCS. */
+
+ eth_data->diag_counters.rx_bytes_cnt += (len - 4);
+
+
+ /* If the packet wraps then copy the packet to the a */
+ /* temporary buffer in order to make the packet contigous */
+ /* packet in memory. */
+
+ if (wrap)
+ {
+
+ uint_t count_len = 0;
+ uint_t pk_len;
+
+ /* Set p_buf the pointer to temporary packet biffer which */
+ /* we will use to copy the packet. */
+
+ u8_t* p_buf = (u8_t*)&eth_data->pkt_buf;
+
+ /* Get the index of the buffer desrcitor of the next frame. */
+
+ uint_t index = nbuf_rx_get_index(p_buf_info);
+
+ do
+ {
+
+ /* Get the buffer descriptor. */
+
+ pNBuf = nbuf_rx_get(p_buf_info, index);
+
+ /* Calculate the length of the data in the buffer */
+ /* descriptor. If we reach the last buffer descriptor, */
+ /* the the actual data size in the last buffer */
+ /* descriptor is the number of bytes we have copied */
+ /* less from the value of the length field of the last */
+ /* buffer descriptor. */
+
+ if (pNBuf->status & RX_BD_L)
+ {
+ pk_len = len - count_len;
+ }
+ else
+ {
+ pk_len = RX_BUFFER_SIZE;
+ }
+
+ /* Copy the content of the buffer to the temporary */
+ /* packet buffer. */
+
+ memcpy(&p_buf[count_len], pNBuf->data, pk_len);
+
+
+ /* Keep count of the number of bytes read from the */
+ /* buffer descriptor. */
+
+ count_len += pk_len;
+
+ /* Advance to the to next buffer descriptor. */
+
+ index = (index + 1) % NUM_RXBDS;
+
+ }while(!(pNBuf->status & RX_BD_L));
+
+ buf_ptr = (u8_t*)&eth_data->pkt_buf;
+
+
+ }
+
+ /* If there is a copy wrap error or the Rx packet filter */
+ /* rejected the packet, pass it to the upper layer. Otherwise, */
+ /* release the buffer descriptors. */
+
+ if (!eth_rx_pkt_filter(buf_ptr, len))
+ {
+
+ /* Inform the upper layer of a complete packet. */
+
+ (sc->funs->eth_drv->recv)(sc, len);
+ }
+ else
+ {
+
+ /* Release the buffer descriptors. */
+
+ nbuf_rx_release_good_pkt(p_buf_info);
+
+
+ /* Notify the FEC that there is at least a receive buffer */
+ /* descriptos available for the FEC. */
+
+ put_reg(MCF5272_SIM->enet.rdar, MCF5272_FEC_RDAR_DESTACT);
+
+ }
+
+ }
+
+ }
+ else
+ {
+
+ /* Indicates that there are no more receive packets. */
+
+ return false;
+ }
+ return true;
+
+}
+/*******************************************************************************
+MCF5272_fec_transmit_handler() - Transmit handler informs the upper
+layer packet of a completion of a transmit packet.
+*/
+
+static
+bool MCF5272_fec_transmit_handler(struct eth_drv_sc * sc)
+
+/* If the FEC has successfull transmitted a packet, then realease the */
+/* buffer used for the packet so that the buffer can be reused. */
+
+{
+
+ /* Check to see which frame has completed sending so we can tell the */
+ /* upper layer to free up ts buffer. */
+
+ buf_info_t* p_buf_info = PBUF_INFO(sc);
+ MCF5272_fec_priv_data_t* eth_data = PMCF5272_FEC_DATA(sc);
+ NBUF* pNbd = NULL;
+ int_t index, i;
+ tx_keys_t key_entry;
+ bool result = true;
+ NBUF* next_bd;
+
+
+ /* Check wether there is any pending transmit buffer descriptors that */
+ /* are to deallocated. */
+
+ if ((index = nbuf_peek_tx_key(p_buf_info)) != -1)
+ {
+
+ /* Get the pointer to the buffer descriptor so that the flags in */
+ /* the status word in the buffer descriptor can be examined. */
+
+ NBUF* pNbuf = nbuf_tx_get(p_buf_info, index);
+
+ CYG_ASSERT(pNbuf->status & TX_BD_L, "Index to BD is not the last BD");
+
+ if (pNbuf->status & TX_BD_R)
+ {
+
+
+ /* Increment the number of times the device driver discovers */
+ /* that the buffer descriptor is still in use by the FEC and it */
+ /* has been skipped. */
+
+ if ((next_bd = nbuf_peek_bd_ahead(p_buf_info)))
+ {
+ if (!(next_bd->status & TX_BD_R) &&
+ pNbuf->status & TX_BD_R)
+ {
+
+ eth_data->diag_counters.tx_not_complete_cnt++;
+ goto RELEASE_BUF;
+
+ }
+ }
+
+ /* If the buffer not ready we return immediatly. */
+
+ return false;
+
+ }
+
+RELEASE_BUF:
+
+ /* Dequeue the packet from the trasnmt packet queue to indicate */
+ /* that the packet is not being transmitted by the FEC. */
+
+ nbuf_deq_tx_key(p_buf_info, &key_entry);
+
+ /* Release the used buffers. */
+
+ for ( i = 0; i < key_entry.num_dbufs; i++)
+
+ {
+
+ /* Get the BD based on the index. */
+
+ pNbd = nbuf_tx_get(p_buf_info,
+ (key_entry.start_index + i) % NUM_TXBDS);
+
+ /* The last buffer descriptor of the packet. */
+
+ if (pNbd->status & TX_BD_L)
+ {
+
+ if (pNbd->status & TX_BD_RL)
+ {
+
+ /* Update the number of retries. */
+
+ eth_data->diag_counters.tx_retry_cnt += 16;
+ eth_data->diag_counters.tx_err_cnt++;
+ eth_data->diag_counters.tx_exes_retry_cnt++;
+ }
+ else
+ {
+
+ /* Check for error status. If there is an error */
+ /* proceed the increment the appropriate statistic */
+ /* counter. */
+
+ if (pNbd->status & (TX_BD_UN |
+ TX_BD_LC |
+ TX_BD_CSL |
+ TX_BD_HB))
+ {
+
+ if (pNbd->status & TX_BD_HB)
+ {
+
+ /* Heartbeat error count. */
+
+ eth_data->diag_counters.tx_hb_err_cnt++;
+ }
+
+ if (pNbd->status & TX_BD_UN)
+ {
+
+ /* Transmit underrun error count. */
+
+ eth_data->diag_counters.tx_underrun_cnt++;
+ }
+
+ if (pNbd->status & TX_BD_CSL)
+ {
+
+ /* Transmit carrier loss count. */
+
+ eth_data->diag_counters.tx_carrrier_loss_cnt++;
+ }
+
+ if (pNbd->status & TX_BD_LC)
+ {
+
+ /* Update the late collision counter. */
+
+ eth_data->diag_counters.tx_late_col_cnt++;
+ }
+
+ /* Update the number transmit error count. */
+
+ eth_data->diag_counters.tx_err_cnt++;
+ }
+ else
+ {
+ /* Update the diagnostic counters */
+
+ if (pNbd->status & TX_BD_DEF)
+ {
+ /* Defer indication count. */
+ eth_data->diag_counters.tx_def_cnt++;
+ }
+
+ /* Update the number of transmitted packets. */
+
+ eth_data->diag_counters.tx_pk_cnt++;
+
+ /* Update the transmitted packet size. If the */
+ /* size is less than the minimum size then take the */
+ /* minimum size as the actual frame length. This */
+ /* is because we take account of the pad bytes that */
+ /* the FEC appends when it sends out frames that */
+ /* has less than the minimum length. */
+
+ eth_data->diag_counters.tx_bytes_cnt +=
+ key_entry.pk_len < ETH_MIN_SIZE ? ETH_MIN_SIZE :
+ key_entry.pk_len;
+ }
+
+ /* Get the number of retries. */
+
+ eth_data->diag_counters.tx_retry_cnt +=
+ (pNbd->status >> 2) & 0xF;
+ }
+
+ }
+
+ /* Release the buffer descriptor so that it can be reused to */
+ /* transmit the next packet. */
+
+ nbuf_tx_release(pNbd);
+
+ /* If the start_index is the same as the index to the last */
+ /* buffer descriptor, then quit the loop. */
+
+ }
+
+ /* Decrement the number of busy descriptors. */
+
+ p_buf_info->num_busy_bd -= key_entry.num_dbufs;
+
+ switch(key_entry.key_type)
+ {
+ case TX_KEY_ECOS:
+
+ /* Inform the upper layer of a completion of the packet. */
+
+ (sc->funs->eth_drv->tx_done)(sc,
+ key_entry.tx_key,
+ 0);
+ break;
+ case TX_KEY_USER:
+
+ /* Inform the application of the completion of the packet. */
+
+ eth_send_done(key_entry.tx_key);
+ break;
+ }
+
+ }
+ else
+ {
+
+ /* Retrun false to indicate that the transmit buffer is empty. */
+
+ result = false;
+ }
+
+ /* Indicate that the packet at the transmit buffer has been */
+ /* successfully handled. */
+
+ return result;
+}
+
+
+/* This routine informs the upper layer of a completion of a sent */
+/* frame and a reception of a frame. */
+
+static void
+MCF5272_fec_deliver(struct eth_drv_sc * sc)
+{
+ u32_t event;
+
+
+ /* Clear the event register. */
+
+ put_reg(MCF5272_SIM->enet.eir,
+ (event = (get_reg(MCF5272_SIM->enet.eir) &
+ MCF5272_FEC_INTERRUPT_MASK)));
+
+ while(event & MCF5272_FEC_INTERRUPT_MASK)
+ {
+
+ /* This flag will specifies whether we need to service the */
+ /* transmit or receive sides of the Ethernet controller. */
+
+ bool packet_status;
+
+
+ /* Keep count of any bus error that might occur when the FEC */
+ /* attempts while the FEC accessing the internal bus. */
+
+ if (event & MCF5272_FEC_EIR_EBERR)
+ {
+ PMCF5272_FEC_DATA(sc)->diag_counters.internal_bus_error_cnt++;
+ }
+
+ do
+ {
+ packet_status = false;
+
+ /* Call receive the handler to receive packets. */
+
+ packet_status |= MCF5252_fec_recv_handler(sc);
+
+ /* Call transit the handed to release the transmit buffers. */
+
+ packet_status |= MCF5272_fec_transmit_handler(sc);
+
+ /* Loop back up until all the receive and transmit buffers */
+ /* are empty. */
+
+ }while(packet_status);
+
+ /* Retrieve the next interrupt event. */
+
+ /* Clear the event register. */
+
+ put_reg(MCF5272_SIM->enet.eir,
+ event = (get_reg(MCF5272_SIM->enet.eir) &
+ MCF5272_FEC_INTERRUPT_MASK));
+
+ }
+
+ /* NOTE: If the a bit in the eir is set after clearing the bit in the */
+ /* eir, unmasking the bit in the imr will generate an interrupt. This */
+ /* assumption is true only if the interrupt line to the microprocessor */
+ /* core is level sensitive. */
+
+ /* Allow interrupts by setting IMR register. */
+
+ put_reg(MCF5272_SIM->enet.eimr, get_reg(MCF5272_SIM->enet.eimr) |
+ MCF5272_FEC_INTERRUPT_MASK
+ );
+
+}
+
+/* Generic Interrupt Service Routine. This routine wakes up the DSR */
+/* for further processing. */
+
+static int
+MCF5272_fec_isr(cyg_vector_t vector, cyg_addrword_t data,
+ HAL_SavedRegisters *regs)
+{
+
+ /* Mask the FEC's interrupts so that it won't generate these */
+ /* interrupts anymore as the driver reads the packets or acknowledges */
+ /* packets. */
+
+ put_reg(MCF5272_SIM->enet.eimr, get_reg(MCF5272_SIM->enet.eimr) &
+ ~(MCF5272_FEC_INTERRUPT_MASK));
+
+ return CYG_ISR_CALL_DSR;
+}
+
+
+/* Call MCF5272_fec_deliver() to poll the FEC. */
+
+static void
+MCF5272_fec_int(struct eth_drv_sc *sc)
+{
+ MCF5272_fec_deliver(sc);
+}
+
+static int
+MCF5272_fec_int_vector(struct eth_drv_sc *sc)
+{
+
+ /* How do you return multiple interrupt vector? */
+
+ return CYGNUM_HAL_VECTOR_ERX;
+}
+
+/* This routine updates the Ethernet statistics counters. This method */
+/* is called by eCos every second. */
+
+static void one_second_alarm_func(cyg_handle_t alarm, cyg_addrword_t data)
+{
+ #define WRAP_SUBTRACT(_VAL1_,_VAL2_) \
+ ({unsigned long val;if (_VAL1_ >= _VAL2_) val = _VAL1_ - _VAL2_; \
+ else val=(0-_VAL2_)+_VAL1_; val;})
+
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_bytes_cnt_sec =
+ WRAP_SUBTRACT(
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_bytes_cnt,
+ ((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_rx_bytes_cnt);
+
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_bytes_cnt_sec =
+ WRAP_SUBTRACT(
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_bytes_cnt,
+ ((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_tx_bytes_cnt);
+
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_pk_cnt_sec =
+ WRAP_SUBTRACT(
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_pk_cnt,
+ ((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_rx_pk_cnt);
+
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_pk_cnt_sec =
+ WRAP_SUBTRACT(
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_pk_cnt,
+ ((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_tx_pk_cnt);
+
+
+ ((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_rx_bytes_cnt =
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_bytes_cnt;
+ ((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_tx_bytes_cnt =
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_bytes_cnt;
+ ((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_rx_pk_cnt =
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.rx_pk_cnt;
+ ((MCF5272_fec_priv_data_t*)data)->diag_info_sup.old_tx_pk_cnt =
+ ((MCF5272_fec_priv_data_t*)data)->diag_counters.tx_pk_cnt;
+}
+
+/* Retrieve the stats information. */
+
+void MCF5272_get_stats(struct eth_drv_sc *sc, MCF5272_FEC_DIAG* stats)
+{
+ memcpy(stats, &PMCF5272_FEC_DATA(sc)->diag_counters,
+ sizeof (MCF5272_FEC_DIAG));
+
+ /* Retrieve the number of available buffer descriptors and the */
+ /* minimum value. */
+
+ PMCF5272_FEC_DATA(sc)->diag_counters.tx_free_bd_cnt =
+ NUM_TXBDS - PBUF_INFO(sc)->num_busy_bd;
+ PMCF5272_FEC_DATA(sc)->diag_counters.tx_free_min_bd_cnt =
+ NUM_TXBDS - PBUF_INFO(sc)->max_num_busy_bd;
+}
+
+
+/*****************************************************************************
+
+ The following functions provide an interface directly to the
+ethernet driver for applications that wish to circumvent the IP stack.
+
+ Applications that wish to take advantage of this should override
+these routine with their own. Leaving these routines as default routes
+all data through the IP stack.
+
+*****************************************************************************/
+
+/*****************************************************************************
+eth_rx_pkt_filter -- Ethernet receive packet filter
+
+ This is an ethernet packet filter function that allows the application
+to receive raw ethernet frames from the driver. The return value of this
+function determines whether or not to pass the packet to the IP stack.
+
+ We declare it weak so that other routine can override it.
+
+INPUT:
+
+ pkt: Pointer to the packet.
+
+ pkt_len: The length of the packet including all headers, the 32-bit
+Ethernet CRC, and any Ethernet frame padding.
+
+OUTPUT:
+
+RETURN VALUE:
+
+ true: Do not send the packet to the IP stack.
+
+ false: Send the packet to the IP stack.
+
+*****************************************************************************/
+int_t eth_rx_pkt_filter(u8_t * pkt, uint_t pkt_len)
+{
+
+ /* Always return false by default. */
+
+ return false;
+}
+
+/*****************************************************************************
+eth_tx_check -- Watch transmitting Ethernet packets
+
+ The driver calls this routine before transmitting packets from the
+IP stack. It provides a hook for applications to watch all packets that
+the IP stack transmits.
+
+ We declare it weak so that other routine can override it.
+
+INPUT:
+
+ sg_list: Pointer to the scatter-gather list.
+
+ sg_len: The number of scatter-gather entries in the list.
+
+OUTPUT:
+
+RETURN VALUE:
+
+ None
+
+*****************************************************************************/
+void eth_tx_check(struct eth_drv_sg * sg_list, unsigned int sg_len)
+{
+
+ /* Do nothing by default. */
+
+}
+
+/*****************************************************************************
+eth_send -- Transmit a raw Ethernet packet
+
+ This function sends a packet to the Ethernet controller thus
+passing the eCos IP stack.
+
+ Note that the application must reuse the buffer parameters to this
+function until the driver releases the buffer with the eth_send_done()
+function.
+
+INPUT:
+
+ sg_list: Pointer to the scatter-gather list to send.
+
+ sg_len: The size of the scatter-gather list.
+
+ tag: A value that we pass as a parameter to eth_send_done()
+function when the FEC has completed sending the packet.
+
+OUTPUT:
+
+RETURN VALUE:
+
+ true: if the packet is successfully queued to the device driver's
+queue.
+
+ false : If the routine fails to send the packet.
+
+*****************************************************************************/
+int_t eth_send(struct eth_drv_sg* sg_list, unsigned int sg_len,
+ int total_len,
+ unsigned long tag)
+{
+ int_t success;
+ cyg_uint32 s;
+
+ s = cyg_splsoftnet();
+
+ /* If there is enough buffer descriptors, then send the packet. */
+ /* Otherwise, throw the packet away and return a false value. */
+
+ if (NUM_TXBDS - PBUF_INFO(&MCF5272_fec_sc)->num_busy_bd > sg_len)
+ {
+
+ /* Call the common send routine to send the packet. */
+
+ MCF5272_fec_common_send(&MCF5272_fec_sc,
+ sg_list,
+ sg_len,
+ total_len,
+ tag,
+ TX_KEY_USER);
+
+ success = true;
+ }
+ else
+ {
+
+ /* Fail to send the packet. */
+
+ success = false;
+ }
+
+ /* Release the Ethernet driver lock. */
+
+ cyg_splx(s);
+
+ return success;
+}
+
+/*****************************************************************************
+eth_send_done -- eth_send callback
+
+ The driver calls this function when it has sent out the packet. The
+parameter tag is the same value as the tag value when the caller calls the
+eth_send to send the packet.
+
+ We declare it weak so that other routine can override it.
+
+INPUT:
+
+ tag: A value that we pass as a parameter to eth_send_done()
+function when the FEC has completed sending the packet.
+
+OUTPUT:
+
+RETURN VALUE:
+
+ None
+
+*****************************************************************************/
+void eth_send_done(unsigned long tag)
+{
+
+}
+
+
+#if 0
+
+
+/* Defined Ethernet Frame Types */
+#define FRAME_IP (0x0800)
+#define FRAME_ARP (0x0806)
+#define FRAME_RARP (0x8035)
+
+/* Offset and size of protocol headers */
+#define ETH_HDR_OFFSET 0 /* Ethernet header at the top of the frame */
+#define ETH_HDR_SIZE 14
+
+/* Assign a protocol number for the loop test */
+static uint16 eth_type = 0x0300;
+
+/* Global variable containing length of data to transmit */
+static uint16 data_length = 512;
+
+/* Transmit data size of each transmti buffer descriptor. */
+
+#define TX_BUFFER_SIZE (576) /* must be divisible by 16 */
+
+
+void
+fec_start_loopback_test(void)
+{
+ /* Initalize the buffer descriptors. */
+
+ nbuf_init(&MCF5272_fec_priv_data.nbuffer);
+
+ /* Initalize the Ethernet controllder device. */
+
+ MCF5272_fec_init(&MCF5272_fec_netdev);
+
+
+}
+
+/********************************************************************/
+static void
+loop_fill_buffers(void)
+{
+ /* Fill all the buffers in the TX buffer ring with a unique data pattern */
+ uint16 index, pattern, i;
+ static unsigned char output_buffer[NUM_TXBDS][TX_BUFFER_SIZE];
+
+
+ uint_t data_length = TX_BUFFER_SIZE;
+
+ for (i = 0; i < NUM_TXBDS; i++)
+ {
+
+ MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data = output_buffer[i];
+ switch (i % 8)
+ {
+ /* Load buffers 0 through 3 with a single data patterns */
+ case (0):
+ memset(&MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[ETH_HDR_SIZE],0x55,data_length);
+ break;
+ case (1):
+ memset(&MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[ETH_HDR_SIZE],0xAA,data_length);
+ break;
+ case (2):
+ memset(&MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[ETH_HDR_SIZE],0x00,data_length);
+ break;
+ case (3):
+ memset(&MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[ETH_HDR_SIZE],0xFF,data_length);
+ break;
+
+ /* Buffer[4]: Load increasing walking ones */
+ case (4):
+ pattern = 1;
+ for (index = 0; index < data_length; index++)
+ {
+ if (pattern == 0x0100)
+ pattern = 0x01;
+ MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[index] = (uint8)pattern;
+ pattern <<= 1;
+ }
+ break;
+
+ /* Buffer[5]: Load decreasing walking ones */
+ case(5):
+ pattern = 0x80;
+ for (index = 0; index < data_length; index++)
+ {
+ if (pattern == 0x00)
+ pattern = 0x80;
+ MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[index] = (uint8)pattern;
+ pattern >>= 1;
+ }
+ break;
+
+ /* Buffer[6]: Load "Increment from 0" pattern */
+ case (6):
+ for (index = 0; index < data_length; index++)
+ MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[index] = (uint8) ((index-14)%256);
+ break;
+
+ /* Buffer[7]: Load "Decrement from 255" pattern */
+ case (7):
+ for (index = 0; index < data_length; index++)
+ MCF5272_fec_priv_data.nbuffer.TxNBUF[i].data[index] = (uint8)(255- ((index-14)%256));
+ break;
+ }
+ }
+}
+
+/********************************************************************/
+void
+loop_handler(void)
+{
+
+ /* This is the loop specific RX handler called from the interrupt */
+ /* receive routine. This routine gets bound to the loop protocol */
+ /* (0x0300) by a call to nif_bind_protocol() and is then called in */
+ /* fec_receive(). This function simply checks to make sure that the */
+ /* receive buffer matches the transmit buffer. */
+
+ int i;
+
+ /* Compare what I received to what I transmitted */
+ for (i = 0; i < (data_length + ETH_HDR_SIZE); i++)
+ {
+ if (TxBuffer[fec_nif->f_rx % NUM_TXBDS].data[i] != pNbuf->data[i])
+ {
+ /* Increment reception error count */
+ fec_nif->f_rx_err++;
+ }
+ }
+
+ /* Increment reception count */
+ fec_nif->f_rx++;
+
+ /* Update progress indicator */
+ if (!(fec_nif->f_rx % 200))
+ {
+ ihash = (ihash + 1) % 4;
+ diag_printf("\b%c",hash[ihash]);
+ }
+
+ return;
+}
+
+#endif
+
+
diff --git a/ecos/packages/devs/eth/mcf52xx/mcf5272/current/src/nbuf.c b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/src/nbuf.c
new file mode 100644
index 0000000..84c3916
--- /dev/null
+++ b/ecos/packages/devs/eth/mcf52xx/mcf5272/current/src/nbuf.c
@@ -0,0 +1,97 @@
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+#include <cyg/devs/eth/nbuf.h>
+/*
+ * Functions to manipulate the network buffers.
+ */
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/devs/eth/if_mcf5272.h>
+#include <cyg/devs/eth/nbuf.h>
+#include <cyg/infra/cyg_ass.h>
+
+/*******************************************************************************
+nbuf_init() - Initalize the networ buffers.
+
+INPUT: pBuf - Pointer to the network buffer data.
+*/
+void
+nbuf_init (buf_info_t* pBuf)
+{
+ uint_t i = 0;
+ uint8 *buf = (uint8*)&(pBuf->RxBuffer);
+ buf = (uint8*)((((uint32)buf+15)/16)*16);
+
+ /* Initialize RxNBUF and TxNBUF */
+ pBuf->RxNBUF = (NBUF*)((((uint32)(&pBuf->nrxbuf[0])+3)/4)*4);
+ pBuf->TxNBUF = (NBUF*)((((uint32)(&pBuf->ntxbuf[0])+3)/4)*4);
+
+ /* Initialize receive descriptor ring */
+ for (i = 0; i < NUM_RXBDS; i++)
+ {
+ pBuf->RxNBUF[i].status = RX_BD_E;
+ pBuf->RxNBUF[i].length = 0;
+ pBuf->RxNBUF[i].data = buf;
+ buf += RX_BUFFER_SIZE;
+ }
+ /* Set the Wrap bit on the last one in the ring */
+ pBuf->RxNBUF[NUM_RXBDS - 1].status |= RX_BD_W;
+
+ /* Initialize transmit descriptor ring */
+ for (i = 0; i < NUM_TXBDS; i++)
+ {
+ pBuf->TxNBUF[i].length = 0;
+ pBuf->TxNBUF[i].data = 0L;
+ pBuf->TxNBUF[i].status = 0;
+ }
+ /* Set the Wrap bit on the last one in the ring */
+ pBuf->TxNBUF[NUM_TXBDS - 1].status |= TX_BD_W;
+
+ /* Initialize the buffer descriptor indexes */
+ pBuf->iTxbd = pBuf->iRxbd = 0;
+
+ /* Intiaize the transmit key queue to zero. */
+ pBuf->tq_front = pBuf->tq_rear = 0;
+
+ // Initalize the nubmer of transmit buffer descriptors used to zero.
+
+ pBuf->num_busy_bd = 0;
+}
+
+
+
+
diff --git a/ecos/packages/devs/eth/microchip/enc424j600/current/ChangeLog b/ecos/packages/devs/eth/microchip/enc424j600/current/ChangeLog
new file mode 100644
index 0000000..7f90d66
--- /dev/null
+++ b/ecos/packages/devs/eth/microchip/enc424j600/current/ChangeLog
@@ -0,0 +1,33 @@
+2012-04-20 Ilija Stanislevik <ilijas@siva.mk>
+
+ * cdl/enc424j600_eth_drivers.cdl:
+ * host/enc424j600_eth_drivers.cdl:
+ * include/enc424j600_eth.h:
+ * src/enc424j600_spi.h:
+ * src/enc424j600_spi.c:
+ * tests/netconn_test_server.c:
+ New package [Bugzilla ID #1000910].
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/microchip/enc424j600/current/cdl/enc424j600_eth_drivers.cdl b/ecos/packages/devs/eth/microchip/enc424j600/current/cdl/enc424j600_eth_drivers.cdl
new file mode 100644
index 0000000..580c5b0
--- /dev/null
+++ b/ecos/packages/devs/eth/microchip/enc424j600/current/cdl/enc424j600_eth_drivers.cdl
@@ -0,0 +1,271 @@
+# ====================================================================
+#
+# enc424j600_eth_drivers.cdl
+#
+# Ethernet driver for Microchip ENC424J600 controller
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Stanislevik
+# Contributors:
+# Date: 2010-11-23
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ENC424J600 {
+ display "Microchip ENC424J600 / ENC624J600 ethernet controller"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_IO_ETH_MULTICAST
+
+ active_if CYGPKG_IO_SPI
+
+ requires { CYGINT_IO_ETH_INT_SUPPORT_REQUIRED implies
+ (CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_VECTOR != "")
+ }
+
+ requires { CYGINT_IO_ETH_INT_SUPPORT_REQUIRED implies
+ (CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_PRIORITY != "")
+ }
+
+ include_dir cyg/io/eth
+ description "
+ Driver for Microchip ENC424J600 and ENC624J600 Ethernet controllers,
+ connected to the platform with an SPI interface."
+
+ compile -library=libextras.a enc424j600_spi.c
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/system.h>"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ENC424J600_OPTIONS {
+ display "Microchip ENC424J600 driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_ENC424J600_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the ENC424J600 ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+
+ }
+
+ cdl_option CYGDAT_IO_ETH_ENC424J600_NAME {
+ display "Ethernet device name"
+ flavor data
+ default_value { "\"eth0\"" }
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ENC424J600_NO_AUTO_NEGOTIATION {
+ display "No auto negotiation of speed and duplex"
+ default_value 0
+ description "
+ Enable this component in order to manually configure the link speed
+ and duplex configuration. Otherwise the chip will automatically
+ negotiate them with the peer."
+
+ cdl_option CYGNUM_DEVS_ETH_ENC424J600_SPEED {
+ display "Ethernet speed in megabit per second"
+ flavor data
+ legal_values { 100 10 }
+ default_value 100
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_ENC424J600_FULL_DUPLEX {
+ display "Full duplex"
+ default_value 1
+ }
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_ENC424J600_SET_ESA {
+ display "Set the Ethernet station address"
+ flavor bool
+ default_value 0
+ description "
+ Enabling this option will override the ENC424J600
+ factory set ethernet station address (MAC address)."
+
+ cdl_option CYGDAT_DEVS_ETH_ENC424J600_ESA {
+ display "Ethernet station address"
+ flavor data
+ default_value { " { 0x00, 0x04, 0xa3, 0x10, 0x08, 0x3e } "}
+ description "The ethernet station address"
+ }
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ENC424J600_ACCEPTABLE_PACKET_SIZE {
+ display "Largest acceptable packet size"
+ flavor data
+ legal_values 60 to 9600
+ default_value 1518
+ description "
+ This option configures the size in bytes of the largest
+ packet expected to be sent or received. The chip will
+ truncate any received or transmitted packet to this
+ size. This size excludes any space required for the
+ Preamble, Start of Frame Delimiter and the Frame Check
+ Sequence (CRC)."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ENC424J600_TXBUF_SIZE {
+ display "Size of transmit buffer"
+ flavor data
+ legal_values CYGNUM_DEVS_ETH_ENC424J600_ACCEPTABLE_PACKET_SIZE to (0x6000 - CYGNUM_DEVS_ETH_ENC424J600_ACCEPTABLE_PACKET_SIZE -2)
+ default_value CYGNUM_DEVS_ETH_ENC424J600_ACCEPTABLE_PACKET_SIZE
+ description "
+ The 0x6000 bytes of on-chip RAM are divided between transmit
+ buffer and receive buffer. This parameter impacts the sizes of
+ both. The transmit buffer must be large enough to hold one
+ transmit packet."
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_ENC424J600_FLOWC {
+ display "Flow control"
+ flavor data
+ default_value { "None" }
+ legal_values { "None" "OnChip" }
+ description "
+ Enabling flow control prevents overflow of the input buffer if
+ received packets are not processed fast enough."
+ }
+
+ cdl_component CYGNUM_DEVS_ETH_ENC424J600_FLOW_CONTROL_PARAMETERS {
+ display "Flow control parameters"
+ active_if { CYGSEM_DEVS_ETH_ENC424J600_FLOWC != "None" }
+ flavor none
+
+ cdl_option CYGNUM_DEVS_ETH_ENC424J600_FLOWC_UPPER_WATERMARK {
+ display "Upper threshold for flow control"
+ flavor data
+ default_value 16
+ legal_values 2 to 255
+ description "
+ This threshold is measured in multiples of blocks of
+ 96 bytes. When this number of blocks have been used
+ in the on-chip receive buffer, the device considers its
+ receive buffer full and initiates flow control."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ENC424J600_FLOWC_LOWER_WATERMARK {
+ display "Lower threshold for flow control"
+ flavor data
+ default_value 15
+ legal_values 1 to (CYGNUM_DEVS_ETH_ENC424J600_FLOWC_UPPER_WATERMARK - 1)
+ description "
+ This threshold is measured in multiples of blocks of
+ 96 bytes. If flow control has been activated, then
+ when the number of occupied blocks in the on-chip
+ receive buffer falls below this level, the device
+ considers the buffer to be empty enough to receive
+ more data and therefore disengages flow control."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ENC424J600_FLOWC_PAUSE {
+ display "Duration of flow control pause"
+ flavor data
+ default_value { 0x1000 }
+ legal_values 0 to 0xffff
+ description "
+ Duration of flow control pause in units of 512 bit times. Valid for full-duplex
+ operation only."
+ }
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ENC424J600_CLOCKOUT_FREQUENCY {
+ display "Frequency of clock output at the CLKOUT pin"
+ flavor data
+ default_value { "0" }
+ legal_values {
+ "0" "33M33" "25M00"
+ "20M00" "16M67" "12M50" "10M00"
+ "8M333" "8M000" "6M250" "5M000"
+ "4M000" "3M125"
+ "0M0" "100K" "50K"
+ }
+ description "
+ The ENC424J600 has a clock output which can be used by
+ other parts of the system. M stands for megahertz, K for
+ kilohertz, and where these letters are used stands for the
+ position of a decimal point. Values 0 and 0M0 both mean
+ DC output, or, in other words, no clock output. This
+ driver does not make use of the clock output facility
+ itself. Control of the clock output frequency is provided
+ here as a convenience."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ENC424J600_INTERRUPT {
+ display "Interrupt configuration"
+ flavor none
+ no_define
+ active_if CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ description "
+ Configuration options related to interrupt handling."
+
+ cdl_option CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_PRIORITY {
+ display "Interrupt priority"
+ flavor data
+ default_value { is_active(CYGNUM_HAL_SPIETH_INTERRUPT_PRIORITY) ? CYGNUM_HAL_SPIETH_INTERRUPT_PRIORITY : "\"\"" }
+ description "
+ Interrupt priority for the ENC424J600. The default value
+ is typically set by the platform HAL."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_VECTOR {
+ display "Interrupt vector"
+ flavor data
+ default_value { is_active(CYGNUM_ETH_SPIETH_HAL_INTERRUPT_VECTOR) ? CYGNUM_ETH_SPIETH_HAL_INTERRUPT_VECTOR : "\"\"" }
+ description "
+ Interrupt vector for the ENC424J600. The default value is
+ typically set by the platform HAL."
+ }
+ }
+}
+
+# End of enc424j600_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/microchip/enc424j600/current/host/test_tcp_client.c b/ecos/packages/devs/eth/microchip/enc424j600/current/host/test_tcp_client.c
new file mode 100644
index 0000000..1cb6f08
--- /dev/null
+++ b/ecos/packages/devs/eth/microchip/enc424j600/current/host/test_tcp_client.c
@@ -0,0 +1,198 @@
+//=================================================================
+//
+// test_tcp_client.c
+//
+// TCP/Ethernet testing - host-side
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Stanislevik
+// Date: 2010-02-10
+//####DESCRIPTIONEND####
+//==========================================================================
+
+/*
+ The target hardware runs a listener/server application. The server
+ calculates checksum on recived packets for the whole duration of
+ connection. Once conection ends, it displays the checksum.
+
+ The host client generates pseudorandom data and sends it to the target.
+ Before sending, it calculates checksum. Once data sent, it dispalys
+ the checksum for comparison with the checksum at target side.
+
+ For now, no attempts has been made to employ a host other than Linux.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#define NUM_ARG 4
+
+struct addrinfo * hostaddr_p;
+int socket_d;
+struct sockaddr serv_addr;
+
+void print_syntax(char *name)
+{
+ printf("Syntax: %s ip_address port bytes_to_send\n", name);
+ printf(" Format ip_address as d1.d2.d3.d4, where dx is integer 0-255\n\n");
+}
+
+int main(int argc, char *argv[])
+{
+ int retval;
+ struct addrinfo hint_s;
+ struct addrinfo *p;
+ char ipstr[INET6_ADDRSTRLEN];
+ unsigned long int msg_len;
+ unsigned long int left_to_send;
+ unsigned long int i;
+ unsigned long int csum;
+ char *msg_p = NULL;
+ char *fill_p;
+ unsigned char value;
+
+ if(NUM_ARG != argc)
+ {
+ printf("\nError: Wrong number of arguments %d instead of %d.\n", argc-1, NUM_ARG-1);
+ print_syntax(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ memset(&hint_s, 0, sizeof(struct addrinfo));
+ hint_s.ai_family = AF_INET;
+ hint_s.ai_socktype = SOCK_STREAM;
+ hint_s.ai_flags = AI_NUMERICSERV;
+ hint_s.ai_protocol = 0; /* Any protocol */
+ hint_s.ai_canonname = NULL;
+ hint_s.ai_addr = NULL;
+ hint_s.ai_next = NULL;
+ retval = getaddrinfo(argv[1], argv[2], &hint_s, &hostaddr_p);
+ if(0 != retval)
+ {
+ printf("\nError: %s\n", gai_strerror(retval));
+ print_syntax(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ printf("IP addresses for %s:\n", argv[1]);
+
+ for(p = hostaddr_p; p != NULL; p = p->ai_next)
+ {
+ void *addr;
+ char *ipver;
+ // get the pointer to the address itself,
+ // different fields in IPv4 and IPv6:
+ if (p->ai_family == AF_INET)
+ { // IPv4
+ struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
+ addr = &(ipv4->sin_addr);
+ ipver = "IPv4";
+ }
+ else
+ { // IPv6
+ struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
+ addr = &(ipv6->sin6_addr);
+ ipver = "IPv6";
+ }
+ // convert the IP to a string and print it:
+ inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
+ printf(" %s: %s\n", ipver, ipstr);
+ }
+
+ socket_d = socket(hostaddr_p->ai_family, hostaddr_p->ai_socktype, hostaddr_p->ai_protocol);
+ if(-1 == socket_d)
+ {
+ printf("Error: Can't get socket. errno %d\n", errno);
+ return EXIT_FAILURE;
+ }
+
+ retval = connect(socket_d, hostaddr_p->ai_addr, hostaddr_p->ai_addrlen);
+ if(0 != retval)
+ {
+ perror("\nError: Failed connect()\n");
+ return EXIT_FAILURE;
+ }
+
+ // Prepare message to send
+ msg_len = strtoul(argv[3], NULL, 0);
+ msg_len &= ~0x3;
+ if (0 == msg_len)
+ {
+ printf("Nothing to do (bytes_to_send == 0). Exiting.\n");
+ return EXIT_SUCCESS;
+ }
+ else
+ {
+ printf("Preparing to send %lu bytes.\n", msg_len);
+ }
+
+ msg_p = malloc(msg_len);
+ if(NULL == msg_p)
+ {
+ printf("Error: Can't allocate %lu bytes.\n", msg_len);
+ return EXIT_FAILURE;
+ }
+
+ fill_p = msg_p;
+ csum = 0;
+
+ for(i=0; i<msg_len; i++)
+ {
+ value = random() & 0xff;
+ *fill_p++ = value;
+ csum += value;
+ }
+
+ left_to_send = msg_len;
+ do
+ {
+ retval = send(socket_d, msg_p, msg_len, 0);
+ left_to_send -= retval;
+ printf("%d bytes sent.\n", retval);
+ } while(left_to_send);
+ printf("Checksum %08lx\n", csum);
+
+ freeaddrinfo(hostaddr_p); // free the linked list
+
+ return EXIT_SUCCESS;
+}
diff --git a/ecos/packages/devs/eth/microchip/enc424j600/current/include/enc424j600_eth.h b/ecos/packages/devs/eth/microchip/enc424j600/current/include/enc424j600_eth.h
new file mode 100644
index 0000000..6d9ec5e
--- /dev/null
+++ b/ecos/packages/devs/eth/microchip/enc424j600/current/include/enc424j600_eth.h
@@ -0,0 +1,100 @@
+#ifndef CYGONCE_DEVS_ETH_ENC424J600_ETH_H_
+#define CYGONCE_DEVS_ETH_ENC424J600_ETH_H_
+
+//==========================================================================
+//
+// enc424j600_eth.h
+//
+// Microchip enc424j600 Ethernet chip
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010, 2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Stanislevik
+// Contributors:
+// Date: 2010-11-23
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_eth_enc424j600.h>
+
+// Ethernet flow control options
+enum enc424j600_flow_control_e
+{
+ ENC424J600_NO_FC, // No flow control
+ ENC424J600_ONCHIP_AUTO_FC // On-chip automatic flow control. Not tested yet.
+};
+
+// enc424j600 clock out frequencies
+enum enc424j600_clkout_e
+{
+ ENC424J600_CLKO_0, // DC
+ ENC424J600_CLKO_33M33, ENC424J600_CLKO_25M00, ENC424J600_CLKO_20M00,
+ ENC424J600_CLKO_16M67, ENC424J600_CLKO_12M50, ENC424J600_CLKO_10M00,
+ ENC424J600_CLKO_8M333, ENC424J600_CLKO_8M000, ENC424J600_CLKO_6M250,
+ ENC424J600_CLKO_5M000, ENC424J600_CLKO_4M000, ENC424J600_CLKO_3M125,
+ ENC424J600_CLKO_0M0, // DC
+ ENC424J600_CLKO_100K, ENC424J600_CLKO_50K
+};
+
+struct enc424j600_priv_data_s;
+typedef cyg_bool (*provide_esa_t)(struct enc424j600_priv_data_s*);
+
+typedef struct enc424j600_priv_data_s
+{
+ // Configurable data
+ cyg_spi_device *spi_service_device; // SPI device used to communicate
+ // with the Ethernet chip
+ provide_esa_t provide_esa;
+ bool hardwired_esa;
+ unsigned char esa[ETHER_ADDR_LEN];
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+ struct cyg_netdevtab_entry *tab;
+
+ // Really private data
+ cyg_uint16 NextPacketPointer;
+ enum { ENC424J600_LINK_OFF, ENC424J600_LINK_ON } link_status;
+ bool txbusy;
+ unsigned long txkey;
+} enc424j600_priv_data_t;
+
+#endif /* CYGONCE_DEVS_ETH_ENC424J600_ETH_H_ */
+
+// End of enc424j600_eth.h
diff --git a/ecos/packages/devs/eth/microchip/enc424j600/current/src/enc424j600_spi.c b/ecos/packages/devs/eth/microchip/enc424j600/current/src/enc424j600_spi.c
new file mode 100644
index 0000000..54ee746
--- /dev/null
+++ b/ecos/packages/devs/eth/microchip/enc424j600/current/src/enc424j600_spi.c
@@ -0,0 +1,1340 @@
+//==========================================================================
+//
+// enc424j600_spi.c
+//
+// Microchip enc424j600 Ethernet chip
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010, 2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Stanislevik
+// Contributors:
+// Date: 2010-11-23
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#include <cyg/io/spi.h> // Common SPI API
+
+#include "enc424j600_spi.h"
+#include <cyg/io/eth/enc424j600_eth.h>
+
+// Set ENC424J600_DEBUG to:
+// 0 to suppress all printout
+// 1 to print error reports
+// 2 to print interrupt tracing
+// 4 printout _init() progress
+// 8 to print progress tracing data
+// 0x10 for test with dummy stack
+// 0x20 to printout status registers
+#define ENC424J600_DEBUG (0)
+
+#define ENC424J600_DONT_DROP_CS (0)
+#define ENC424J600_DO_DROP_CS (1)
+#define ENC424J600_TXBUF_START (0)
+
+#define ENC424J600_RXBUF_START (ENC424J600_TXBUF_START + CYGNUM_DEVS_ETH_ENC424J600_TXBUF_SIZE)
+
+#ifndef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+# define SPI_POLLING true
+#else
+# define SPI_POLLING false
+#endif
+
+static enc424j600_priv_data_t eth0_enc424j600_priv_data;
+
+ETH_DRV_SC(eth0_spi_sc,
+ &eth0_enc424j600_priv_data, // Driver specific data.
+ CYGDAT_IO_ETH_ENC424J600_NAME,
+ enc424j600_spi_start,
+ enc424j600_spi_stop,
+ enc424j600_spi_control,
+ enc424j600_spi_can_send,
+ enc424j600_spi_send,
+ enc424j600_spi_recv,
+ enc424j600_spi_deliver,
+ enc424j600_spi_poll,
+ enc424j600_spi_int_vector
+);
+
+NETDEVTAB_ENTRY(eth0_spi_netdev,
+ "eth_spi",
+ enc424j600_spi_init,
+ &eth0_spi_sc);
+
+// Local service functions
+
+// Interface for enc424j600 "single byte instruction".
+static void
+simple_operation(enc424j600_priv_data_t *dpd, enum enc424j600_spi_opcode_1_e opcode)
+{
+ cyg_spi_transaction_begin(dpd->spi_service_device);
+ cyg_spi_transaction_transfer(dpd->spi_service_device,
+ SPI_POLLING,
+ 1,
+ & opcode,
+ NULL, // not interested in answer
+ ENC424J600_DO_DROP_CS);
+ cyg_spi_transaction_end(dpd->spi_service_device);
+
+ return;
+}
+
+// Interface for enc424j600 "banked N-byte instructions".
+// Banked read, write, bit set or bit clear operation with control register
+static int
+banked_register_operation(enc424j600_priv_data_t *cpd,
+ enum enc424j600_spi_opcode_e opcode,
+ cyg_uint8 address,
+ cyg_uint16 length,
+ cyg_uint8 *buffer)
+{
+ if ((NULL == buffer) || (0 == length))
+ {
+#if ENC424J600_DEBUG & 1
+ diag_printf("Wrong parm buffer=0x%x or length=%d.\n", (int)buffer, length);
+#endif
+ return -1;
+ }
+
+ if ((ENC424J600_ECON1H < address) || (opcode & ENC424J600_ECON1H))
+ {
+#if ENC424J600_DEBUG & 1
+ diag_printf("Wrong address=0x%02x or opcode=0x%02x for banked operation.\n",
+ address, opcode);
+#endif
+ return -1;
+ }
+
+ address |= opcode; // combine them in single byte
+ cyg_spi_transaction_begin(cpd->spi_service_device);
+ // Send the opcode and address,
+ cyg_spi_transaction_transfer(cpd->spi_service_device,
+ SPI_POLLING,
+ 1,
+ & address,
+ NULL, // not interested in answer
+ ENC424J600_DONT_DROP_CS);
+ // then the data.
+ cyg_spi_transaction_transfer(cpd->spi_service_device,
+ SPI_POLLING,
+ length,
+ (ENC424J600_READCR == opcode) ? NULL : buffer,
+ (ENC424J600_READCR == opcode) ? buffer : NULL,
+ ENC424J600_DO_DROP_CS);
+ cyg_spi_transaction_end(cpd->spi_service_device);
+
+ return 0;
+}
+
+// Interface for enc424j600 "unbanked N-byte instructions".
+// Unbanked read, write, bit set or bit clear operation with control register
+static int
+unbanked_register_operation(enc424j600_priv_data_t *cpd,
+ enum enc424j600_spi_opcode_u_e opcode,
+ cyg_uint8 address,
+ cyg_uint16 length,
+ cyg_uint8 *buffer)
+{
+ if ((NULL == buffer) || (0 == length))
+ {
+#if ENC424J600_DEBUG & 1
+ diag_printf("Wrong parm buffer=0x%x or length=%d.\n", (int)buffer, length);
+#endif
+ return -1;
+ }
+
+ cyg_spi_transaction_begin(cpd->spi_service_device);
+ // Send the opcode,
+ cyg_spi_transaction_transfer(cpd->spi_service_device,
+ SPI_POLLING,
+ 1,
+ & opcode,
+ NULL, // not interested in answer
+ ENC424J600_DONT_DROP_CS);
+ // then the address
+ cyg_spi_transaction_transfer(cpd->spi_service_device,
+ SPI_POLLING,
+ 1,
+ & address,
+ NULL, // not interested in answer
+ ENC424J600_DONT_DROP_CS);
+ // and finally the data.
+ cyg_spi_transaction_transfer(cpd->spi_service_device,
+ SPI_POLLING,
+ length,
+ (ENC424J600_READCRU == opcode) ? NULL : buffer,
+ (ENC424J600_READCRU == opcode) ? buffer : NULL,
+ ENC424J600_DO_DROP_CS);
+ cyg_spi_transaction_end(cpd->spi_service_device);
+
+ return 0;
+}
+
+// Get ESA from the Ethernet chip, unbanked
+static int
+read_esa_u(enc424j600_priv_data_t *cpd, cyg_uint8 *esa_buf)
+{
+ int retval = -1;
+ cyg_uint8 response_msg[ETHER_ADDR_LEN];
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("read_esa_u()...\n");
+#endif
+ if (NULL == esa_buf)
+ {
+ return -1;
+ }
+
+ retval = unbanked_register_operation(cpd, ENC424J600_READCRU, ENC424J600_MAADR3_U, ETHER_ADDR_LEN,
+ &response_msg[0]);
+ if (0 != retval)
+ {
+ return retval;
+ }
+ *esa_buf++ = response_msg[4];
+ *esa_buf++ = response_msg[5];
+ *esa_buf++ = response_msg[2];
+ *esa_buf++ = response_msg[3];
+ *esa_buf++ = response_msg[0];
+ *esa_buf = response_msg[1];
+
+ return 0;
+}
+
+// Set ESA into Ethernet chip, unbanked
+static int
+write_esa_u(enc424j600_priv_data_t *dpd, cyg_uint8 *esa_buf)
+{
+ int retval = -1;
+ cyg_uint8 msg[8];
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("write_esa_u()...1...\n");
+#endif
+ if (NULL == esa_buf)
+ {
+ return -1;
+ }
+
+ msg[4] = *esa_buf++;
+ msg[5] = *esa_buf++;
+ msg[2] = *esa_buf++;
+ msg[3] = *esa_buf++;
+ msg[0] = *esa_buf++;
+ msg[1] = *esa_buf;
+
+ retval = unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MAADR3_U, 6, &msg[0]);
+ if (0 != retval)
+ {
+#if ENC424J600_DEBUG & 1
+ diag_printf("Writing ESA into chip failed.\n");
+#endif
+ return retval;
+ }
+
+ return 0;
+}
+
+#if ENC424J600_DEBUG & 0x20
+// Read data from PHY register
+static void
+read_phy(enc424j600_priv_data_t *dpd,
+ const enum enc424j600_pr_address_e pr_address,
+ cyg_uint16 *retval_p)
+{
+ cyg_uint8 aux[2] = {pr_address, 0x01};
+ cyg_uint8 status;
+
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MIREGADR_U, 2, &aux[0]);
+ unbanked_register_operation(dpd, ENC424J600_READCRU, ENC424J600_MICMD_U, 2, &aux[0]);
+ aux[0] |= ENC424J600_MIIRD;
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MICMD_U, 2, &aux[0]);
+ CYGACC_CALL_IF_DELAY_US(26);
+ do
+ { // Check and busy wait for read operation to complete
+ unbanked_register_operation(dpd, ENC424J600_READCRU, ENC424J600_MISTAT_U, 1, &status);
+ } while(0 != (status & ENC424J600_MISTAT_BUSY));
+
+ aux[0] &= !ENC424J600_MIIRD; // Clear ENC424J600_MIIRD bit
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MICMD_U, 2, &aux[0]);
+
+ unbanked_register_operation(dpd, ENC424J600_READCRU, ENC424J600_MIRD_U, 2, &aux[0]);
+ *retval_p = aux[0] + 256 * aux[1];
+
+ return;
+}
+#endif
+
+// Write data to PHY register
+static void
+write_phy(enc424j600_priv_data_t *dpd,
+ const enum enc424j600_pr_address_e pr_address,
+ const cyg_uint16 value)
+{
+ cyg_uint8 aux[2] = {pr_address, 0x01};
+
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MIREGADR_U, 2, &aux[0]);
+ aux[0] = value & 0xff;
+ aux[1] = (value >> 8) & 0xff;
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MIWR_U, 2, &aux[0]);
+
+ return;
+ // There must be no other MIIM operation in the following 25.6 us!
+}
+
+// Write value for on-chip pointer.
+static void
+set_pointer(enc424j600_priv_data_t *dpd,
+ enum enc424j600_spi_bufferp_e oc_pointer,
+ cyg_uint16 value
+ )
+{
+ cyg_spi_transaction_begin(dpd->spi_service_device);
+ cyg_spi_transaction_transfer(dpd->spi_service_device,
+ SPI_POLLING,
+ 1,
+ & oc_pointer,
+ NULL, // not interested in answer
+ ENC424J600_DONT_DROP_CS);
+ cyg_spi_transaction_transfer(dpd->spi_service_device,
+ SPI_POLLING,
+ 2,
+ (cyg_uint8 *) & value,
+ NULL, // not interested in answer
+ ENC424J600_DO_DROP_CS);
+ cyg_spi_transaction_end(dpd->spi_service_device);
+ return;
+}
+
+static inline void
+write_to_tx_buffer(enc424j600_priv_data_t *dpd,
+ cyg_uint16 length,
+ cyg_uint8 *buffer)
+{
+ cyg_uint8 oc_pointer = ENC424J600_WGPDATA; // We use General Purpose Buffer
+
+ cyg_spi_transaction_begin(dpd->spi_service_device);
+ cyg_spi_transaction_transfer(dpd->spi_service_device,
+ SPI_POLLING,
+ 1,
+ & oc_pointer,
+ NULL, // not interested in answer
+ ENC424J600_DONT_DROP_CS);
+ cyg_spi_transaction_transfer(dpd->spi_service_device,
+ SPI_POLLING,
+ length,
+ buffer,
+ NULL,
+ ENC424J600_DO_DROP_CS);
+ cyg_spi_transaction_end(dpd->spi_service_device);
+
+ return;
+}
+
+static int
+read_from_rx_buffer(enc424j600_priv_data_t *dpd,
+ cyg_uint16 length,
+ cyg_uint8 *buffer)
+{
+ cyg_uint8 oc_pointer = ENC424J600_RRXDATA;
+
+// if ((0 == length) || (NULL == buffer))
+ if (0 == length)
+ {
+ return -1;
+ }
+ cyg_spi_transaction_begin(dpd->spi_service_device);
+ cyg_spi_transaction_transfer(dpd->spi_service_device,
+ SPI_POLLING,
+ 1,
+ & oc_pointer,
+ NULL, // not interested in answer
+ ENC424J600_DONT_DROP_CS);
+ cyg_spi_transaction_transfer(dpd->spi_service_device,
+ SPI_POLLING,
+ length,
+ NULL,
+ buffer,
+ ENC424J600_DO_DROP_CS);
+ cyg_spi_transaction_end(dpd->spi_service_device);
+
+ return 0;
+}
+
+static void
+set_MAC(enc424j600_priv_data_t *dpd,
+ cyg_uint8 ethernet_status // As read from upper byte of ESTAT register
+ )
+{
+ cyg_uint8 aux[2];
+
+ if (0 != (ethernet_status & ENC424J600_PHYDPX))
+ { // Full duplex
+#if ENC424J600_DEBUG & 0x20
+ diag_printf("Full duplex\n");
+#endif
+ unbanked_register_operation(dpd, ENC424J600_READCRU, ENC424J600_MACON2_U, 2, &aux[0]);
+ aux[0] |= ENC424J600_FULDPX; // Set MAC to full duplex
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MACON2_U, 2, &aux[0]);
+
+ aux[1] = 0;
+ aux[0] = 0x15; // Inter-packet gap
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MABBIPG_U, 2, &aux[0]);
+ }
+ else
+ { // Half duplex
+#if ENC424J600_DEBUG & 0x20
+ diag_printf("Half duplex\n");
+#endif
+ unbanked_register_operation(dpd, ENC424J600_READCRU, ENC424J600_MACON2_U, 2, &aux[0]);
+ aux[0] &= !ENC424J600_FULDPX; // Set MAC to half duplex
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MACON2_U, 2, &aux[0]);
+
+ aux[1] = 0;
+ aux[0] = 0x12; // Inter-packet gap
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MABBIPG_U, 2, &aux[0]);
+ }
+
+ return;
+}
+
+static void
+enc424j600_spi_LINKevent(struct eth_drv_sc *sc)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ cyg_uint8 iflag = ENC424J600_LINKIF;
+ cyg_uint8 aux[2];
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("enc424j600_spi_LINKevent()....\n");
+#endif
+
+ banked_register_operation(dpd, ENC424J600_READCR, ENC424J600_ESTATL, 2, &aux[0]);
+#if ENC424J600_DEBUG & 0x20
+ diag_printf("ESTAT %02x%02x Link ", aux[1], aux[0]);
+#endif
+ if (0 != (aux[1] & ENC424J600_PHYLNK))
+ {
+ dpd->link_status = ENC424J600_LINK_ON;
+
+#if ENC424J600_DEBUG & 0x20
+ diag_printf("ON\n");
+#endif
+ // Link is just established. Set up the MAC
+ set_MAC(dpd, aux[1]);
+ }
+ else
+ {
+ dpd->link_status = ENC424J600_LINK_OFF;
+
+#if ENC424J600_DEBUG & 0x20
+ diag_printf("OFF\n");
+#endif
+ }
+#if ENC424J600_DEBUG & 0x20
+ unbanked_register_operation(dpd, ENC424J600_READCRU, ENC424J600_MACON1_U, 2, &aux[0]);
+ diag_printf("MACON1 %02x%02x\n", aux[1], aux[0]);
+ unbanked_register_operation(dpd, ENC424J600_READCRU, ENC424J600_MACON2_U, 2, &aux[0]);
+ diag_printf("MACON2 %02x%02x\n", aux[1], aux[0]);
+ read_phy(dpd, ENC424J600_PHSTAT1, (cyg_uint16 *) &aux[0]);
+ diag_printf("PHSTAT1 %02x%02x\n", aux[1], aux[0]);
+ read_phy(dpd, ENC424J600_PHSTAT3, (cyg_uint16 *) &aux[0]);
+ diag_printf("PHSTAT3 %02x%02x\n", aux[1], aux[0]);
+ read_phy(dpd, ENC424J600_PHANLPA, (cyg_uint16 *) &aux[0]);
+ diag_printf("PHANLPA %02x%02x\n", aux[1], aux[0]);
+ read_phy(dpd, ENC424J600_PHANA, (cyg_uint16 *) &aux[0]);
+ diag_printf("PHANA %02x%02x\n", aux[1], aux[0]);
+ banked_register_operation(dpd, ENC424J600_READCR, ENC424J600_ECON1L, 2, &aux[0]);
+ diag_printf("ECON1 %02x%02x\n", aux[1], aux[0]);
+ unbanked_register_operation(dpd, ENC424J600_READCRU, ENC424J600_ECON2_U, 2, &aux[0]);
+ diag_printf("ECON2 %02x%02x\n", aux[1], aux[0]);
+
+#endif
+
+ // Clear Link interrupt flag
+ banked_register_operation(dpd, ENC424J600_BITFIELDCLEAR, ENC424J600_EIRH, 1, &iflag);
+}
+
+static void
+enc424j600_spi_PCFULevent(struct eth_drv_sc *sc)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ cyg_uint8 flags = ENC424J600_PCFULIF;
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("\nenc424j600_spi_PCFULevent()....\n\n");
+#endif
+ simple_operation(dpd, ENC424J600_SETPKTDEC); // Decrement received packet counter
+ banked_register_operation(dpd, ENC424J600_BITFIELDCLEAR, ENC424J600_EIRL, 1, &flags);
+}
+
+static void
+enc424j600_spi_RXABTevent(struct eth_drv_sc *sc)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ cyg_uint8 flags = ENC424J600_RXABTIF;
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("\nenc424j600_spi_RXABTevent()....\n\n");
+#endif
+ banked_register_operation(dpd, ENC424J600_BITFIELDCLEAR, ENC424J600_EIRL, 1, &flags);
+}
+
+static void
+enc424j600_spi_TXevent(struct eth_drv_sc *sc)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ cyg_uint8 iflag = ENC424J600_TXIF;
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("TX event.\n");
+#endif
+
+ dpd->txbusy = false;
+ banked_register_operation(dpd, ENC424J600_BITFIELDCLEAR, ENC424J600_EIRL, 1, &iflag);
+}
+
+static void
+enc424j600_spi_TXABTevent(struct eth_drv_sc *sc)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ cyg_uint8 iflag = ENC424J600_TXABTIF;
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("TXABT event.\n");
+#endif
+
+ dpd->txbusy = false;
+ banked_register_operation(dpd, ENC424J600_BITFIELDCLEAR, ENC424J600_EIRL, 1, &iflag);
+}
+
+static void
+enc424j600_spi_RXevent(struct eth_drv_sc *sc)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ cyg_uint8 pkcnt; // Local copy of the packet counter
+ cyg_uint8 rsv[2];
+ cyg_uint16 packet_length;
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("enc424j600_spi_RXevent()....\n");
+#endif
+
+ // Take info on single received packet
+ banked_register_operation(dpd, ENC424J600_READCR, ENC424J600_ESTATL, 1, &pkcnt);
+ if (0 != pkcnt)
+ {
+#if ENC424J600_DEBUG & 8
+ diag_printf("There are %u packets pending in receive buffer.\n", pkcnt);
+#endif
+ // Prepare on-chip read pointer
+ set_pointer(dpd, ENC424J600_RXRDPT, dpd->NextPacketPointer);
+ // The two bytes to read next point to the next packet
+ read_from_rx_buffer(dpd, 2, (cyg_uint8 *) & dpd->NextPacketPointer);
+
+ // Next 6 bytes to read are the Read Status Vector. We need only the first two.
+ read_from_rx_buffer(dpd, 2, & rsv[0]);
+ read_from_rx_buffer(dpd, 4, NULL);
+ packet_length = rsv[0] + rsv[1] * 256;
+ sc->funs->eth_drv->recv(sc, packet_length);
+ }
+
+ return;
+}
+
+// - End of local service functions -------------------------
+
+// - Higher level interface functions -----------------------
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+// This ISR is called when the Ethernet interrupt occurs
+static cyg_uint32
+enc424j600_spi_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_drv_interrupt_mask(CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_VECTOR);
+ cyg_drv_interrupt_acknowledge(CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_VECTOR);
+
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+static void
+enc424j600_spi_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)data;
+ struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(dpd->tab);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+#if (ENC424J600_DEBUG & 2)
+ diag_printf("DSR: Interrupt! count %u\n", count);
+#endif
+
+#if (ENC424J600_DEBUG & 0x10)
+ extern void fake_eth_drv_dsr(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+
+ fake_eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+#else
+ eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+#endif
+
+ return;
+}
+#endif // #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+// Initialization of driver and chip
+
+#define ENC424J600_INIT_SPI_READY_RETRY 100
+#define ENC424J600_INIT_CLK_READY_RETRY 100
+#define ENC424J600_INIT_RETRY_PERIOD_US 100
+
+static bool
+enc424j600_spi_init(struct cyg_netdevtab_entry *tab)
+{
+ int retval;
+ cyg_uint8 aux_8[2];
+ cyg_bool esa_configured = false;
+#ifdef CYGSEM_DEVS_ETH_ENC424J600_SET_ESA
+ cyg_uint8 esa_from_cdl[ETHER_ADDR_LEN] = CYGDAT_DEVS_ETH_ENC424J600_ESA;
+#endif
+ unsigned int i; // loop counter
+
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+
+ dpd->tab = tab;
+
+ CYG_DEVS_ETH_ENC424J600_PLF_INIT(tab); // Platform HAL should define this macro
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ // Install interrupt handler.
+ cyg_drv_interrupt_create(CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_VECTOR,
+ CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_PRIORITY,
+ (cyg_addrword_t)dpd, // Data item passed to interrupt handler
+ (cyg_ISR_t *)enc424j600_spi_isr,
+ (cyg_DSR_t *)enc424j600_spi_dsr,
+ &dpd->interrupt_handle,
+ &dpd->interrupt_object);
+ cyg_drv_interrupt_attach(dpd->interrupt_handle);
+ cyg_drv_interrupt_configure(CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_VECTOR,
+ ENC424J600_ETH_INTERRUPT_LEVEL_LOW, ENC424J600_ETH_INTERRUPT_EDGE_FALLING);
+ cyg_drv_interrupt_acknowledge(CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_VECTOR);
+ cyg_drv_interrupt_unmask(CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_VECTOR);
+#if ENC424J600_DEBUG & 4
+ diag_printf("%s(): Interrupt handler is installed.\n", __FUNCTION__);
+#endif
+#endif // #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+ // Check if the Ethernet chip is connected and listening
+ for (i=0; i <= ENC424J600_INIT_SPI_READY_RETRY; i++)
+ {
+ aux_8[1] = (cyg_uint8)0x12; // Test pattern
+ aux_8[0] = (cyg_uint8)0x34;
+ banked_register_operation(dpd, ENC424J600_WRITECR, ENC424J600_EUDASTL, 2, &aux_8[0]);
+ banked_register_operation(dpd, ENC424J600_READCR, ENC424J600_EUDASTL, 2, &aux_8[0]);
+ // Verify the test pattern
+ if ((0x12 == aux_8[1]) && (0x34 == aux_8[0]))
+ { // verified
+ break;
+ }
+ CYGACC_CALL_IF_DELAY_US(ENC424J600_INIT_RETRY_PERIOD_US);
+ }
+
+ if (i > ENC424J600_INIT_SPI_READY_RETRY)
+ {
+ CYG_FAIL("enc424j600 SPI is not ready!\n");
+ return false;
+ }
+
+#if ENC424J600_DEBUG & 4
+ diag_printf("enc424j600 SPI is there.\n");
+#endif
+
+ // Check if ENC424J600_CLKRDY flag is set
+ for (i=0; i <= ENC424J600_INIT_CLK_READY_RETRY; i++)
+ {
+ banked_register_operation(dpd, ENC424J600_READCR, ENC424J600_ESTATL, 2, &aux_8[0]);
+ if (0 == (aux_8[1] & ENC424J600_CLKRDY))
+ {
+ i++;
+ }
+ else
+ { // clock is ready
+ break;
+ }
+ CYGACC_CALL_IF_DELAY_US(ENC424J600_INIT_RETRY_PERIOD_US);
+ }
+ if (i > ENC424J600_INIT_CLK_READY_RETRY)
+ {
+ CYG_FAIL("enc424j600 clock is not ready!\n");
+ return false;
+ }
+
+#if ENC424J600_DEBUG & 4
+ diag_printf("enc424j600 clock is ready.\n");
+#endif
+
+ // Issue a System Reset for Ethernet chip
+ aux_8[0] = ENC424J600_ETHRST;
+ unbanked_register_operation(dpd, ENC424J600_BITFIELDSETU, ENC424J600_ECON2_U, 1, &aux_8[0]);
+ CYGACC_CALL_IF_DELAY_US(25);
+ // Check if the reset really happened
+ banked_register_operation(dpd, ENC424J600_READCR, ENC424J600_EUDASTL, 2, &aux_8[0]);
+ if ((0 != aux_8[0]) || (0 != aux_8[1]))
+ {
+ CYG_FAIL("enc424j600 is not reset!\n");
+ return false;
+ }
+#if ENC424J600_DEBUG & 4
+ diag_printf("Successful reset of the Ethernet chip.\n");
+#endif
+
+ CYGACC_CALL_IF_DELAY_US(256);
+
+#define CLOCKOUT_CODE(_freq_) CLOCKOUT_LABEL(_freq_)
+#define CLOCKOUT_LABEL(_freq_) (ENC424J600_CLKO_##_freq_)
+
+ // Set clock output frequency. External hardware may need it.
+ unbanked_register_operation(dpd, ENC424J600_READCRU, ENC424J600_ECON2_U + 1, 1, &aux_8[1]);
+ aux_8[1] &= 0xf0;
+ aux_8[1] |= (cyg_uint8)CLOCKOUT_CODE(CYGNUM_DEVS_ETH_ENC424J600_CLOCKOUT_FREQUENCY);
+#if ENC424J600_DEBUG & 4
+ diag_printf("Setting clock out, ECON2H 0x%02x\n", aux_8[1]);
+#endif
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_ECON2_U + 1, 1, &aux_8[1]);
+
+
+ // Find ESA - check possible sources in sequence and stop when
+ // one provides the ESA:
+ // RedBoot option (via provide_esa)
+ // Set by application
+ // Set by configuration option
+ // Ethernet chip (manufacture-time set)
+
+ if (NULL != dpd->provide_esa)
+ {
+ esa_configured = dpd->provide_esa(dpd);
+# if ENC424J600_DEBUG & 4
+ if (esa_configured)
+ diag_printf("Got ESA from RedBoot option\n");
+# endif
+ }
+ if (!esa_configured && dpd->hardwired_esa)
+ {
+ // ESA is already set in dpd->esa[]
+#if ENC424J600_DEBUG & 4
+ diag_printf("Got hardcoded ESA\n");
+#endif
+ esa_configured = true;
+ }
+#ifdef CYGSEM_DEVS_ETH_ENC424J600_SET_ESA
+ else
+ {
+ memcpy(dpd->esa, esa_from_cdl, ETHER_ADDR_LEN);
+ esa_configured = true;
+# if ENC424J600_DEBUG & 4
+ diag_printf("Got ESA from CDL.\n");
+# endif
+ }
+#endif // #ifdef CYGSEM_DEVS_ETH_ENC424J600_SET_ESA
+
+ if (!esa_configured)
+ {
+# if ENC424J600_DEBUG & 4
+ diag_printf("ESA is not provided. Getting it from the chip.\n");
+# endif
+ retval = read_esa_u(dpd, &(dpd->esa[0]));
+ if (0 != retval)
+ {
+ CYG_FAIL("Reading ESA from chip failed.\n");
+ return false;
+ }
+ }
+ else
+ {
+# if ENC424J600_DEBUG & 4
+ diag_printf("Setting ESA into chip. Will last till next reset.\n");
+# endif
+ retval = write_esa_u(dpd, &(dpd->esa[0]));
+ if (0 != retval)
+ {
+ CYG_FAIL("Writing ESA into chip failed.\n");
+ return false;
+ }
+ }
+
+# if ENC424J600_DEBUG & 4
+ cyg_uint8 cesa[ETHER_ADDR_LEN] = {0,0,0,0,0,0};
+ diag_printf("ESA %02x:%02x:%02x:%02x:%02x:%02x\n",
+ dpd->esa[0], dpd->esa[1], dpd->esa[2],
+ dpd->esa[3], dpd->esa[4], dpd->esa[5]);
+ retval = read_esa_u(dpd, &cesa[0]);
+ if (0 != retval)
+ {
+ diag_printf("Reading ESA from chip failed.\n");
+ }
+ diag_printf("Control reading from chip: ");
+ diag_printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
+ cesa[0], cesa[1], cesa[2],
+ cesa[3], cesa[4], cesa[5]);
+# endif
+
+ // Set receive filters
+ aux_8[0] = ENC424J600_BCEN | ENC424J600_UCEN | ENC424J600_RUNTEN | ENC424J600_CRCEN;
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_ERXFCON_U, 1, &aux_8[0]);
+
+#ifdef CYGSEM_DEVS_ETH_ENC424J600_FLOWC_OnChip
+#if ENC424J600_DEBUG & 4
+ diag_printf("eth_spi_enc424j600_init() Setting auto flow control\n");
+#endif
+ // Duration of pause
+ aux_8[0] = CYGNUM_DEVS_ETH_ENC424J600_FLOWC_PAUSE & 0xff;
+ aux_8[1] = (CYGNUM_DEVS_ETH_ENC424J600_FLOWC_PAUSE >> 8 ) & 0xff;
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_EPAUS_U, 2, &aux_8[0]);
+
+ // Thresholds for flow control
+ aux_8[0] = CYGNUM_DEVS_ETH_ENC424J600_FLOWC_LOWER_WATERMARK;
+ aux_8[1] = CYGNUM_DEVS_ETH_ENC424J600_FLOWC_UPPER_WATERMARK;
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_ERXWM_U, 2, &aux_8[0]);
+
+ aux_8[0] = ENC424J600_AUTOFC; // Enable automatic flow control
+ unbanked_register_operation(dpd, ENC424J600_BITFIELDSETU, ENC424J600_ECON2_U, 1, &aux_8[0]);
+
+#else
+ // No flow control
+ simple_operation(dpd, ENC424J600_FCDISABLE);
+#endif
+
+ // Set PHY speed and duplex
+ aux_8[0] = aux_8[1] = 0;
+#ifndef CYGNUM_DEVS_ETH_ENC424J600_NO_AUTO_NEGOTIATION
+ aux_8[1] = ENC424J600_ANEN; // Enable auto negotiation
+#else
+# if(CYGNUM_DEVS_ETH_ENC424J600_SPEED == 100)
+ aux_8[1] |= ENC424J600_SPD100;
+# endif
+# ifdef CYGSEM_DEVS_ETH_ENC424J600_FULL_DUPLEX
+ aux_8[1] |= ENC424J600_PFULDPX;
+# endif
+#endif
+#if ENC424J600_DEBUG & 4
+ diag_printf("Writing PHCON1 0x%02x%02x\n", aux_8[1], aux_8[0]);
+#endif
+ write_phy(dpd, ENC424J600_PHCON1, (aux_8[1] << 8) + aux_8[0]);
+ CYGACC_CALL_IF_DELAY_US(26);
+
+ // Compose and set PHY capabilities advertisement register
+ aux_8[1] = 0;
+ aux_8[0] = ENC424J600_IEEE802_3STD;
+#ifdef CYGNUM_DEVS_ETH_ENC424J600_FLOWC_ENC424J600_ONCHIP_AUTO_FC
+ aux_8[1] |= ENC424J600_ADPAUS_SYMM;
+#endif
+
+#ifdef CYGNUM_DEVS_ETH_ENC424J600_NO_AUTO_NEGOTIATION
+# ifdef CYGSEM_DEVS_ETH_ENC424J600_FULL_DUPLEX
+# if(CYGNUM_DEVS_ETH_ENC424J600_SPEED == 100)
+ aux_8[1] |= ENC424J600_AD100FD;
+# else
+ aux_8[0] |= ENC424J600_AD10FD;
+# endif
+# else
+# if(CYGNUM_DEVS_ETH_ENC424J600_SPEED == 100)
+ aux_8[0] |= ENC424J600_AD100;
+# else
+ aux_8[0] |= ENC424J600_AD10;
+# endif
+# endif
+#else
+ aux_8[1] |= ENC424J600_AD100FD;
+ aux_8[0] |= ENC424J600_AD100 | ENC424J600_AD10FD | ENC424J600_AD10;
+#endif
+
+ write_phy(dpd, ENC424J600_PHANA, (aux_8[1] << 8) + aux_8[0]);
+
+#if ENC424J600_DEBUG & 4
+ diag_printf("Setting CRC generation\n");
+#endif
+
+ // Set ENC424J600_TXCRCEN, PADCFG
+ unbanked_register_operation(dpd, ENC424J600_READCRU, ENC424J600_MACON2_U, 2, &aux_8[0]);
+ aux_8[0] = 0xa0; // Pad VLAN frames to 64bytes, others to 60
+ aux_8[0] |= ENC424J600_TXCRCEN; // Calculate and append CRC in transmit frames
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MACON2_U, 2, &aux_8[0]);
+
+#if ENC424J600_DEBUG & 4
+ diag_printf("Setting acceptable packet size\n");
+#endif
+ // Set acceptable packet size
+ aux_8[0] = CYGNUM_DEVS_ETH_ENC424J600_ACCEPTABLE_PACKET_SIZE & 0xff;
+ aux_8[1] = (CYGNUM_DEVS_ETH_ENC424J600_ACCEPTABLE_PACKET_SIZE >> 8) & 0xff;
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_MAMXFL_U, 2, &aux_8[0]);
+
+#if ENC424J600_DEBUG & 2
+ diag_printf("Initializing upper level driver\n");
+#endif
+ (sc->funs->eth_drv->init)(sc, dpd->esa);
+
+#if ENC424J600_DEBUG & 4
+ diag_printf("End of _init().\n");
+#endif
+
+ return true;
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+enc424j600_spi_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ cyg_uint8 aux[2];
+ cyg_uint8 pkcnt;
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("enc424j600_spi_start() begin.\n");
+#endif
+ // Disable packet reception
+ simple_operation(dpd, ENC424J600_DISABLERX);
+
+ // Enable interrupts in Ethernet chip
+ simple_operation(dpd, ENC424J600_CLREIE); // First disable interrupts globally
+
+ aux[0] = ENC424J600_PKTIE | ENC424J600_TXIE | ENC424J600_TXABTIE | ENC424J600_RXABTIE | ENC424J600_PCFULIE; // then set the desired ones
+ aux[1] = ENC424J600_LINKIE;
+ unbanked_register_operation(dpd, ENC424J600_BITFIELDSETU, ENC424J600_EIE_U, 2, &aux[0]);
+
+ // Are there any packets left in receive buffer?
+ banked_register_operation(dpd, ENC424J600_READCR, ENC424J600_ESTATL, 1, &pkcnt);
+
+ while (0 < pkcnt--)
+ {
+ simple_operation(dpd, ENC424J600_SETPKTDEC); // Decrement on-chip packet counter
+ } // This clears ENC424J600_PKTIF, if set.
+
+ // Set the chip's receive buffer start address and buffer head.
+ aux[0] = ENC424J600_RXBUF_START & 0xfe; // make it even, just in case it's not
+ aux[1] = (ENC424J600_RXBUF_START >> 8) & 0x7f; // clear the MSB
+#if ENC424J600_DEBUG & 8
+ diag_printf("Setting receive buffer start address, ERXST 0x%02x%02x.\n",
+ aux[1], aux[0]);
+#endif
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_ERXST_U, 2, &aux[0]);
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_ERXHEAD_U, 2, &aux[0]);
+
+ // Next packet will be received at the buffer start address
+ *(cyg_uint8 *) & dpd->NextPacketPointer = ENC424J600_RXBUF_START & 0xff;
+ *(((cyg_uint8 *)&dpd->NextPacketPointer) + 1) = (ENC424J600_RXBUF_START >> 8 ) & 0xff;
+
+ // Set receive buffer tail
+ aux[1] = 0x5f; // just bellow the end of on-chip SRAM
+ aux[0] = 0xfe;
+#if ENC424J600_DEBUG & 8
+ diag_printf("Setting receive buffer tail, ERXTAIL 0x%02x%02x.\n",
+ aux[1], aux[0]);
+#endif
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_ERXTAIL_U, 2, &aux[0]);
+
+ // Abort any pending transmission
+ aux[0] = ENC424J600_TXRTS;
+ banked_register_operation(dpd, ENC424J600_BITFIELDCLEAR, ENC424J600_ECON1L, 1, &aux[0]);
+ dpd->txbusy = false;
+
+ // Set start of transmit buffer
+ aux[0] = ENC424J600_TXBUF_START & 0xff;
+ aux[1] = (ENC424J600_TXBUF_START >> 8 ) & 0xff;
+#if ENC424J600_DEBUG & 8
+ diag_printf("Writing ETXST 0x%02x%02x.\n", aux[1], aux[0]);
+#endif
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_ETXST_U, 2, &aux[0]);
+
+ // Clear any remaining interrupt flags
+ aux[0] = ENC424J600_TXIF | ENC424J600_TXABTIF | ENC424J600_RXABTIF | ENC424J600_PCFULIF;
+ aux[1] = ENC424J600_LINKIF;
+ banked_register_operation(dpd, ENC424J600_BITFIELDCLEAR, ENC424J600_EIRL, 2, &aux[0]);
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ simple_operation(dpd, ENC424J600_SETEIE); // Enable interrupts
+#endif
+
+ // Enable packet reception
+ simple_operation(dpd, ENC424J600_ENABLERX);
+
+ banked_register_operation(dpd, ENC424J600_READCR, ENC424J600_ESTATL, 2, &aux[0]);
+ if (0 != (aux[1] & ENC424J600_PHYLNK))
+ {
+ if (ENC424J600_LINK_ON != dpd->link_status)
+ {
+ dpd->link_status = ENC424J600_LINK_ON;
+ set_MAC(dpd, aux[1]);
+ }
+ }
+ else
+ {
+ dpd->link_status = ENC424J600_LINK_OFF;
+ }
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("enc424j600_spi_start() end.\n");
+#endif
+
+ return;
+}
+
+// Stop receiving and sending packets
+static void
+enc424j600_spi_stop(struct eth_drv_sc *sc)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ cyg_uint8 aux[2];
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("enc424j600_spi_stop() begin.\n");
+#endif
+ // Disable packet reception
+ simple_operation(dpd, ENC424J600_DISABLERX);
+
+ // Disable interrupts in Ethernet chip
+ aux[1] = ENC424J600_INTIE;
+ aux[0] = ENC424J600_PKTIE | ENC424J600_TXIE | ENC424J600_TXABTIE | ENC424J600_RXABTIE | ENC424J600_PCFULIE;
+ unbanked_register_operation(dpd, ENC424J600_BITFIELDCLEARU, ENC424J600_EIE_U, 2, &aux[0]);
+
+ return;
+}
+
+static void
+enc424j600_spi_deliver(struct eth_drv_sc *sc)
+{
+
+ enc424j600_spi_poll(sc);
+
+ return;
+}
+
+// Special control operations
+static int
+enc424j600_spi_control(struct eth_drv_sc *sc, unsigned long key, void *data,
+ int data_length)
+{
+ enc424j600_priv_data_t *dpd;
+ unsigned char *esa;
+ struct eth_drv_mc_list *mc_list;
+ cyg_uint8 aux;
+
+ if ((NULL == sc) || (NULL == data))
+ {
+#if ENC424J600_DEBUG & 1
+ diag_printf("Wrong parameter(s) for enc424j600_spi_control().\n");
+#endif
+ return -1;
+ }
+ dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ switch (key)
+ {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ if (ETHER_ADDR_LEN != data_length)
+ {
+#if ENC424J600_DEBUG & 1
+ diag_printf("Wrong data length for ETH_DRV_SET_MAC_ADDRESS.\n");
+#endif
+ return -1;
+ }
+ esa = (unsigned char *)data;
+ // Write ESA in the chip. Will last till the next reset.
+ return write_esa_u(dpd, esa);
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ if (ETHER_ADDR_LEN > data_length)
+ {
+#if ENC424J600_DEBUG & 1
+ diag_printf("Too small data length for ETH_DRV_GET_MAC_ADDRESS.\n");
+#endif
+ return -1;
+ }
+ esa = (unsigned char *)data;
+ // Get ESA from the chip
+ return read_esa_u(dpd, esa);
+#endif
+
+ case ETH_DRV_SET_MC_LIST:
+ case ETH_DRV_SET_MC_ALL:
+ // Note: this code always affects all multicast addresses if any
+ // are desired.
+ mc_list = data;
+ simple_operation(dpd, ENC424J600_DISABLERX);
+ aux = ENC424J600_MCEN;
+ if (0 == mc_list->len)
+ { // Disable reception of multicast packets
+ unbanked_register_operation(dpd,
+ ENC424J600_BITFIELDCLEARU, ENC424J600_ERXFCON_U, 1, &aux);
+ }
+ else
+ { // Enable reception of multicast packets
+ unbanked_register_operation(dpd,
+ ENC424J600_BITFIELDSETU, ENC424J600_ERXFCON_U, 1, &aux);
+ }
+ simple_operation(dpd, ENC424J600_ENABLERX);
+
+ return 0;
+
+ default:
+#if ENC424J600_DEBUG & 1
+ diag_printf("Unsupported key %lx for enc424j600_spi_control().\n", key);
+#endif
+ return -1;
+ }
+}
+
+// Continue transfer from chip's buffer where the enc424j600_spi_RXevent() stopped.
+// Take one packet.
+static void
+enc424j600_spi_recv(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list,
+ int chunks)
+{
+ int chunk;
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ cyg_uint16 rbuf_tail;
+ cyg_uint8 * aux_p;
+ cyg_uint8 aux[2];
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("enc424j600_spi_recv()...\n");
+#endif
+
+ for(chunk = 0; chunk < chunks; chunk++)
+ {
+ read_from_rx_buffer(dpd, (*sg_list).len, (cyg_uint8 *)(*sg_list).buf);
+ sg_list++;
+ }
+ aux_p = (cyg_uint8 *) & dpd->NextPacketPointer;
+ rbuf_tail = *aux_p + *(aux_p+1) * (cyg_uint16)256 ;
+ rbuf_tail -= 2;
+ if (rbuf_tail == ENC424J600_RXBUF_START)
+ { // Wrap over
+ rbuf_tail = 0x5ffe;
+ }
+ aux[0] = rbuf_tail & 0xff;
+ aux[1] = (rbuf_tail >> 8) & 0xff;
+#if ENC424J600_DEBUG & 8
+ diag_printf("Setting receive buffer tail, ERXTAIL 0x%02x%02x.\n",
+ aux[1], aux[0]);
+#endif
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_ERXTAIL_U, 2, &aux[0]);
+
+ simple_operation(dpd, ENC424J600_SETPKTDEC); // Decrement packet count. If zeroed,
+ // ENC424J600_PKTIF interrupt flag will be reset.
+
+ return;
+}
+
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+static int
+enc424j600_spi_can_send(struct eth_drv_sc *sc)
+{
+ if (((enc424j600_priv_data_t *)sc->driver_private)->txbusy)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+// This routine is called to send data to the hardware.
+static void
+enc424j600_spi_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list,
+ int sg_len,
+ int total,
+ unsigned long key)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ int block;
+ cyg_uint8 aux[2];
+ cyg_uint8 opcode = ENC424J600_WGPDATA;
+
+ if (0 >= sg_len) return;
+
+ // Check if there is enough room in transmit buffer
+ if (total > ENC424J600_RXBUF_START - ENC424J600_TXBUF_START)
+ {
+ sc->funs->eth_drv->tx_done(sc, (CYG_ADDRESS)key, 0);
+#if ENC424J600_DEBUG & 1
+ diag_printf("enc424j600_spi_send(): Packet to send is too large (%d bytes).\n",
+ total);
+#endif
+ return;
+ }
+
+ dpd->txbusy = true;
+ dpd->txkey = key;
+
+ aux[0] = ENC424J600_TXBUF_START & 0xff;
+ aux[1] = (((cyg_uint8)ENC424J600_TXBUF_START) >> 8) & 0xff;
+ set_pointer(dpd, ENC424J600_GPBWRPT, (aux[1] << 8) + aux[0]);
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("Starting SPI transaction to send a packet.\n");
+#endif
+ cyg_spi_transaction_begin(dpd->spi_service_device);
+ cyg_spi_transaction_transfer(dpd->spi_service_device,
+ SPI_POLLING,
+ 1,
+ & opcode,
+ NULL,
+ ENC424J600_DONT_DROP_CS);
+
+ for (block = 0; block < sg_len; block++)
+ {
+ cyg_spi_transaction_transfer(dpd->spi_service_device,
+ SPI_POLLING,
+ sg_list->len,
+ (cyg_uint8 *)sg_list->buf,
+ NULL,
+ (block == sg_len) ? ENC424J600_DO_DROP_CS : ENC424J600_DONT_DROP_CS );
+ sg_list++;
+ }
+ cyg_spi_transaction_end(dpd->spi_service_device);
+
+ aux[0] = total & 0xff;
+ aux[1] = (total >> 8 ) & 0xff;
+#if ENC424J600_DEBUG & 8
+ diag_printf("Writing ETXLEN 0x%02x%02x.\n", aux[1], aux[0]);
+#endif
+ unbanked_register_operation(dpd, ENC424J600_WRITECRU, ENC424J600_ETXLEN_U, 2, &aux[0]);
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("Setting request to send.\n");
+#endif
+ simple_operation(dpd, ENC424J600_SETTXRTS);
+
+ sc->funs->eth_drv->tx_done(sc, (CYG_ADDRESS)key, 0);
+
+ return;
+}
+
+static void
+enc424j600_spi_poll(struct eth_drv_sc *sc)
+{
+ enc424j600_priv_data_t *dpd = (enc424j600_priv_data_t *)sc->driver_private;
+ cyg_uint8 aux[2];
+ cyg_uint16 iflags;
+
+#if ENC424J600_DEBUG & 8
+ diag_printf("enc424j600_spi_poll(%x)...\n", (cyg_uint32)sc);
+#endif
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ // Globally disable interrupt source in Ethernet chip
+ simple_operation(dpd, ENC424J600_CLREIE);
+#endif
+ do
+ {
+ // Figure out what caused the interrupt
+ banked_register_operation(dpd, ENC424J600_READCR, ENC424J600_EIRL, 2, &aux[0]);
+ aux[1] &= ENC424J600_LINKIF;
+ aux[0] &= (ENC424J600_PKTIF | ENC424J600_TXIF | ENC424J600_TXABTIF | ENC424J600_RXABTIF | ENC424J600_PCFULIF);
+ iflags = aux[0] + (cyg_uint16)256 * aux[1];
+ if (0 != (aux[0] & ENC424J600_PKTIF))
+ { // Packets are pending in chip's receive buffer
+ enc424j600_spi_RXevent(sc);
+ }
+ if ( 0 != (aux[1] & ENC424J600_LINKIF))
+ { // Link status changed
+ enc424j600_spi_LINKevent(sc);
+ }
+ if (0 != (aux[0] & ENC424J600_TXIF))
+ { // Packet has been sent
+ enc424j600_spi_TXevent(sc);
+ }
+ if (0 != (aux[0] & ENC424J600_TXABTIF))
+ { // Packet send has been aborted
+ enc424j600_spi_TXABTevent(sc);
+ }
+ if ( 0 != (aux[0] & ENC424J600_PCFULIF))
+ { // Packet counter overflow
+ enc424j600_spi_PCFULevent(sc);
+ }
+ if ( 0 != (aux[0] & ENC424J600_RXABTIF))
+ { // Incoming packet rejected due to buffer or counter overflow
+ enc424j600_spi_RXABTevent(sc);
+ }
+ } while(0 != iflags);
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_unmask(CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_VECTOR);
+
+ // Globally enable interrupt source in Ethernet chip
+ simple_operation(dpd, ENC424J600_SETEIE);
+#endif
+
+ return;
+}
+
+static int
+enc424j600_spi_int_vector(struct eth_drv_sc *sc)
+{
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ return CYGNUM_DEVS_ETH_ENC424J600_INTERRUPT_VECTOR;
+#else
+ return 0;
+#endif
+}
+
+// - End of higher level interface -----------------------------
+
+// End of enc424j600_spi.c
diff --git a/ecos/packages/devs/eth/microchip/enc424j600/current/src/enc424j600_spi.h b/ecos/packages/devs/eth/microchip/enc424j600/current/src/enc424j600_spi.h
new file mode 100644
index 0000000..c766f23
--- /dev/null
+++ b/ecos/packages/devs/eth/microchip/enc424j600/current/src/enc424j600_spi.h
@@ -0,0 +1,344 @@
+#ifndef CYGONCE_DEVS_ETH_ENC424J600_SPI_H_
+#define CYGONCE_DEVS_ETH_ENC424J600_SPI_H_
+//==========================================================================
+//
+// enc424j600_spi.h
+//
+// Microchip enc424j600 Ethernet chip
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Stanislevik
+// Contributors:
+// Date: 2010-11-23
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// Addresses of enc424j600 registers, banked access
+// Banks 0, 1, 2 & 3
+#define ENC424J600_EUDASTL (0X16)
+#define ENC424J600_EUDASTH (0X17)
+#define ENC424J600_EUDANDL (0X18)
+#define ENC424J600_EUDANDH (0X19)
+#define ENC424J600_ESTATL (0x1a)
+#define ENC424J600_ESTATH (0x1b)
+#define ENC424J600_EIRL (0x1c)
+#define ENC424J600_EIRH (0x1d)
+#define ENC424J600_ECON1L (0x1e)
+#define ENC424J600_ECON1H (0x1f)
+
+// Only bank 0
+#define ENC424J600_ETXSTL (0x00)
+#define ENC424J600_ETXSTH (0x01)
+#define ENC424J600_ETXLENL (0x02)
+#define ENC424J600_ETXLENH (0x03)
+#define ENC424J600_ERXSTL (0x04)
+#define ENC424J600_ERXSTH (0x05)
+#define ENC424J600_ERXTAILL (0x06)
+#define ENC424J600_ERXTAILH (0x07)
+#define ENC424J600_ERXHEADL (0x08)
+#define ENC424J600_ERXHEADH (0x09)
+
+// Only bank 1
+#define ENC424J600_ERXFCONL (0x14)
+#define ENC424J600_ERXFCONH (0x15)
+
+// Only bank 2
+#define ENC424J600_MACON1L (0x00)
+#define ENC424J600_MACON1H (0x01)
+#define ENC424J600_MACON2L (0x02)
+#define ENC424J600_MACON2H (0x03)
+#define ENC424J600_MABBIPGL (0x04)
+#define ENC424J600_MABBIPGH (0x05)
+#define ENC424J600_MAMXFLL (0x0a)
+#define ENC424J600_MAMXFLH (0x0b)
+#define ENC424J600_MICMDL (0x12)
+#define ENC424J600_MICMDH (0x13)
+#define ENC424J600_MIREGADRL (0x14)
+#define ENC424J600_MIREGADRH (0x15)
+#define ENC424J600_EIRL (0x1c)
+#define ENC424J600_EIRH (0x1d)
+#define ENC424J600_ECON1L (0x1e)
+#define ENC424J600_ECON1H (0x1f)
+
+// Only bank 3
+#define ENC424J600_MAADR3L (0x00)
+#define ENC424J600_MIWRL (0x06)
+#define ENC424J600_MIWRH (0x07)
+#define ENC424J600_MIRDL (0x08)
+#define ENC424J600_MIRDH (0x09)
+#define ENC424J600_MISTATL (0x0a)
+#define ENC424J600_MISTATH (0x0b)
+#define ENC424J600_EPAUSL (0x0c)
+#define ENC424J600_EPAUSH (0x0d)
+#define ENC424J600_ECON2L (0x0e)
+#define ENC424J600_ECON2H (0x0f)
+#define ENC424J600_ERXWML (0x10)
+#define ENC424J600_ERXWMH (0x11)
+#define ENC424J600_EIEL (0x12)
+#define ENC424J600_EIEH (0x13)
+
+// Addresses of enc424j600 registers, unbanked access
+// Bank 0
+#define ENC424J600_BANK0_Of (0)
+#define ENC424J600_ETXST_U (ENC424J600_ETXSTL + ENC424J600_BANK0_Of)
+#define ENC424J600_ETXLEN_U (ENC424J600_ETXLENL + ENC424J600_BANK0_Of)
+#define ENC424J600_EUDAST_U (ENC424J600_EUDASTL + ENC424J600_BANK0_Of)
+#define ENC424J600_EUDAND_U (ENC424J600_EUDANDL + ENC424J600_BANK0_Of)
+#define ENC424J600_ESTAT_U (ENC424J600_ESTATL + ENC424J600_BANK0_Of)
+#define ENC424J600_ERXST_U (ENC424J600_ERXSTL + ENC424J600_BANK0_Of)
+#define ENC424J600_ERXTAIL_U (ENC424J600_ERXTAILL + ENC424J600_BANK0_Of)
+#define ENC424J600_ERXHEAD_U (ENC424J600_ERXHEADL + ENC424J600_BANK0_Of)
+
+// Bank 1
+#define ENC424J600_BANK1_Of (0x20)
+#define ENC424J600_ERXFCON_U ( ENC424J600_ERXFCONL + ENC424J600_BANK1_Of)
+
+// Bank 2
+#define ENC424J600_BANK2_Of (0x40)
+#define ENC424J600_MACON1_U (ENC424J600_MACON1L + ENC424J600_BANK2_Of)
+#define ENC424J600_MACON2_U (ENC424J600_MACON2L + ENC424J600_BANK2_Of)
+#define ENC424J600_MABBIPG_U (ENC424J600_MABBIPGL + ENC424J600_BANK2_Of)
+#define ENC424J600_MAMXFL_U (ENC424J600_MAMXFLL + ENC424J600_BANK2_Of)
+#define ENC424J600_MICMD_U (ENC424J600_MICMDL + ENC424J600_BANK2_Of)
+#define ENC424J600_MIREGADR_U (ENC424J600_MIREGADRL + ENC424J600_BANK2_Of)
+#define ENC424J600_EIR_U (ENC424J600_EIRL + ENC424J600_BANK2_Of)
+#define ENC424J600_ECON1_U (ENC424J600_ECON1L + ENC424J600_BANK2_Of)
+
+// Bank 3
+#define ENC424J600_BANK3_Of (0x60)
+#define ENC424J600_MAADR3_U (ENC424J600_MAADR3L + ENC424J600_BANK3_Of)
+#define ENC424J600_MIWR_U (ENC424J600_MIWRL + ENC424J600_BANK3_Of)
+#define ENC424J600_MIRD_U (ENC424J600_MIRDL + ENC424J600_BANK3_Of)
+#define ENC424J600_MISTAT_U (ENC424J600_MISTATL + ENC424J600_BANK3_Of)
+#define ENC424J600_EPAUS_U (ENC424J600_EPAUSL + ENC424J600_BANK3_Of)
+#define ENC424J600_ECON2_U (ENC424J600_ECON2L + ENC424J600_BANK3_Of)
+#define ENC424J600_ERXWM_U (ENC424J600_ERXWML + ENC424J600_BANK3_Of)
+#define ENC424J600_EIE_U (ENC424J600_EIEL + ENC424J600_BANK3_Of)
+
+// Addresses of enc424j600 PHY registers, special access
+
+enum enc424j600_pr_address_e
+{
+ ENC424J600_PHCON1 = 0,
+ ENC424J600_PHSTAT1 = 1,
+ ENC424J600_PHANA = 4,
+ ENC424J600_PHANLPA = 5,
+ ENC424J600_PHANE = 6,
+ ENC424J600_PHCON2 = 0x11,
+ ENC424J600_PHSTST2 = 0x1b,
+ ENC424J600_PHSTAT3 = 0x1f
+};
+
+//---------- end of register addresses --------------------------------------------------
+
+//---------- definitions of bits in control registers -----------------------------------
+
+// Interrupt flags (EIR register) higher byte
+#define ENC424J600_MODEXIF (0x40)
+#define ENC424J600_HASHIF (0x20)
+#define ENC424J600_AESIF (0x10)
+#define ENC424J600_LINKIF (0x08) // PHY status has changed
+
+// Interrupt flags (EIR register) lower byte
+#define ENC424J600_PKTIF (0x40) // RX packet(s) pending
+#define ENC424J600_DMAIF (0x20)
+#define ENC424J600_TXIF (0x08) // Transmit done
+#define ENC424J600_TXABTIF (0x04) // Packet transmission aborted due to an error
+#define ENC424J600_RXABTIF (0x02) // RX packet rejected due to lack of space / to many
+ // pending packets
+#define ENC424J600_PCFULIF (0x01) // To many pending packets
+
+// Interrupt enable bits (EIE register) higher byte
+#define ENC424J600_INTIE (0x80) // Global interrupt enable
+#define ENC424J600_MODEXIE (0x40)
+#define ENC424J600_HASHIE (0x20)
+#define ENC424J600_AESIE (0x10)
+#define ENC424J600_LINKIE (0x08) // PHY status has changed
+
+// Interrupt enable bits (EIE register) lower byte
+#define ENC424J600_PKTIE (0x40) // RX packet(s) pending
+#define ENC424J600_DMAIE (0x20)
+#define ENC424J600_TXIE (0x08) // Transmit done
+#define ENC424J600_TXABTIE (0x04) // Packet transmission aborted due to an error
+#define ENC424J600_RXABTIE (0x02) // RX packet rejected due to lack of space / too many
+ // pending packets
+#define ENC424J600_PCFULIE (0x01) // Too many pending packets
+
+// MICMD
+#define ENC424J600_MIIRD (0x01)
+#define ENC424J600_MIISCAN (0x02)
+
+// MISTAT
+#define ENC424J600_MISTAT_BUSY (0x01)
+#define ENC424J600_MISTAT_SCAN (0x02)
+#define ENC424J600_MISTAT_NVALID (0x04)
+
+//ESTAT upper byte
+#define ENC424J600_PHYLNK (0x01)
+#define ENC424J600_PHYDPX (0x04)
+#define ENC424J600_CLKRDY (0x10)
+#define ENC424J600_RXBUSY (0x20)
+#define ENC424J600_FCIDLE (0x40)
+#define ENC424J600_INT (0x80)
+
+// ECON1 lower byte
+#define ENC424J600_TXRTS (0x02)
+
+//ECON2 upper byte
+#define ENC424J600_STRCH (0x40)
+#define ENC424J600_ETHEN (0x80)
+
+// ECON2 lower byte
+#define ENC424J600_ETHRST (0x10)
+#define ENC424J600_AUTOFC (0x80)
+
+// MACON2 upper byte
+#define ENC424J600_NOBKOFF (0x10)
+#define ENC424J600_BPEN (0x20)
+#define ENC424J600_DEFER (0x40)
+
+// MACON2 lower byte
+#define ENC424J600_FULDPX (0x01)
+#define ENC424J600_HFRMEN (0x04)
+#define ENC424J600_PHDREN (0x08)
+#define ENC424J600_TXCRCEN (0x10)
+
+// ERXFCON lower byte
+#define ENC424J600_BCEN (0x01) // accept broadcast packets
+#define ENC424J600_MCEN (0x02) // accept multicast packets
+#define ENC424J600_UCEN (0x08) // accept packets destined for local MAC address
+#define ENC424J600_RUNTEN (0x10) // discard runt packets
+#define ENC424J600_CRCEN (0x40) // discard packets with invalid CRC
+
+// PHCON1 upper byte
+#define ENC424J600_PFULDPX (0x01) // full duplex
+#define ENC424J600_RENEG (0x02) // restart negotiation
+#define ENC424J600_ANEN (0x10) // auto negotiation enable
+#define ENC424J600_SPD100 (0x20) // 100Mb/s
+
+// PHANA upper byte
+#define ENC424J600_ADPAUS_BOTH (0x0c) // both symmetric and asymmetric flow control
+#define ENC424J600_ADPAUS_ASYM (0x08) // asymmetric flow control towards link partner
+#define ENC424J600_ADPAUS_SYMM (0x04) // symmetric flow control
+#define ENC424J600_ADPAUS_NONE (0x00) // no flow control
+#define ENC424J600_AD100FD (0x01)
+
+// PHANA lower byte
+#define ENC424J600_AD100 (0x80)
+#define ENC424J600_AD10FD (0x40)
+#define ENC424J600_AD10 (0x20)
+#define ENC424J600_IEEE802_3STD (0x01) // IEEE Standard Selector Field bits
+
+//---------- end of definitions of bits in control registers -------------------------
+
+// enc424j600 SPI instructions opcodes
+
+// Single byte instructions
+enum enc424j600_spi_opcode_1_e
+{
+ ENC424J600_SETETHRST = 0xca, // Issue System Reset
+ ENC424J600_SETPKTDEC = 0xcc, // Decrement packet counter
+ ENC424J600_SETTXRTS = 0xd4, // Send a packet
+ ENC424J600_FCDISABLE = 0xe0, // Disable flow control
+ ENC424J600_FCSINGLE = 0xe2, // Send a single pause frame
+ ENC424J600_FCMULTIPLE = 0xe4, // Keep sending pause frames
+ ENC424J600_FCCLEAR = 0xe6, // Send the final pause frame
+ ENC424J600_ENABLERX = 0xe8, // Enable receiver
+ ENC424J600_DISABLERX = 0xea, // Disable receiver
+ ENC424J600_SETEIE = 0xec, // Enable interrupts
+ ENC424J600_CLREIE = 0xee, // Disable interrupts
+};
+
+// Pointer definitions for 3-byte instructions
+enum enc424j600_spi_bufferp_e
+{
+ ENC424J600_GPBRDPT = 0x60, // General purpose buffer read pointer
+ ENC424J600_RXRDPT = 0x64, // Receive buffer read pointer
+ ENC424J600_UDARDPT = 0x68, // User-defined area read pointer
+ ENC424J600_GPBWRPT = 0x6c, // General purpose buffer write pointer
+ ENC424J600_RXWRPT = 0x70, // Receive buffer write pointer
+ ENC424J600_UDAWRPT = 0x74, // User-defined area write pointer
+
+};
+
+enum enc424j600_spi_opcode_3_e
+{
+ ENC424J600_WRITE3 = 0x00, // Pointer writing
+ ENC424J600_READ3 = 0x02 // Pointer reading
+
+};
+
+// N-byte unbanked SFR instructions
+enum enc424j600_spi_opcode_u_e
+{
+ ENC424J600_READCRU = 0x20, // Read Control Register, Unbanked
+ ENC424J600_WRITECRU = 0x22, // Write Control Register, Unbanked
+ ENC424J600_BITFIELDSETU = 0x24, // Bit Field Set, Unbanked
+ ENC424J600_BITFIELDCLEARU = 0x26 // Bit Field Clear, Unbanked
+};
+
+// N-byte banked SFR instructions
+enum enc424j600_spi_opcode_e
+{
+ ENC424J600_READCR = 0x00, // Read Control Register, Banked
+ ENC424J600_WRITECR = 0x40, // Write Control Register, Banked
+ ENC424J600_BITFIELDSET = 0x80, // Bit Field Set, Banked
+ ENC424J600_BITFIELDCLEAR = 0xa0 // Bit Field Clear, Banked
+};
+
+// N-byte SRAM instructions
+enum enc424j600_spi_opcode_sram_e
+{
+ ENC424J600_RGPDATA = 0x28, // Read from General Purpose buffer
+ ENC424J600_WGPDATA = 0x2a, // Write to General Purpose buffer
+ ENC424J600_RRXDATA = 0x2c, // Read from Rx buffer
+ ENC424J600_WRXDATA = 0x2e // Write to Rx buffer
+};
+
+#define ENC424J600_ETH_INTERRUPT_LEVEL_HIGH (true)
+#define ENC424J600_ETH_INTERRUPT_LEVEL_LOW (false)
+#define ENC424J600_ETH_INTERRUPT_EDGE_RISING (true)
+#define ENC424J600_ETH_INTERRUPT_EDGE_FALLING (false)
+
+//#define ETH_DRV_GET_MAC_ADDRESS (0x1100)
+
+#endif /* ifndef CYGONCE_DEVS_ETH_ENC424J600_SPI_H_ */
+// End of enc424j600_spi.h
diff --git a/ecos/packages/devs/eth/microchip/enc424j600/current/tests/netconn_test_server.c b/ecos/packages/devs/eth/microchip/enc424j600/current/tests/netconn_test_server.c
new file mode 100644
index 0000000..55a62c2
--- /dev/null
+++ b/ecos/packages/devs/eth/microchip/enc424j600/current/tests/netconn_test_server.c
@@ -0,0 +1,354 @@
+//==========================================================================
+//
+// netconn_test_server.c
+//
+// Utility to test enc424j600 Ethernet driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Stanislevik
+// Contributors:
+// Date: 2010-08-04
+// Purpose:
+// Description: Utility to test enc424j600 (or any other) Ethernet driver
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/testcase.h> // Test macros
+#include <cyg/infra/cyg_ass.h> // Assertion macros
+#include <cyg/infra/diag.h> // Diagnostic output
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <cyg/error/codes.h>
+#include <cyg/io/io.h>
+
+#include <cyg/io/spi.h>
+
+#include <cyg/io/eth/netdev.h>
+#include <network.h>
+
+#include <lwip/netif.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#define PORTNUM 2000
+
+// Threads' data structures
+typedef struct thread_s
+{
+ cyg_uint8 stack [CYGNUM_HAL_STACK_SIZE_TYPICAL];
+ cyg_thread data;
+ cyg_handle_t handle;
+} thread_s_t;
+
+typedef struct
+{
+ struct netconn * connection_p;
+ cyg_uint32 id;
+} server_argument_t;
+
+//#define INIT_PRIORITY 5
+#define INIT_PRIORITY 12
+#define LISTENER_PRIORITY INIT_PRIORITY+1
+#define SERVER_PRIORITY LISTENER_PRIORITY-1
+
+// Init thread
+
+thread_s_t init_thread;
+
+void run_init(void)
+{
+ diag_printf("i: Initializing network stack...\n");
+ cyg_lwip_sequential_init();
+}
+
+// Server thread
+
+void server(cyg_addrword_t arg_p)
+{
+ struct netconn *newconn = NULL;
+ struct netbuf *income_buffer = NULL;
+ struct ip_addr from_addr;
+ struct ip_addr my_addr;
+ cyg_uint16 from_port = 0;
+ cyg_uint16 my_port = 0;
+ cyg_uint8 *addr_byte_p = NULL;
+ cyg_uint16 total_len;
+ cyg_uint8 * data_buf = NULL;
+ cyg_int32 retval;
+ cyg_uint32 id;
+ cyg_uint32 csum;
+
+ newconn = ((server_argument_t *)arg_p) -> connection_p;
+ id = ((server_argument_t *)arg_p) -> id;
+
+ retval = netconn_addr(newconn, &my_addr, &my_port);
+ if(0 != retval)
+ {
+ diag_printf("%u: netconn_addr() return %d. Exiting.\n", id, retval);
+ netconn_delete(newconn);
+ cyg_thread_exit();
+ }
+
+ retval = netconn_peer(newconn, &from_addr, &from_port);
+ if(0 != retval)
+ {
+ diag_printf("%u: netconn_peer() return %d. Exiting.\n", id, retval);
+ netconn_delete(newconn);
+ cyg_thread_exit();
+ }
+
+ addr_byte_p = (cyg_uint8 *) & from_addr.addr;
+ diag_printf("%u: Connected to remote peer %u.%u.%u.%u port %u, at my port %u\n", id,
+ *addr_byte_p, *(addr_byte_p+1), *(addr_byte_p+2), *(addr_byte_p+3),
+ from_port, my_port);
+ diag_printf("newconn %x\n", (unsigned)newconn);
+
+ csum =0;
+
+ while((income_buffer = netconn_recv(newconn)) != NULL)
+ {
+ total_len = netbuf_len(income_buffer);
+ if(0 != total_len)
+ {
+ data_buf = malloc(total_len);
+ if(NULL == data_buf)
+ {
+ diag_printf("%u: Can not allocate %u bytes. Exiting.\n", id, total_len);
+ netconn_delete(newconn);
+ cyg_thread_exit();
+ }
+
+ cyg_uint8 *local_data_p = data_buf;
+ do
+ {
+ cyg_uint8 *in_data_p;
+ cyg_uint16 len;
+ int i;
+
+ netbuf_data(income_buffer, (void **)&in_data_p, &len);
+ for(i=0; i<len; i++)
+ {
+ csum += *local_data_p++ = *in_data_p++;
+ }
+ } while(netbuf_next(income_buffer) >= 0);
+ diag_printf("\nReceived %u bytes\n", total_len);
+
+ free(data_buf);
+ }
+ netbuf_delete(income_buffer);
+ }
+
+ diag_printf("Checksum %08x\n", csum);
+
+ retval = netconn_close(newconn);
+ if( 0 != retval)
+ {
+ diag_printf("%u: netconn_close(%x) return %d.\n", id, (unsigned)newconn, retval);
+ }
+
+ retval = netconn_delete(newconn);
+ if( 0 != retval)
+ {
+ diag_printf("%u: netconn_delete(%x) return %d. Exiting.\n", id, (unsigned)newconn, retval);
+ cyg_thread_exit();
+ }
+
+ diag_printf("%u: TCP connection closed.\n", id);
+
+}
+
+// Listener thread
+
+thread_s_t listener_thread;
+
+void listener(void)
+{
+ struct netconn *conn = NULL;
+ struct netconn *newconn = NULL;
+ struct netif *mynetif = NULL;
+ server_argument_t server_launch_args_s;
+ cyg_uint32 server_id = 0;
+ thread_s_t * new_thread_data = NULL;
+ char server_name[20];
+ cyg_int32 retval;
+
+ // This large malloc is just for testing
+// new_thread_data = malloc(150 * sizeof(thread_s_t));
+
+ cyg_thread_delay(500); // Sleep over the initialization of network
+
+ mynetif = netif_find("et0");
+ diag_printf("l: netif_find(et0) return %x\n", (unsigned int)mynetif);
+ retval = netif_is_up(mynetif);
+ diag_printf("l: netif_is_up() return %u\n", retval);
+
+ diag_printf("l: Creating TCP connection...\n");
+ conn = netconn_new(NETCONN_TCP);
+ if (NULL == conn)
+ {
+ diag_printf("l: netconn_new() return NULL. Exiting.\n");
+ cyg_thread_exit();
+ }
+ diag_printf("l: Binding to port %d...\n", PORTNUM);
+ retval = netconn_bind(conn, NULL, PORTNUM);
+ if (0 != retval)
+ {
+ diag_printf("l: netconn_bind() return %d. Exiting.\n", retval);
+ cyg_thread_exit();
+ }
+
+ diag_printf("l: Setting up for listening...\n");
+ retval = netconn_listen(conn);
+ if( 0!= retval)
+ {
+ diag_printf("l: netconn_listen() return %d. Exiting.\n", retval);
+ cyg_thread_exit();
+ }
+
+ do
+ {
+ diag_printf("l: Waiting for a new connection...\n");
+ newconn = netconn_accept(conn);
+ if (NULL == newconn)
+ {
+ diag_printf("l: netconn_accept() return NULL. Exiting.\n");
+ cyg_thread_exit();
+ }
+
+ // It's time to start a server thread
+
+ new_thread_data = malloc(sizeof(thread_s_t));
+ if(NULL == new_thread_data)
+ {
+ diag_printf("l: Can't allocate memory for another server.\n");
+ netconn_close(newconn);
+ netconn_delete(newconn);
+ continue;
+ }
+ /*
+ * Thread data is never freed after the thread exit.
+ * After a number of connections made, it will be impossible to
+ * allocate memory for additional servers.
+ */
+
+ server_launch_args_s.connection_p = newconn;
+ server_launch_args_s.id = ++server_id;
+ sprintf(server_name, "s%u", server_id);
+
+ diag_printf("l: Starting %s...\n", server_name);
+
+ cyg_thread_create(
+ SERVER_PRIORITY,
+ (cyg_thread_entry_t*) server,
+ (cyg_addrword_t)&server_launch_args_s,
+ server_name,
+ &(new_thread_data->stack[0]),
+ CYGNUM_HAL_STACK_SIZE_TYPICAL,
+ &(new_thread_data->handle),
+ &(new_thread_data->data)
+ );
+ cyg_thread_resume(new_thread_data->handle);
+
+ } while(true);
+}
+
+//---------------------------------------------------------------------------
+void show_threads(void)
+{
+ cyg_handle_t thread = 0;
+ cyg_uint16 id = 0;
+
+ while( cyg_thread_get_next( &thread, &id ) )
+ {
+ cyg_thread_info info;
+
+ if( !cyg_thread_get_info( thread, id, &info ) )
+ break;
+
+ diag_printf("ID: %04x name: %10s pri: %d\n",
+ info.id, info.name?info.name:"----", info.set_pri );
+ diag_printf(" stack_base %x stack_size %d\n", info.stack_base, info.stack_size);
+ }
+}
+
+void cyg_user_start(void)
+{
+ diag_printf("%u: Starting initializer...\n", __LINE__);
+ cyg_thread_create(
+ INIT_PRIORITY,
+ (cyg_thread_entry_t*) run_init,
+ 0,
+ "initializer",
+ &init_thread.stack[0],
+ CYGNUM_HAL_STACK_SIZE_TYPICAL,
+ &init_thread.handle,
+ &init_thread.data
+ );
+ cyg_thread_resume(init_thread.handle);
+
+ diag_printf("%u: Starting listener...\n", __LINE__);
+
+ cyg_thread_create(
+ LISTENER_PRIORITY,
+ (cyg_thread_entry_t*) listener,
+ 0,
+ "listener",
+ &listener_thread.stack[0],
+ CYGNUM_HAL_STACK_SIZE_TYPICAL,
+ &listener_thread.handle,
+ &listener_thread.data
+ );
+ cyg_thread_resume(listener_thread.handle);
+
+ show_threads();
+
+ diag_printf("%u: Starting scheduler...\n", __LINE__);
+ cyg_scheduler_start();
+}
+
+//=============================================================================
+
diff --git a/ecos/packages/devs/eth/mips/atlas/current/ChangeLog b/ecos/packages/devs/eth/mips/atlas/current/ChangeLog
new file mode 100644
index 0000000..7211911
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/atlas/current/ChangeLog
@@ -0,0 +1,71 @@
+2003-03-21 Nick Garnett <nickg@balti.calivar.com>
+
+ * src/saa9730.h:
+ * src/if_atlas.c:
+ Many small changes to make this driver work correctly in eCos.
+
+2003-03-13 Nick Garnett <nickg@balti.calivar.com>
+
+ * cdl/atlas_eth_drivers.cdl:
+ Changed CYGPKG_DEVS_ETH_ARM_ATLAS_OPTIONS to
+ CYGPKG_DEVS_ETH_MIPS_ATLAS_OPTIONS.
+
+ * src/if_atlas.c (atlas_saa9730_init): ifdeffed out bogus code to
+ set MAC address in non-redboot configuration just to make it
+ compile. Note that there are other problems with this driver in
+ eCos.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_atlas.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2001-10-18 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_atlas.c: net_debug is no longer used.
+
+2001-10-05 Jesper Skov <jskov@redhat.com>
+
+ * src/if_atlas.c: Use new HAL endian conversion macros.
+
+ * src/saa9730.h: Deleted endian conversion macros.
+
+2001-02-15 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/saa9730.h:
+ * src/if_atlas.c:
+ Added support for getting RX interrupts. This is solely for the
+ purposes of doing Ctrl-C processing in RedBoot, more work would be
+ needed to get full eCos driver support going.
+
+2001-01-30 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_atlas.c: New RedBoot config data layout.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/mips/atlas/current/cdl/atlas_eth_drivers.cdl b/ecos/packages/devs/eth/mips/atlas/current/cdl/atlas_eth_drivers.cdl
new file mode 100644
index 0000000..a585786
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/atlas/current/cdl/atlas_eth_drivers.cdl
@@ -0,0 +1,101 @@
+# ====================================================================
+#
+# atlas_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for MIPS Atlas
+# board using a Philips SAA9730 IO chip.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data: msalter
+# Contributors:
+# Date: 2000-12-04
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_MIPS_ATLAS {
+ display "MIPS Atlas ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_MIPS_ATLAS
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "Ethernet driver for MIPS Atlas boards w/ SAA9730."
+ compile -library=libextras.a if_atlas.c if_buffers.S
+
+ cdl_component CYGSEM_MIPS_ATLAS_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_MIPS_ATLAS_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xd0, 0xa0, 0x00, 0x00, 0x10}"}
+ description "The ethernet station address"
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MIPS_ATLAS_OPTIONS {
+ display "MIPS Atlas ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_MIPS_ATLAS_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the MIPS Atlas ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/mips/atlas/current/src/if_atlas.c b/ecos/packages/devs/eth/mips/atlas/current/src/if_atlas.c
new file mode 100644
index 0000000..3cec669
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/atlas/current/src/if_atlas.c
@@ -0,0 +1,1042 @@
+//==========================================================================
+//
+// dev/if_atlas.c
+//
+// Ethernet device driver for MIPS Atlas using Philips SAA9730
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: msalter, nickg
+// Date: 2000-12-06
+// Purpose:
+// Description: hardware driver for SAA9730 ethernet
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// Ethernet device driver for MIPS Atlas
+// Based on SAA9730
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_mips_atlas.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <cyg/kernel/kapi.h>
+#endif
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_endian.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#ifdef CYGPKG_IO_PCI
+#include <cyg/io/pci.h>
+// So we can check the validity of the PCI window against the MLTs opinion,
+// and thereby what the malloc heap consumes willy-nilly:
+#include CYGHWR_MEMORY_LAYOUT_H
+#else
+#error "Need PCI package here"
+#endif
+
+#ifndef CYGSEM_MIPS_ATLAS_SET_ESA
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+RedBoot_config_option("Network hardware address [MAC]",
+ atlas_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif
+#endif
+#endif
+
+// SAA9730 LAN definitions
+#include "saa9730.h"
+
+// Exported statistics and the like
+#include <cyg/io/eth/eth_drv_stats.h>
+
+#ifndef CYGPKG_REDBOOT
+//#define DEBUG
+#endif
+#define db_printf diag_printf
+
+#define ETHER_ADDR_LEN 6
+
+static unsigned poll_count = 0; // for bug workaround
+static void __tx_poll(struct eth_drv_sc *sc);
+
+struct saa9730_priv_data {
+ int active;
+ cyg_uint32 vector;
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+ cyg_uint32 devid; // PCI device id
+ cyg_uint32 base; // PCI memory map base
+ void *ndp;
+
+ // index of next RX buffer
+ cyg_uint8 next_rx_bindex;
+
+ // index of next packet within RX buffer
+ cyg_uint8 next_rx_pindex;
+
+ // index of next TX buffer
+ cyg_uint8 next_tx_bindex;
+
+ // index of next packet within TX buffer
+ cyg_uint8 next_tx_pindex;
+
+ cyg_uint32 *tx_buffer[SAA9730_BUFFERS][SAA9730_TXPKTS_PER_BUFFER];
+ cyg_uint32 *rx_buffer[SAA9730_BUFFERS][SAA9730_RXPKTS_PER_BUFFER];
+
+ int tx_busy;
+ unsigned long tx_key[SAA9730_BUFFERS][SAA9730_TXPKTS_PER_BUFFER];
+ int tx_used[SAA9730_BUFFERS];
+
+} saa9730_priv_data;
+
+ETH_DRV_SC(atlas_sc,
+ &saa9730_priv_data, // Driver specific data
+ "eth0", // Name for this interface
+ saa9730_start,
+ saa9730_stop,
+ saa9730_control,
+ saa9730_can_send,
+ saa9730_send,
+ saa9730_recv,
+ saa9730_deliver, // "pseudoDSR" called from fast net thread
+ saa9730_poll,
+ saa9730_int_vector);
+
+NETDEVTAB_ENTRY(atlas_netdev,
+ "atlas",
+ atlas_saa9730_init,
+ &atlas_sc);
+
+#ifdef CYGSEM_MIPS_ATLAS_SET_ESA
+static unsigned char enaddr[] = CYGDAT_MIPS_ATLAS_ESA;
+#else
+static unsigned char enaddr[ETHER_ADDR_LEN];
+#endif
+
+static void saa9730_poll(struct eth_drv_sc *sc);
+
+// This ISR is called when the ethernet interrupt occurs
+static int
+saa9730_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)data;
+ unsigned long __base = spd->base;
+
+#ifndef CYGPKG_REDBOOT
+ SAA9730_EVM_IER_SW &= ~(SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
+ SAA9730_EVM_ISR = SAA9730_EVM_LAN_INT;
+ cyg_drv_interrupt_mask(vector);
+#endif
+#ifdef DEBUG
+ db_printf("saa9730_isr\n");
+#endif
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+#ifndef CYGPKG_REDBOOT
+static
+void saa9730_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)data;
+ struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(spd->ndp);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+#ifdef DEBUG
+ db_printf("saa9730_dsr\n");
+#endif
+
+ eth_drv_dsr(vector, count, (cyg_addrword_t)sc);
+}
+#endif
+
+static int
+saa9730_int_vector(struct eth_drv_sc *sc)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+
+ return spd->vector;
+}
+
+static void
+__init_buffers(struct saa9730_priv_data *spd)
+{
+ extern char cyg_io_atlas_2kbuffers[];
+ cyg_uint32 *bufp = (cyg_uint32 *)CYGARC_UNCACHED_ADDRESS((unsigned)cyg_io_atlas_2kbuffers);
+ int i, j;
+
+ for (i = 0; i < SAA9730_BUFFERS; i++) {
+ for (j = 0; j < SAA9730_RXPKTS_PER_BUFFER; j++) {
+ memset(bufp, 0, 2048);
+ spd->rx_buffer[i][j] = bufp;
+ bufp += SAA9730_PACKET_SIZE/sizeof(*bufp);
+ }
+ }
+ for (i = 0; i < SAA9730_BUFFERS; i++) {
+ for (j = 0; j < SAA9730_TXPKTS_PER_BUFFER; j++) {
+ memset(bufp, 0, 2048);
+ *bufp = CYG_CPU_TO_LE32(TX_EMPTY);
+ spd->tx_buffer[i][j] = bufp;
+ bufp += SAA9730_PACKET_SIZE/sizeof(*bufp);
+ }
+ }
+
+ spd->next_rx_pindex = 0;
+ spd->next_rx_bindex = 0;
+ spd->next_tx_pindex = 0;
+ spd->next_tx_bindex = 0;
+}
+
+static void
+__select_buffer(struct saa9730_priv_data *spd, int buf_nr)
+{
+ unsigned long __base = spd->base;
+ cyg_uint32 *p;
+ int i;
+
+ // Enable RX buffer
+ for (i = 0; i < SAA9730_RXPKTS_PER_BUFFER; i++) {
+ p = spd->rx_buffer[buf_nr][i];
+ *p = CYG_CPU_TO_LE32(RX_READY);
+ }
+
+ if (buf_nr)
+ SAA9730_OK2USE |= SAA9730_OK2USE_RXB;
+ else
+ SAA9730_OK2USE |= SAA9730_OK2USE_RXA;
+
+}
+
+static void
+__init_cam(struct saa9730_priv_data *spd)
+{
+ unsigned long __base = spd->base;
+ cyg_uint32 abuf[3]; // room for 2 copies of mac address
+ int i,j,cam_offset;
+
+ // make 2 contiguous copies of mac addr
+ memcpy((char *)abuf, enaddr, 6);
+ memcpy((char *)abuf + 6, enaddr, 6);
+
+ // Setting up the address compare regs is weird because you have
+ // to access by word addresses even though addresses don't have
+ // an integral number of words.
+ cam_offset = 0;
+ for (i = 0; i < SAA9730_CAM_ENTRIES; i++) {
+ for (j = 0; j < 3; j++, cam_offset++) {
+ SAA9730_CAMADR = cam_offset;
+ SAA9730_CAMDAT = CYG_CPU_TO_BE32(abuf[j]);
+ }
+ }
+}
+
+static void
+__stop_dma(struct saa9730_priv_data *spd)
+{
+ unsigned long __base = spd->base;
+
+ // Stop DMA
+ SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX);
+
+ // Stop tx/rx
+ SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX;
+ SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX;
+
+ // Set DMA and MAC reset bits
+ SAA9730_DMATST |= SAA9730_DMATST_RESET;
+ SAA9730_MACCTL |= SAA9730_MACCTL_RESET;
+}
+
+
+static void
+__init_dma(struct saa9730_priv_data *spd)
+{
+ unsigned long __base = spd->base;
+
+ __stop_dma(spd);
+
+ // reset DMA engine
+ SAA9730_DMATST |= SAA9730_DMATST_RESET;
+
+ // setup buffers
+ SAA9730_TXBUFA = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->tx_buffer[0][0]);
+ SAA9730_TXBUFB = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->tx_buffer[1][0]);
+ SAA9730_RXBUFA = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->rx_buffer[0][0]);
+ SAA9730_RXBUFB = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->rx_buffer[1][0]);
+
+ SAA9730_PKTCNT = ((SAA9730_TXPKTS_PER_BUFFER << 24) |
+ (SAA9730_TXPKTS_PER_BUFFER << 16) |
+ (SAA9730_RXPKTS_PER_BUFFER << 8) |
+ (SAA9730_RXPKTS_PER_BUFFER << 0));
+
+ SAA9730_OK2USE = 0;
+
+ __select_buffer(spd, 0);
+
+ // initialize DMA control register
+ SAA9730_DMACTL = SAA9730_DMACTL_BLKINT |
+ SAA9730_DMACTL_MAXXFER_ANY |
+ SAA9730_DMACTL_ENDIAN_LITTLE;
+
+ SAA9730_DMACTL |= SAA9730_DMACTL_RXINT;
+ SAA9730_DMACTL |= (1<<SAA9730_DMACTL_RXINTCNT_SHIFT);
+ SAA9730_DMACTL &= ~SAA9730_DMACTL_BLKINT;
+
+#ifndef CYGPKG_REDBOOT
+ SAA9730_DMACTL |= SAA9730_DMACTL_TXINT;
+#endif
+
+ SAA9730_TIMOUT = 200;
+
+ // accept broadcast packets */
+ SAA9730_CAMCTL = SAA9730_CAMCTL_BROADCAST |
+ SAA9730_CAMCTL_COMPARE;
+
+ SAA9730_TXCTL = 0;
+ SAA9730_RXCTL |= SAA9730_RXCTL_STRIPCRC;
+
+ SAA9730_CAMENA = 1;
+
+}
+
+static void
+__check_mii(struct saa9730_priv_data *spd)
+{
+ unsigned long __base = spd->base;
+ cyg_uint32 opmode;
+
+#ifdef DEBUG
+ db_printf("__check_mii\n");
+#endif
+
+ // spin till station is not busy
+ while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY)
+ ;
+
+ // set PHY address = 'STATUS'
+ SAA9730_MDCTL = SAA9730_MDCTL_BUSY |
+ (PHY_ADDRESS << SAA9730_MDCTL_PHY_SHIFT) |
+ PHY_STATUS;
+
+ // spin till station is not busy
+ while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY)
+ ;
+
+ hal_delay_us(1000);
+
+ // check the link status
+ if (SAA9730_MDDATA & PHY_STATUS_LINK_UP) {
+
+ SAA9730_MDCTL = SAA9730_MDCTL_BUSY |
+ (PHY_ADDRESS << SAA9730_MDCTL_PHY_SHIFT) |
+ PHY_REG31;
+
+ // spin till station is not busy
+ while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY)
+ ;
+
+ hal_delay_us(1000);
+
+ opmode = (SAA9730_MDDATA & PHY_REG31_OPMODE_MSK) >> PHY_REG31_OPMODE_SHIFT;
+
+#ifdef DEBUG
+ db_printf("MII mode %d\n", opmode);
+#endif
+
+ if ((opmode == OPMODE_10BASET_FULLDUPLEX) ||
+ (opmode == OPMODE_100BASEX_FULLDUPLEX))
+ SAA9730_MACCTL = SAA9730_MACCTL_CONMODE_FORCE_MII | SAA9730_MACCTL_FULLDUP;
+ else
+ SAA9730_MACCTL = SAA9730_MACCTL_CONMODE_FORCE_MII;
+ }
+#ifdef DEBUG
+ else
+ db_printf("Link is down\n");
+#endif
+}
+
+
+static void
+saa9730_reset(struct saa9730_priv_data *spd)
+{
+ unsigned long __base = spd->base;
+
+ __init_buffers(spd);
+
+ __base = spd->base;
+
+ // Stop DMA
+ SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX);
+
+ // Stop tx/rx
+ SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX;
+ SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX;
+
+ // Set DMA and MAC reset bits
+ SAA9730_DMATST |= SAA9730_DMATST_RESET;
+ SAA9730_MACCTL |= SAA9730_MACCTL_RESET;
+
+ __init_cam(spd);
+ __init_dma(spd);
+ __check_mii(spd);
+
+ spd->tx_busy = 0;
+}
+
+
+static bool
+atlas_saa9730_init(struct cyg_netdevtab_entry *tab)
+{
+ static int initialized = 0; // only probe PCI et al *once*
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+
+#ifdef DEBUG
+ db_printf("atlas_saa9730_init\n");
+#endif
+
+ if (0 == initialized) {
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+
+ cyg_pci_init();
+
+ devid = CYG_PCI_NULL_DEVID;
+
+ if (cyg_pci_find_device(CYG_PCI_VENDOR_PHILIPS, 0x9730, &devid) ) {
+
+ spd->devid = devid;
+
+ cyg_pci_get_device_info(devid, &dev_info);
+
+ if (!cyg_pci_configure_device(&dev_info)) {
+#ifdef DEBUG
+ db_printf("Failed to configure eth device\n");
+#endif
+ return false;
+ }
+
+ // Philips SAA9730 implements only one function memory mapped
+ // into a single contigous memory region.
+ //
+ // According to spec. the BAR#1 is to be used for memory mapped IO.
+ spd->base = dev_info.base_map[1];
+
+ // FIXME! All IO units share an interrupt
+ spd->vector = CYGNUM_HAL_INTERRUPT_INTB;
+
+ // Setup timing stuff
+ cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid),
+ CYG_PCI_DEV_GET_DEVFN(devid),
+ CYG_PCI_CFG_LATENCY_TIMER, 0x20);
+ cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid),
+ CYG_PCI_DEV_GET_DEVFN(devid),
+ CYG_PCI_CFG_MIN_GNT, 9);
+ cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid),
+ CYG_PCI_DEV_GET_DEVFN(devid),
+ CYG_PCI_CFG_MAX_LAT, 24);
+
+#ifdef DEBUG
+ db_printf("eth0 found: bus[%d] dev[%d] base[%x] vector[%d]\n",
+ CYG_PCI_DEV_GET_BUS(devid),
+ CYG_PCI_DEV_GET_DEV(CYG_PCI_DEV_GET_DEVFN(devid)),
+ spd->base, spd->vector);
+#endif
+
+ spd->ndp = tab;
+
+#ifndef CYGPKG_REDBOOT
+ cyg_drv_interrupt_create(
+ spd->vector,
+ 0, // Priority - unused
+ (CYG_ADDRWORD)spd, // Data item passed to ISR & DSR
+ saa9730_isr, // ISR
+ saa9730_dsr, // DSR
+ &spd->interrupt_handle, // handle to intr obj
+ &spd->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(spd->interrupt_handle);
+ cyg_drv_interrupt_acknowledge(spd->vector);
+ cyg_drv_interrupt_unmask(spd->vector);
+#endif
+ {
+ // When in Redboot we want to get RX interrupts. These
+ // will be picked up by the default interrupt handler and
+ // checked for ^C.
+ unsigned long __base = spd->base;
+ SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
+ SAA9730_EVM_IER |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
+ SAA9730_EVM_ISR |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
+ }
+
+#ifdef DEBUG
+ db_printf(" **** Device enabled for I/O and Memory and Bus Master\n");
+#endif
+
+ } else {
+#ifdef DEBUG
+ db_printf("eth0 not found\n");
+#endif
+ }
+
+ saa9730_stop(sc);
+
+ spd->active = 0;
+
+ initialized = 1;
+ }
+
+ // Fetch hardware address
+#if defined(CYGPKG_REDBOOT) && \
+ defined(CYGSEM_REDBOOT_FLASH_CONFIG) && \
+ !defined(CYGSEM_MIPS_ATLAS_SET_ESA)
+ flash_get_config("atlas_esa", enaddr, CONFIG_ESA);
+#else
+#define CONFIG_ESA 6
+ CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "atlas_esa", enaddr, CONFIG_ESA );
+#ifdef DEBUG
+ db_printf("ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ enaddr[0],enaddr[1],enaddr[2],enaddr[3],enaddr[4],enaddr[5]);
+#endif
+#endif
+
+ saa9730_reset(spd);
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, enaddr);
+
+ return true;
+}
+
+static void
+saa9730_stop(struct eth_drv_sc *sc)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+ unsigned long __base = spd->base;
+
+ // Stop DMA
+ SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX);
+
+ // Stop tx/rx
+ SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX;
+ SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX;
+
+ // Set DMA and MAC reset bits
+ SAA9730_DMATST |= SAA9730_DMATST_RESET;
+ SAA9730_MACCTL |= SAA9730_MACCTL_RESET;
+
+ spd->active = 0;
+}
+
+static void
+__do_start(struct saa9730_priv_data *spd)
+{
+ unsigned long __base = spd->base;
+ int i;
+
+ spd->active = 1;
+ spd->tx_busy = 0;
+
+ for (i = 0; i < SAA9730_BUFFERS; i++)
+ spd->tx_used[i] = 0;
+
+ // for tx, turn on MAC first
+ SAA9730_TXCTL |= SAA9730_TXCTL_ENTX;
+ SAA9730_DMACTL |= SAA9730_DMACTL_ENTX;
+
+ // for rx, turn on DMA first
+ SAA9730_DMACTL |= SAA9730_DMACTL_ENRX;
+ SAA9730_RXCTL |= SAA9730_RXCTL_ENRX;
+
+ __select_buffer(spd, spd->next_rx_bindex);
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+saa9730_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+
+ if (spd->active)
+ saa9730_stop(sc);
+
+ __do_start(spd);
+}
+
+//
+// This routine is called to perform special "control" opertions
+//
+static int
+saa9730_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ return 0;
+ break;
+ default:
+ return 1;
+ break;
+ }
+}
+
+//
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+//
+static int
+saa9730_can_send(struct eth_drv_sc *sc)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+ unsigned long __base = spd->base;
+
+ __tx_poll(sc);
+
+ if (spd->next_tx_bindex == 0 && (SAA9730_OK2USE & SAA9730_OK2USE_TXA))
+ return 0;
+
+ if (spd->next_tx_bindex == 1 && (SAA9730_OK2USE & SAA9730_OK2USE_TXB))
+ return 0;
+
+ return 1;
+}
+
+
+static int tx_poll_count;
+
+//
+// This routine is called to send data to the hardware.
+static void
+saa9730_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+ unsigned long __base = spd->base;
+ int bindex, pindex;
+ cyg_uint32 pktlen = total_len;
+ cyg_uint8 *pktdata, *to_p;
+ volatile cyg_uint32 *pktstat ;
+ struct eth_drv_sg *last_sg;
+
+#ifdef DEBUG
+ db_printf("saa9730_send: %d sg's, %d bytes, KEY %x\n",
+ sg_len, total_len, key );
+#endif
+
+ if (!spd->active)
+ return;
+
+ bindex = spd->next_tx_bindex;
+ pindex = spd->next_tx_pindex;
+
+ spd->next_tx_pindex++;
+ if (spd->next_tx_pindex >= SAA9730_TXPKTS_PER_BUFFER) {
+ spd->next_tx_pindex = 0;
+ spd->next_tx_bindex ^= 1;
+ }
+
+ pktstat = spd->tx_buffer[bindex][pindex];
+
+ if (bindex == 0 && (SAA9730_OK2USE & SAA9730_OK2USE_TXA))
+ return;
+
+ if (bindex == 1 && (SAA9730_OK2USE & SAA9730_OK2USE_TXB))
+ return;
+
+ spd->tx_key[bindex][pindex] = key;
+ spd->tx_used[bindex] += 1;
+
+ pktdata = (cyg_uint8 *)((unsigned)pktstat + 4);
+
+ // Copy from the sglist into the tx buffer
+ to_p = pktdata;
+
+ for (last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++) {
+ cyg_uint8 *from_p;
+ int l;
+
+ from_p = (cyg_uint8 *)(sg_list->buf);
+ l = sg_list->len;
+
+ if (l > total_len)
+ l = total_len;
+
+ memcpy((unsigned char *)to_p, from_p, l);
+ to_p += l;
+ total_len -= l;
+
+ if (total_len < 0)
+ break; // Should exit via sg_last normally
+ }
+
+ // pad to minimum size
+ if (pktlen < SAA9730_MIN_PACKET_SIZE) {
+ memset(to_p, 0, SAA9730_MIN_PACKET_SIZE-pktlen);
+ pktlen = SAA9730_MIN_PACKET_SIZE;
+ }
+
+ // Set transmit status WORD for hardware (LAN-DMA-ENGINE)
+ *pktstat = CYG_CPU_TO_LE32(TX_READY | pktlen);
+
+ // start hardware
+ if (bindex == 0)
+ SAA9730_OK2USE |= SAA9730_OK2USE_TXA;
+ else
+ SAA9730_OK2USE |= SAA9730_OK2USE_TXB;
+
+ if (!spd->tx_busy) {
+ tx_poll_count = 0;
+ spd->tx_busy = bindex + 1;
+ }
+}
+
+
+static void
+__check_rxstate(struct saa9730_priv_data *spd)
+{
+ unsigned long __base = spd->base;
+ cyg_uint32 status, flag, size;
+ cyg_uint32 *pkt;
+ int i, j;
+
+#ifdef DEBUG
+ db_printf("__check_rxstate\n");
+#endif
+
+#ifdef CYGPKG_REDBOOT
+ // Clear SAA9730 LAN interrupt and re-enable interrupts.
+ SAA9730_EVM_ISR = SAA9730_EVM_LAN_INT;
+ SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
+#endif
+
+ if ((SAA9730_DBGRXS & SAA9730_DBGRXS_RXDII_MASK) == SAA9730_DBGRXS_RXDII_ERROR) {
+ // re-init driver and controller
+#ifdef DEBUG
+ db_printf("DBGRXS: reset\n");
+#endif
+ saa9730_reset(spd);
+ __do_start(spd);
+ return;
+ }
+
+ // Check RX packet status
+ for (i = 0; i < SAA9730_BUFFERS; i++) {
+ for (j = 1; j < SAA9730_RXPKTS_PER_BUFFER; j++) {
+ pkt = spd->rx_buffer[i][j];
+ status = CYG_LE32_TO_CPU(*pkt);
+ size = status & RXPACKET_STATUS_SIZE_MASK;
+ flag = status & RXPACKET_STATUS_FLAG_MASK;
+ if (flag == RX_INVALID_STAT || size > 1514 || *(pkt - 1)) {
+ // re-init driver and controller
+#ifdef DEBUG
+ db_printf("rxpkt: reset\n");
+#endif
+ saa9730_reset(spd);
+ __do_start(spd);
+ return;
+ }
+ }
+ }
+}
+
+
+static void
+__tx_poll(struct eth_drv_sc *sc)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+ int bindex, pindex;
+ volatile cyg_uint32 *pktstat;
+ cyg_uint32 status;
+
+ if (!spd->tx_busy)
+ return;
+
+ bindex = spd->tx_busy - 1;
+ pindex = spd->tx_used[bindex] - 1; // watch last pkt in buffer
+
+ pktstat = spd->tx_buffer[bindex][pindex];
+
+ status = CYG_LE32_TO_CPU(*pktstat);
+ if ((status & TXPACKET_STATUS_FLAG_MASK) != TX_HWDONE) {
+
+ hal_delay_us(1000);
+
+ if (++tx_poll_count > 1000) {
+ // reset
+
+ for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++)
+ (sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1);
+
+ bindex ^= 1;
+
+ for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++)
+ (sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1);
+
+ saa9730_reset(spd);
+ __do_start(spd);
+ }
+ return;
+ }
+
+ for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++) {
+ /* Check for error. */
+ pktstat = spd->tx_buffer[bindex][pindex];
+ status = CYG_LE32_TO_CPU(*pktstat);
+
+ if (status & TXPACKET_STATUS_ERROR) {
+ if (status & TXPACKET_STATUS_EXDEFER)
+ db_printf("tx deferred\n");
+
+ if (status & TXPACKET_STATUS_LATECOLLERR)
+ db_printf("tx late collision\n");
+
+ if (status & TXPACKET_STATUS_LOSTCARRIER)
+ db_printf("tx no carrier\n");
+
+ if (status & TXPACKET_STATUS_UNDERRUN)
+ db_printf("tx underrun\n");
+
+ if (status & TXPACKET_STATUS_SQERR)
+ db_printf("tx sq\n");
+ }
+ /* free the space */
+ *pktstat = CYG_CPU_TO_LE32(TX_EMPTY);
+
+ (sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1 /* status */);
+ }
+
+ tx_poll_count = 0;
+ spd->tx_used[bindex] = 0;
+
+ bindex ^= 1;
+ if (spd->tx_used[bindex])
+ spd->tx_busy = bindex + 1;
+ else
+ spd->tx_busy = 0;
+}
+
+
+static void
+__rx_poll(struct eth_drv_sc *sc)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+ int bindex, pindex, done;
+ volatile cyg_uint32 *pkt;
+ cyg_uint32 status, pktlen;
+
+#ifdef DEBUG
+ db_printf("__rx_poll\n");
+#endif
+ if (!spd->active)
+ return;
+
+ done = 0;
+ while (!done) {
+ // index of next packet buffer
+ bindex = spd->next_rx_bindex;
+
+ // index of next packet within buffer
+ pindex = spd->next_rx_pindex;
+
+ pkt = spd->rx_buffer[bindex][pindex];
+
+ // stop now if no more packets
+ if (((status = CYG_LE32_TO_CPU(*pkt)) & RXPACKET_STATUS_FLAG_MASK) == RX_READY)
+ break;
+#ifdef DEBUG
+ db_printf("__rx_poll pkt %08x status %08x\n",pkt,status);
+#endif
+ // if this is the first packet in a buffer, switch the SAA9730 to
+ // use the next buffer for subsequent incoming packets.
+ if (pindex == 0)
+ __select_buffer(spd, bindex == 0);
+
+ // check for good packet
+ if (status & RXPACKET_STATUS_GOOD) {
+
+ pktlen = status & RXPACKET_STATUS_SIZE_MASK ;
+
+ if (pktlen > 0) {
+ (sc->funs->eth_drv->recv)(sc, pktlen);
+ // done = 1;
+ }
+ }
+#ifdef DEBUG
+ else
+ db_printf("rx bad: %08x %08x\n",pkt,status);
+#endif
+
+ /* go to next packet in sequence */
+ spd->next_rx_pindex++;
+ if (spd->next_rx_pindex >= SAA9730_RXPKTS_PER_BUFFER) {
+ spd->next_rx_pindex = 0;
+ spd->next_rx_bindex++;
+ if (spd->next_rx_bindex >= SAA9730_BUFFERS)
+ spd->next_rx_bindex = 0;
+ }
+ }
+
+ if (((poll_count++) % 100) == 0)
+ __check_rxstate(spd);
+}
+
+
+static void
+saa9730_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+ volatile cyg_uint32 *pkt;
+ cyg_uint32 pktlen, status;
+ struct eth_drv_sg *last_sg;
+
+ if (!spd->active)
+ return;
+
+ pkt = spd->rx_buffer[spd->next_rx_bindex][spd->next_rx_pindex];
+
+ status = CYG_LE32_TO_CPU(*pkt);
+ if (status & RXPACKET_STATUS_GOOD) {
+ // packet is good
+ pktlen = status & RXPACKET_STATUS_SIZE_MASK;
+
+ if (pktlen > 0) {
+ int total_len;
+ cyg_uint8 *from_p;
+
+ // check we have memory to copy into; we would be called even if
+ // caller was out of memory in order to maintain our state.
+ if (0 == sg_len || 0 == sg_list)
+ return; // caller was out of mbufs
+
+ total_len = pktlen;
+ from_p = (cyg_uint8 *)((unsigned)pkt + 4);
+
+ for (last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++) {
+ cyg_uint8 *to_p;
+ int l;
+
+ to_p = (cyg_uint8 *)(sg_list->buf);
+ l = sg_list->len;
+
+ if (0 >= l || 0 == to_p)
+ return; // caller was out of mbufs
+
+ if (l > total_len)
+ l = total_len;
+
+ memcpy(to_p, (unsigned char *)from_p, l);
+ from_p += l;
+ total_len -= l;
+ }
+ }
+ }
+}
+
+static inline void
+__do_deliver(struct eth_drv_sc *sc)
+{
+ // First pass any rx data up the stack
+ __rx_poll(sc);
+
+ // Then scan for completed Txen and inform the stack
+ __tx_poll(sc);
+}
+
+static void
+saa9730_poll(struct eth_drv_sc *sc)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+
+#ifndef CYGPKG_REDBOOT
+ cyg_drv_interrupt_mask(spd->vector);
+#endif
+
+ (void)saa9730_isr(spd->vector, (cyg_addrword_t)spd);
+
+ __do_deliver(sc);
+
+ cyg_drv_interrupt_acknowledge(spd->vector);
+
+#ifndef CYGPKG_REDBOOT
+ cyg_drv_interrupt_unmask(spd->vector);
+#endif
+}
+
+
+// The deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+saa9730_deliver(struct eth_drv_sc *sc)
+{
+ struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+ unsigned long __base = spd->base;
+
+ if (spd->active)
+ __do_deliver(sc);
+
+ cyg_drv_interrupt_acknowledge(spd->vector);
+
+#ifndef CYGPKG_REDBOOT
+ // Clear SAA9730 LAN interrupt and re-enable interrupts.
+ SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
+ cyg_drv_interrupt_unmask(spd->vector);
+#endif
+}
+
+
diff --git a/ecos/packages/devs/eth/mips/atlas/current/src/if_buffers.S b/ecos/packages/devs/eth/mips/atlas/current/src/if_buffers.S
new file mode 100644
index 0000000..6c58a85
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/atlas/current/src/if_buffers.S
@@ -0,0 +1,63 @@
+// #========================================================================
+// #
+// # if_buffers.S
+// #
+// # Declare a chunk of 4Kbyte aligned memory for use by bus-mastering
+// # PCI ethernet device.
+// #
+// #========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// #========================================================================
+// ######DESCRIPTIONBEGIN####
+// #
+// # Author(s): msalter
+// # Contributors: msalter
+// # Date: 2000-11-03
+// # Purpose:
+// # Description: This file defines a chunk of 2Kbyte aligned memory for use
+// # by bus-mastering PCI ethernet device.
+// #
+// #####DESCRIPTIONEND####
+// #
+// #========================================================================
+
+#include "saa9730.h"
+
+ .bss
+ .p2align(11)
+ .globl cyg_io_atlas_2kbuffers
+cyg_io_atlas_2kbuffers:
+ .rept (SAA9730_RXPKTS_PER_BUFFER + SAA9730_TXPKTS_PER_BUFFER) \
+ * SAA9730_BUFFERS * SAA9730_PACKET_SIZE
+ .byte 0
+ .endr
diff --git a/ecos/packages/devs/eth/mips/atlas/current/src/saa9730.h b/ecos/packages/devs/eth/mips/atlas/current/src/saa9730.h
new file mode 100644
index 0000000..d292be6
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/atlas/current/src/saa9730.h
@@ -0,0 +1,362 @@
+#ifndef CYGONCE_DEVS_ETH_MIPS_ATLAS_SAA9730_H
+#define CYGONCE_DEVS_ETH_MIPS_ATLAS_SAA9730_H
+/*==========================================================================
+//
+// saa9730.h
+// Philips SAA9730 IO Chip Ethernet Interface
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: msalter, nickg
+// Date: 2000-12-09
+// Description: Definitions for Philips SAA9730 Ethernet module.
+//
+//####DESCRIPTIONEND####
+*/
+
+// QS6612 PHY definitions
+
+#define PHY_CONTROL 0
+#define PHY_STATUS 1
+#define PHY_REG31 31
+
+#define PHY_CONTROL_RESET (1 << 15)
+#define PHY_CONTROL_AUTO_NEG (1 << 12)
+#define PHY_CONTROL_RESTART_AUTO_NEG (1 << 9)
+
+#define PHY_STATUS_LINK_UP (1 << 2)
+
+#define PHY_REG31_OPMODE_SHIFT 2
+#define PHY_REG31_OPMODE_MSK (7 << PHY_REG31_OPMODE_SHIFT)
+
+#define OPMODE_AUTONEGOTIATE 0
+#define OPMODE_10BASET_HALFDUPLEX 1
+#define OPMODE_100BASEX_HALFDUPLEX 2
+#define OPMODE_REPEATER_MODE 3
+#define OPMODE_UNDEFINED 4
+#define OPMODE_10BASET_FULLDUPLEX 5
+#define OPMODE_100BASEX_FULLDUPLEX 6
+#define OPMODE_ISOLATE 7
+
+#define QS6612_PHY_ADDRESS 0
+#define PHY_ADDRESS QS6612_PHY_ADDRESS
+
+// Number of 6-byte entries in the CAM
+#define SAA9730_CAM_ENTRIES 10
+
+// TX and RX packet size fixed at 2k bytes by hw
+#define SAA9730_PACKET_SIZE 2048
+
+// Number of TX buffers = number of RX buffers = 2,
+// which is fixed according to HW requirements
+#define SAA9730_BUFFERS 2
+
+// Number of RX packets per RX buffer
+#define SAA9730_RXPKTS_PER_BUFFER 2
+
+// Number of TX packets per TX buffer
+#define SAA9730_TXPKTS_PER_BUFFER 1
+
+// Minimum packet size
+#define SAA9730_MIN_PACKET_SIZE 60
+
+// owner ship bit
+#define SAA9730_BLOCK_OWNED_BY_SYSTEM 0
+#define SAA9730_BLOCK_OWNED_BY_HARDWARE 1
+
+// Default Rcv interrupt count
+#define SAA9730_DEFAULT_RCV_INTERRUPT_CNT 4
+
+// Default maxium transmit retry
+#define SAA9730_DEFAULT_MAX_TXM_RETRY 16
+
+// Default time out value
+#define SAA9730_DEFAULT_TIME_OUT_CNT 200
+
+// MAX map registers
+#define SAA9730__MAX_MAP_REGISTERS 64
+
+// Defines used by Interrupt code
+#define SAA9730_DMA_PACKET_SIZE 2048
+#define SAA9730_VALID_PACKET 0xC0000000
+#define SAA9730_FRAME_TYPELEN_OFFSET 12
+#define SAA9730_ETH_MIN_FRAME_SIZE 60
+#define SAA9730_DEST_ADDR_SIZE 6
+#define SAA9730_SRC_ADDR_SIZE 6
+#define SAA9730_TYPE_LEN_SIZE 2
+
+// MAC receive error
+#define SAA9730_MAC_GOOD_RX (0x00004000) << 11
+#define SAA9730_MAC_RCV_ALIGN_ERROR (0x00000100) << 11
+#define SAA9730_MAC_RCV_CRC_ERROR (0x00000200) << 11
+#define SAA9730_MAC_RCV_OVERFLOW (0x00000400) << 11
+
+// This number is arbitrary and can be increased if needed
+#define SAA9730_MAX_MULTICAST_ADDRESSES 20
+
+// SAA9730 Event Manager Registers
+#define SAA9730_EVM_ISR *((volatile unsigned *)(__base + 0x02000))
+#define SAA9730_EVM_IER *((volatile unsigned *)(__base + 0x02004))
+#define SAA9730_EVM_IMR *((volatile unsigned *)(__base + 0x02008))
+
+#define SAA9730_EVM_IER_SW *((volatile unsigned *)(__base + 0x0202c))
+
+#define SAA9730_EVM_LAN_INT (1<<16) // LAN interrupt bit
+#define SAA9730_EVM_MASTER (1<<0) // Master interrupt bit
+
+// SAA9730 LAN Registers
+#define SAA9730_TXBUFA *((volatile unsigned *)(__base + 0x20400)) // TX buffer A
+
+#define SAA9730_TXBUFB *((volatile unsigned *)(__base + 0x20404)) // TX buffer B
+
+#define SAA9730_RXBUFA *((volatile unsigned *)(__base + 0x20408)) // RX buffer A
+
+#define SAA9730_RXBUFB *((volatile unsigned *)(__base + 0x2040C)) // RX buffer B
+
+#define SAA9730_PKTCNT *((volatile unsigned *)(__base + 0x20410)) // Packet count
+
+#define SAA9730_OK2USE *((volatile unsigned *)(__base + 0x20414)) // OK-to-use
+# define SAA9730_OK2USE_TXA 8
+# define SAA9730_OK2USE_TXB 4
+# define SAA9730_OK2USE_RXA 2
+# define SAA9730_OK2USE_RXB 1
+
+#define SAA9730_DMACTL *((volatile unsigned *)(__base + 0x20418)) // DMA control
+# define SAA9730_DMACTL_BLKINT (1 << 31)
+# define SAA9730_DMACTL_MAXXFER_ANY (0 << 18)
+# define SAA9730_DMACTL_MAXXFER_8 (1 << 18)
+# define SAA9730_DMACTL_MAXXFER_32 (2 << 18)
+# define SAA9730_DMACTL_MAXXFER_64 (3 << 18)
+# define SAA9730_DMACTL_ENDIAN_LITTLE (0 << 16)
+# define SAA9730_DMACTL_ENDIAN_2143 (1 << 16)
+# define SAA9730_DMACTL_ENDIAN_4321 (2 << 16)
+# define SAA9730_DMACTL_RXINTCNT_SHIFT 8
+# define SAA9730_DMACTL_RXINTCNT_MSK (0xff << SAA9730_DMACTL_RXINTCNT_SHIFT)
+# define SAA9730_DMACTL_ENTX (1 << 7)
+# define SAA9730_DMACTL_ENRX (1 << 6)
+# define SAA9730_DMACTL_RXFULL (1 << 5)
+# define SAA9730_DMACTL_RXTOINT (1 << 4)
+# define SAA9730_DMACTL_RXINT (1 << 3)
+# define SAA9730_DMACTL_TXINT (1 << 2)
+# define SAA9730_DMACTL_MACTXINT (1 << 1)
+# define SAA9730_DMACTL_MACRXINT (1 << 0)
+
+#define SAA9730_TIMOUT *((volatile unsigned *)(__base + 0x2041C)) // Time out
+
+#define SAA9730_DMASTA *((volatile unsigned *)(__base + 0x20420)) // DMA status
+# define SAA9730_DMASTA_TXABADR_MSK (1 << 19)
+# define SAA9730_DMASTA_TXBBADR_MSK (1 << 18)
+# define SAA9730_DMASTA_RXABADR_MSK (1 << 17)
+# define SAA9730_DMASTA_RXBBADR_MSK (1 << 16)
+# define SAA9730_DMASTA_RXBBADR_SHIFT 8
+# define SAA9730_DMASTA_RXPCKCNT_MASK (0xff << SAA9730_DMASTA_RXPCKCNT_SHIFT)
+# define SAA9730_DMASTA_TXMACBUSY_MSK (1 << 7)
+# define SAA9730_DMASTA_RXAFULL_MSK (1 << 6)
+# define SAA9730_DMASTA_RXBFULL_MSK (1 << 5)
+# define SAA9730_DMASTA_RXTOINT_MSK (1 << 4)
+# define SAA9730_DMASTA_RXINT_MSK (1 << 3)
+# define SAA9730_DMASTA_TXINT_MSK (1 << 2)
+# define SAA9730_DMASTA_MACTXINT_MSK (1 << 1)
+# define SAA9730_DMASTA_MACRXINT_MSK (1 << 0)
+
+#define SAA9730_DMATST *((volatile unsigned *)(__base + 0x20424)) // DMA loop back
+# define SAA9730_DMATST_LPBACK (1 << 24)
+# define SAA9730_DMATST_RESET 1
+
+#define SAA9730_PAUSE *((volatile unsigned *)(__base + 0x20430)) // Pause count
+
+#define SAA9730_REMPAUSE *((volatile unsigned *)(__base + 0x20434)) // Remote Pause count
+
+#define SAA9730_MACCTL *((volatile unsigned *)(__base + 0x20440)) // MAC control
+# define SAA9730_MACCTL_MISSRINT (1 << 13)
+# define SAA9730_MACCTL_MISSROLL (1 << 10)
+# define SAA9730_MACCTL_LOOP10 (1 << 7)
+# define SAA9730_MACCTL_CONMODE_AUTOMATIC (0 << 5)
+# define SAA9730_MACCTL_CONMODE_FORCE_10MB (1 << 5)
+# define SAA9730_MACCTL_CONMODE_FORCE_MII (2 << 5)
+# define SAA9730_MACCTL_LPBACK (1 << 4)
+# define SAA9730_MACCTL_FULLDUP (1 << 3)
+# define SAA9730_MACCTL_RESET (1 << 2)
+# define SAA9730_MACCTL_HALTNOW (1 << 1)
+# define SAA9730_MACCTL_HALTREQ (1 << 0)
+
+#define SAA9730_CAMCTL *((volatile unsigned *)(__base + 0x20444)) // CAM control
+# define SAA9730_CAMCTL_COMPARE (1 << 4)
+# define SAA9730_CAMCTL_NEGATE (1 << 3)
+# define SAA9730_CAMCTL_BROADCAST (1 << 2)
+# define SAA9730_CAMCTL_MULTICAST (1 << 1)
+# define SAA9730_CAMCTL_UNICAST (1 << 0)
+
+#define SAA9730_TXCTL *((volatile unsigned *)(__base + 0x20448)) // TX control
+# define SAA9730_TXCTL_COMPLINT (1 << 14)
+# define SAA9730_TXCTL_TXPARINT (1 << 13)
+# define SAA9730_TXCTL_LATECOLLINT (1 << 12)
+# define SAA9730_TXCTL_EXCOLLINT (1 << 11)
+# define SAA9730_TXCTL_CARRIERINT (1 << 10)
+# define SAA9730_TXCTL_DEFERINT (1 << 9)
+# define SAA9730_TXCTL_UNDERINT (1 << 8)
+# define SAA9730_TXCTL_MII10 (1 << 7)
+# define SAA9730_TXCTL_SDPAUSE (1 << 6)
+# define SAA9730_TXCTL_NOEXDEF (1 << 5)
+# define SAA9730_TXCTL_FBACK (1 << 4)
+# define SAA9730_TXCTL_NOCRC (1 << 3)
+# define SAA9730_TXCTL_NOPAD (1 << 2)
+# define SAA9730_TXCTL_TXHALT (1 << 1)
+# define SAA9730_TXCTL_ENTX (1 << 0)
+
+#define SAA9730_TXSTA *((volatile unsigned *)(__base + 0x2044C)) // TX status
+# define SAA9730_TXSTA_SQERR (1 << 16)
+# define SAA9730_TXSTA_TXHALTED (1 << 15)
+# define SAA9730_TXSTA_COMPLETION (1 << 14)
+# define SAA9730_TXSTA_PARITYERR (1 << 13)
+# define SAA9730_TXSTA_LATECOLLERR (1 << 12)
+# define SAA9730_TXSTA_WAS10MB (1 << 11)
+# define SAA9730_TXSTA_LOSTCARRIER (1 << 10)
+# define SAA9730_TXSTA_EXDEFER (1 << 9)
+# define SAA9730_TXSTA_UNDERRUN (1 << 8)
+# define SAA9730_TXSTA_INTERRUPT (1 << 7)
+# define SAA9730_TXSTA_PAUSED (1 << 6)
+# define SAA9730_TXSTA_DEFERRED (1 << 5)
+# define SAA9730_TXSTA_EXCOLL (1 << 4)
+# define SAA9730_TXSTA_COLLISIONS_MASK 0xf
+
+#define SAA9730_RXCTL *((volatile unsigned *)(__base + 0x20450)) // RX control
+# define SAA9730_RXCTL_ENGOOD (1 << 14)
+# define SAA9730_RXCTL_ENPARITY (1 << 13)
+# define SAA9730_RXCTL_ENLONGERR (1 << 11)
+# define SAA9730_RXCTL_ENOVER (1 << 10)
+# define SAA9730_RXCTL_ENCRCERR (1 << 9)
+# define SAA9730_RXCTL_ENALIGN (1 << 8)
+# define SAA9730_RXCTL_IGNORECRC (1 << 6)
+# define SAA9730_RXCTL_PASSCTL (1 << 5)
+# define SAA9730_RXCTL_STRIPCRC (1 << 4)
+# define SAA9730_RXCTL_SHORTEN (1 << 3)
+# define SAA9730_RXCTL_LONGEN (1 << 2)
+# define SAA9730_RXCTL_RXHALT (1 << 1)
+# define SAA9730_RXCTL_ENRX (1 << 0)
+
+#define SAA9730_RXSTA *((volatile unsigned *)(__base + 0x20454)) // RX status
+# define SAA9730_RXSTA_HALTED (1 << 15)
+# define SAA9730_RXSTA_GOOD (1 << 14)
+# define SAA9730_RXSTA_PARITY (1 << 13)
+# define SAA9730_RXSTA_LONGERR (1 << 11)
+# define SAA9730_RXSTA_OVERFLOW (1 << 10)
+# define SAA9730_RXSTA_CRCERR (1 << 9)
+# define SAA9730_RXSTA_ALIGNERR (1 << 8)
+# define SAA9730_RXSTA_WAS10MB (1 << 7)
+# define SAA9730_RXSTA_INTERRUPT (1 << 6)
+# define SAA9730_RXSTA_CONTROLRCV (1 << 5)
+
+#define SAA9730_MDDATA *((volatile unsigned *)(__base + 0x20458)) // PHY mgmt data
+# define SAA9730_MDDATA_DATA_MASK (0xffff << SAA9730_MDDATA_DATA_SHIFT)
+
+#define SAA9730_MDCTL *((volatile unsigned *)(__base + 0x2045C)) // PHY mgmt control
+# define SAA9730_MDCTL_PRESUP (1 << 12)
+# define SAA9730_MDCTL_BUSY (1 << 11)
+# define SAA9730_MDCTL_WRITE (1 << 10)
+# define SAA9730_MDCTL_PHY_SHIFT 5
+# define SAA9730_MDCTL_PHY_MASK (0x1f << SAA9730_MDCTL_PHY_SHIFT)
+# define SAA9730_MDCTL_ADDR_MASK 0x1f
+
+#define SAA9730_CAMADR *((volatile unsigned *)(__base + 0x20460)) // CAM address
+# define SAA9730_CAMADR_ADDRESS_MASK (0x1ff << SAA9730_CAMADR_ADDRESS_SHIFT)
+
+#define SAA9730_CAMDAT *((volatile unsigned *)(__base + 0x20464)) // CAM data
+
+#define SAA9730_CAMENA *((volatile unsigned *)(__base + 0x20468)) // CAM enable
+# define SAA9730_CAMENA_ENABLE_MASK (0x3fffff << SAA9730_CAMENA_ENABLE_SHIFT)
+
+#define SAA9730_DBGRXS *((volatile unsigned *)(__base + 0x20508)) // DEBUG
+# define SAA9730_DBGRXS_RXPI_MASK (0x3ff << 16)
+# define SAA9730_DBGRXS_RXPI_ERROR (0x001 << 16)
+# define SAA9730_DBGRXS_RXDII_MASK 0x1ff
+# define SAA9730_DBGRXS_RXDII_ERROR 8
+
+
+#define SAA9730_DBGRXFIFO *((volatile unsigned *)(__base + 0x20510)) // DEBUG
+
+#define SAA9730_DBGLANSTA *((volatile unsigned *)(__base + 0x20514)) // DEBUG
+
+// ******** Packet control/status **********
+
+#define TXPACKET_CTL_FLAG_MASK (0x3 << 30)
+# define TX_EMPTY (0 << 30)
+# define TX_READY (2 << 30)
+# define TX_HWDONE (3 << 30)
+
+# define TXPACKET_CTL_IRQ_MASK (1 << 29)
+# define TXPACKET_CTL_NOCRC_MASK (1 << 28)
+# define TXPACKET_CTL_NOPAD_MASK (1 << 27)
+# define TXPACKET_CTL_SIZE_MASK 0x7ff
+
+#define TXPACKET_STATUS_FLAG_MASK (0x3 << 30)
+# define TXPACKET_STATUS_SQERR (1 << 27)
+# define TXPACKET_STATUS_TXHALTED (1 << 26)
+# define TXPACKET_STATUS_COMPLETION (1 << 25)
+# define TXPACKET_STATUS_PARITYERR (1 << 24)
+# define TXPACKET_STATUS_LATECOLLERR (1 << 23)
+# define TXPACKET_STATUS_WAS10MB (1 << 22)
+# define TXPACKET_STATUS_LOSTCARRIER (1 << 21)
+# define TXPACKET_STATUS_EXDEFER (1 << 20)
+# define TXPACKET_STATUS_UNDERRUN (1 << 19)
+# define TXPACKET_STATUS_COLLISIONS_SHIFT 11
+# define TXPACKET_STATUS_COLLISIONS_MASK (0x1f << TXPACKET_STATUS_COLLISIONS_SHIFT)
+# define TXPACKET_STATUS_SIZE_MASK 0x7ff
+
+# define TXPACKET_STATUS_ERROR (TXPACKET_STATUS_EXDEFER | \
+ TXPACKET_STATUS_LATECOLLERR | \
+ TXPACKET_STATUS_LOSTCARRIER | \
+ TXPACKET_STATUS_UNDERRUN | \
+ TXPACKET_STATUS_SQERR)
+
+# define RXPACKET_STATUS_FLAG_MASK (0x3 << 30)
+# define RX_NDIS (0 << 30)
+# define RX_INVALID_STAT (1 << 30)
+# define RX_READY (2 << 30)
+# define RX_HWDONE (3 << 30)
+
+# define RXPACKET_STATUS_GOOD (1 << 25)
+# define RXPACKET_STATUS_PARITY (1 << 24)
+# define RXPACKET_STATUS_LONGERR (1 << 22)
+# define RXPACKET_STATUS_OVERFLOW (1 << 21)
+# define RXPACKET_STATUS_CRCERR (1 << 20)
+# define RXPACKET_STATUS_ALIGNERR (1 << 19)
+# define RXPACKET_STATUS_WAS10MB (1 << 18)
+# define RXPACKET_STATUS_SIZE_MASK 0x7ff
+
+#endif // CYGONCE_DEVS_ETH_MIPS_ATLAS_SAA9730_H
diff --git a/ecos/packages/devs/eth/mips/idt79s334a/current/ChangeLog b/ecos/packages/devs/eth/mips/idt79s334a/current/ChangeLog
new file mode 100644
index 0000000..59a69d6
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/idt79s334a/current/ChangeLog
@@ -0,0 +1,28 @@
+2003-02-13 Tim Michals <t.michals@attbi.com>
+2003-02-13 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * New package - support for MIPS IDT 79s334a board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/mips/idt79s334a/current/cdl/refidt334_eth_drivers.cdl b/ecos/packages/devs/eth/mips/idt79s334a/current/cdl/refidt334_eth_drivers.cdl
new file mode 100755
index 0000000..29e7e78
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/idt79s334a/current/cdl/refidt334_eth_drivers.cdl
@@ -0,0 +1,148 @@
+# ====================================================================
+#
+# refidt334_eth_drivers.cdl
+#
+# Ethernet drivers
+# Intel PRO/100+ platform specific support for IDT MIPS 334
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Tim Michals
+# Original data: hmt
+# Contributors:
+# Date: 2003-02-13
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_MIPS_REFIDT334 {
+ display "MIPS IDT 79RC32334 reference platform ethernet driver"
+ description "Ethernet driver for MIPS IDT 79RC32334 reference platform."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_MIPS_IDT32334_REFIDT334
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82559 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
+ display "Intel i82559 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_refidt334.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_mips_refidt334.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0 {
+ display "IDT 79RC32334 ethernet port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ i82559 ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x00, 0x00, 0x00, 0x00, 0x01}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1 {
+ display "IDT 79RC32334 ethernet port 1 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH1
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_NAME {
+ display "Device name for the ETH0 ethernet port 1 driver"
+ flavor data
+ default_value {"\"eth1\""}
+ description "
+ This option sets the name of the ethernet device for the
+ i82559 ethernet port 1."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x00, 0x00, 0x00, 0x00, 0x02}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+}
+
+# EOF refidt334_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/mips/idt79s334a/current/include/devs_eth_refidt334.inl b/ecos/packages/devs/eth/mips/idt79s334a/current/include/devs_eth_refidt334.inl
new file mode 100644
index 0000000..be0c71f
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/idt79s334a/current/include/devs_eth_refidt334.inl
@@ -0,0 +1,172 @@
+//==========================================================================
+//
+// devs_eth_refidt334.inl
+//
+// IDT79S334a i82559 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Tim Michals
+// Contributors:jskov
+// Date: 2003-02-13
+// Purpose: IDT79s334A i82559 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#if 1 < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT
+#define CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL
+#endif // multiple devs, so demux_all needed
+
+
+#if defined(CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0) || defined(CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1)
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE 0xa0100000
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE 0x100000 //CYGMEM_SECTION_pci_window_SIZE
+
+#define CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS( _x_ ) (((cyg_uint32)(_x_))|0)
+#define CYGHWR_INTEL_I82559_PCI_BUS_TO_VIRT( _x_ ) (((cyg_uint32)(_x_))&~0)
+#endif
+
+
+#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0
+
+static I82559 i82559_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_SET_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc0,
+ &i82559_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev0,
+ "i82559_" CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_NAME,
+ i82559_init,
+ &i82559_sc0);
+
+#endif // CYGPKG_DEVS_ETH_XXX_ETH0
+
+
+
+
+#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1
+
+static I82559 i82559_eth1_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_SET_ESA
+ hardwired_esa:2,
+ mac_address: CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_SET_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc1,
+ &i82559_eth1_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev1,
+ "i82559_" CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_NAME,
+ i82559_init,
+ &i82559_sc1);
+
+#endif // CYGPKG_DEVS_ETH_XXX_ETH1
+
+
+
+
+// These arrays are used for sanity checking of pointers
+I82559 *
+i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0
+ &i82559_eth0_priv_data,
+#endif
+#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1
+ &i82559_eth1_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0
+ &i82559_netdev0,
+#endif
+
+#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1
+ &i82559_netdev1,
+#endif
+
+};
+
+struct eth_drv_sc *
+i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0
+ &i82559_sc0,
+#endif
+#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1
+ &i82559_sc1,
+#endif
+};
+#endif
+
+// EOF devs_eth_refidt334.inl
diff --git a/ecos/packages/devs/eth/mips/malta/current/ChangeLog b/ecos/packages/devs/eth/mips/malta/current/ChangeLog
new file mode 100644
index 0000000..5b12b5e
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/malta/current/ChangeLog
@@ -0,0 +1,59 @@
+2001-07-26 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_mips_mips32_malta.inl: Removed ESA init
+ definition again now driver has been fixed.
+
+2001-07-24 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_mips_mips32_malta.inl
+ (CYGHWR_AMD_PCNET_BROKEN_ESA_INIT): Defined.
+
+2001-07-18 Jesper Skov <jskov@redhat.com>
+
+ * cdl/mips_mips32_malta_eth_drivers.cdl: Default to use eeprom ESA.
+
+2001-07-12 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_mips_mips32_malta.inl: Let driver find base and
+ interrupt details. Updated esa options.
+
+2001-06-27 Jesper Skov <jskov@redhat.com>
+
+ * cdl/mips_mips32_malta_eth_drivers.cdl: Implements net drivers.
+
+2001-04-23 Mark Salter <msalter@redhat.com>
+
+ * include/devs_eth_mips_mips32_malta.inl: Adjust base address to
+ match changed PCI allocation base. This should really be gotten
+ at runtime from the PCI interface, not from a build time constant.
+
+2001-04-03 Jesper Skov <jskov@redhat.com>
+
+ * cdl/mips_mips32_malta_eth_drivers.cdl: Platform specific
+ information required to use the generic AMD PCNet driver for the
+ Malta platform.
+ * include/devs_eth_mips_mips32_malta.inl: Same.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/mips/malta/current/cdl/mips_mips32_malta_eth_drivers.cdl b/ecos/packages/devs/eth/mips/malta/current/cdl/mips_mips32_malta_eth_drivers.cdl
new file mode 100644
index 0000000..3f677ee
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/malta/current/cdl/mips_mips32_malta_eth_drivers.cdl
@@ -0,0 +1,129 @@
+# ====================================================================
+#
+# malta_eth_drivers.cdl
+#
+# Ethernet drivers - support for AMD PCnet ethernet controller
+# on the MIPS MALTA board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-04-02
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA {
+ display "MIPS MALTA board ethernet driver"
+ description "Ethernet driver for MIPS MALTA board."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_MIPS_MALTA
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the AMD_PCNET package
+ cdl_interface CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED {
+ display "AMD PCNET ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_PCNET_INL <cyg/io/devs_eth_mips_mips32_malta.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_PCNET_CFG <pkgconf/devs_eth_mips_mips32_malta.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0 {
+ display "MALTA ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ MALTA port 0."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED
+
+ cdl_option CYGNUM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_RX_RING_SIZE {
+ display "Size of RX ring for ETH0"
+ flavor data
+ default_value 4
+ legal_values { 4 8 16 32 64 128 }
+ description "
+ This option sets the size of the RX ring."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_TX_RING_SIZE {
+ display "Size of TX ring for ETH0"
+ flavor data
+ default_value 16
+ legal_values { 4 8 16 32 64 128 }
+ description "
+ This option sets the size of the TX ring."
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ MALTA port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/mips/malta/current/include/devs_eth_mips_mips32_malta.inl b/ecos/packages/devs/eth/mips/malta/current/include/devs_eth_mips_mips32_malta.inl
new file mode 100644
index 0000000..e44dac0
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/malta/current/include/devs_eth_mips_mips32_malta.inl
@@ -0,0 +1,108 @@
+//==========================================================================
+//
+// devs/eth/mips/malta/include/devs_eth_mips_mips32_malta.inl
+//
+// Malta ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-04-02
+// Purpose: Malta ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#ifdef __WANT_CONFIG
+
+#define CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE CYGARC_UNCACHED_ADDRESS((cyg_uint32)(&CYGMEM_SECTION_pci_window[0]))
+#define CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE ((cyg_uint32)(CYGMEM_SECTION_pci_window_SIZE))
+
+#endif // __WANT_CONFIG
+
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0
+
+static pcnet_priv_data amd_pcnet_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+ config_esa : NULL,
+ rx_ring : NULL,
+ rx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_RX_RING_SIZE*/,
+ rx_ring_log_cnt : 2,
+ tx_ring : NULL,
+ tx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_TX_RING_SIZE*/,
+ tx_ring_log_cnt : 2,
+};
+
+ETH_DRV_SC(amd_pcnet_sc,
+ &amd_pcnet_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_NAME,
+ pcnet_start,
+ pcnet_stop,
+ pcnet_control,
+ pcnet_can_send,
+ pcnet_send,
+ pcnet_recv,
+ pcnet_deliver, // "pseudoDSR" called from fast net thread
+ pcnet_poll, // poll function, encapsulates ISR and DSR
+ pcnet_int_vector);
+
+NETDEVTAB_ENTRY(pcnet_netdev,
+ "pcnet_" CYGDAT_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_NAME,
+ amd_pcnet_init,
+ &amd_pcnet_sc);
+#endif // CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0
+
+// These arrays are used for sanity checking of pointers
+struct pcnet_priv_data *
+pcnet_priv_array[CYGNUM_DEVS_ETH_AMD_PCNET_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0
+ &amd_pcnet_eth0_priv_data,
+#endif
+};
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_mips_mips32_malta.inl
diff --git a/ecos/packages/devs/eth/mips/ocelot/current/ChangeLog b/ecos/packages/devs/eth/mips/ocelot/current/ChangeLog
new file mode 100644
index 0000000..c986e5a
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/ocelot/current/ChangeLog
@@ -0,0 +1,43 @@
+2001-06-22 Jesper Skov <jskov@redhat.com>
+
+ * cdl/mips_rm7000_ocelot_eth_drivers.cdl: Default to getting ESA
+ from EEPROM.
+
+ * include/devs_eth_mips_rm7000_ocelot.inl: Tell driver to expect
+ EEPROM without CRC.
+
+2001-03-02 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_mips_rm7000_ocelot.inl: Define controller PCI
+ details.
+
+2001-11-29 Jesper Skov <jskov@redhat.com>
+
+ * cdl/mips_rm7000_ocelot_eth_drivers.cdl: Platform specific
+ information required to use the generic i82559 driver for the
+ Ocelot platform.
+ * include/devs_eth_mips_rm7000_ocelot.inl: Same.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/mips/ocelot/current/cdl/mips_rm7000_ocelot_eth_drivers.cdl b/ecos/packages/devs/eth/mips/ocelot/current/cdl/mips_rm7000_ocelot_eth_drivers.cdl
new file mode 100644
index 0000000..b753f4a
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/ocelot/current/cdl/mips_rm7000_ocelot_eth_drivers.cdl
@@ -0,0 +1,112 @@
+# ====================================================================
+#
+# ocelot_eth_drivers.cdl
+#
+# Ethernet drivers - support for i82559 ethernet controller
+# on the PMC-Sierra Ocelot board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-01-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT {
+ display "PMC-Sierra Ocelot board ethernet driver"
+ description "Ethernet driver for PMC-Sierra Ocelot board."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_MIPS_RM7000_OCELOT
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82559 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
+ display "Intel i82559 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_mips_rm7000_ocelot.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_mips_rm7000_ocelot.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0 {
+ display "Ocelot ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ Ocelot port 0 - that is the connector on the front of
+ the board."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ Ocelot port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/mips/ocelot/current/include/devs_eth_mips_rm7000_ocelot.inl b/ecos/packages/devs/eth/mips/ocelot/current/include/devs_eth_mips_rm7000_ocelot.inl
new file mode 100644
index 0000000..3e99c7b
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/ocelot/current/include/devs_eth_mips_rm7000_ocelot.inl
@@ -0,0 +1,117 @@
+//==========================================================================
+//
+// devs/eth/mips/ocelot/include/devs_eth_mips_rm7000_ocelot.inl
+//
+// Ocelot ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-01-25
+// Purpose: Ocelot ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#ifdef CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0
+
+#ifndef CYGSEM_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_SET_ESA
+# define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM 0
+# define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_WITHOUT_CRC
+#endif
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE (CYGARC_UNCACHED_ADDRESS(0x0ff00000))
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE 0x00100000
+
+static I82559 i82559_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc0,
+ &i82559_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev0,
+ "i82559_" CYGDAT_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_NAME,
+ i82559_init,
+ &i82559_sc0);
+
+#endif // CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+I82559 *
+i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0
+ &i82559_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0
+ &i82559_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0
+ &i82559_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// EOF devs_eth_mips_rm7000_ocelot.inl
diff --git a/ecos/packages/devs/eth/mips/upd985xx/current/ChangeLog b/ecos/packages/devs/eth/mips/upd985xx/current/ChangeLog
new file mode 100644
index 0000000..4ed1ef6
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/upd985xx/current/ChangeLog
@@ -0,0 +1,254 @@
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_upd985xx.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2001-09-13 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (upd985xx_eth_upd985xx_init): Fake an ESA if
+ we see all ones from the EEPROM as well as all zeros.
+
+2001-08-30 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/upd985xx_eth_drivers.cdl: Make the "..._E2ONLY" workaround
+ option on by default since this is how it will be used - the CPU
+ load does suffer somewhat if promisc mode is set in the hardware.
+ This should be unset to allow the workaround for E1 at 100Mbit.
+
+2001-08-30 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (PacketRxReady): Re-write the manual
+ implementation of ESA matching for workaround E1E2 when the device
+ is in promiscuous mode. It was having problems with the previous
+ version; this works better.
+
+2001-08-24 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/upd985xx_eth_drivers.cdl: Configury for an alternate case
+ where we workaround hardware bug E2 only, as a subset of the E1E2
+ complete fix. Added more description to the options too.
+
+ * src/if_upd985xx.c (eth_upd985xx_configure): Handle an alternate
+ case where we workaround hardware bug E2 only. This means leaving
+ the device in normal mode (unless set to promisc) and doing MAC
+ address filtering by hand anyway.
+
+2001-08-20 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c: Guard all entrypoints that can mess with
+ hardware state by "active" check. If the net is included in an
+ app, but not used, it is init'd but not started - this can leave a
+ pending interrupt from RedBoot's use of the network to take us
+ completely by surprise. So init() acks and masks the interrupt,
+ can_send(), recv() and deliver() now demur if not active.
+ Also some additional STATIC's on entrypoint functions.
+
+2001-08-16 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (upd985xx_eth_upd985xx_init): If the EEPROM
+ contains nothing (or isn't fitted?) fake an ESA so we can get
+ RedBoot going on the board without special configury.
+
+2001-08-16 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (eth_upd985xx_configure): Use smaller numbers
+ for the Tx Fill Threshold [TX_FLTH] and DMA Tx Burst Size [DTBS]
+ because the hardware is even more broken than first throught -
+ this is new information on fault E4. I also tagged this with the
+ name of the option we would use if this were cdl controlled - but
+ since it's just setup I see no need to change it, so no CDL.
+
+2001-08-16 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (TxDone): Since it still wedged occasionally,
+ with an "out of rx buffers" status but nothing else, this is a
+ much simplified workaround for bug E8. If we see the suspect
+ transmit status, simply reset the whole subsystem there and then.
+ This leaves it in far more of a known state. It's neater anyway.
+
+2001-08-15 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (eth_upd985xx_send): Small hacks to recover
+ from various wedged states with bogus or unexpected ETH_ISR
+ values... 0x80000000: We detect this in the deliver routine and
+ totally reset the system. "out of rx buffers" with no "good rx":
+ we unmask and check for all these RX interrupts, not just "good
+ rx". Also PacketRxReady() shortcuts to resetting the receive
+ engine when it sees the problem. I suspect these might be caused
+ by the E8 workaround below, perhaps introducing some race
+ condition with turning off the receiver just when it rx'd - and of
+ course E1E2 means it receives far more packets.
+
+2001-08-07 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c: Workaround various bugs in the hardware;
+ these workarounds are conditionally compiled via CDL options named
+ CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_xxx in general; 'xxx'
+ is the reference for the mis-feature. All are enabled by default.
+
+ To summarize:
+ (eth_upd985xx_reset): xxx=S1: insert reads between writes to the
+ device to avoid a possible deadlock; macro FLUSH_WRITES().
+ (PacketRxReady): xxx=E1E2: we set the device in promiscuous mode
+ always, and implement ESA matching in code. The cost is small.
+ If promisc mode is set by the stack, we pass all packets.
+ (eth_upd985xx_send): xxx=E3: we copy any transmit that uses 3 or
+ more SGs into a static contiguous buffer and transmit from that
+ thus using only one buffer descriptor.
+ (eth_upd985xx_send):
+ (TxDone): xxx=E8: we make a note that a tx ended badly and when
+ starting the next tx, we disable and reset the transmitter.
+
+ * cdl/upd985xx_eth_drivers.cdl: New subcomponent for controlling
+ these workarounds: CYGPKG_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS.
+ "Workarounds for Ethernet Hardware bugs"
+
+2001-07-16 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (PacketRxReady): Test for, rather than assert,
+ packet size in range. The hardware can report a tiny packet as
+ AOK, with no bad in the status, despite the doc's reassurances.
+
+2001-07-13 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/upd985xx_eth_drivers.cdl: Turn off the startup chatter.
+
+2001-07-13 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (TxDone): Test a few more bits for tx
+ complete; it turns out you can get tx underruns when the CPU us
+ heavily loaded, as in the tcp_echo tests with high load.
+
+2001-07-13 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (eth_upd985xx_send): Use HAL_DCACHE_STORE()
+ rather than syncing the whole of cache every sglist entry(=mbuf).
+ Turns out the cache op must be cache line aligned to work on the
+ 4120, boo, unlike other MIPS and unlike the doc, even.
+
+2001-07-12 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/upd985xx_eth_drivers.cdl (CYGPKG_DEVS_ETH_MIPS_UPD985XX_ETH0):
+ Whole new section to address configuring the source of the MAC
+ address. Also allows configury of the device's name ("eth0") for
+ cohabitation with additional devices.
+
+ * src/if_upd985xx.c (upd985xx_eth_upd985xx_init): Pick up the ESA
+ from EEPROM if it's available, also support a fixed ESA from CDL
+ configuration land. A few minor changes to the structure
+ initialization to accommodate this; also pick up the interrupt
+ vector from struct init.
+ (eth_set_mac_address): New routine available via the ioctl()
+ entry, for use when neither a fixed nor EEPROM address is
+ available.
+
+2001-07-12 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (NUM_RXBUFS): Reduce NUM_RXBUFS to 8; IME
+ fewer results in lost rx's in typical systems. Enlarge rx buffers
+ slightly, to accommodate oversize VLAN packets. 128 bytes extra
+ should be enough. Implemented eth_upd985xx_configure() selection
+ of promiscuous mode and allow oversize packets - up to the allowed
+ oversize. Otherwise we would get confused if a packet ate more
+ than 1 rx buffer.
+
+2001-07-12 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c: Tidy up debug print defaults; make functions
+ static; add a few extra statistics to the device object; pass a
+ p_eth_upd985xx around more consistently for if we switch to
+ multiple devices in future; comment out mii_write(); handle
+ stopping the device with a tx pending; remove some commented-out
+ templates copied from another driver; and fill in SNMP statistics.
+ In other words, many minor changes.
+
+2001-07-11 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c (PacketRxReady): Recover from running out of
+ receive buffers. All very dodgy, but it seems to work.
+ Additional efforts are also made to reset the device, having
+ realized how hard it is to re-initialize the receive engine once
+ it has been awakened.
+
+2001-07-11 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c: Efficient Rx now essentially working, with a
+ simple circular buffer, always linked into a ring, and one entry
+ of which is always NULL,NULL to bring the rx machinery to a halt.
+ If it reaches thus far the rx mechanism seems to jam; will deal
+ with that next.
+
+2001-07-09 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_upd985xx.c: Rejigged version of the rx buffer system;
+ still not working properly, still not a good match for the
+ hardware's elusive semantics. Committed anyway, to keep it around
+ for reference.
+ (eth_upd985xx_status): Also removed all the cruft about
+ renegotiating line status; it's not needed.
+
+2001-07-06 Hugo Tyson <hmt@redhat.com>
+
+ * include/upd985xx_eth.h (ETH_MADR_PHY_DEVICE_PHYS_ADDRESS):
+ Change name of PHY address symbol to generic not SEEQ.
+ Comment out the non-standard symbols for useful bits that the
+ previous PHY device supported.
+
+ * src/if_upd985xx.c (eth_upd985xx_reset): If there is a valid ESA
+ in the MAC already, run with it - it would have come from the
+ not-fitted serial EEPROM, via some different registers.
+ (upd985xx_eth_upd985xx_init): Moved the call to reset about to
+ accommodate this.
+ (eth_upd985xx_status): Omit renegotiation of link properties and
+ use the intersection of the capabilities bits to report what
+ speed, duplex, we are running at. More portable.
+ (mii_write):
+ (mii_read): Change name of PHY address symbol to generic not SEEQ
+ 'cos the board has changed.
+
+2001-07-06 Hugo Tyson <hmt@redhat.com>
+
+ * ChangeLog:
+ * cdl/upd985xx_eth_drivers.cdl:
+ * include/upd985xx_eth.h:
+ * src/if_upd985xx.c:
+ New files. Initial checkin of limping along version of
+ NEC upd985xx ethernet driver.
+
+ Limitations:
+ ESA is hard coded.
+ It talks to the PHY just to make sure - helped with debug anyway.
+ No SNMP data exported.
+ No ioctl() for promiscuous mode or VLAN mode.
+ Only one TX at once.
+ Only one RX buffer, so no RX until serviced.
+ It seems to loose interrupts - inevitably, for an eth device - and
+ there's no "catchup" defense against this yet.
+
+ It's oriented to the "old" (already) board - so the particular PHY
+ and GPIO layout.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/mips/upd985xx/current/cdl/upd985xx_eth_drivers.cdl b/ecos/packages/devs/eth/mips/upd985xx/current/cdl/upd985xx_eth_drivers.cdl
new file mode 100644
index 0000000..7357aca
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/upd985xx/current/cdl/upd985xx_eth_drivers.cdl
@@ -0,0 +1,204 @@
+# ====================================================================
+#
+# upd985xx_eth_drivers.cdl
+#
+# Ethernet drivers
+# NEC uPD985xx device specific support
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): hmt
+# Original data: hmt
+# Contributors: gthomas
+# Date: 2001-06-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_MIPS_UPD985XX {
+ display "NEC uPD985xx ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_MIPS_UPD985XX
+
+ implements CYGHWR_NET_DRIVER_ETH0
+
+ implements CYGHWR_NET_DRIVERS
+ include_dir cyg/devs/eth
+
+ description "Ethernet driver for NEC uPD985xx devices."
+ compile -library=libextras.a if_upd985xx.c
+
+ cdl_option CYGDBG_DEVS_ETH_MIPS_UPD985XX_CHATTER {
+ display "Prints ethernet device status info during startup"
+ default_value 0
+ description "
+ The ethernet device initialization code can print lots of info
+ to confirm that it has booted correctly."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_MIPS_UPD985XX_DEV_COUNT {
+ display "Number of supported interfaces."
+ #legal_values 1
+ #default_value 1
+ calculated 1
+ flavor data
+ description "
+ This option selects the number of ethernet interfaces to
+ be supported by the driver."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MIPS_UPD985XX_ETH0 {
+ display "Ethernet port 0 driver"
+ flavor bool
+ calculated 1
+ description "
+ This option includes the ethernet device driver for
+ port 0 - that is the only connector
+ depending on your particular hardware."
+
+
+ cdl_option CYGDAT_DEVS_ETH_UPD985XX_ETH0_NAME {
+ display "Device name for the ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_UPD985XX_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value false
+ requires !CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_UPD985XX_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xBA, 0xCA, 0xDD, 0x1E, 0xDD}"}
+ description "The ethernet station address"
+ }
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA {
+ display "Get the ethernet station address from EEPROM"
+ flavor bool
+ default_value !CYGSEM_DEVS_ETH_UPD985XX_ETH0_SET_ESA
+ requires !CYGSEM_DEVS_ETH_UPD985XX_ETH0_SET_ESA
+ description "Enabling this option will allow the ethernet
+ station address to be read from a serial EEPROM (such as 93C06,
+ 93C46...). If this is not valid, your application must set the
+ ESA manually via an ioctl() call or similar."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MIPS_UPD985XX_OPTIONS {
+ display "NEC uPD985xx ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_MIPS_UPD985XX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the NEC uPD985xx ethernet driver
+ package. These flags are used in addition to the set of
+ global flags."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS {
+ display "Workarounds for Ethernet Hardware bugs "
+ flavor bool
+ default_value 1
+ description "
+ This component controls whether code workarounds for the numerous
+ hardware bugs in the uPD98503 Ethernet device are included.
+ These might not all be necessary depending on the speed and mode in
+ which the interface is used. Please refer to the manufacturer's
+ Behaviour Analysis Report to make your decision about which of
+ these options to enable or disable.
+ The default is to enable all workarounds for best reliability."
+
+ cdl_option CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_S1 {
+ display "S1 - CPU to IBUS write restriction"
+ flavor bool
+ default_value 1
+ description "Enable a workaround for hardware bug S1"
+ }
+ cdl_component CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2 {
+ display "E1,E2 - Status queue corruption and MAC filtering"
+ flavor bool
+ default_value 1
+ description "Enable a workaround for hardware bugs E1 and/or E2."
+
+ cdl_option CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY {
+ display "Do not set device in promisc mode - solve E2 only"
+ flavor bool
+ default_value 1
+ description "Work around bug E2 only - do not set the device
+ in promiscuous mode by default.
+ Setting this option prevents the work around
+ for bug E1."
+ }
+ }
+ cdl_option CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3 {
+ display "E3 - Transmit descriptor error"
+ flavor bool
+ default_value 1
+ description "Enable a workaround for hardware bug E3"
+
+ }
+ cdl_option CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E8 {
+ display "E8 - Transmission error under abnormal conditions"
+ flavor bool
+ default_value 1
+ description "Enable a workaround for hardware bug E8"
+ }
+ }
+}
+
+# EOF upd985xx_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/mips/upd985xx/current/include/upd985xx_eth.h b/ecos/packages/devs/eth/mips/upd985xx/current/include/upd985xx_eth.h
new file mode 100644
index 0000000..398099f
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/upd985xx/current/include/upd985xx_eth.h
@@ -0,0 +1,464 @@
+#ifndef CYGONCE_HAL_UPD985XX_ETH_H
+#define CYGONCE_HAL_UPD985XX_ETH_H
+//==========================================================================
+//
+// upd985xx_eth.h
+//
+// Architecture specific abstractions for the on-chip ethernet
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt, nickg
+// Contributors: nickg
+// Date: 2001-06-28
+// Purpose: Define architecture abstractions
+// Description: This file contains any extra or modified definitions for
+// this variant of the architecture's ethernet controller.
+// Usage: #include <cyg/io/upd985xx_eth.h>
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/var_arch.h>
+
+// --------------------------------------------------------------------------
+// By default we use the definition of UPD985XX_SYSETH_REG( n ) from
+// var_arch.h - if we port to a KORVA with multiple ethernet controllers we
+// will have to vary this to account for the different base addresses.
+
+// (the noise at the end of these lines is the default value)
+//
+// Table 5-2. MAC Control Register Map
+//
+#define ETH_MACC1 UPD985XX_SYSETH_REG( 0x000) // MAC configuration register 1 R/W 0000_0000H
+#define ETH_MACC2 UPD985XX_SYSETH_REG( 0x004) // MAC configuration register 2 R/W 0000_0000H
+#define ETH_IPGT UPD985XX_SYSETH_REG( 0x008) // Back-to-Back IPG register R/W 0000_0013H
+#define ETH_IPGR UPD985XX_SYSETH_REG( 0x00C) // Non Back-to-Back IPG register R/W 0000_0E13H
+#define ETH_CLRT UPD985XX_SYSETH_REG( 0x010) // Collision register R/W 0000_370FH
+#define ETH_LMAX UPD985XX_SYSETH_REG( 0x014) // Max packet length register R/W 0000_0600H
+// N/A UPD985XX_SYSETH_REG( 0x018) // Reserved for future use - -
+#define ETH_RETX UPD985XX_SYSETH_REG( 0x020) // Retry count register R/W 0000_0000H
+// N/A UPD985XX_SYSETH_REG( 0x024) // Reserved for future use - -
+#define ETH_LSA2 UPD985XX_SYSETH_REG( 0x054) // Station Address register 2 R/W 0000_0000H
+#define ETH_LSA1 UPD985XX_SYSETH_REG( 0x058) // Station Address register 1 R/W 0000_0000H
+#define ETH_PTVR UPD985XX_SYSETH_REG( 0x05C) // Pause timer value read register R 0000_0000H
+// N/A UPD985XX_SYSETH_REG( 0x060) // Reserved for future use - -
+#define ETH_VLTP UPD985XX_SYSETH_REG( 0x064) // VLAN type register R/W 0000_0000H
+#define ETH_MIIC UPD985XX_SYSETH_REG( 0x080) // MII configuration register R/W 0000_0000H
+// N/A UPD985XX_SYSETH_REG( 0x084) // Reserved for future use - -
+#define ETH_MCMD UPD985XX_SYSETH_REG( 0x094) // MII command register W 0000_0000H
+#define ETH_MADR UPD985XX_SYSETH_REG( 0x098) // MII address register R/W 0000_0000H
+#define ETH_MWTD UPD985XX_SYSETH_REG( 0x09C) // MII write data register R/W 0000_0000H
+#define ETH_MRDD UPD985XX_SYSETH_REG( 0x0A0) // MII read data register R 0000_0000H
+#define ETH_MIND UPD985XX_SYSETH_REG( 0x0A4) // MII indicator register R 0000_0000H
+// N/A UPD985XX_SYSETH_REG( 0x0A8) // Reserved for future use - -
+#define ETH_AFR UPD985XX_SYSETH_REG( 0x0C8) // Address Filtering register R/W 0000_0000H
+#define ETH_HT1 UPD985XX_SYSETH_REG( 0x0CC) // Hash table register 1 R/W 0000_0000H
+#define ETH_HT2 UPD985XX_SYSETH_REG( 0x0D0) // Hash table register 2 R/W 0000_0000H
+// N/A UPD985XX_SYSETH_REG( 0x0D4) // Reserved for future use - -
+#define ETH_CAR1 UPD985XX_SYSETH_REG( 0x0DC) // Carry register 1 R/W 0000_0000H
+#define ETH_CAR2 UPD985XX_SYSETH_REG( 0x0E0) // Carry register 2 R/W 0000_0000H
+// N/A UPD985XX_SYSETH_REG( 0x0E4) // Reserved for future use - -
+#define ETH_CAM1 UPD985XX_SYSETH_REG( 0x130) // Carry mask register 1 R/W 0000_0000H
+#define ETH_CAM2 UPD985XX_SYSETH_REG( 0x134) // Carry mask register 2 R/W 0000_0000H
+// N/A UPD985XX_SYSETH_REG( 0x138) // Reserved for future use - -
+//
+// Table 5-3. Statistics Counter Register Map
+//
+#define ETH_RBYT UPD985XX_SYSETH_REG( 0x140) // Receive Byte Counter R/W
+#define ETH_RPKT UPD985XX_SYSETH_REG( 0x144) // Receive Packet Counter R/W
+#define ETH_RFCS UPD985XX_SYSETH_REG( 0x148) // Receive FCS Error Counter R/W
+#define ETH_RMCA UPD985XX_SYSETH_REG( 0x14C) // Receive Multicast Packet Counter R/W
+#define ETH_RBCA UPD985XX_SYSETH_REG( 0x150) // Receive Broadcast Packet Counter R/W
+#define ETH_RXCF UPD985XX_SYSETH_REG( 0x154) // Receive Control Frame Packet Counter R/W
+#define ETH_RXPF UPD985XX_SYSETH_REG( 0x158) // Receive PAUSE Frame Packet Counter R/W
+#define ETH_RXUO UPD985XX_SYSETH_REG( 0x15C) // Receive Unknown OP code Counter R/W
+#define ETH_RALN UPD985XX_SYSETH_REG( 0x160) // Receive Alignment Error Counter R/W
+#define ETH_RFLR UPD985XX_SYSETH_REG( 0x164) // Receive Frame Length Out of Range Counter R/W
+#define ETH_RCDE UPD985XX_SYSETH_REG( 0x168) // Receive Code Error Counter R/W
+#define ETH_RFCR UPD985XX_SYSETH_REG( 0x16C) // Receive False Carrier Counter R/W
+#define ETH_RUND UPD985XX_SYSETH_REG( 0x170) // Receive Undersize Packet Counter R/W
+#define ETH_ROVR UPD985XX_SYSETH_REG( 0x174) // Receive Oversize Packet Counter R/W
+#define ETH_RFRG UPD985XX_SYSETH_REG( 0x178) // Receive Error Undersize Packet Counter R/W
+#define ETH_RJBR UPD985XX_SYSETH_REG( 0x17C) // Receive Error Oversize Packet Counter R/W
+#define ETH_R64 UPD985XX_SYSETH_REG( 0x180) // Receive 64 Byte Frame Counter R/W
+#define ETH_R127 UPD985XX_SYSETH_REG( 0x184) // Receive 65 to 127 Byte Frame Counter R/W
+#define ETH_R255 UPD985XX_SYSETH_REG( 0x188) // Receive 128 to 255 Byte Frame Counter R/W
+#define ETH_R511 UPD985XX_SYSETH_REG( 0x18C) // Receive 256 to 511 Byte Frame Counter R/W
+#define ETH_R1K UPD985XX_SYSETH_REG( 0x190) // Receive 512 to 1023 Byte Frame Counter R/W
+#define ETH_RMAX UPD985XX_SYSETH_REG( 0x194) // Receive Over 1023 Byte Frame Counter R/W
+#define ETH_RVBT UPD985XX_SYSETH_REG( 0x198) // Receive Valid Byte Counter R/W
+#define ETH_TBYT UPD985XX_SYSETH_REG( 0x1C0) // Transmit Byte Counter R/W
+#define ETH_TPCT UPD985XX_SYSETH_REG( 0x1C4) // Transmit Packet Counter R/W
+#define ETH_TFCS UPD985XX_SYSETH_REG( 0x1C8) // Transmit CRC Error Packet Counter R/W
+#define ETH_TMCA UPD985XX_SYSETH_REG( 0x1CC) // Transmit Multicast Packet Counter R/W
+#define ETH_TBCA UPD985XX_SYSETH_REG( 0x1D0) // Transmit Broadcast Packet Counter R/W
+#define ETH_TUCA UPD985XX_SYSETH_REG( 0x1D4) // Transmit Unicast Packet Counter R/W
+#define ETH_TXPF UPD985XX_SYSETH_REG( 0x1D8) // Transmit PAUSE control Frame Counter R/W
+#define ETH_TDFR UPD985XX_SYSETH_REG( 0x1DC) // Transmit Single Deferral Packet Counter R/W
+#define ETH_TXDF UPD985XX_SYSETH_REG( 0x1E0) // Transmit Excessive Deferral Packet Counter R/W
+#define ETH_TSCL UPD985XX_SYSETH_REG( 0x1E4) // Transmit Single Collision Packet Counter R/W
+#define ETH_TMCL UPD985XX_SYSETH_REG( 0x1E8) // Transmit Multiple collision Packet Counter R/W
+#define ETH_TLCL UPD985XX_SYSETH_REG( 0x1EC) // Transmit Late Collision Packet Counter R/W
+#define ETH_TXCL UPD985XX_SYSETH_REG( 0x1F0) // Transmit Excessive Collision Packet Counter R/W
+#define ETH_TNCL UPD985XX_SYSETH_REG( 0x1F4) // Transmit Total Collision Counter R/W
+#define ETH_TCSE UPD985XX_SYSETH_REG( 0x1F8) // Transmit Carrier Sense Error Counter R/W
+#define ETH_TIME UPD985XX_SYSETH_REG( 0x1FC) // Transmit Internal MAC Error Counter R/W
+//
+// Table 5-4. DMA and FIFO Management Registers Map
+//
+#define ETH_TXCR UPD985XX_SYSETH_REG( 0x200) // Transmit Configuration Register R/W 0000_0000H
+#define ETH_TXFCR UPD985XX_SYSETH_REG( 0x204) // Transmit FIFO Control Register R/W FFFF_40C0H
+#define ETH_TXDTR UPD985XX_SYSETH_REG( 0x208) // Transmit Data Register W 0000_0000H
+#define ETH_TXSR UPD985XX_SYSETH_REG( 0x20C) // Transmit Status Register R 0000_0000H
+// N/A UPD985XX_SYSETH_REG( 0x210) // Reserved for future use - -
+#define ETH_TXDPR UPD985XX_SYSETH_REG( 0x214) // Transmit Descriptor Pointer R/W 0000_0000H
+#define ETH_RXCR UPD985XX_SYSETH_REG( 0x218) // Receive Configuration Register R/W 0000_0000H
+#define ETH_RXFCR UPD985XX_SYSETH_REG( 0x21C) // Receive FIFO Control Register R/W C040_0040H
+#define ETH_RXDTR UPD985XX_SYSETH_REG( 0x220) // Receive Data Register R 0000_0000H
+#define ETH_RXSR UPD985XX_SYSETH_REG( 0x224) // Receive Status Register R 0000_0000H
+// N/A UPD985XX_SYSETH_REG( 0x228) // Reserved for future use - -
+#define ETH_RXDPR UPD985XX_SYSETH_REG( 0x22C) // Receive Descriptor Pointer R/W 0000_0000H
+#define ETH_RXPDR UPD985XX_SYSETH_REG( 0x230) // Receive Pool Descriptor Register R/W 0000_0000H
+//
+// Table 5-5. Interrupt and Configuration Registers Map
+//
+#define ETH_CCR UPD985XX_SYSETH_REG( 0x234) // Configuration Register R/W 0000_0000H
+#define ETH_ISR UPD985XX_SYSETH_REG( 0x238) // Interrupt Service Register R 0000_0000H
+#define ETH_MSR UPD985XX_SYSETH_REG( 0x23C) // Mask Serves Register R/W 0000_0000H
+
+// --------------------------------------------------------------------------
+// Now the fields within all those registers...
+//
+// Table 5-2. MAC Control Register Map
+//
+// ETH_MACC1 0x000 MAC configuration register 1 R/W 0000_0000H
+#define ETH_MACC1_MACLB (1<<14) // MAC loopback: 0
+#define ETH_MACC1_TXFC (1<<11) // Transmit flow control enable: 0
+#define ETH_MACC1_RXFC (1<<10) // Receive flow control enable: 0
+#define ETH_MACC1_SRXEN (1<< 9) // Receive enable: 0
+#define ETH_MACC1_PARF (1<< 8) // Control packet pass: 0
+#define ETH_MACC1_PUREP (1<< 7) // Pure preamble: 0
+#define ETH_MACC1_FLCHT (1<< 6) // Length field check: 0
+#define ETH_MACC1_NOBO (1<< 5) // No Back Off: 0
+#define ETH_MACC1_CRCEN (1<< 3) // CRC append enable: 0
+#define ETH_MACC1_PADEN (1<< 2) // PAD append enable: 0
+#define ETH_MACC1_FDX (1<< 1) // Full duplex enable: 0
+#define ETH_MACC1_HUGEN (1<< 0) // Large packet enable: 0
+// ETH_MACC2 0x004 MAC configuration register 2 R/W 0000_0000H
+#define ETH_MACC2_MCRST (1<<10) // MAC Control Block software reset: 0
+#define ETH_MACC2_RFRST (1<< 9) // Receive Function Block software reset: 0
+#define ETH_MACC2_TFRST (1<< 8) // Transmit Function Block software reset: 0
+#define ETH_MACC2_BPNB (1<< 6) // Back Pressure No Back Off: 0
+#define ETH_MACC2_APD (1<< 5) // Auto VLAN PAD: 0
+#define ETH_MACC2_VPD (1<< 4) // VLAN PAD mode: 0
+
+// ETH_IPGT 0x008 Back-to-Back IPG register R/W 0000_0013H
+// ETH_IPGR 0x00C Non Back-to-Back IPG register R/W 0000_0E13H
+// ETH_CLRT 0x010 Collision register R/W 0000_370FH
+// ETH_LMAX 0x014 Max packet length register R/W 0000_0600H
+// N/A 0x018 Reserved for future use - -
+// ETH_RETX 0x020 Retry count register R/W 0000_0000H
+// N/A 0x024 Reserved for future use - -
+// ETH_LSA2 0x054 Station Address register 2 R/W 0000_0000H
+// ETH_LSA1 0x058 Station Address register 1 R/W 0000_0000H
+// ETH_PTVR 0x05C Pause timer value read register R 0000_0000H
+// N/A 0x060 Reserved for future use - -
+// ETH_VLTP 0x064 VLAN type register R/W 0000_0000H
+#define ETH_VLTP_VLTP (0x00008100) // magic number from example
+// ETH_MIIC 0x080 MII configuration register R/W 0000_0000H
+#define ETH_MIIC_MIRST (1<<15) // MII Management Interface Block software reset
+#define ETH_MIIC_CLKS (0x0C) // 3:2 CLKS Select frequency range:
+#define ETH_MIIC_25 (0x00) // 00: HCLK is equal to 25 MHz
+#define ETH_MIIC_33 (0x04) // 01: HCLK is less than or equal to 33 MHz
+#define ETH_MIIC_50 (0x08) // 10: HCLK is less than or equal to 50 MHz
+#define ETH_MIIC_66 (0x0C) // 11: HCLK is less than or equal to 66 MHz
+// ETH_MCMD 0x094 MII command register W 0000_0000H
+#define ETH_MCMD_SCANC (1<< 1) // SCAN command: 0
+#define ETH_MCMD_RSTAT (1<< 0) // MII management read: 0
+// ETH_MADR 0x098 MII address register R/W 0000_0000H
+#define ETH_MADR_PHY_ADDR_SHIFT (8)
+// ETH_MWTD 0x09C MII write data register R/W 0000_0000H
+// ETH_MRDD 0x0A0 MII read data register R 0000_0000H
+// ETH_MIND 0x0A4 MII indicator register R 0000_0000H
+#define ETH_MIND_NVALID (1<< 2) // SCAN command start status: 0
+#define ETH_MIND_SCANA (1<< 1) // SCAN command active: 0
+#define ETH_MIND_BUSY (1<< 0) // BUSY: 0
+// ETH_AFR 0x0C8 Address Filtering register R/W 0000_0000H
+#define ETH_AFR_PRO (1<< 3) // Promiscuous mode: 0
+#define ETH_AFR_PRM (1<< 2) // Accept Multicast: 0
+#define ETH_AFR_AMC (1<< 1) // Accept Multicast ( qualified ): 0
+#define ETH_AFR_ABC (1<< 0) // Accept Broadcast: 0
+// ETH_HT1 0x0CC Hash table register 1 R/W 0000_0000H
+// ETH_HT2 0x0D0 Hash table register 2 R/W 0000_0000H
+// ETH_CAR1 0x0DC Carry register 1 R/W 0000_0000H
+// ETH_CAR2 0x0E0 Carry register 2 R/W 0000_0000H
+// ETH_CAM1 0x130 Carry mask register 1 R/W 0000_0000H
+// ETH_CAM2 0x134 Carry mask register 2 R/W 0000_0000H
+//
+// Table 5-3. Statistics Counter Register Map
+// <snip>
+//
+// Table 5-4. DMA and FIFO Management Registers Map
+//
+// ETH_TXCR 0x200 Transmit Configuration Register R/W 0000_0000H
+#define ETH_TXCR_TXE (1<<31) // Transmit Enable:
+#define ETH_TXCR_DTBS_SHIFT (16) // 18:16 DMA Transmit Burst Size:
+#define ETH_TXCR_DTBS (0x70000) // 18:16 DMA Transmit Burst Size:
+#define ETH_TXCR_DTBS_1 (0x00000) // 000: 1 Word (4 bytes)
+#define ETH_TXCR_DTBS_2 (0x10000) // 001: 2 Word (8 bytes)
+#define ETH_TXCR_DTBS_4 (0x20000) // 010: 4 Word (16 bytes)
+#define ETH_TXCR_DTBS_8 (0x30000) // 011: 8 Word (32 bytes)
+#define ETH_TXCR_DTBS_16 (0x40000) // 100: 16 Word (64 bytes)
+#define ETH_TXCR_DTBS_32 (0x50000) // 101: 32 Word (128 bytes)
+#define ETH_TXCR_DTBS_64 (0x60000) // 110: 64 Word (256 bytes)
+#define ETH_TXCR_AFCE (1<< 0) // Auto Flow Control Enable:
+// ETH_TXFCR 0x204 Transmit FIFO Control Register R/W FFFF_40C0H
+#define ETH_TXFCR_TPTV_SHIFT (16) // 31:16 Transmit Pause Timer Value: FFFFH
+#define ETH_TXFCR_TPTV (0xffff0000) // 31:16 Transmit Pause Timer Value: FFFFH
+#define ETH_TXFCR_TX_DRTH_SHIFT (10) // 15:10 Transmit Drain Threshold Level: 10H
+#define ETH_TXFCR_TX_DRTH (0x0000fc00) // 15:10 Transmit Drain Threshold Level: 10H
+#define ETH_TXFCR_TX_FLTH_SHIFT (2) // 7:2 Transmit Fill Threshold Level: 03H
+#define ETH_TXFCR_TX_FLTH (0x000000fc) // 7:2 Transmit Fill Threshold Level: 03H
+#define ETH_TXFCR_TPTV_DEFAULT (0x10000000) // default 0x1000 slot time (1slot:512bit)
+#define ETH_TXFCR_TX_DRTH_DEFAULT (0x00002000) // 001000b (8long, 32byte)
+#define ETH_TXFCR_TX_FLTH_DEFAULT (0x000000c0) // default 110000b (48word, 192byte)
+// ETH_TXDTR 0x208 Transmit Data Register W 0000_0000H
+// ETH_TXSR 0x20C Transmit Status Register R 0000_0000H
+#define ETH_TXSR_CSE (1<<31) // Carrier lost was detected during the transmission 0
+#define ETH_TXSR_TBP (1<<30) // Back pressure occurred when the packet was received 0
+#define ETH_TXSR_TPP (1<<29) // A packet request during the PAUSE operation was transmitted 0
+#define ETH_TXSR_TPCF (1<<28) // A PAUSE control frame was transmitted 0
+#define ETH_TXSR_TCFR (1<<27) // A control frame was transmitted 0
+#define ETH_TXSR_TUDR (1<<26) // The TPUR pin was set high and aborted. Note 2 0
+#define ETH_TXSR_TGNT (1<<25) // A huge packet was transmitted and aborted. 0
+#define ETH_TXSR_LCOL (1<<24) // Collision occurred
+#define ETH_TXSR_ECOL (1<<23) // Excess collisions
+#define ETH_TXSR_TEDFR (1<<22) // Excess deferred
+#define ETH_TXSR_TDFR (1<<21) // Transmission deferral occurred
+#define ETH_TXSR_TBRO (1<<20) // A broadcast packet was transmitted. 0
+#define ETH_TXSR_TMUL (1<<19) // A multicast packet was transmitted. 0
+#define ETH_TXSR_TDONE (1<<18) // Transmission was completed. 0
+#define ETH_TXSR_TFLOR (1<<17) // Value of the length field was huge
+#define ETH_TXSR_TFLER (1<<16) // Value of the length field didn~t match the actual data count
+#define ETH_TXSR_TCRCE (1<<15) // Attached CRC didn~t match the internal generated CRC
+
+#define ETH_TXSR_TCBC_SHIFT (11) // 14:11 collisions for the previous transmission
+#define ETH_TXSR_TCBC (0x7800) // 14:11 collisions for the previous transmission
+#define ETH_TXSR_TBYT_SHIFT (0) // 10:0 transmitted bytes not including collided bytes
+#define ETH_TXSR_TBYT (0x07FF) // 10:0 transmitted bytes not including collided bytes
+
+// ETH_RXCR UPD985XX_SYSETH_REG( 0x218) // Receive Configuration Register R/W 0000_0000H
+#define ETH_RXCR_RXE (1<<31) // Receive Enable:
+#define ETH_RXCR_DRBS_SHIFT (16) // 18:16 DRBS DMA Transmit Burst Size: 0
+#define ETH_RXCR_DRBS (0x70000) //
+#define ETH_RXCR_DRBS_1 (0x00000) // 000: 1 Word (4 bytes)
+#define ETH_RXCR_DRBS_2 (0x10000) // 001: 2 Word (8 bytes)
+#define ETH_RXCR_DRBS_4 (0x20000) // 010: 4 Word (16 bytes)
+#define ETH_RXCR_DRBS_8 (0x30000) // 011: 8 Word (32 bytes)
+#define ETH_RXCR_DRBS_16 (0x40000) // 100: 16 Word (64 bytes)
+#define ETH_RXCR_DRBS_32 (0x50000) // 101: 32 Word (128 bytes)
+#define ETH_RXCR_DRBS_64 (0x60000) // 110: 64 Word (256 bytes)
+
+// ETH_RXFCR 0x21C Receive FIFO Control Register R/W C040_0040H
+#define ETH_RXFCR_UWM (0xfc000000) // 31:26 Upper Water Mark: 30H
+#define ETH_RXFCR_UWM_SHIFT (26) // 31:26 Upper Water Mark: 30H
+#define ETH_RXFCR_LWM (0x00fc0000) // 23:18 Lower Water Mark: 10H
+#define ETH_RXFCR_LWM_SHIFT (18) // 23:18 Lower Water Mark: 10H
+#define ETH_RXFCR_RX_DRTH (0x000000fc) // 7: 2 Receive Drain Threshold Level 10H
+#define ETH_RXFCR_RX_DRTH_SHIFT (2) // 7: 2 Receive Drain Threshold Level 10H
+#define ETH_RXFCR_UWM_DEFAULT (0xE0000000) // default 110000b ( 48word, 192byte )
+#define ETH_RXFCR_LWM_DEFAULT (0x00400000) // default 010000b (16word, 64byte)
+#define ETH_RXFCR_DRTH16W (0x00000040) // default 010000b (16word, 64byte)
+
+// ETH_RXDTR 0x220 Receive Data Register R 0000_0000H
+// ETH_RXSR 0x224 Receive Status Register R 0000_0000H
+#define ETH_RXSR_RLENE (1<<31) // A toosmall or toolarge packet was received.
+#define ETH_RXSR_VLAN (1<<30) // A VLAN was received.
+#define ETH_RXSR_USOP (1<<29) // A control frame containing an unknown OP code was received.
+#define ETH_RXSR_PRCF (1<<28) // A control frame containing the PAUSE OP code was received.
+#define ETH_RXSR_RCFR (1<<27) // A control frame was received.
+#define ETH_RXSR_DBNB (1<<26) // An alignment error occurred.
+#define ETH_RXSR_RBRO (1<<25) // A broadcast packet was received. 0
+#define ETH_RXSR_RMUL (1<<24) // A multicast packet was received. 0
+#define ETH_RXSR_RXOK (1<<23) // A good packet was received.
+#define ETH_RXSR_RLOR (1<<22) // The value of the length field was huge
+#define ETH_RXSR_RLER (1<<21) // The value of the length field didn~t match
+#define ETH_RXSR_RCRCE (1<<20) // A CRC error occurred. 0
+#define ETH_RXSR_RCV (1<<19) // RXER was detected. 0
+#define ETH_RXSR_CEPS (1<<18) // A False Carrier was detected. 0
+#define ETH_RXSR_REPS (1<<17) // A packet which had a preamble and SFD only or one data nibble
+#define ETH_RXSR_PAIG (1<<16) //
+#define ETH_RXSR_RBYT (0xffff) // 15:0 The received byte count 0
+#define ETH_RXSR_RBYT_SHIFT (0) // 15:0 The received byte count 0
+// ETH_RXDPR 0x22C Receive Descriptor Register R/W 0000_0000H
+// ETH_RXPDR 0x230 Receive Pool Descriptor Register R/W 0000_0000H
+#define ETH_RXPDR_AL (0x70000000) // 30:28 AL[2:0] Alert Level 0H
+#define ETH_RXPDR_AL_SHIFT (28)
+#define ETH_RXPDR_RNOD (0xffff) // 15:0 Remaining Number of Descriptor 0H
+#define ETH_RXPDR_RNOD_SHIFT (0)
+//
+// Table 5-5. Interrupt and Configuration Registers Map
+//
+// ETH_CCR 0x234 Configuration Register R/W 0000_0000H
+#define ETH_CCR_SRT (1) // Software Reset (cleared automatically to '0')
+// ETH_ISR 0x238 Interrupt Service Register R 0000_0000H
+#define ETH_ISR_XMTDN (1<<15) // Transmit Done
+#define ETH_ISR_TBDR (1<<14) // Transmit Buffer Descriptor Request at Null
+#define ETH_ISR_TFLE (1<<13) // Transmit Frame Length Exceed
+#define ETH_ISR_UR (1<<12) // Underrun
+#define ETH_ISR_TABR (1<<11) // Transmit Aborted
+#define ETH_ISR_TCFRI (1<<10) // Control Frame Transmit
+#define ETH_ISR_RCVDN (1<<7 ) // Receive Done
+#define ETH_ISR_RBDRS (1<<6 ) // Receive Buffer Descriptor Request at alert level
+#define ETH_ISR_RBDRU (1<<5 ) // Receive Buffer Descriptor Request at zero
+#define ETH_ISR_OF (1<<4 ) // Overflow
+#define ETH_ISR_LFAL (1<<3 ) // Link Failed
+#define ETH_ISR_CARRY (1<<0 ) // Carry Flag:
+// ETH_MSR 0x23C Mask Serves Register R/W 0000_0000H
+// As above
+
+// --------------------------------------------------------------------------
+// And the "buffer descriptor" control structures in RAM...
+
+
+#define ETH_BUF_LAST (1<<31) // Last Descriptor
+#define ETH_BUF_D_L (1<<30) // Data Buffer / Link Pointer
+#define ETH_BUF_D_L_DATA (1<<30) // Data Buffer / Link Pointer
+#define ETH_BUF_D_L_LINK (0<<30) // Data Buffer / Link Pointer
+#define ETH_BUF_OWN (1<<29) // Owner 1:Ethernet Controller 0: VR4120A
+#define ETH_BUF_OWN_ETH (1<<29)
+#define ETH_BUF_OWN_CPU (0<<29)
+
+#define ETH_BUF_DBRWE (1<<28) // Buffer Access Error
+#define ETH_BUF_OK (1<<16) // Tx or Rx OK
+#define ETH_BUF_SIZE (0xffff) // Byte Count
+
+#define ETH_BUF_TX_TUDR (1<<27) // Transmit Underrun Error
+#define ETH_BUF_TX_CSE (1<<26) // Carrier Sense Lost Error
+#define ETH_BUF_TX_LCOL (1<<25) // Late Collision
+#define ETH_BUF_TX_ECOL (1<<24) // Excessive Collision
+#define ETH_BUF_TX_EDFR (1<<23) // Excessive Deferral
+#define ETH_BUF_TX_TGNT (1<<18) // Transmit Giant Frame
+#define ETH_BUF_TX_HBF (1<<17) // Heart Beat Fail for ENDEC mode
+
+#define ETH_BUF_RX_OVRN (1<<24) // Overrun Error
+#define ETH_BUF_RX_RUNT (1<<23) // Runt packet
+#define ETH_BUF_RX_FRGE (1<<22) // Fragment Error
+#define ETH_BUF_RX_RCV (1<<21) // Detects RXER
+#define ETH_BUF_RX_FC (1<<20) // False Carrier
+#define ETH_BUF_RX_CRCE (1<<19) // CRC Error
+#define ETH_BUF_RX_FAE (1<<18) // Frame Alignment Error
+#define ETH_BUF_RX_RFLE (1<<17) // Receive Frame Length Error
+
+#define ETH_BUF_RX_FTYP (0x0e000000) // 27:25 Frame Type[2:0]
+#define ETH_BUF_RX_FTYP_SHIFT (25) // 27:25 Frame Type[2:0]
+// I don't think we need to know these...
+// 000 Broadcast Frame
+// 001 Multicast Frame
+// 010 Unicast Frame
+// 011 VLAN Frame
+// 100 PAUSE control frame
+// 101 Control Frame (except pause)
+// 11x Reserved for future use
+
+
+// --------------------------------------------------------------------------
+// MII stuff for talking to the separate PHY
+// Initially this was a SEEQ NQ80225 but now it is a LU3X31T-T64.
+
+//#define SEEQ_DEVICE_PHYS_ADDRESS (1) // this from the board documentation
+#define LU3X31T_DEVICE_PHYS_ADDRESS (2)
+
+#define ETH_MADR_PHY_DEVICE_PHYS_ADDRESS \
+ (LU3X31T_DEVICE_PHYS_ADDRESS << ETH_MADR_PHY_ADDR_SHIFT)
+
+// I don't know how much they have in common, but I think MII is pretty
+// standard, and the "mandated" registers ought to be common.
+
+#define PHY_CONTROL_REG (0)
+#define PHY_STATUS_REG (1)
+#define PHY_ID_ONE (2)
+#define PHY_ID_TWO (3)
+#define PHY_AUTONEG_ADVERT (4)
+#define PHY_AUTONEG_REMOTE (5)
+#define PHY_STATUS_DETECT_REG (18)
+
+#define PHY_CONTROL_RESET (1<<15)
+#define PHY_CONTROL_LOOPBACK (1<<14)
+#define PHY_CONTROL_SPEED100 (1<<13)
+#define PHY_CONTROL_AUTONEG_EN (1<<12)
+#define PHY_CONTROL_POWERDOWN (1<<11)
+#define PHY_CONTROL_MII_DIS (1<<10)
+#define PHY_CONTROL_AUTONEG_RST (1<< 9)
+#define PHY_CONTROL_DPLX_FULL (1<< 8)
+#define PHY_CONTROL_COLLTEST (1<< 7)
+
+#define PHY_STATUS_CAP_T4 (1<<15)
+#define PHY_STATUS_CAP_100TXF (1<<14)
+#define PHY_STATUS_CAP_100TXH (1<<13)
+#define PHY_STATUS_CAP_10TF (1<<12)
+#define PHY_STATUS_CAP_10TH (1<<11)
+#define PHY_STATUS_CAP_SUPR (1<< 6)
+#define PHY_STATUS_AUTONEG_ACK (1<< 5)
+#define PHY_STATUS_REMOTEFAULT (1<< 4)
+#define PHY_STATUS_CAP_AUTONEG (1<< 3)
+#define PHY_STATUS_LINK_OK (1<< 2)
+#define PHY_STATUS_JABBER (1<< 1)
+#define PHY_STATUS_EXTREGS (1<< 0)
+
+// These are the same for both AUTONEG registers
+#define PHY_AUTONEG_NEXT (1<<15)
+#define PHY_AUTONEG_ACK (1<<14)
+#define PHY_AUTONEG_REMOTEFAULT (1<<13)
+#define PHY_AUTONEG_100BASET4 (1<< 9)
+#define PHY_AUTONEG_100BASETX_FDX (1<< 8)
+#define PHY_AUTONEG_100BASETX_HDX (1<< 7)
+#define PHY_AUTONEG_10BASET_FDX (1<< 6)
+#define PHY_AUTONEG_10BASET_HDX (1<< 5)
+#define PHY_AUTONEG_CSMA_802_3 (1<< 0)
+
+#if 0
+// Others are undocumented
+#define PHY_STATUS_DETECT_SPEED100 (1<< 7)
+#define PHY_STATUS_DETECT_DPLX_FULL (1<< 6)
+#endif
+
+// Phew!
+// --------------------------------------------------------------------------
+#endif // CYGONCE_HAL_UPD985XX_ETH_H
+// End of upd985xx_eth.h
diff --git a/ecos/packages/devs/eth/mips/upd985xx/current/src/if_upd985xx.c b/ecos/packages/devs/eth/mips/upd985xx/current/src/if_upd985xx.c
new file mode 100644
index 0000000..b9c92b3
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/upd985xx/current/src/if_upd985xx.c
@@ -0,0 +1,1610 @@
+//==========================================================================
+//
+// if_upd985xx.c
+//
+// Ethernet drivers
+// NEC UPD985XX device ethernet specific support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt, gthomas
+// Contributors:
+// Date: 2001-06-28
+// Purpose:
+// Description: hardware driver for uPD985xx ethernet devices
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_mips_upd985xx.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <net/if.h> /* Needed for struct ifnet */
+#else
+#include <cyg/hal/hal_if.h>
+#endif
+
+#include <cyg/devs/eth/upd985xx_eth.h>
+
+#include <cyg/io/eth/eth_drv_stats.h>
+
+// ------------------------------------------------------------------------
+
+#ifdef CYGDBG_DEVS_ETH_MIPS_UPD985XX_CHATTER
+#define nDEBUG_TRAFFIC // This one prints stuff as packets come and go
+#define nDEBUG_IOCTL // ioctl() call printing
+#define DEBUG // Startup printing mainly
+#endif
+
+#define os_printf diag_printf
+#define db_printf diag_printf
+
+#define STATIC static
+
+// ------------------------------------------------------------------------
+// I/O access macros as inlines for later changes to >1 device?
+//
+// (If we need to do this, then these macros would *assume* the
+// presence of a valid p_eth_upd985xx just like we always have)
+
+static inline void OUTL( volatile cyg_uint32 *io_address, cyg_uint32 value )
+{ *io_address = value; }
+
+static inline cyg_uint32 INL( volatile cyg_uint32 *io_address )
+{ return *io_address; }
+
+// These map cachable addresses to uncachable ones and vice versa.
+// This is all fixed on MIPS. 8-9xxxxxxx uncachable, A-Bxxxxxxx cachable.
+#define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_))
+static inline cyg_uint8 *virt_to_bus(cyg_uint32 p_memory)
+{
+ return (cyg_uint8 *)(0xa0000000u + (p_memory & ~0xe0000000u));
+}
+#define BUS_TO_VIRT( _x_ ) bus_to_virt((cyg_uint32)(_x_))
+static inline cyg_uint8 *bus_to_virt(cyg_uint32 p_memory)
+{
+ return (cyg_uint8 *)(0x80000000u + (p_memory & ~0xe0000000u));
+}
+
+
+// ------------------------------------------------------------------------
+#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_S1
+#define FLUSH_WRITES() CYG_MACRO_START \
+ (void) INL( ETH_RXSR ); \
+CYG_MACRO_END
+#else
+#define FLUSH_WRITES() CYG_EMPTY_STATEMENT
+#endif
+
+// ------------------------------------------------------------------------
+//
+// DEVICES AND PACKET QUEUES
+//
+// ------------------------------------------------------------------------
+
+// 128 bytes extra for VLAN packets should be enough; AFAICT usually the
+// encapsulation is only 4 or 10 bytes extra.
+#define MAX_ETHERNET_PACKET_SIZE 1536 // Ethernet Rx packet size
+#define MAX_OVERSIZE_PACKET_SIZE 1664 // VLAN Rx packet size
+#define MAX_RX_PACKET_SIZE MAX_OVERSIZE_PACKET_SIZE
+
+#define NUM_RXBUFS (8)
+
+// This one is the hardware definition.
+struct bufdesc {
+ volatile cyg_uint32 attr;
+ cyg_uint8 *ptr;
+};
+
+// Rx databuffer.
+STATIC cyg_uint8 rx_databuf[ NUM_RXBUFS ] [ MAX_RX_PACKET_SIZE ];
+
+#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3
+// Tx databuffer
+STATIC cyg_uint8 tx_databuf[ MAX_RX_PACKET_SIZE ];
+#endif
+
+struct eth_upd985xx {
+ cyg_uint8 active, index, tx_busy, mac_addr_ok;
+ cyg_uint8 vector; // interrupt numbers are small
+ cyg_uint8 phy_status; // from PHY_STATUS_ flags below
+ cyg_uint8 hardwired_esa;
+#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
+ cyg_uint8 promisc;
+#endif
+ cyg_uint8 mac_address[6];
+
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+
+ struct cyg_netdevtab_entry *ndp;
+
+ // these shall hold uncached addresses of the structures following...
+ volatile struct bufdesc *txring;
+ volatile struct bufdesc *rxring_active;
+ volatile struct bufdesc *rxring_next;
+ int rxring_active_index;
+ int rxring_next_index;
+ cyg_uint32 intrs;
+ cyg_uint32 tx_keys[1];
+
+ // -----------------------------------------------------------------
+ // Statistics counters
+ cyg_uint32 count_rx_resource;
+ cyg_uint32 count_rx_restart;
+ cyg_uint32 count_interrupts;
+ cyg_uint32 count_bad_isr_restarts;
+ cyg_uint32 count_bad_tx_completion;
+
+ // -----------------------------------------------------------------
+ // DO NOT ACCESS THESE DIRECTLY - THE DEVICE HAS TO SEE THEM UNCACHED
+
+ // Initially, enough for one whole transmission to be described in one go,
+ // plus a null link on the end.
+ struct bufdesc tx_bufdesc[ MAX_ETH_DRV_SG + 2 ];
+
+ // Pending rx buffers, of full size.
+ struct bufdesc rx_bufdesc[ NUM_RXBUFS+1 ];
+
+ // -----------------------------------------------------------------
+};
+
+struct eth_upd985xx eth_upd985xx[CYGNUM_DEVS_ETH_MIPS_UPD985XX_DEV_COUNT] = {
+ {
+ index: 0,
+ vector: CYGNUM_HAL_INTERRUPT_ETHER,
+#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
+ promisc: 0,
+#endif
+#ifdef CYGSEM_DEVS_ETH_UPD985XX_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_UPD985XX_ETH0_ESA,
+ mac_addr_ok: 1,
+#else
+ hardwired_esa: 0,
+ mac_addr_ok: 0,
+#endif
+ }
+};
+
+// eth0
+
+ETH_DRV_SC(upd985xx_sc0,
+ &eth_upd985xx[0], // Driver specific data
+ CYGDAT_DEVS_ETH_UPD985XX_ETH0_NAME, // name for this interface
+ eth_upd985xx_start,
+ eth_upd985xx_stop,
+ eth_upd985xx_ioctl,
+ eth_upd985xx_can_send,
+ eth_upd985xx_send,
+ eth_upd985xx_recv,
+ eth_upd985xx_deliver,
+ eth_upd985xx_poll,
+ eth_upd985xx_int_vector
+ );
+
+NETDEVTAB_ENTRY(upd985xx_netdev0,
+ "upd985xx-" CYGDAT_DEVS_ETH_UPD985XX_ETH0_NAME,
+ upd985xx_eth_upd985xx_init,
+ &upd985xx_sc0);
+
+
+// This is in a macro so that if more devices arrive it can easily be changed
+#define CHECK_NDP_SC_LINK() CYG_MACRO_START \
+ CYG_ASSERT( ((void *)ndp == (void *)&upd985xx_netdev0), "Bad ndp" ); \
+ CYG_ASSERT( ((void *)sc == (void *)&upd985xx_sc0), "Bad sc" ); \
+ CYG_ASSERT( (void *)p_eth_upd985xx == sc->driver_private, \
+ "sc pointer bad" ); \
+ CYG_ASSERT( (void *)p_eth_upd985xx == (void *)&eth_upd985xx[0], \
+ "bad p_eth_upd985x" ); \
+CYG_MACRO_END
+
+#define NUM_ELEMENTS( _x_ ) (sizeof( (_x_) ) / sizeof( (_x_[0]) ) )
+
+// ------------------------------------------------------------------------
+//
+// FUNCTION PROTOTYPES
+//
+// ------------------------------------------------------------------------
+STATIC void InitRxRing(struct eth_upd985xx* p_eth_upd985xx);
+STATIC void NextRxRing(struct eth_upd985xx* p_eth_upd985xx);
+STATIC void InitTxRing(struct eth_upd985xx* p_eth_upd985xx);
+STATIC void ResetTxRing(struct eth_upd985xx* p_eth_upd985xx);
+
+#ifdef CYGPKG_NET
+STATIC int eth_upd985xx_configure(struct eth_upd985xx* p_eth_upd985xx,
+ int promisc, int oversized);
+#endif
+
+STATIC void PacketRxReady(struct eth_upd985xx* p_eth_upd985xx);
+STATIC void TxDone(struct eth_upd985xx* p_eth_upd985xx);
+
+#define PHY_STATUS_LINK (1)
+#define PHY_STATUS_FDX (2)
+#define PHY_STATUS_100MBPS (4)
+STATIC int eth_upd985xx_status( struct eth_upd985xx *p_eth_upd985xx );
+STATIC int eth_set_mac_address( struct eth_upd985xx *p_eth_upd985xx, void *data );
+
+// ------------------------------------------------------------------------
+//
+// MII ACCESS TO PHY DEVICE
+//
+// ------------------------------------------------------------------------
+
+STATIC cyg_bool mii_read( cyg_uint32 reg, cyg_uint32 *pvalue,
+ struct eth_upd985xx *p_eth_upd985xx )
+{
+ int i = 1000;
+ // wait a bit for it to be idle
+ while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
+ & INL(ETH_MIND)) )
+ if ( --i < 0 )
+ return false;
+ // Tell it the register address and PHY address
+ OUTL( ETH_MADR, ETH_MADR_PHY_DEVICE_PHYS_ADDRESS | reg );
+ OUTL( ETH_MCMD, ETH_MCMD_RSTAT ); // "do a read"
+ // wait for the read to complete
+ while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
+ & INL(ETH_MIND)) )
+ if ( --i < 0 )
+ return false;
+ // so get the data
+ *pvalue = INL( ETH_MRDD );
+ return true;
+}
+
+#if 0
+STATIC cyg_bool mii_write( cyg_uint32 reg, cyg_uint32 value,
+ struct eth_upd985xx *p_eth_upd985xx )
+{
+ int i = 1000;
+ // wait a bit for it to be idle
+ while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
+ & INL(ETH_MIND)) )
+ if ( --i < 0 )
+ return false;
+ // Tell it the register address and PHY address
+ OUTL( ETH_MADR, ETH_MADR_PHY_DEVICE_PHYS_ADDRESS | reg );
+ // And write the data:
+ OUTL( ETH_MWTD, value );
+ // wait a bit for it to be idle
+ while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
+ & INL(ETH_MIND)) )
+ if ( --i < 0 )
+ return false;
+ return true;
+}
+#endif
+
+// ------------------------------------------------------------------------
+//
+// INTERRUPT HANDLERS
+//
+// ------------------------------------------------------------------------
+
+STATIC cyg_uint32 eth_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_drv_interrupt_mask( vector );
+
+ return CYG_ISR_CALL_DSR; // schedule DSR
+}
+
+// ------------------------------------------------------------------------
+// This is a callback from the higher level thread in consequence of the DSR
+STATIC void
+eth_upd985xx_deliver(struct eth_drv_sc *sc)
+{
+ register int intrs;
+ struct eth_upd985xx *p_eth_upd985xx;
+ p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
+
+ p_eth_upd985xx->count_interrupts++;
+
+ intrs = INL( ETH_ISR ); // Read-clear
+ // Acknowledge once at the start anyway to prevent an interrupt loop in
+ // case of a transient - interrupts latch in the interrupt controller
+ // as well as in the ethernet device.
+ cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
+
+#ifdef DEBUG_TRAFFIC
+ os_printf("\n[[[[[[[ Deliver intrs = %x\n", intrs );
+#endif
+
+ // Guard possible external entry points
+ if ( ! p_eth_upd985xx->active )
+ return; // without unmasking the interrupt
+
+ while ( intrs ) {
+ if ( 0xffff0000 & intrs ) {
+ // Then something very bad has happened
+ p_eth_upd985xx->count_bad_isr_restarts++;
+ CYG_ASSERT ( p_eth_upd985xx->active, "Device not active!" );
+ eth_upd985xx_stop( sc );
+ eth_upd985xx_start( sc, NULL, 0 );
+ intrs = INL( ETH_ISR ); // Read-clear
+ }
+ p_eth_upd985xx->intrs = intrs;
+ if ( ( ETH_ISR_XMTDN | ETH_ISR_TABR ) & intrs ) {
+ // Scan for completed Txen and inform the stack
+ TxDone(p_eth_upd985xx);
+ }
+ if ( ( ETH_ISR_RCVDN | ETH_ISR_RBDRS | ETH_ISR_RBDRU ) & intrs ) {
+ // Pass any rx data up the stack
+ PacketRxReady(p_eth_upd985xx);
+ }
+ // Now we have made the interrupt causes go away, acknowledge and
+ // *then* read the ISR again. That way the race can result in a
+ // spurious interrupt rather than a lost interrupt.
+ cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
+ intrs = INL( ETH_ISR ); // Read-clear
+#ifdef DEBUG_TRAFFIC
+ if ( intrs )
+ os_printf("------- Again intrs = %x\n", intrs );
+#endif
+ }
+#ifdef DEBUG_TRAFFIC
+ os_printf("]]]]]]]] Done intrs = %x\n\n", intrs );
+#endif
+
+ cyg_drv_interrupt_unmask(p_eth_upd985xx->vector);
+}
+
+// ------------------------------------------------------------------------
+// Device table entry to operate the chip in a polled mode.
+// Only diddle the interface we were asked to!
+
+STATIC void
+eth_upd985xx_poll(struct eth_drv_sc *sc)
+{
+ struct eth_upd985xx *p_eth_upd985xx;
+
+ p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
+
+ // As it happens, this driver always requests the DSR to be called:
+ (void)eth_isr( p_eth_upd985xx->vector, (cyg_addrword_t)sc );
+ eth_upd985xx_deliver( sc );
+}
+
+// ------------------------------------------------------------------------
+// Determine interrupt vector used by a device - for attaching GDB stubs
+// packet handler.
+STATIC int
+eth_upd985xx_int_vector(struct eth_drv_sc *sc)
+{
+ struct eth_upd985xx *p_eth_upd985xx;
+ p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
+ return (p_eth_upd985xx->vector);
+}
+
+// ------------------------------------------------------------------------
+
+STATIC int
+eth_set_mac_address( struct eth_upd985xx *p_eth_upd985xx, void *data )
+{
+ cyg_uint8 *p = (cyg_uint8 *)data;
+ cyg_uint8 *mac_address;
+
+ mac_address = &p_eth_upd985xx->mac_address[0];
+
+ mac_address[5] = p[5];
+ mac_address[4] = p[4];
+ mac_address[3] = p[3];
+ mac_address[2] = p[2];
+ mac_address[1] = p[1];
+ mac_address[0] = p[0];
+
+ p_eth_upd985xx->mac_addr_ok = 1;
+
+ // Set the ESA in the device regs
+ OUTL( ETH_LSA2,
+ (p_eth_upd985xx->mac_address[1]) |
+ (p_eth_upd985xx->mac_address[0] << 8 ) );
+ OUTL( ETH_LSA1,
+ (p_eth_upd985xx->mac_address[5]) |
+ (p_eth_upd985xx->mac_address[4] << 8 ) |
+ (p_eth_upd985xx->mac_address[3] << 16 ) |
+ (p_eth_upd985xx->mac_address[2] << 24) );
+
+ return 0; // OK
+}
+
+// ------------------------------------------------------------------------
+
+STATIC void
+eth_upd985xx_reset( struct eth_upd985xx *p_eth_upd985xx )
+{
+ int i;
+
+ // Reset whole device: Software Reset (clears automatically)
+ OUTL( ETH_CCR, ETH_CCR_SRT );
+ for ( i = 0; i < 10000; i++ ) /* nothing */;
+ // Reset internal units
+ OUTL( ETH_MACC2, ETH_MACC2_MCRST | ETH_MACC2_RFRST | ETH_MACC2_TFRST );
+ for ( i = 0; i < 10000; i++ ) /* nothing */;
+ FLUSH_WRITES();
+ OUTL( ETH_MACC2, 0 ); // (and release reset)
+ // Enable CRC adding, padding
+ FLUSH_WRITES();
+ OUTL( ETH_MACC1,
+ ETH_MACC1_CRCEN | ETH_MACC1_PADEN |
+ ETH_MACC1_TXFC | ETH_MACC1_RXFC | ETH_MACC1_PARF );
+ FLUSH_WRITES();
+ OUTL( ETH_MACC2, ETH_MACC2_APD ); // Auto VLAN pad
+ FLUSH_WRITES();
+ OUTL( ETH_HT1, 0 );
+ FLUSH_WRITES();
+ OUTL( ETH_HT2, 0 );
+
+ // Enable rx of broadcasts, multicasts, but not promiscuous...
+ FLUSH_WRITES();
+#if defined( CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2 ) && \
+ !defined( CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY )
+ // Unless we are faking it.
+ OUTL( ETH_AFR, ETH_AFR_ABC | ETH_AFR_PRM | ETH_AFR_PRO );
+#else
+ OUTL( ETH_AFR, ETH_AFR_ABC | ETH_AFR_PRM );
+#endif
+
+ FLUSH_WRITES();
+ OUTL( ETH_IPGT, 0x00000013 );
+ FLUSH_WRITES();
+ OUTL( ETH_IPGR, 0x00000e13 );
+ FLUSH_WRITES();
+ OUTL( ETH_CLRT, 0x0000380f );
+ FLUSH_WRITES();
+ OUTL( ETH_LMAX, MAX_ETHERNET_PACKET_SIZE );
+
+ // Select a clock for the MII
+ FLUSH_WRITES();
+ OUTL( ETH_MIIC, ETH_MIIC_66 ); // Example code sets to 66.
+ // Set VLAN type reg
+ FLUSH_WRITES();
+ OUTL( ETH_VLTP, ETH_VLTP_VLTP );
+
+ // Set the ESA in the device regs
+ if ( p_eth_upd985xx->mac_addr_ok ) {
+ FLUSH_WRITES();
+ OUTL( ETH_LSA2,
+ (p_eth_upd985xx->mac_address[1]) |
+ (p_eth_upd985xx->mac_address[0] << 8 ) );
+ FLUSH_WRITES();
+ OUTL( ETH_LSA1,
+ (p_eth_upd985xx->mac_address[5]) |
+ (p_eth_upd985xx->mac_address[4] << 8 ) |
+ (p_eth_upd985xx->mac_address[3] << 16 ) |
+ (p_eth_upd985xx->mac_address[2] << 24) );
+ }
+
+ FLUSH_WRITES();
+ OUTL( ETH_RXFCR, ETH_RXFCR_UWM_DEFAULT |
+ ETH_RXFCR_LWM_DEFAULT | ETH_RXFCR_DRTH16W );
+
+ FLUSH_WRITES();
+ // Fault E4 - use only 32 for FLTH, not the previously recommended 48 (words)
+ // Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E4
+ // but no config opt is provided.
+ OUTL( ETH_TXFCR, ETH_TXFCR_TPTV_DEFAULT |
+ ETH_TXFCR_TX_DRTH_DEFAULT | (32 << ETH_TXFCR_TX_FLTH_SHIFT) );
+
+ // Transmit and receive config regs we hit when enabling those
+ // functions separately, and the wet string end of the receiver
+ // which is controlled by MACC1 |= ETH_MACC1_SRXEN;
+
+ // Tx and Rx interrupts enabled internally;
+ // Tx done/aborted, and rx OK.
+ FLUSH_WRITES();
+ OUTL( ETH_MSR, ETH_ISR_XMTDN | ETH_ISR_TABR |
+ ETH_ISR_RCVDN | ETH_ISR_RBDRS | ETH_ISR_RBDRU );
+ FLUSH_WRITES();
+}
+
+// ------------------------------------------------------------------------
+//
+// NETWORK INTERFACE INITIALIZATION
+//
+// ------------------------------------------------------------------------
+STATIC bool
+upd985xx_eth_upd985xx_init(struct cyg_netdevtab_entry * ndp)
+{
+ struct eth_drv_sc *sc;
+ cyg_uint8 *mac_address;
+ struct eth_upd985xx *p_eth_upd985xx;
+
+#ifdef DEBUG
+ db_printf("upd985xx_eth_upd985xx_init\n");
+#endif
+
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+ p_eth_upd985xx = (struct eth_upd985xx *)(sc->driver_private);
+
+ CHECK_NDP_SC_LINK();
+
+ p_eth_upd985xx->tx_busy = 0;
+
+ // record the net dev pointer
+ p_eth_upd985xx->ndp = (void *)ndp;
+
+ mac_address = &p_eth_upd985xx->mac_address[0];
+
+#ifdef CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA
+ if ( ! p_eth_upd985xx->hardwired_esa ) {
+ cyg_uint8 *p;
+ union macar {
+ struct {
+ cyg_uint32 macar1, macar2, macar3;
+ } integers;
+ cyg_uint8 bytes[12];
+ } eeprom;
+
+ eeprom.integers.macar1 = INL( MACAR1 ); // MAC Address Register 1
+ eeprom.integers.macar2 = INL( MACAR2 ); // MAC Address Register 2
+ eeprom.integers.macar3 = INL( MACAR3 ); // MAC Address Register 3
+
+ if ( (0 != eeprom.integers.macar1 ||
+ 0 != eeprom.integers.macar2 ||
+ 0 != eeprom.integers.macar3 )
+ &&
+ (0xffffffff != eeprom.integers.macar1 ||
+ 0xffffffff != eeprom.integers.macar2 ||
+ 0xffffffff != eeprom.integers.macar3 ) ) {
+ // Then we have good data in the EEPROM
+#ifdef DEBUG
+ os_printf( "EEPROM data %08x %08x %08x\n",
+ eeprom.integers.macar1,
+ eeprom.integers.macar2,
+ eeprom.integers.macar3 );
+#endif
+ p = &eeprom.bytes[0]; // pick up either set of ESA info
+ if ( 1 == p_eth_upd985xx->index )
+ p += 6;
+
+ mac_address[5] = p[5];
+ mac_address[4] = p[4];
+ mac_address[3] = p[3];
+ mac_address[2] = p[2];
+ mac_address[1] = p[1];
+ mac_address[0] = p[0];
+ p_eth_upd985xx->mac_addr_ok = 1;
+ }
+ else {
+ // Fake it so we can get RedBoot going on a board with no EEPROM
+ mac_address[0] = 0;
+ mac_address[1] = 0xBA;
+ mac_address[2] = 0xD0;
+ mac_address[3] = 0xEE;
+ mac_address[4] = 0x00;
+ mac_address[5] = p_eth_upd985xx->index;
+ p_eth_upd985xx->mac_addr_ok = 1;
+ }
+ }
+#endif // CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA
+
+ // Init the underlying hardware and insert the ESA:
+ eth_upd985xx_reset(p_eth_upd985xx);
+
+#ifdef DEBUG
+ os_printf("MAC Address %s, ESA = %02X %02X %02X %02X %02X %02X\n",
+ p_eth_upd985xx->mac_addr_ok ? "OK" : "**BAD**",
+ mac_address[0], mac_address[1], mac_address[2], mac_address[3],
+ mac_address[4], mac_address[5]);
+#endif
+
+ // Set up the pointers to data structures
+ InitTxRing(p_eth_upd985xx);
+
+ // Construct the interrupt handler
+ p_eth_upd985xx->active = 0;
+ cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
+ cyg_drv_interrupt_mask(p_eth_upd985xx->vector);
+ cyg_drv_interrupt_create(
+ p_eth_upd985xx->vector,
+ 0, // Priority - unused
+ (CYG_ADDRWORD)sc, // Data item passed to ISR & DSR
+ eth_isr, // ISR
+ eth_drv_dsr, // DSR (generic)
+ &p_eth_upd985xx->interrupt_handle, // handle to intr obj
+ &p_eth_upd985xx->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(p_eth_upd985xx->interrupt_handle);
+
+ // Initialize upper level driver
+ if ( p_eth_upd985xx->mac_addr_ok )
+ (sc->funs->eth_drv->init)(sc, &(p_eth_upd985xx->mac_address[0]) );
+ else
+ (sc->funs->eth_drv->init)(sc, 0 );
+
+ return (1);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : eth_upd985xx_start
+//
+// ------------------------------------------------------------------------
+STATIC void
+eth_upd985xx_start( struct eth_drv_sc *sc,
+ unsigned char *enaddr, int flags )
+{
+ struct eth_upd985xx *p_eth_upd985xx;
+ cyg_uint32 ss;
+#ifdef CYGPKG_NET
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+
+ p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
+
+#ifdef DEBUG
+ os_printf("eth_upd985xx_start %d flg %x\n", p_eth_upd985xx->index, *(int *)p_eth_upd985xx );
+#endif
+
+ if ( p_eth_upd985xx->active )
+ eth_upd985xx_stop( sc );
+
+ p_eth_upd985xx->active = 1;
+
+#ifdef CYGPKG_NET
+ /* Enable promiscuous mode if requested, reception of oversized frames always.
+ * The latter is needed for VLAN support and shouldn't hurt even if we're not
+ * using VLANs.
+ */
+ eth_upd985xx_configure(p_eth_upd985xx, !!(ifp->if_flags & IFF_PROMISC), 1);
+#endif
+
+ // renegotiate link status
+ p_eth_upd985xx->phy_status = eth_upd985xx_status( p_eth_upd985xx );
+
+ if ( p_eth_upd985xx->phy_status & PHY_STATUS_FDX ) {
+ cyg_uint32 ss;
+ // then enable full duplex in the MAC
+ ss = INL( ETH_MACC1 );
+ ss |= ETH_MACC1_FDX;
+ OUTL( ETH_MACC1, ss );
+ }
+
+#ifdef DEBUG
+ {
+ int status = p_eth_upd985xx->phy_status;
+ os_printf("eth_upd985xx_start %d Link = %s, %s Mbps, %s Duplex\n",
+ p_eth_upd985xx->index,
+ status & PHY_STATUS_LINK ? "Up" : "Down",
+ status & PHY_STATUS_100MBPS ? "100" : "10",
+ status & PHY_STATUS_FDX ? "Full" : "Half"
+ );
+ }
+#endif
+
+
+ // Start the receive engine
+ p_eth_upd985xx->count_rx_restart++;
+ // Initialize all but one buffer: [B0,B1,B2,...Bx,NULL,LINK]
+ InitRxRing( p_eth_upd985xx );
+ // Point the hardware at the list of buffers
+ OUTL( ETH_RXDPR, (cyg_uint32)p_eth_upd985xx->rxring_active );
+ // Tell it about the buffers via the rx descriptor count
+ OUTL( ETH_RXPDR, ETH_RXPDR_AL | (NUM_RXBUFS-1) );
+ // Ack any pending interrupts from the system
+ p_eth_upd985xx->intrs = INL( ETH_ISR ); // Read-clear
+ // Start the rx.
+ OUTL( ETH_RXCR, ETH_RXCR_RXE | ETH_RXCR_DRBS_16 );
+
+ // Enable the wet string end of the receiver
+ ss = INL( ETH_MACC1 );
+ ss |= ETH_MACC1_SRXEN;
+ OUTL( ETH_MACC1, ss );
+
+ // And unmask the interrupt
+ cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
+ cyg_drv_interrupt_unmask(p_eth_upd985xx->vector);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : eth_upd985xx_status; 10/100 and Full/Half Duplex (FDX/HDX)
+//
+// ------------------------------------------------------------------------
+STATIC int eth_upd985xx_status( struct eth_upd985xx *p_eth_upd985xx )
+{
+ int status;
+ int i, j;
+ // Some of these bits latch and only reflect "the truth" on a 2nd reading.
+ // So read and discard.
+ mii_read( PHY_CONTROL_REG, &i, p_eth_upd985xx );
+ mii_read( PHY_STATUS_REG, &i, p_eth_upd985xx );
+ // Use the "and" of the local and remote capabilities words to infer
+ // what is selected:
+ status = 0;
+ if ( mii_read( PHY_STATUS_REG, &i, p_eth_upd985xx ) ) {
+ if ( PHY_STATUS_LINK_OK & i )
+ status |= PHY_STATUS_LINK;
+ }
+ if ( mii_read( PHY_AUTONEG_ADVERT, &j, p_eth_upd985xx ) &&
+ mii_read( PHY_AUTONEG_REMOTE, &i, p_eth_upd985xx ) ) {
+#if defined( DEBUG_TRAFFIC ) || defined( DEBUG_IOCTL )
+ os_printf( "MII: capabilities are %04x, %04x; common %04x\n",
+ i, j, i & j );
+#endif
+ j &= i; // select only common capabilities
+
+ if ( (PHY_AUTONEG_100BASET4 |
+ PHY_AUTONEG_100BASETX_FDX |
+ PHY_AUTONEG_100BASETX_HDX) & j )
+ status |= PHY_STATUS_100MBPS;
+ if ( (PHY_AUTONEG_100BASETX_FDX | PHY_AUTONEG_10BASET_FDX) & j )
+ status |= PHY_STATUS_FDX;
+ }
+ return status;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : eth_upd985xx_stop
+//
+// ------------------------------------------------------------------------
+
+STATIC void eth_upd985xx_stop( struct eth_drv_sc *sc )
+{
+ struct eth_upd985xx *p_eth_upd985xx;
+
+ p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
+
+ // No more interrupts
+ cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
+ cyg_drv_interrupt_mask(p_eth_upd985xx->vector);
+
+#ifdef DEBUG
+ os_printf("eth_upd985xx_stop %d flg %x\n", p_eth_upd985xx->index, *(int *)p_eth_upd985xx );
+#endif
+
+ p_eth_upd985xx->active = 0; // stop people tormenting it
+
+ if ( p_eth_upd985xx->tx_busy ) {
+ // Then it is finshed now, by force:
+ cyg_uint32 key = p_eth_upd985xx->tx_keys[ 0 ];
+ // Turn off the transmitter (before the callback to the stack).
+ OUTL( ETH_TXCR, 0 );
+#ifdef DEBUG_TRAFFIC
+ os_printf("Stop: tidying up TX, KEY %x\n", key );
+#endif
+ // Leave tx_busy true so no recursion can occur here.
+ // Then tell the stack we are done:
+ if ( key ) {
+ (sc->funs->eth_drv->tx_done)( sc, key, 0 );
+ }
+ }
+ p_eth_upd985xx->tx_keys[ 0 ] = 0;
+ p_eth_upd985xx->tx_busy = p_eth_upd985xx->active = 0;
+
+ eth_upd985xx_reset(p_eth_upd985xx);
+
+ ResetTxRing( p_eth_upd985xx );
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : InitRxRing
+//
+// ------------------------------------------------------------------------
+STATIC void InitRxRing(struct eth_upd985xx* p_eth_upd985xx)
+{
+ int i;
+ struct bufdesc *bp;
+
+ // first just blat the various flags and addresses: the first N
+ // bufdescs point to data buffers, the last one is NULL.
+ bp = (struct bufdesc *)VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[0] );
+ // Record the initial active buffer:
+ p_eth_upd985xx->rxring_active = bp;
+ p_eth_upd985xx->rxring_active_index = 0;
+ for ( i = 0; i < NUM_RXBUFS - 1; i++, bp++ ) {
+ bp->ptr = VIRT_TO_BUS( &rx_databuf[i][0] );
+ bp->attr = ( ETH_BUF_D_L_DATA | ETH_BUF_OWN_CPU
+ | (ETH_BUF_SIZE & sizeof( rx_databuf[0] )) );
+ }
+ CYG_ASSERT( i == NUM_RXBUFS-1, "Penultimate rx buffer index mismatch" );
+ CYG_ASSERT( (cyg_uint8 *)bp ==
+ VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[NUM_RXBUFS-1] ),
+ "Penultimate rx buffer address mismatch" );
+
+ // NULL out the penultimate one
+ bp->ptr = NULL;
+ bp->attr = 0;
+ // And record it as next one to use
+ p_eth_upd985xx->rxring_next = bp;
+ p_eth_upd985xx->rxring_next_index = NUM_RXBUFS-1;
+
+ // Step on to the extra entry at the end which makes a ring:
+ bp++;
+ CYG_ASSERT( (cyg_uint8 *)bp ==
+ VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[NUM_RXBUFS] ),
+ "Ultimate rx buffer address mismatch" );
+
+ // Link the Ultimate back to the start
+ bp->ptr = (cyg_uint8 *)p_eth_upd985xx->rxring_active; // Zeroth entry
+ bp->attr = ETH_BUF_D_L_LINK;
+
+ // All done.
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : NextRxRing
+//
+// ------------------------------------------------------------------------
+
+STATIC void NextRxRing(struct eth_upd985xx* p_eth_upd985xx )
+{
+ volatile struct bufdesc *next, *dead;
+ int iactive;
+ int inext;
+
+ iactive = p_eth_upd985xx->rxring_active_index;
+ inext = p_eth_upd985xx->rxring_next_index;
+
+ // Preconditions:
+ CYG_ASSERT( 0 <= inext && inext < NUM_RXBUFS, "Bad inext" );
+ CYG_ASSERT( 0 <= iactive && iactive < NUM_RXBUFS, "Bad iactive" );
+ CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] )
+ == (cyg_uint8 *)p_eth_upd985xx->rxring_next, "Next rx_bufdesc bad" );
+ CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] )
+ == (cyg_uint8 *)p_eth_upd985xx->rxring_active, "Active rx_bufdesc bad" );
+ CYG_ASSERT( ETH_BUF_D_L_LINK == p_eth_upd985xx->rxring_next->attr, "Next not a link" );
+ CYG_ASSERT( ETH_BUF_D_L_DATA & p_eth_upd985xx->rxring_active->attr, "Active not data" );
+ CYG_ASSERT( NULL == p_eth_upd985xx->rxring_next->ptr, "Next not NULL" );
+ CYG_ASSERT( VIRT_TO_BUS( &rx_databuf[iactive][0] ) ==
+ p_eth_upd985xx->rxring_active->ptr, "Active bad data pointer" );
+ CYG_ASSERT( (iactive - 1 == inext) || (0 == iactive && NUM_RXBUFS - 1 == inext),
+ "Chasing pointers mismatch" );
+
+ // Select the new bufdesc to be active - ie. next to scan for reception:
+ if ( ++iactive >= NUM_RXBUFS )
+ iactive = 0;
+ dead = p_eth_upd985xx->rxring_active; // the one that just died
+ // Step ahead the new active buffer:
+ p_eth_upd985xx->rxring_active = (volatile struct bufdesc *)
+ VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] );
+ p_eth_upd985xx->rxring_active_index = iactive;
+
+ // Blow away the currently active entry; we have dealt with it already
+ // and it is needed for an end stop to the ring:
+ dead->ptr = NULL;
+ dead->attr = 0;
+
+ // Select the next bufdesc to enliven
+ next = p_eth_upd985xx->rxring_next;
+ next->ptr = VIRT_TO_BUS( &rx_databuf[inext][0] );
+ next->attr = ( ETH_BUF_D_L_DATA | ETH_BUF_OWN_CPU
+ | (ETH_BUF_SIZE & sizeof( rx_databuf[0] )) );
+
+ // And update the external info to reflect this:
+ if ( ++inext >= NUM_RXBUFS )
+ inext = 0;
+ next = (volatile struct bufdesc *)
+ VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] );
+
+ p_eth_upd985xx->rxring_next = next;
+ p_eth_upd985xx->rxring_next_index = inext;
+
+ // Postconditions:
+ CYG_ASSERT( 0 <= inext && inext < NUM_RXBUFS, "Bad inext" );
+ CYG_ASSERT( 0 <= iactive && iactive < NUM_RXBUFS, "Bad iactive" );
+ CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] )
+ == (cyg_uint8 *)p_eth_upd985xx->rxring_next, "Next rx_bufdesc bad" );
+ CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] )
+ == (cyg_uint8 *)p_eth_upd985xx->rxring_active, "Active rx_bufdesc bad" );
+ CYG_ASSERT( ETH_BUF_D_L_LINK == p_eth_upd985xx->rxring_next->attr, "Next not a link" );
+ CYG_ASSERT( ETH_BUF_D_L_DATA & p_eth_upd985xx->rxring_active->attr, "Active not data" );
+ CYG_ASSERT( NULL == p_eth_upd985xx->rxring_next->ptr, "Next not NULL" );
+ CYG_ASSERT( VIRT_TO_BUS( &rx_databuf[iactive][0] ) ==
+ p_eth_upd985xx->rxring_active->ptr, "Active bad data pointer" );
+ CYG_ASSERT( (iactive - 1 == inext) || (0 == iactive && NUM_RXBUFS - 1 == inext),
+ "Chasing pointers mismatch" );
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : PacketRxReady (Called from delivery thread)
+//
+// ------------------------------------------------------------------------
+STATIC void PacketRxReady(struct eth_upd985xx* p_eth_upd985xx)
+{
+ struct cyg_netdevtab_entry *ndp;
+ struct eth_drv_sc *sc;
+ cyg_uint32 ss, length;
+ cyg_bool reset_required = 0;
+
+ ndp = (struct cyg_netdevtab_entry *)(p_eth_upd985xx->ndp);
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ CHECK_NDP_SC_LINK();
+
+#ifdef DEBUG_TRAFFIC
+ ss = INL( ETH_RXSR );
+ os_printf("PacketRxReady: RXSR %x\n", ss );
+#endif
+
+ if ( ETH_ISR_RBDRU & p_eth_upd985xx->intrs )
+ reset_required = 1; // Out of buffers
+ if ( ! ETH_ISR_RCVDN & p_eth_upd985xx->intrs )
+ reset_required = 1; // or if no reception completed, reset anyway
+
+ // For all ready rx blocks...
+ do {
+ volatile struct bufdesc *bp;
+
+ bp = p_eth_upd985xx->rxring_active; // Current rx candidate
+
+ ss = bp->attr;
+#ifdef DEBUG_TRAFFIC
+ os_printf("PacketRxReady attr %x at %x\n", ss, bp );
+#endif
+ if ( ETH_BUF_OWN_CPU == (ETH_BUF_OWN & ss) ) {
+ // Then the packet is untouched...
+ break;
+ }
+#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
+ // Perform address recognition by hand, hardware is in promisc mode
+ // (we have settable "software" promisc mode too of course)
+ if ( ETH_BUF_OK & ss ) {
+ cyg_uint8 *esa = (cyg_uint8 *)bp->ptr; // (this is a non-cachable address)
+ int ok = 0;
+ if ( p_eth_upd985xx->promisc )
+ ok = 1; // accept the packet
+ else
+ if ( p_eth_upd985xx->mac_address[0] == esa[0] &&
+ p_eth_upd985xx->mac_address[1] == esa[1] &&
+ p_eth_upd985xx->mac_address[2] == esa[2] &&
+ p_eth_upd985xx->mac_address[3] == esa[3] &&
+ p_eth_upd985xx->mac_address[4] == esa[4] &&
+ p_eth_upd985xx->mac_address[5] == esa[5] )
+ ok = 1; // Then they are equal - accept
+ else
+ if ( 0xff == esa[0] &&
+ 0xff == esa[1] &&
+ 0xff == esa[2] &&
+ 0xff == esa[3] &&
+ 0xff == esa[4] &&
+ 0xff == esa[5] )
+ ok = 1; // Then they are equal - accept
+
+ if ( !ok )
+ ss = 0; // Easiest way...
+ }
+#endif
+ if ( ETH_BUF_OK & ss ) {
+ length = ETH_BUF_SIZE & ss;
+#ifdef DEBUG_TRAFFIC
+ os_printf("PacketRxReady found a packet size %d attr %x\n", length, ss );
+#endif
+ // Asserts for the length in-range can fire, with good status
+ // in the block, so be defensive here instead. Belt and braces.
+ if ( 63 < length && length <= MAX_RX_PACKET_SIZE ) {
+ CYG_ASSERT( ETH_BUF_D_L_DATA == (ETH_BUF_D_L & ss), "Not data buffer" );
+ CYG_ASSERT( length > 63, "Tiny packet" );
+ CYG_ASSERT( length <= MAX_RX_PACKET_SIZE, "Too big packet" );
+ CYG_ASSERT( ETH_BUF_LAST & ss, "Not last buffer" );
+ (sc->funs->eth_drv->recv)( sc, length );
+ } // Else drop it on the floor.
+ }
+
+ // Step along to the next buffer descriptor...
+ NextRxRing( p_eth_upd985xx );
+ if ( ! reset_required ) {
+ // And tell the device it can have a biscuit:
+ OUTL( ETH_RXPDR, ETH_RXPDR_AL | 1 );
+
+ // Now, before moving on to the next packet, find out if receptions
+ // had caught up with us before adding that new buffer:
+ ss = INL( ETH_RXPDR );
+ ss &= ETH_RXPDR_RNOD;
+ ss >>= ETH_RXPDR_RNOD_SHIFT;
+ if ( 1 >= ss ) {
+ // Then it was zero before. So the rx engine is stopped.
+#ifdef DEBUG_TRAFFIC
+ os_printf( "***ZERO rx buffers were left\n" );
+#endif
+ reset_required = 1;
+ }
+ // Otherwise we carry on as usual.
+ }
+ } while ( 1 );
+
+ if ( reset_required ) {
+ p_eth_upd985xx->count_rx_resource++;
+ // Disable the wet string end of the receiver
+ ss = INL( ETH_MACC1 );
+ ss &=~ETH_MACC1_SRXEN;
+ OUTL( ETH_MACC1, ss );
+ // Disable the DMA engine
+ OUTL( ETH_RXCR, 0 );
+ // Reset the RxRing from scratch
+ InitRxRing( p_eth_upd985xx );
+ // Point the hardware at the list of buffers
+ OUTL( ETH_RXDPR, (cyg_uint32)p_eth_upd985xx->rxring_active );
+ // Tell it about the buffers via the rx descriptor count:
+ ss = INL( ETH_RXPDR );
+ ss &= ETH_RXPDR_RNOD;
+ ss >>= ETH_RXPDR_RNOD_SHIFT;
+ // This awful register *increments* by what you write, even if the
+ // machinery is halted. Vile filthy evil rubbish.
+ OUTL( ETH_RXPDR, ETH_RXPDR_AL | ((NUM_RXBUFS-1) - ss) );
+ ss = INL( ETH_RXPDR );
+ CYG_ASSERT( (ETH_RXPDR_AL | (NUM_RXBUFS-1)) == ss, "RXPDR not right" );
+ // Start the rx.
+ OUTL( ETH_RXCR, ETH_RXCR_RXE | ETH_RXCR_DRBS_16 );
+ // Enable the wet string end of the receiver
+ ss = INL( ETH_MACC1 );
+ ss |= ETH_MACC1_SRXEN;
+ OUTL( ETH_MACC1, ss );
+ // All done.
+#ifdef DEBUG_TRAFFIC
+ os_printf( "***Rx Machine restarted\n" );
+#endif
+ }
+}
+
+// and the callback function
+
+STATIC void
+eth_upd985xx_recv( struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list, int sg_len )
+{
+ struct eth_upd985xx *p_eth_upd985xx;
+ int total_len;
+ struct eth_drv_sg *last_sg;
+ cyg_uint8 *from_p;
+ volatile struct bufdesc *bp;
+
+ p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
+
+ // Guard possible external entry points
+ if ( ! p_eth_upd985xx->active )
+ return;
+
+ bp = p_eth_upd985xx->rxring_active; // Current rx candidate
+
+#ifdef DEBUG_TRAFFIC
+ os_printf("Rx status %x\n", bp->attr );
+#endif
+
+ if ( 0 == (ETH_BUF_OK & bp->attr) )
+ return;
+
+ total_len = ETH_BUF_SIZE & bp->attr;
+
+#ifdef DEBUG_TRAFFIC
+ os_printf("Rx %d %x (status %x): %d sg's, %d bytes\n",
+ p_eth_upd985xx->index, (int)p_eth_upd985xx,
+ bp->attr,
+ sg_len, total_len);
+#endif
+
+ // Copy the data to the network stack
+ from_p = bp->ptr; // (this is a non-cachable address)
+
+ // check we have memory to copy into; we would be called even if
+ // caller was out of memory in order to maintain our state.
+ if ( 0 == sg_len || 0 == sg_list )
+ return; // caller was out of mbufs
+
+ CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
+ CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
+
+ for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
+ cyg_uint8 *to_p;
+ int l;
+
+ to_p = (cyg_uint8 *)(sg_list->buf);
+ l = sg_list->len;
+
+ CYG_ASSERT( 0 <= l, "sg length -ve" );
+
+ if ( 0 >= l || 0 == to_p )
+ return; // caller was out of mbufs
+
+ if ( l > total_len )
+ l = total_len;
+
+ memcpy( to_p, from_p, l );
+ from_p += l;
+ total_len -= l;
+ }
+
+ CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" );
+ CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" );
+ CYG_ASSERT( bp->ptr < from_p, "from_p wild in rx" );
+ CYG_ASSERT( bp->ptr + MAX_RX_PACKET_SIZE >= from_p,
+ "from_p overflow in rx" );
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : InitTxRing
+//
+// ------------------------------------------------------------------------
+STATIC void InitTxRing(struct eth_upd985xx* p_eth_upd985xx)
+{
+ int i;
+ volatile struct bufdesc *bp;
+
+ p_eth_upd985xx->txring =
+ (struct bufdesc *)VIRT_TO_BUS( &p_eth_upd985xx->tx_bufdesc[0] );
+
+ bp = p_eth_upd985xx->txring;
+
+ for ( i = 0; i < NUM_ELEMENTS( p_eth_upd985xx->tx_bufdesc ); i++, bp++ ) {
+ bp->ptr = NULL;
+ bp->attr = 0;
+ }
+ // Last one is a NULL link
+ bp--;
+ bp->ptr = NULL;
+ bp->attr = ETH_BUF_D_L_LINK;
+
+ ResetTxRing(p_eth_upd985xx);
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : ResetTxRing
+//
+// ------------------------------------------------------------------------
+STATIC void ResetTxRing(struct eth_upd985xx* p_eth_upd985xx)
+{
+ int i;
+ volatile struct bufdesc *bp;
+ bp = p_eth_upd985xx->txring;
+ for ( i = 0; i < NUM_ELEMENTS( p_eth_upd985xx->tx_bufdesc ) - 1; i++, bp++ ) {
+ bp->attr =
+ ETH_BUF_LAST |
+ ETH_BUF_D_L_DATA |
+ ETH_BUF_OWN_CPU |
+ (ETH_BUF_SIZE & 0);
+ }
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : TxDone (Called from delivery thread)
+//
+// This returns Tx's from the Tx Machine to the stack (ie. reports
+// completion) - allowing for missed interrupts, and so on.
+// ------------------------------------------------------------------------
+
+STATIC void TxDone(struct eth_upd985xx* p_eth_upd985xx)
+{
+ struct cyg_netdevtab_entry *ndp;
+ struct eth_drv_sc *sc;
+
+ ndp = (struct cyg_netdevtab_entry *)(p_eth_upd985xx->ndp);
+ sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ CHECK_NDP_SC_LINK();
+
+ if ( p_eth_upd985xx->tx_busy ) {
+ cyg_uint32 ss;
+
+ ss = INL( ETH_TXSR ); // Get tx status
+ if ( ss & (ETH_TXSR_CSE |
+ ETH_TXSR_TUDR |
+ ETH_TXSR_TGNT |
+ ETH_TXSR_LCOL |
+ ETH_TXSR_ECOL |
+ ETH_TXSR_TEDFR |
+ ETH_TXSR_TDFR |
+ ETH_TXSR_TBRO |
+ ETH_TXSR_TMUL |
+ ETH_TXSR_TDONE ) ) {
+ // Then it finished; somehow...
+ cyg_uint32 key = p_eth_upd985xx->tx_keys[ 0 ];
+
+ // Turn off the transmitter (before the callback to the stack).
+ OUTL( ETH_TXCR, 0 );
+
+#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E8
+ // Must take action after certain types of tx failure:
+ if ( ss & (ETH_TXSR_TUDR |
+ ETH_TXSR_LCOL |
+ ETH_TXSR_ECOL) ) {
+ p_eth_upd985xx->count_bad_tx_completion++;
+ CYG_ASSERT ( p_eth_upd985xx->active, "Device not active!" );
+ eth_upd985xx_stop( sc );
+ eth_upd985xx_start( sc, NULL, 0 );
+ key = 0; // Important! Stop above already fed it back.
+ }
+#endif
+
+#ifdef DEBUG_TRAFFIC
+ os_printf("TxDone %d %x: KEY %x\n",
+ p_eth_upd985xx->index, (int)p_eth_upd985xx, key );
+#endif
+ // Finished, ready for the next one
+ p_eth_upd985xx->tx_keys[ 0 ] = 0;
+ p_eth_upd985xx->tx_busy = 0;
+ // Then tell the stack we are done:
+ if (key) {
+ (sc->funs->eth_drv->tx_done)( sc, key,
+ 0 == (p_eth_upd985xx->intrs & ETH_ISR_TABR) );
+ }
+ }
+ }
+}
+
+
+// ------------------------------------------------------------------------
+//
+// Function : eth_upd985xx_can_send
+//
+// ------------------------------------------------------------------------
+
+STATIC int
+eth_upd985xx_can_send(struct eth_drv_sc *sc)
+{
+ struct eth_upd985xx *p_eth_upd985xx;
+
+ p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
+
+ // Guard possible external entry points
+ if ( ! p_eth_upd985xx->active )
+ return 0;
+
+ return ! p_eth_upd985xx->tx_busy;
+}
+
+// ------------------------------------------------------------------------
+//
+// Function : eth_upd985xx_send
+//
+// ------------------------------------------------------------------------
+
+STATIC void
+eth_upd985xx_send(struct eth_drv_sc *sc,
+ struct eth_drv_sg *sg_list, int sg_len, int total_len,
+ unsigned long key)
+{
+ struct eth_upd985xx *p_eth_upd985xx;
+ struct eth_drv_sg *last_sg;
+ volatile struct bufdesc *bp;
+#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3
+ struct eth_drv_sg local_sg[2];
+#endif
+
+ p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
+
+#ifdef DEBUG_TRAFFIC
+ os_printf("Tx %d %x: %d sg's, %d bytes, KEY %x\n",
+ p_eth_upd985xx->index, (int)p_eth_upd985xx, sg_len, total_len, key );
+#endif
+
+ if ( ! p_eth_upd985xx->active )
+ return; // device inactive, no return
+
+ CYG_ASSERT( ! p_eth_upd985xx->tx_busy, "Can't send when busy!" );
+
+ p_eth_upd985xx->tx_busy++;
+
+ p_eth_upd985xx->tx_keys[0] = key;
+ bp = &p_eth_upd985xx->txring[0]; // Current free tx
+ CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
+ CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
+
+#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3
+ // We must copy any Tx that is more than two SGs into just one buffer.
+ if ( sg_len > 2 ) {
+ cyg_uint8 *from_p, *to_p;
+ to_p = &tx_databuf[0]; // normal cached address
+ if ( sizeof( tx_databuf ) < total_len )
+ total_len = sizeof( tx_databuf );
+ for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
+ int l;
+
+ from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address
+ l = sg_list->len;
+
+ if ( l > total_len )
+ l = total_len;
+
+ memcpy( to_p, from_p, l ); // All in cached memory
+ to_p += l;
+ total_len -= l;
+
+ if ( 0 > total_len )
+ break; // Should exit via sg_last normally
+ }
+
+ // Set up SGs describing the single tx buffer
+ total_len = to_p - &tx_databuf[0];
+ local_sg[0].buf = (CYG_ADDRESS)&tx_databuf[0];
+ local_sg[0].len = (CYG_ADDRWORD)total_len;
+ local_sg[1].buf = (CYG_ADDRESS)0;
+ local_sg[1].len = (CYG_ADDRWORD)0;
+
+ // And make the subsequent code use it.
+ sg_len = 1;
+ sg_list = &local_sg[0];
+ }
+#endif
+
+ for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
+ cyg_uint8 *from_p;
+ int l;
+
+ from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address
+ l = sg_list->len;
+
+ if ( l > total_len )
+ l = total_len;
+
+ // Ensure the mbuf contents really is in RAM where DMA can see it.
+ // (Must round to cache lines apparantly for 4120)
+ HAL_DCACHE_STORE( ((CYG_ADDRESS)from_p) &~(HAL_DCACHE_LINE_SIZE-1),
+ l + HAL_DCACHE_LINE_SIZE );
+
+ bp->ptr = VIRT_TO_BUS( from_p ); // uncached real RAM address
+ bp->attr &=~(ETH_BUF_LAST | ETH_BUF_SIZE);
+ bp->attr |= ETH_BUF_SIZE & l;
+ bp->attr |= ETH_BUF_D_L_DATA;
+
+ total_len -= l;
+ bp++;
+
+ if ( 0 > total_len )
+ break; // Should exit via sg_last normally
+ }
+
+ CYG_ASSERT( bp > &p_eth_upd985xx->txring[0], "bp underflow" );
+ CYG_ASSERT( bp < &p_eth_upd985xx->txring[
+ NUM_ELEMENTS(p_eth_upd985xx->tx_bufdesc)
+ ], "bp underflow" );
+
+ bp--;
+ bp->attr |= ETH_BUF_LAST;
+
+ // Make the rest be null links
+ for ( bp++; bp <
+ &p_eth_upd985xx->txring[NUM_ELEMENTS(p_eth_upd985xx->tx_bufdesc)];
+ bp++ ) {
+ bp->attr = ETH_BUF_D_L_LINK;
+ bp->ptr = NULL;
+ }
+
+ CYG_ASSERT( 0 == total_len, "length mismatch in tx" );
+ CYG_ASSERT( last_sg == sg_list, "sg count mismatch in tx" );
+
+ // And start off the tx system
+
+ // Point the hardware at the list of buffers
+ OUTL( ETH_TXDPR, (cyg_uint32)p_eth_upd985xx->txring );
+ // and start the tx.
+
+ // Fault E4 - use only 8 for DTBS, not the previously recommended 16.
+ // Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E4
+ // but no config opt is provided.
+
+ // Fault E7: ETH_TXCR_AFCE must not be used.
+ // Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E7
+ // but no config opt is provided.
+
+ OUTL( ETH_TXCR, ETH_TXCR_TXE | ETH_TXCR_DTBS_8 /* | ETH_TXCR_AFCE */ );
+}
+
+#ifdef CYGPKG_NET
+// ------------------------------------------------------------------------
+//
+// Function : eth_upd985xx_configure
+//
+// Return : 0 = It worked.
+// non0 = It failed.
+// ------------------------------------------------------------------------
+
+STATIC int
+eth_upd985xx_configure(struct eth_upd985xx* p_eth_upd985xx, int promisc, int oversized)
+{
+ int ss;
+
+ // We implement permission of oversize packets by changing LMAX (rather
+ // than enabling HUGEN in ETH_MACC1) because we rely on only one
+ // reception per rx descriptor. General oversize packets could eat
+ // many rx descriptors and we would become ...confused.
+
+ // Sanity check the numbers we're about to use.
+ CYG_ASSERT( sizeof( rx_databuf[0] ) >= MAX_OVERSIZE_PACKET_SIZE,
+ "Oversize packet would overflow rx buffer" );
+ CYG_ASSERT( sizeof( rx_databuf[0] ) >= MAX_ETHERNET_PACKET_SIZE,
+ "Ethernet packet would overflow rx buffer" );
+ if ( oversized )
+ OUTL( ETH_LMAX, MAX_OVERSIZE_PACKET_SIZE );
+ else
+ OUTL( ETH_LMAX, MAX_ETHERNET_PACKET_SIZE );
+
+#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
+ ss = promisc ? 1 : 0; // avoid unused var warning
+ p_eth_upd985xx->promisc = ss;
+#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY
+ // Then we must also set the mode in the chip
+ ss = INL( ETH_AFR );
+ if ( promisc )
+ ss |= ETH_AFR_PRO;
+ else
+ ss &=~ETH_AFR_PRO;
+ OUTL( ETH_AFR, ss );
+#endif // CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY
+#else
+ ss = INL( ETH_AFR );
+ if ( promisc )
+ ss |= ETH_AFR_PRO;
+ else
+ ss &=~ETH_AFR_PRO;
+ OUTL( ETH_AFR, ss );
+#endif
+ return 0; // OK
+}
+#endif
+
+// ------------------------------------------------------------------------
+//
+// Function : eth_upd985xx_ioctl
+//
+// ------------------------------------------------------------------------
+STATIC int
+eth_upd985xx_ioctl(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ struct eth_upd985xx *p_eth_upd985xx;
+
+ p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
+
+#ifdef DEBUG_IOCTL
+ db_printf( "eth_upd985xx_ioctl: device eth%d at %x; key is 0x%x, data at %x[%d]\n",
+ p_eth_upd985xx->index, p_eth_upd985xx, key, data, data_length );
+#endif
+
+ // DO NOT guard possible external entry points - want to be able eg. to
+ // set a mac address of a down interface before bringing it up!
+
+ switch ( key ) {
+
+#ifdef ETH_DRV_SET_MAC_ADDRESS
+ case ETH_DRV_SET_MAC_ADDRESS:
+ if ( 6 != data_length )
+ return -2;
+ return eth_set_mac_address( p_eth_upd985xx, data );
+#endif
+
+#ifdef ETH_DRV_GET_IF_STATS_UD
+ case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+#endif
+ // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+ case ETH_DRV_GET_IF_STATS:
+#endif
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+ {
+ struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+ int i;
+
+ // Chipset entry is no longer supported; RFC1573.
+ for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+ p->snmp_chipset[i] = 0;
+
+ // This perhaps should be a config opt, so you can make up your own
+ // description, or supply it from the instantiation.
+ strcpy( p->description, "NEC uPD985xx on-chip ethernet (CANDY)" );
+ // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+ i = eth_upd985xx_status( p_eth_upd985xx );
+
+ if ( !( i & PHY_STATUS_LINK) ) {
+ p->operational = 2; // LINK DOWN
+ p->duplex = 1; // UNKNOWN
+ p->speed = 0;
+ }
+ else {
+ p->operational = 3; // LINK UP
+ p->duplex = (i & PHY_STATUS_FDX) ? 3 : 2; // 2 = SIMPLEX, 3 = DUPLEX
+ p->speed = ((i & PHY_STATUS_100MBPS) ? 100 : 10) * 1000000;
+ }
+
+ // Admit to it...
+ p->supports_dot3 = true;
+
+ // Those commented out are not available on this chip.
+ p->tx_good = INL( ETH_TPCT ) ;
+ p->tx_max_collisions = INL( ETH_TXCL ) ;
+ p->tx_late_collisions = INL( ETH_TLCL ) ;
+ //p->tx_underrun = INL( ) ;
+ p->tx_carrier_loss = INL( ETH_TCSE ) ;
+ p->tx_deferred = INL( ETH_TDFR ) +
+ INL( ETH_TXDF ) ;
+ //p->tx_sqetesterrors = INL( ) ;
+ p->tx_single_collisions = INL( ETH_TSCL ) ;
+ p->tx_mult_collisions = INL( ETH_TMCL ) ;
+ p->tx_total_collisions = INL( ETH_TSCL ) +
+ INL( ETH_TMCL ) +
+ INL( ETH_TLCL ) +
+ INL( ETH_TXCL ) ;
+ p->rx_good = INL( ETH_RPKT ) ;
+ p->rx_crc_errors = INL( ETH_RFCS ) ;
+ p->rx_align_errors = INL( ETH_RALN ) ;
+ p->rx_resource_errors = p_eth_upd985xx->count_rx_resource;
+ //p->rx_overrun_errors = INL( ) ;
+ //p->rx_collisions = INL( ) ;
+ p->rx_short_frames = INL( ETH_RUND ) ;
+ p->rx_too_long_frames = INL( ETH_ROVR ) ;
+ p->rx_symbol_errors = INL( ETH_RXUO ) ;
+
+ p->interrupts = p_eth_upd985xx->count_interrupts;
+ p->rx_count = INL( ETH_RBYT ) ;
+ p->rx_deliver = INL( ETH_RPKT ) ;
+ p->rx_resource = p_eth_upd985xx->count_rx_resource;
+ p->rx_restart = p_eth_upd985xx->count_rx_resource +
+ p_eth_upd985xx->count_rx_restart;
+ p->tx_count = INL( ETH_TBYT ) ;
+ p->tx_complete = INL( ETH_TPCT ) ;
+ p->tx_dropped = INL( ETH_TNCL ) ;
+
+ p->tx_queue_len = 1;
+
+ return 0; // OK
+ }
+#endif
+
+ default:
+ break;
+ }
+ return -1;
+}
+
+// ------------------------------------------------------------------------
+
+// EOF if_upd985xx.c
diff --git a/ecos/packages/devs/eth/mips/vrc4375/current/ChangeLog b/ecos/packages/devs/eth/mips/vrc4375/current/ChangeLog
new file mode 100644
index 0000000..b12e094
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/vrc4375/current/ChangeLog
@@ -0,0 +1,30 @@
+2001-09-27 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/vrc4375_eth_drivers.cdl: New file.
+ * include/devs_eth_vrc4375.inl: New file.
+ Instantiation data for the Intel 21143 Ethernet Device driver,
+ as used in the NEC MIPS vrc4375 'Blue Nile' board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/mips/vrc4375/current/cdl/vrc4375_eth_drivers.cdl b/ecos/packages/devs/eth/mips/vrc4375/current/cdl/vrc4375_eth_drivers.cdl
new file mode 100644
index 0000000..0dced48
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/vrc4375/current/cdl/vrc4375_eth_drivers.cdl
@@ -0,0 +1,115 @@
+# ====================================================================
+#
+# vrc4375_eth_drivers.cdl
+#
+# Ethernet drivers - support for i21143 ethernet controller
+# on the NEC VRC4375 "Blue Nile" board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): hmt
+# Contributors:
+# Date: 2001-09-17
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_MIPS_VRC4375 {
+ display "NEC vrc4375 ethernet driver"
+ description "
+ Ethernet driver for vrc4375 'Blue Nile' board with one Intel
+ i21143 Ethernet controller attached via the PCI bus."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_MIPS_VR4300_VRC4375
+
+ include_dir cyg/io
+
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I21143_REQUIRED {
+ display "Intel i21143 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I21143_INL <cyg/io/devs_eth_vrc4375.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I21143_CFG <pkgconf/devs_eth_mips_vrc4375.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0 {
+ display "Vrc4375 ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ vrc4375Engine or vrc4375Bridge port 0 - that is the connector one
+ slot in from the corner of the board, or the only connector
+ depending on your particular hardware."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I21143_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_MIPS_VRC4375_ETH0_NAME {
+ display "Device name for the ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_MIPS_VRC4375_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_MIPS_VRC4375_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0x12, 0x34, 0x55, 0x55, 0x66}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
+
+# EOF vrc4375_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/mips/vrc4375/current/include/devs_eth_vrc4375.inl b/ecos/packages/devs/eth/mips/vrc4375/current/include/devs_eth_vrc4375.inl
new file mode 100644
index 0000000..d511f8e
--- /dev/null
+++ b/ecos/packages/devs/eth/mips/vrc4375/current/include/devs_eth_vrc4375.inl
@@ -0,0 +1,126 @@
+//==========================================================================
+//
+// devs/eth/mips/vrc4375/..../include/devs_eth_vrc4375.inl
+//
+// vrc4375 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors:
+// Date: 2001-09-17
+// Purpose: vrc4375 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// --------------------------------------------------------------
+// Construct the interface
+
+#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0
+
+static I21143 i21143_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_MIPS_VRC4375_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_MIPS_VRC4375_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i21143_sc0,
+ &i21143_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_MIPS_VRC4375_ETH0_NAME, // Name for device
+ i21143_start,
+ i21143_stop,
+ i21143_ioctl,
+ i21143_can_send,
+ i21143_send,
+ i21143_recv,
+ i21143_deliver,
+ i21143_poll,
+ i21143_int_vector
+ );
+
+NETDEVTAB_ENTRY(i21143_netdev0,
+ "i21143_" CYGDAT_DEVS_ETH_MIPS_VRC4375_ETH0_NAME,
+ i21143_init,
+ &i21143_sc0);
+
+#endif // CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0
+
+// --------------------------------------------------------------
+// These arrays are used for sanity checking of pointers
+I21143 *
+i21143_priv_array[CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0
+ &i21143_eth0_priv_data,
+#endif
+#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH1
+ &i21143_eth1_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i21143_netdev_array[CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0
+ &i21143_netdev0,
+#endif
+#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH1
+ &i21143_netdev1,
+#endif
+};
+
+struct eth_drv_sc *
+i21143_sc_array[CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0
+ &i21143_sc0,
+#endif
+#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH1
+ &i21143_sc1,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// --------------------------------------------------------------
+// Debugging
+
+//#define CYGDBG_DEVS_ETH_INTEL_I21143_CHATTER 1
+
+// --------------------------------------------------------------
+
+// EOF devs_eth_vrc4375.inl
diff --git a/ecos/packages/devs/eth/mn10300/asb2305/current/ChangeLog b/ecos/packages/devs/eth/mn10300/asb2305/current/ChangeLog
new file mode 100644
index 0000000..8bd07c4
--- /dev/null
+++ b/ecos/packages/devs/eth/mn10300/asb2305/current/ChangeLog
@@ -0,0 +1,27 @@
+2001-07-27 David Howells <dhowells@redhat.com>
+
+ * Ethernet support for ASB2305 platform added.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/mn10300/asb2305/current/cdl/mn10300_asb2305_eth.cdl b/ecos/packages/devs/eth/mn10300/asb2305/current/cdl/mn10300_asb2305_eth.cdl
new file mode 100644
index 0000000..82d87fe
--- /dev/null
+++ b/ecos/packages/devs/eth/mn10300/asb2305/current/cdl/mn10300_asb2305_eth.cdl
@@ -0,0 +1,129 @@
+# ====================================================================
+#
+# mn10300_asb2305_eth.cdl
+#
+# Ethernet drivers - support for AMD PCnet ethernet controller
+# on the ASB2305 board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): dhowells
+# Contributors: jskov
+# Date: 2001-07-23
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_MN10300_ASB2305 {
+ display "MN10300 ASB2305 board ethernet driver"
+ description "Ethernet driver for MN10300 ASB2305 onboard ethernet device."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_MN10300_AM33_ASB2305
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the AMD_PCNET package
+ cdl_interface CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED {
+ display "AMD PCNET ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_PCNET_INL <cyg/io/mn10300_asb2305_eth.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_PCNET_CFG <pkgconf/devs_eth_mn10300_asb2305.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_MN10300_ASB2305_ETH0 {
+ display "ASB2305 ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ ASB2305 port 0."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED
+
+ cdl_option CYGNUM_DEVS_ETH_MN10300_ASB2305_ETH0_RX_RING_SIZE {
+ display "Size of RX ring for ETH0"
+ flavor data
+ default_value 4
+ legal_values { 4 8 16 32 64 128 }
+ description "
+ This option sets the size of the RX ring."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_MN10300_ASB2305_ETH0_TX_RING_SIZE {
+ display "Size of TX ring for ETH0"
+ flavor data
+ default_value 16
+ legal_values { 4 8 16 32 64 128 }
+ description "
+ This option sets the size of the TX ring."
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_MN10300_ASB2305_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ ASB2305 port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_MN10300_ASB2305_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_MN10300_ASB2305_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/mn10300/asb2305/current/include/mn10300_asb2305_eth.inl b/ecos/packages/devs/eth/mn10300/asb2305/current/include/mn10300_asb2305_eth.inl
new file mode 100644
index 0000000..b1b3cde
--- /dev/null
+++ b/ecos/packages/devs/eth/mn10300/asb2305/current/include/mn10300_asb2305_eth.inl
@@ -0,0 +1,108 @@
+//==========================================================================
+//
+// devs/eth/mn10300/asb2305/include/mn10300_asb2305_eth.inl
+//
+// ASB2305 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dhowells
+// Contributors:jskov
+// Date: 2001-07-23
+// Purpose: ASB2305 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#ifdef __WANT_CONFIG
+
+#define CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE CYGARC_UNCACHED_ADDRESS((cyg_uint32)(&CYGMEM_SECTION_pci_window[0]))
+#define CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE ((cyg_uint32)(CYGMEM_SECTION_pci_window_SIZE))
+
+#endif // __WANT_CONFIG
+
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_MN10300_ASB2305_ETH0
+
+static pcnet_priv_data amd_pcnet_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_MN10300_ASB2305_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_MN10300_ASB2305_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+ config_esa : NULL,
+ rx_ring : NULL,
+ rx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_MN10300_ASB2305_ETH0_RX_RING_SIZE*/,
+ rx_ring_log_cnt : 2,
+ tx_ring : NULL,
+ tx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_MN10300_ASB2305_ETH0_TX_RING_SIZE*/,
+ tx_ring_log_cnt : 2,
+};
+
+ETH_DRV_SC(amd_pcnet_sc,
+ &amd_pcnet_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_MN10300_ASB2305_ETH0_NAME,
+ pcnet_start,
+ pcnet_stop,
+ pcnet_control,
+ pcnet_can_send,
+ pcnet_send,
+ pcnet_recv,
+ pcnet_deliver, // "pseudoDSR" called from fast net thread
+ pcnet_poll, // poll function, encapsulates ISR and DSR
+ pcnet_int_vector);
+
+NETDEVTAB_ENTRY(pcnet_netdev,
+ "pcnet_" CYGDAT_DEVS_ETH_MN10300_ASB2305_ETH0_NAME,
+ amd_pcnet_init,
+ &amd_pcnet_sc);
+#endif // CYGPKG_DEVS_ETH_MN10300_ASB2305_ETH0
+
+// These arrays are used for sanity checking of pointers
+struct pcnet_priv_data *
+pcnet_priv_array[CYGNUM_DEVS_ETH_AMD_PCNET_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_MN10300_ASB2305_ETH0
+ &amd_pcnet_eth0_priv_data,
+#endif
+};
+
+#endif // __WANT_DEVS
+
+// EOF mn10300_asb2305_eth.inl
diff --git a/ecos/packages/devs/eth/ns/dp83816/current/ChangeLog b/ecos/packages/devs/eth/ns/dp83816/current/ChangeLog
new file mode 100644
index 0000000..c82fcae
--- /dev/null
+++ b/ecos/packages/devs/eth/ns/dp83816/current/ChangeLog
@@ -0,0 +1,77 @@
+2005-07-18 David Vrabel <dvrabel@arcom.com>
+
+ * src/if_dp83816.c: Use CYG_CPU_TO_LE32 and CYG_LE32_TO_CPU macros
+ instead of the _h2le and _le2h functions.
+
+ * src/dp83816.h: #define's for MEAR (EEPROM access) register.
+
+ * src/dp83816.c [CYGHWR_NS_DP83186_USE_EEPROM]: Read MAC address
+ from EEPROM.
+
+2004-08-24 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_dp83816.c: Enable start/stop functions (device was always
+ enabled once configured before)
+
+2004-05-14 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/if_dp83816.c (dp83816_init): Make ESA diag_printf()
+ controlled by DEBUG flag.
+ (dp83816_init):
+ (dp83816_poll): Fixed interrupt enable, masking and acknowledges
+ so that the driver correctly handles Ctrl-C interrupts in RedBoot.
+
+2004-05-13 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/if_dp83816.c (dp83816_poll): Removed test for locked up
+ transmit engine. This test triggers in otherwise normal situations
+ and the warm reset messes things up a lot in both the driver and
+ network stack.
+ (dp83816_recv): Avoid memcpy() when passed a NULL buffer, this can
+ happen when the stack runs out of MBUFs.
+
+2003-10-14 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_dp83816.c (dp83816_poll): Try to better detect condition
+ where device just stops. This seems to be related to Rx overruns,
+ but there is no status reported. The best that can be done is
+ detect the condition and then reset/restart the device.
+
+2003-10-02 Gary Thomas <gary@mlbassoc.com>
+
+ * src/dp83816.h: Let default ESA be a pointer, so platforms can more
+ easily set it a runtime.
+
+2003-09-30 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_dp83816.c:
+ * src/dp83816.h:
+ * cdl/ns_dp83816_eth_drivers.cdl: New package - ethernet driver for
+ National Semiconductor DP83816 PCI
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/ns/dp83816/current/cdl/ns_dp83816_eth_drivers.cdl b/ecos/packages/devs/eth/ns/dp83816/current/cdl/ns_dp83816_eth_drivers.cdl
new file mode 100644
index 0000000..91e8c7a
--- /dev/null
+++ b/ecos/packages/devs/eth/ns/dp83816/current/cdl/ns_dp83816_eth_drivers.cdl
@@ -0,0 +1,85 @@
+# ====================================================================
+#
+# ns_dp83816_eth_drivers.cdl
+#
+# Ethernet drivers - device support for NS DP83816 Ethernet
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors:
+# Date: 2003-09-29
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_NS_DP83816 {
+ display "NS DP83816 ethernet drivers"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ implements CYGHWR_NET_DRIVERS
+
+ active_if CYGINT_DEVS_ETH_NS_DP83816_REQUIRED
+
+ include_dir cyg/io
+ description "Ethernet driver for NS DP83816 ethernet controller."
+ compile -library=libextras.a if_dp83816.c
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_NS_DP83816_CFG";
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_NS_DP83816_OPTIONS {
+ display "DP83816 ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_NS_DP83816_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the National Semiconductor (DP839x) ethernet driver package.
+ These flags are used in addition to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/ns/dp83816/current/src/dp83816.h b/ecos/packages/devs/eth/ns/dp83816/current/src/dp83816.h
new file mode 100644
index 0000000..dcb85a5
--- /dev/null
+++ b/ecos/packages/devs/eth/ns/dp83816/current/src/dp83816.h
@@ -0,0 +1,276 @@
+//==========================================================================
+//
+// dev/dp83816.h
+//
+// National Semiconductor DP83816 ethernet chip
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors:
+// Date: 2003-09-29
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+#include <pkgconf/devs_eth_ns_dp83816.h>
+
+// ------------------------------------------------------------------------
+// Debugging details
+
+// Set to perms of:
+// 0 disables all debug output
+// 1 for process debug output
+// 2 for added data IO output: get_reg, put_reg
+// 4 for packet allocation/free output
+// 8 for only startup status, so we can tell we're installed OK
+#define DEBUG 0
+__externC int norecurse;
+#if DEBUG & 1
+#define DEBUG_FUNCTION() do { if (!norecurse) { norecurse=1; diag_printf("%s\n", __FUNCTION__); norecurse=0;}} while (0)
+#define DEBUG_LINE() do { diag_printf("%d\n", __LINE__); } while (0)
+#else
+#define DEBUG_FUNCTION() do {} while(0)
+#define DEBUG_LINE() do {} while(0)
+#endif
+
+// ------------------------------------------------------------------------
+// Buffer descriptors
+typedef struct dp83816_bd {
+ volatile struct dp83816_bd *next; // Next descriptor
+ volatile unsigned long stat; // Buffer status & flags
+ volatile unsigned char *buf; // Buffer memory
+ volatile unsigned long key; // Internal use only
+} dp83816_bd_t;
+
+// ------------------------------------------------------------------------
+// Private driver structure
+typedef struct dp83816_priv_data {
+ char *esa_key; // RedBoot 'key' for device ESA
+ unsigned char *enaddr;
+ int rxnum; // Number of Rx buffers
+ unsigned char *rxbuf; // Rx buffer space
+ dp83816_bd_t *rxd; // Rx descriptor pool
+ int txnum; // Number of Tx buffers
+ unsigned char *txbuf; // Tx buffer space
+ dp83816_bd_t *txd; // Tx descriptor pool
+ cyg_uint8 *base;
+ int interrupt; // Interrupt vector
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+#endif
+ dp83816_bd_t *rxnext; // Next Rx to interrupt
+ dp83816_bd_t *txfill; // Next Tx to fill
+ dp83816_bd_t *txint; // Next Tx to interrupt
+ int txbusy; // Number of busy Tx buffers
+} dp83816_priv_data_t;
+
+// ------------------------------------------------------------------------
+// Macros for accessing DP registers
+// These can be overridden by the platform header
+// Note: the only accesses used must be 32 bit little endian.
+
+#ifndef DP_IN
+# define DP_IN(_b_, _o_, _d_) HAL_READ_UINT32((cyg_addrword_t)(_b_)+(_o_), (_d_))
+# define DP_OUT(_b_, _o_, _d_) HAL_WRITE_UINT32((cyg_addrword_t)(_b_)+(_o_), (_d_))
+#endif
+
+// ------------------------------------------------------------------------
+// Macros allowing platform to customize some of the driver details
+
+#ifndef CYGHWR_NS_DP83816_PLF_RESET
+# define CYGHWR_NS_DP83816_PLF_RESET(_b_) do { } while (0)
+#endif
+
+#ifndef CYGHWR_NS_DP83816_PLF_INT_CLEAR
+# define CYGHWR_NS_DP83816_PLF_INT_CLEAR(_dp_)
+#endif
+
+#ifndef CYGHWR_NS_DP83816_PLF_INIT
+#define CYGHWR_NS_DP83816_PLF_INIT(dp) do { } while (0)
+#endif
+
+
+// ------------------------------------------------------------------------
+// Some forward declarations
+static void dp83816_poll(struct eth_drv_sc *sc);
+
+// ------------------------------------------------------------------------
+// Register offsets
+
+#define DP_CR 0x00 // Command register
+#define _CR_RST 0x100 // Chip reset
+#define _CR_RXR 0x020 // Rx reset
+#define _CR_TXR 0x010 // Tx reset
+#define _CR_RXD 0x008 // Rx disable
+#define _CR_RXE 0x004 // Rx enable
+#define _CR_TXD 0x002 // Tx disable
+#define _CR_TXE 0x001 // Tx enable
+#define DP_CFG 0x04 // Configuration register
+#define _CFG_LNKSTS (1<<31) // Link status
+#define _CFG_SPD100 (1<<30) // 100Mb
+#define _CFG_FDUP (1<<29) // Full duplex
+#define _CFG_POL (1<<28) // 10Mb polarity
+#define _CFG_ANDONE (1<<27) // Auto-negotiation done
+#define DP_MEAR 0x08 // EEPROM access
+#define _MEAR_EESEL (1<<3) // EEPROM chip select
+#define _MEAR_EECLK (1<<2) // EEPROM serial clock
+#define _MEAR_EEDO (1<<1) // EEPROM data out
+#define _MEAR_EEDI (1<<0) // EEPROM data in
+#define DP_ISR 0x10 // Interrupt status
+#define _ISR_TXRCMP (1<<25) // Tx reset complete
+#define _ISR_RXRCMP (1<<24) // Rx reset complete
+#define _ISR_DPERR (1<<23) // Detected parity error
+#define _ISR_SSERR (1<<22) // Signalled system error
+#define _ISR_RMABT (1<<21) // Received master abort
+#define _ISR_RTABT (1<<20) // Received target abort
+#define _ISR_RXSOVR (1<<16) // Rx status FIFO overrun
+#define _ISR_HIBERR (1<<15) // High bits set (25-16)
+#define _ISR_PHY (1<<14) // PHY interrupt
+#define _ISR_PME (1<<13) // Power management event
+#define _ISR_SWI (1<<12) // Software interrpt
+#define _ISR_MIB (1<<11) // MII service
+#define _ISR_TXURN (1<<10) // Tx underrun
+#define _ISR_TXIDLE (1<<9) // Tx idle (end of list)
+#define _ISR_TXERR (1<<8) // Tx packet error
+#define _ISR_TXDESC (1<<7) // Tx descriptor with INTS
+#define _ISR_TXOK (1<<6) // Last Tx descriptor done
+#define _ISR_RXORN (1<<5) // Rx overrun
+#define _ISR_RXIDLE (1<<4) // Rx idle (end of list)
+#define _ISR_RXEARLY (1<<3) // Rx early threshold met
+#define _ISR_RXERR (1<<2) // Rx packet error
+#define _ISR_RXDESC (1<<1) // Rx descriptor with INTS
+#define _ISR_RXOK (1<<0) // Last Rx descriptor done
+#define DP_IMR 0x14 // Interrupt mask
+#define DP_IER 0x18 // Interrupt enable
+#define DP_IHR 0x1C // Interrupt hold
+#define DP_TXDP 0x20 // Tx descriptor pointer
+#define DP_TXCFG 0x24 // Tx configuration
+#define _TXCFG_CSI (1<<31) // Ignore carrier sense
+#define _TXCFG_HBI (1<<30) // Ignore heartbeat
+#define _TXCFG_MLB (1<<29) // Loopback
+#define _TXCFG_ATP (1<<28) // Automatic padding
+#define _TXCFG_ECRTRY (1<<23) // Excessive collision enable
+#define _TXCFG_MXDMA_SHIFT 20
+#define _TXCFG_MXDMA_MASK 0x7
+#define _TXCFG_MXDMA_512 (0x0<<20)
+#define _TXCFG_MXDMA_4 (0x1<<20)
+#define _TXCFG_MXDMA_8 (0x2<<20)
+#define _TXCFG_MXDMA_16 (0x3<<20)
+#define _TXCFG_MXDMA_32 (0x4<<20)
+#define _TXCFG_MXDMA_64 (0x5<<20)
+#define _TXCFG_MXDMA_128 (0x6<<20)
+#define _TXCFG_MXDMA_256 (0x7<<20)
+#define _TXCFG_FLTH_SHIFT 8
+#define _TXCFG_FLTH_MASK 0x3F
+#define _TXCFG_DRTH_SHIFT 0
+#define _TXCFG_DRTH_MASK 0x3F
+#define DP_RXDP 0x30 // Rx descriptor pointer
+#define DP_RXCFG 0x34 // Rx configuration
+#define _RXCFG_AEP (1<<31) // Accept error packets
+#define _RXCFG_ARP (1<<30) // Accept runt packets
+#define _RXCFG_ATX (1<<28) // Accept Tx packets (loopback)
+#define _RXCFG_ALP (1<<27) // Accpet long packets (> 1518 bytes)
+#define _RXCFG_MXDMA_SHIFT 20
+#define _RXCFG_MXDMA_MASK 0x7
+#define _RXCFG_MXDMA_512 (0x0<<20)
+#define _RXCFG_MXDMA_4 (0x1<<20)
+#define _RXCFG_MXDMA_8 (0x2<<20)
+#define _RXCFG_MXDMA_16 (0x3<<20)
+#define _RXCFG_MXDMA_32 (0x4<<20)
+#define _RXCFG_MXDMA_64 (0x5<<20)
+#define _RXCFG_MXDMA_128 (0x6<<20)
+#define _RXCFG_MXDMA_256 (0x7<<20)
+#define _RXCFG_FLTH_SHIFT 8
+#define _RXCFG_FLTH_MASK 0x3F
+#define _RXCFG_DRTH_SHIFT 0
+#define _RXCFG_DRTH_MASK 0x3F
+#define DP_RFCR 0x48 // Receive filter control
+#define _RFCR_RFEN (1<<31) // Rx filter enable
+#define _RFCR_AAB (1<<30) // Accept all broadcast
+#define _RFCR_AAM (1<<29) // Accept all multicast
+#define _RFCR_AAU (1<<28) // Accept all unicast
+#define _RFCR_APM (1<<27) // Accept on perfect match
+#define _RFCR_APAT (1<<26) // Accept on patern match
+#define _RFCR_AARP (1<<22) // Accept ARP
+#define _RFCR_MHEN (1<<21) // Multicast hash enable
+#define _RFCR_UHEN (1<<20) // Unicast hash enable
+#define _RFCR_ULM (1<<19) // U/L bit ignore
+#define DP_RFDR 0x4C // Receive filter data register
+
+// Buffer descriptor status/flags
+#define BD_OWN (1<<31) // Owned by producer (Tx=driver, Rx=DP83816)
+#define BD_MORE (1<<30) // More descriptors in this frame
+#define BD_INTR (1<<29) // Interrupt when this descriptor processed
+#define BD_CRC (1<<28) // Include CRC
+#define BD_OK (1<<27) // Packet OK
+// Tx buffer flags
+#define BD_TXA (1<<26) // Tx abort
+#define BD_TFU (1<<25) // Tx underrun
+#define BD_CRS (1<<24) // Carrier sense lost
+#define BD_TD (1<<23) // Transmission deferred
+#define BD_ED (1<<22) // Excessive Tx deferrals
+#define BD_OWC (1<<21) // Out of window collision
+#define BD_EC (1<<20) // Excessive collisions
+#define BD_CCNT_MASK 0x0F
+#define BD_CCNT_SHIFT 16 // Collision count
+// Rx buffer flags
+#define BD_RXA (1<<26) // Rx abort
+#define BD_RXO (1<<25) // Rx overrun
+#define BD_DEST_MASK (3<<23)
+#define BD_DEST_REJECT (0<<23) // Packet rejected
+#define BD_DEST_UNICAST (1<<23) // Unicast packet
+#define BD_DEST_MULTICAST (2<<23) // Multicast packet
+#define BD_DEST_BROADCAST (3<<23) // Broadcast packet
+#define BD_LONG (1<<22) // Too long packet received
+#define BD_RUNT (1<<21) // Runt packet
+#define BD_ISE (1<<20) // Illegal symbol
+#define BD_CRCE (1<<19) // CRC error
+#define BD_FAE (1<<18) // Frame alignment error
+#define BD_LBP (1<<17) // Loopback frame
+#define BD_COL (1<<16) // Collision during frame
+// Length field
+#define BD_LENGTH_MASK 0x0FFF
+
+#define IEEE_8023_MAX_FRAME 1518 // Largest possible ethernet frame
+#define IEEE_8023_MIN_FRAME 64 // Smallest possible ethernet frame
+
+#define _DP83816_BUFSIZE 1540 // Size of buffers
diff --git a/ecos/packages/devs/eth/ns/dp83816/current/src/if_dp83816.c b/ecos/packages/devs/eth/ns/dp83816/current/src/if_dp83816.c
new file mode 100644
index 0000000..f328152
--- /dev/null
+++ b/ecos/packages/devs/eth/ns/dp83816/current/src/if_dp83816.c
@@ -0,0 +1,587 @@
+//==========================================================================
+//
+// dev/if_dp83816.c
+//
+// Ethernet device driver for NS DP83816 ethernet controller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors:
+// Date: 2003-09-29
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_endian.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/netdev.h>
+#include <string.h> // memcpy
+
+#include "dp83816.h"
+#include CYGDAT_DEVS_ETH_NS_DP83816_INL
+
+#if DEBUG & 1
+int norecurse;
+#endif
+
+#ifdef CYGHWR_NS_DP83816_USE_EEPROM
+static cyg_uint16 dp83816_eeprom_read(struct dp83816_priv_data *dp, int location);
+#endif
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+// This ISR is called when the ethernet interrupt occurs
+static cyg_uint32
+dp83816_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
+ dp83816_priv_data_t *dp = (dp83816_priv_data_t *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ cyg_drv_interrupt_mask(dp->interrupt);
+ cyg_drv_interrupt_acknowledge(dp->interrupt);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+// The deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+dp83816_deliver(struct eth_drv_sc *sc)
+{
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ dp83816_priv_data_t *dp = (dp83816_priv_data_t *)sc->driver_private;
+#endif
+
+ DEBUG_FUNCTION();
+
+ // Service the interrupt:
+ dp83816_poll(sc);
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(dp->interrupt);
+#endif
+}
+
+static bool
+dp83816_reset(dp83816_priv_data_t *dp)
+{
+ unsigned char *bp;
+ dp83816_bd_t *bdp;
+ cyg_uint32 stat;
+ int i, timeout;
+
+ DP_OUT(dp->base, DP_CR, _CR_RST); // Reset device
+ timeout = 10000;
+ do {
+ DP_IN(dp->base, DP_CR, stat);
+ } while (((stat & _CR_RST) != 0) && (--timeout > 0));
+ if (timeout == 0) {
+ diag_printf("DP83816 - reset timed out! - stat: %x\n", stat);
+ return false;
+ }
+
+ // Rx ring
+ bdp = dp->rxnext = CYGARC_UNCACHED_ADDRESS(dp->rxd);
+ bp = dp->rxbuf;
+ for (i = 0; i < dp->rxnum; i++, bdp++) {
+ bdp->next = (dp83816_bd_t *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(bdp+1));
+ bdp->stat = CYG_CPU_TO_LE32(BD_INTR | _DP83816_BUFSIZE); // Max buffer
+ bdp->buf = (unsigned char *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(bp));
+ bp += _DP83816_BUFSIZE;
+ }
+ bdp--; bdp->next = (dp83816_bd_t *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(dp->rxd));
+ DP_OUT(dp->base, DP_RXCFG, _RXCFG_MXDMA_128 | ((64/32)<<_RXCFG_DRTH_SHIFT));
+ DP_OUT(dp->base, DP_RXDP, CYGARC_PHYSICAL_ADDRESS(dp->rxd));
+ // Tx ring
+ bdp = dp->txfill = dp->txint = CYGARC_UNCACHED_ADDRESS(dp->txd);
+ bp = dp->txbuf;
+ for (i = 0; i < dp->txnum; i++, bdp++) {
+ bdp->next = (dp83816_bd_t *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(bdp+1));
+ bdp->stat = 0; // Driver owns buffer for now
+ bdp->buf = (unsigned char *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(bp));
+ bp += _DP83816_BUFSIZE;
+ }
+ bdp--; bdp->next = (dp83816_bd_t *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(dp->txd));
+ DP_OUT(dp->base, DP_TXCFG, _TXCFG_ATP |
+ _TXCFG_MXDMA_128 |
+ /* _TXCFG_CSI | */
+ ((256/32)<<_TXCFG_FLTH_SHIFT) |
+ ((512/32)<<_TXCFG_DRTH_SHIFT));
+ DP_OUT(dp->base, DP_TXDP, CYGARC_PHYSICAL_ADDRESS(dp->txd));
+ dp->txbusy = 0;
+ // Fill in ESA
+ for (i = 0; i < 6; i+=2) {
+ DP_OUT(dp->base, DP_RFCR, i);
+ DP_OUT(dp->base, DP_RFDR, dp->enaddr[i] | (dp->enaddr[i+1]<<8));
+ }
+ // Setup up acceptance criteria
+ DP_OUT(dp->base, DP_RFCR, _RFCR_RFEN | _RFCR_AAB | _RFCR_APM);
+ // Set up interrupts
+ DP_IN(dp->base, DP_ISR, stat); // Clear any current interrupts
+ DP_OUT(dp->base, DP_IMR, 0x00000000); // Disable them all!
+ DP_OUT(dp->base, DP_IER, 0);
+ return true;
+}
+
+static bool
+dp83816_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ dp83816_priv_data_t *dp = (dp83816_priv_data_t *)sc->driver_private;
+ cyg_uint8 *base;
+ bool esa_ok = false;
+ unsigned char enaddr[6];
+
+ DEBUG_FUNCTION();
+
+ CYGHWR_NS_DP83816_PLF_INIT(dp);
+ base = dp->base;
+ if (!base) return false; // No device found
+
+#ifdef CYGPKG_REDBOOT
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+ esa_ok = flash_get_config(dp->esa_key, enaddr, CONFIG_ESA);
+#endif
+#elif defined (CONFIG_ESA)
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ dp->esa_key, enaddr, CONFIG_ESA);
+#endif
+ // Get physical device address
+ // There are two different implementations due to parallel implementations.
+ // Both are included for backward compatibility, but
+ // the CYGHWR_DEVS_ETH_NS_DP83816_USE_EEPROM_ESA implementation is
+ // preferred simply because it is smaller.
+#if defined(CYGHWR_DEVS_ETH_NS_DP83816_USE_EEPROM_ESA)
+ if (!esa_ok)
+ {
+ // Read the ESA from the PMATCH receive filter register, which
+ // will have been initialised from the EEPROM.
+ cyg_uint32 rfcrdat;
+ cyg_ucount8 i;
+ for (i = 0; i < 6; i+=2) {
+ DP_OUT(dp->base, DP_RFCR, i);
+ DP_IN(dp->base, DP_RFDR, rfcrdat );
+ enaddr[i] = rfcrdat & 0xff;
+ enaddr[i+1] = (rfcrdat>>8) & 0xff;
+ }
+ esa_ok = true;
+ }
+#elif defined(CYGHWR_NS_DP83816_USE_EEPROM)
+ // This define (CYGHWR_NS_DP83816_USE_EEPROM) is deprecated.
+ {
+ cyg_uint16 t;
+
+ t = (dp83816_eeprom_read(dp, 0x0006) >> 15)
+ | (dp83816_eeprom_read(dp, 0x0007) << 1);
+ enaddr[0] = t & 0xFF;
+ enaddr[1] = t >> 8;
+ t = (dp83816_eeprom_read(dp, 0x0007) >> 15)
+ | (dp83816_eeprom_read(dp, 0x0008) << 1);
+ enaddr[2] = t & 0xFF;
+ enaddr[3] = t >> 8;
+ t = (dp83816_eeprom_read(dp, 0x0008) >> 15)
+ | (dp83816_eeprom_read(dp, 0x0009) << 1);
+ enaddr[4] = t & 0xFF;
+ enaddr[5] = t >> 8;
+
+ esa_ok = true;
+ }
+#endif
+ if (esa_ok) {
+ memcpy(dp->enaddr, enaddr, sizeof(enaddr));
+ } else {
+ // Can't figure out ESA
+ diag_printf("DP83816 - Warning! ESA unknown\n");
+ }
+
+ // DEBUG_FUNCTION();
+
+ if (!dp83816_reset(dp)) return false;
+
+#if DEBUG & 8
+ diag_printf("DP83816 - ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ dp->enaddr[0], dp->enaddr[1], dp->enaddr[2],
+ dp->enaddr[3], dp->enaddr[4], dp->enaddr[5] );
+#endif
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_create(
+ dp->interrupt,
+ 0, // Priority - unused
+ (cyg_addrword_t)sc, // Data item passed to ISR & DSR
+ dp83816_isr, // ISR
+ eth_drv_dsr, // DSR
+ &dp->interrupt_handle, // handle to intr obj
+ &dp->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(dp->interrupt_handle);
+ cyg_drv_interrupt_unmask(dp->interrupt);
+#elif defined(CYGPKG_REDBOOT)
+ cyg_drv_interrupt_unmask(dp->interrupt);
+#endif
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, dp->enaddr);
+
+ return true;
+}
+
+static void
+dp83816_stop(struct eth_drv_sc *sc)
+{
+ dp83816_priv_data_t *dp = (dp83816_priv_data_t *)sc->driver_private;
+
+ DP_OUT(dp->base, DP_IMR, 0x00000000); // Disable interrupts
+ DP_OUT(dp->base, DP_IER, 0);
+ DP_OUT(dp->base, DP_CR, _CR_RXD | _CR_TXD);
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+dp83816_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ dp83816_priv_data_t *dp = (dp83816_priv_data_t *)sc->driver_private;
+
+ DP_OUT(dp->base, DP_IMR, 0xFFFFFFFF); // Enable interrupts
+ DP_OUT(dp->base, DP_IER, 1);
+ DP_OUT(dp->base, DP_CR, _CR_RXE | _CR_TXE);
+}
+
+//
+// This routine is called to perform special "control" opertions
+//
+static int
+dp83816_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_len)
+{
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ return 0;
+ break;
+ default:
+ return 1;
+ break;
+ }
+}
+
+//
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+//
+static int
+dp83816_can_send(struct eth_drv_sc *sc)
+{
+ dp83816_priv_data_t *dp = (dp83816_priv_data_t *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+ return (dp->txnum - dp->txbusy);
+}
+
+//
+// This routine is called to send data to the hardware. It is known a-priori
+// that there is free buffer space (dp->tx_next).
+//
+static void
+dp83816_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
+ int i, len;
+ unsigned char *data;
+ dp83816_bd_t *bdp;
+#if 0
+ cyg_uint32 ints;
+ cyg_drv_dsr_lock();
+ HAL_DISABLE_INTERRUPTS(ints);
+#endif
+
+ bdp= dp->txfill;
+
+ DEBUG_FUNCTION();
+
+ len = total_len;
+ if (len < IEEE_8023_MIN_FRAME) len = IEEE_8023_MIN_FRAME;
+ data = (unsigned char *)CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->buf));
+#if DEBUG & 1
+ if (!norecurse) {
+ norecurse=1;
+ diag_printf("send sg_len==%d, txbusy=%d, len=%d, total_len=%d\n", sg_len, dp->txbusy, len, total_len);
+ norecurse = 0;
+ }
+#endif
+ for (i = 0; i < sg_len; i++) {
+ memcpy(data, (unsigned char *)sg_list[i].buf, sg_list[i].len);
+ data += sg_list[i].len;
+ }
+ bdp->key = key;
+ bdp->stat = CYG_CPU_TO_LE32(len | BD_OWN | BD_INTR);
+ dp->txbusy++;
+ bdp = (dp83816_bd_t *)CYGARC_UNCACHED_ADDRESS(CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->next)));
+ dp->txfill = bdp;
+ // Kick the device, in case it went idle
+ DP_OUT(dp->base, DP_CR, _CR_TXE);
+#if 0
+ cyg_drv_dsr_unlock();
+ HAL_RESTORE_INTERRUPTS(ints);
+#endif
+}
+
+static void
+dp83816_TxEvent(struct eth_drv_sc *sc)
+{
+ struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
+ dp83816_bd_t *bdp = dp->txint;
+
+ DEBUG_FUNCTION();
+ while ((CYG_LE32_TO_CPU(bdp->stat) & (BD_OWN|BD_INTR)) == BD_INTR) {
+ // Tell higher level we sent this packet
+ (sc->funs->eth_drv->tx_done)(sc, bdp->key, 0);
+ bdp->stat = 0; // retake buffer
+ bdp->key = 0;
+ dp->txbusy--;
+ bdp = (dp83816_bd_t *)CYGARC_UNCACHED_ADDRESS(CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->next)));
+ }
+ dp->txint = bdp;
+}
+
+//
+// This function is called when a packet has been received. It's job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'dp83816_recv' will be called to actually fetch it from the hardware.
+//
+static void
+dp83816_RxEvent(struct eth_drv_sc *sc)
+{
+ struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
+ dp83816_bd_t *bdp = CYGARC_UNCACHED_ADDRESS(dp->rxd);
+ dp83816_bd_t *bdfirst = CYGARC_UNCACHED_ADDRESS(dp->rxd);
+ int len, err;
+
+ DEBUG_FUNCTION();
+
+ while (true) {
+ if ((CYG_LE32_TO_CPU(bdp->stat) & BD_OWN) != 0) {
+ err = CYG_LE32_TO_CPU(bdp->stat) & (BD_RXA|BD_RXO|BD_LONG|BD_RUNT|BD_ISE|BD_CRCE|BD_FAE|BD_COL);
+ if (err != 0) {
+ diag_printf("RxError: %x\n", err);
+ }
+ len = CYG_LE32_TO_CPU(bdp->stat) & BD_LENGTH_MASK;
+ dp->rxnext = bdp;
+ (sc->funs->eth_drv->recv)(sc, len);
+ bdp->stat = CYG_CPU_TO_LE32(BD_INTR | _DP83816_BUFSIZE); // Give back buffer
+ }
+ bdp = (dp83816_bd_t *)CYGARC_UNCACHED_ADDRESS(CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->next)));
+ if (bdp == bdfirst) {
+ break;
+ }
+ }
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// It's job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+dp83816_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
+ dp83816_bd_t *bdp = dp->rxnext;
+ unsigned char *data;
+ int i;
+
+ data = (unsigned char *)CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->buf));
+ for (i = 0; i < sg_len; i++) {
+ if( sg_list[i].buf )
+ memcpy((void *)sg_list[i].buf, data, sg_list[i].len);
+ data += sg_list[i].len;
+ }
+}
+
+static void
+dp83816_warm_reset(struct eth_drv_sc *sc)
+{
+ struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
+ dp83816_bd_t *bdp;
+ int i;
+
+ DEBUG_FUNCTION();
+ // Free up any active Tx buffers
+ bdp = CYGARC_UNCACHED_ADDRESS(dp->txd);
+ for (i = 0; i < dp->txnum; i++, bdp++) {
+ if (bdp->key) {
+ (sc->funs->eth_drv->tx_done)(sc, bdp->key, 0);
+ }
+ }
+ // Reset the device
+ dp83816_reset(dp);
+ DP_OUT(dp->base, DP_CR, _CR_RXE | _CR_TXE);
+}
+
+static void
+dp83816_poll(struct eth_drv_sc *sc)
+{
+ struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
+ unsigned long stat, cr_stat;
+
+#if defined(CYGPKG_REDBOOT)
+ cyg_drv_interrupt_acknowledge(dp->interrupt);
+#endif
+
+ DP_IN(dp->base, DP_ISR, stat);
+ do {
+ if ((stat & (_ISR_TXDESC|_ISR_TXOK)) != 0) {
+ dp83816_TxEvent(sc);
+ }
+ if ((stat & (_ISR_RXDESC|_ISR_RXOK|_ISR_RXERR)) != 0) {
+ dp83816_RxEvent(sc);
+ }
+ DP_IN(dp->base, DP_CR, cr_stat);
+ if ((stat & (_ISR_HIBERR|_ISR_TXURN|_ISR_RXORN)) != 0) {
+#if DEBUG & 2
+ diag_printf("DP83816 - major error: %x, cmd_stat: %x\n", stat, cr_stat);
+#endif
+ // Try to reset the device
+ dp83816_warm_reset(sc);
+ }
+#if 0
+ if (((cr_stat & _CR_RXE) == 0) ||
+ ((dp->txbusy > 1) && ((cr_stat & _CR_TXE) == 0)))
+ {
+#if DEBUG & 2
+ // What happened?
+ diag_printf("DP83816 went to lunch? - stat: %x/%x, txbusy: %x, bdstat: %x\n", cr_stat, stat, dp->txbusy, dp->txint->stat);
+#endif
+ // Try to reset the device
+ dp83816_warm_reset(sc);
+ }
+#endif
+ DP_IN(dp->base, DP_ISR, stat);
+ } while (stat != 0);
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ CYGHWR_NS_DP83816_PLF_INT_CLEAR(dp);
+#endif
+}
+
+static int
+dp83816_int_vector(struct eth_drv_sc *sc)
+{
+ struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
+ return dp->interrupt;
+}
+
+/* EEPROM Functions */
+#ifdef CYGHWR_NS_DP83816_USE_EEPROM
+
+#define EEPROM_READ(dp, x) DP_IN((dp)->base, DP_MEAR, (x))
+#define EEPROM_WRITE(dp, x) DP_OUT((dp)->base, DP_MEAR, (x))
+#define EEPROM_DELAY(dp) CYG_MACRO_START cyg_uint16 t; EEPROM_READ((dp), t); CYG_MACRO_END
+
+#define DP83816_EEPROM_ADDR_LEN 6
+#define DP83816_EE_READ_CMD (6 << DP83816_EEPROM_ADDR_LEN)
+
+
+/* EEPROM data is bit-swapped. */
+static cyg_uint16 dp83816_eeprom_fixup_data(cyg_uint16 input)
+{
+ cyg_uint16 output = 0;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ output = (output << 1) | (input & 0x0001);
+ input >>= 1;
+ }
+ return output;
+}
+
+static cyg_uint16 dp83816_eeprom_command(struct dp83816_priv_data *dp, int cmd, int cmd_len)
+{
+ int d = 0;
+
+ EEPROM_WRITE(dp, _MEAR_EESEL);
+
+ do {
+ cyg_uint32 c = (cmd & (1 << cmd_len)) ? _MEAR_EEDI : 0;
+ cyg_uint8 t;
+
+ EEPROM_WRITE(dp, c | _MEAR_EESEL);
+ EEPROM_DELAY(dp);
+ EEPROM_WRITE(dp, c | _MEAR_EESEL | _MEAR_EECLK);
+ EEPROM_DELAY(dp);
+
+ EEPROM_READ(dp, t);
+ d <<= 1;
+ d |= (t & _MEAR_EEDO) ? 1 : 0;
+ } while (cmd_len--);
+
+ EEPROM_WRITE(dp, _MEAR_EESEL);
+ EEPROM_WRITE(dp, 0);
+
+ return d & 0xffff;
+}
+
+static cyg_uint16 dp83816_eeprom_read(struct dp83816_priv_data *dp, int loc)
+{
+ cyg_uint16 d;
+
+ d = dp83816_eeprom_command(dp, (loc | DP83816_EE_READ_CMD) << 16,
+ 3 + DP83816_EEPROM_ADDR_LEN + 16);
+
+ return dp83816_eeprom_fixup_data(d);
+}
+
+#endif /* CYGHWR_NS_DP83816_USE_EEPROM */
diff --git a/ecos/packages/devs/eth/ns/dp83902a/current/ChangeLog b/ecos/packages/devs/eth/ns/dp83902a/current/ChangeLog
new file mode 100644
index 0000000..73b719c
--- /dev/null
+++ b/ecos/packages/devs/eth/ns/dp83902a/current/ChangeLog
@@ -0,0 +1,144 @@
+2004-08-12 Jani Monoses <jani@iv.ro>
+
+ * src/if_dp83902a.c: Fix builing with lwip.
+
+2003-11-19 David Woodhouse <dwmw2@redhat.com>
+
+ * src/if_dp83902a.c: Set STOP bit in CR after setting CURP
+ register; required for AX88796 chip. Fix handling of BNDRY
+ pointer w.r.t. ring buffer wrap-around. Add extra delays
+ ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_dp83902a.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-05-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_dp83902a.c: Use CYGINT_IO_ETH_INT_SUPPORT_REQUIRED instead
+ of CYGPKG_NET where required.
+
+2002-04-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_dp83902a.c: Clean up warnings.
+
+2002-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/ns_dp83902a_eth_drivers.cdl: Fix spelling of _OPTIONS
+ component as this is magic (CDL requires that it match the
+ package or it is ignored).
+
+2002-01-14 Jesper Skov <jskov@redhat.com>
+
+ * src/if_dp83902a.c (dp83902a_ClearCounters): Fix warning.
+
+2001-12-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * src/if_dp83902a.c (dp83902a_RxEvent): Remove unused argument.
+ (dp83902a_TxEvent): Likewise.
+ (dp83902a_BufEvent): Remove.
+ (dp83902a_ClearCounters): New.
+ (dp83902a_Overflow): New.
+ (dp83902a_poll): Rework polling loop to use the new functions.
+
+2001-10-16 Jesper Skov <jskov@redhat.com>
+
+ * include/dp83902a.h: Removed hardwired buffer
+ allocation. Replaced with per-device configuration.
+ * src/if_dp83902a.c: Same.
+
+2001-10-15 Jesper Skov <jskov@redhat.com>
+
+ * include/dp83902a.h: Added new page allocation layout.
+
+2001-10-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_dp83902a.c: Leave out interrupt code - not needed in
+ non-NET configurations.
+
+2001-10-10 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_dp83902a.c:
+ * include/dp83902a.h: More flexible setup. Chip reset address is
+ now in device data, along with changes to the PLF reset functions.
+ Also, a new PLF init function can be defined which allows the driver
+ to work in a PCI enviroment (addresses unknown at compile time).
+
+2001-09-12 Jesper Skov <jskov@redhat.com>
+
+ * src/if_dp83902a.c: Apply a little more DMA magic.
+
+2001-08-25 Gary Thomas <gthomas@redhat.com>
+
+ * include/dp83902a.h (DP_DATAPORT): Add - used by ESA discovery
+ on SC/LPE card.
+
+2001-06-21 Jesper Skov <jskov@redhat.com>
+
+ * src/if_dp83902a.c: Fix various build problems when net package
+ is included.
+
+2001-06-16 Jesper Skov <jskov@redhat.com>
+
+ * src/if_dp83902a.c (dp83902a_poll): Ignore spurious Tx events.
+
+2001-06-15 Jesper Skov <jskov@redhat.com>
+
+ * src/if_dp83902a.c: Added crude CR race check. Use plf interrupt
+ clear to allow for CF driver to use this driver. Cleaned up debug
+ output some.
+ (dp83902a_send): Added some magic delays to get driver working on
+ some (apparently) broken boards.
+
+ * src/dp83902a.h: Moved..
+ * include/dp83902a.h: to here. Moved macro definitions here from
+ the src file.
+
+ * cdl/ns_dp83902a_eth_drivers.cdl: Export header file.
+
+2001-06-14 Jesper Skov <jskov@redhat.com>
+
+ * src/if_dp83902a.c: Added some more debug info.
+
+ * src/dp83902a.h: Added 16bit/BE macros (untested).
+
+ * src/if_dp83902a.c: Add some debug code, fix endian issue. Proper
+ handling of odd-length reads in 16bit mode.
+
+2001-06-13 Jesper Skov <jskov@redhat.com>
+
+ * src/if_dp83902a.c: Assume LE ordering of read header data.
+
+ * src/dp83902a.h: BE/LE versions of data IO. Define proper DCR
+ init value depending on data access width.
+
+ * Cloned from DP8390 driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/ns/dp83902a/current/cdl/ns_dp83902a_eth_drivers.cdl b/ecos/packages/devs/eth/ns/dp83902a/current/cdl/ns_dp83902a_eth_drivers.cdl
new file mode 100644
index 0000000..313d2a3
--- /dev/null
+++ b/ecos/packages/devs/eth/ns/dp83902a/current/cdl/ns_dp83902a_eth_drivers.cdl
@@ -0,0 +1,85 @@
+# ====================================================================
+#
+# ns_dp83902a_eth_drivers.cdl
+#
+# Ethernet drivers - device support for NS DP83902A Ethernet
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov
+# Date: 2001-06-13
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_NS_DP83902A {
+ display "NS DP83902A ethernet drivers"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ implements CYGHWR_NET_DRIVERS
+
+ active_if CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED
+
+ include_dir cyg/io
+ description "Ethernet driver for NS DP83902A (and DP8390) ethernet controller."
+ compile -library=libextras.a if_dp83902a.c
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_NS_DP83902A_CFG";
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_NS_DP83902A_OPTIONS {
+ display "DP83902A ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_NS_DP83902A_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the National Semiconductor (DP839x) ethernet driver package.
+ These flags are used in addition to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/ns/dp83902a/current/include/dp83902a.h b/ecos/packages/devs/eth/ns/dp83902a/current/include/dp83902a.h
new file mode 100644
index 0000000..98f6577
--- /dev/null
+++ b/ecos/packages/devs/eth/ns/dp83902a/current/include/dp83902a.h
@@ -0,0 +1,373 @@
+//==========================================================================
+//
+// dev/dp83902a.h
+//
+// National Semiconductor DP83902a ethernet chip
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Date: 2001-06-13
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+#include <pkgconf/devs_eth_ns_dp83902a.h>
+
+#define __WANT_CONFIG
+#include CYGDAT_DEVS_ETH_NS_DP83902A_INL
+#undef __WANT_CONFIG
+
+// ------------------------------------------------------------------------
+// Debugging details
+
+// Set to perms of:
+// 0 disables all debug output
+// 1 for process debug output
+// 2 for added data IO output: get_reg, put_reg
+// 4 for packet allocation/free output
+// 8 for only startup status, so we can tell we're installed OK
+#define DEBUG 0x0
+
+#if DEBUG & 1
+#define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0)
+#define DEBUG_LINE() do { diag_printf("%d\n", __LINE__); } while (0)
+#else
+#define DEBUG_FUNCTION() do {} while(0)
+#define DEBUG_LINE() do {} while(0)
+#endif
+
+// ------------------------------------------------------------------------
+// MAcros for keeping track of statistics
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+#define KEEP_STATISTICS
+#endif
+
+#ifdef KEEP_STATISTICS
+#define INCR_STAT( _x_ ) (dp->stats. _x_ ++)
+#else
+#define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
+#endif
+
+// ------------------------------------------------------------------------
+// Private driver structure
+typedef struct dp83902a_priv_data {
+ cyg_uint8* base;
+ cyg_uint8* data;
+ cyg_uint8* reset;
+ int tx_next; // First free Tx page
+ int tx_int; // Expecting interrupt from this buffer
+ int rx_next; // First free Rx page
+ int tx1, tx2; // Page numbers for Tx buffers
+ unsigned long tx1_key, tx2_key; // Used to ack when packet sent
+ int tx1_len, tx2_len;
+ bool tx_started, running, hardwired_esa;
+ struct cyg_netdevtab_entry *tab;
+ cyg_uint8 esa[6];
+ cyg_vector_t interrupt; // Interrupt vector used by controller
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+ void* plf_priv;
+
+ // For debugging
+ volatile int cr_lock;
+ volatile int cr_owner;
+
+ // Buffer allocation
+ int tx_buf1, tx_buf2;
+ int rx_buf_start, rx_buf_end;
+} dp83902a_priv_data_t;
+
+// ------------------------------------------------------------------------
+// Macros for accessing structure elements
+
+#define _SU8( _base_, _offset_) \
+ *((volatile cyg_uint8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU16( _base_, _offset_) \
+ *((volatile cyg_uint16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU32( _base_, _offset_) \
+ *((volatile cyg_uint32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+#define _SI8( _base_, _offset_) \
+ *((volatile cyg_int8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI16( _base_, _offset_) \
+ *((volatile cyg_int16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI32( _base_, _offset_) \
+ *((volatile cyg_int32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+// ------------------------------------------------------------------------
+// Macros for accessing DP registers
+// These can be overridden by the platform header
+
+#ifndef DP_IN
+# define DP_IN(_b_, _o_, _d_) HAL_READ_UINT8 ((cyg_addrword_t)(_b_)+(_o_), (_d_))
+# define DP_OUT(_b_, _o_, _d_) HAL_WRITE_UINT8((cyg_addrword_t)(_b_)+(_o_), (_d_))
+#endif
+
+#ifndef DP_IN_DATA
+# ifdef CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+# ifdef BIGEND
+# define DP_IN_DATA(_b_, _d_) \
+ CYG_MACRO_START \
+ cyg_uint16 _t; \
+ HAL_READ_UINT16 ((cyg_addrword_t)(_b_), _t); \
+ DELAY(); \
+ (_d_) = ((_t >> 8) & 0xff) | ((_t & 0xff) << 8); \
+ CYG_MACRO_END
+
+# define DP_OUT_DATA(_b_, _d_) \
+ CYG_MACRO_START \
+ cyg_uint16 _t; \
+ _t = (_d_); \
+ (_t) = (((_t) >> 8) & 0xff) | ((_t & 0xff) << 8); \
+ HAL_WRITE_UINT16((cyg_addrword_t)(_b_), _t); \
+ DELAY(); \
+ CYG_MACRO_END
+# else
+# define DP_IN_DATA(_b_, _d_) HAL_READ_UINT16 ((cyg_addrword_t)(_b_), (_d_))
+# define DP_OUT_DATA(_b_, _d_) HAL_WRITE_UINT16 ((cyg_addrword_t)(_b_), (_d_))
+# endif
+# else
+# define DP_IN_DATA(_b_, _d_) HAL_READ_UINT8 ((cyg_addrword_t)(_b_), (_d_))
+# define DP_OUT_DATA(_b_, _d_) HAL_WRITE_UINT8 ((cyg_addrword_t)(_b_), (_d_))
+# endif
+#endif
+
+// ------------------------------------------------------------------------
+// Macros allowing platform to customize some of the driver details
+
+#ifndef CYGHWR_NS_DP83902A_PLF_RESET
+# define CYGHWR_NS_DP83902A_PLF_RESET(_b_) do { } while (0)
+#endif
+
+#ifndef CYGHWR_NS_DP83902A_PLF_INT_CLEAR
+# define CYGHWR_NS_DP83902A_PLF_INT_CLEAR(_dp_)
+#endif
+
+#ifndef CYGHWR_NS_DP83902A_PLF_INIT
+#define CYGHWR_NS_DP83902A_PLF_INIT(dp) do { } while (0)
+#endif
+
+// ------------------------------------------------------------------------
+// Hack that should go away, probably
+#define CR_UP() \
+ CYG_MACRO_START \
+ if (++dp->cr_lock > 1) { \
+ diag_printf("*** Race on CR %s:%d owner %d\n", \
+ __FUNCTION__, __LINE__, dp->cr_owner); \
+ for (;;); \
+ } \
+ dp->cr_owner = __LINE__; \
+ CYG_MACRO_END
+
+#define CR_DOWN() \
+ dp->cr_lock--;
+
+// ------------------------------------------------------------------------
+// Some forward declarations
+static void dp83902a_poll(struct eth_drv_sc *sc);
+
+// ------------------------------------------------------------------------
+// Register offsets
+
+#define DP_CR 0x00
+#define DP_CLDA0 0x01
+#define DP_PSTART 0x01 // write
+#define DP_CLDA1 0x02
+#define DP_PSTOP 0x02 // write
+#define DP_BNDRY 0x03
+#define DP_TSR 0x04
+#define DP_TPSR 0x04 // write
+#define DP_NCR 0x05
+#define DP_TBCL 0x05 // write
+#define DP_FIFO 0x06
+#define DP_TBCH 0x06 // write
+#define DP_ISR 0x07
+#define DP_CRDA0 0x08
+#define DP_RSAL 0x08 // write
+#define DP_CRDA1 0x09
+#define DP_RSAH 0x09 // write
+#define DP_RBCL 0x0a // write
+#define DP_RBCH 0x0b // write
+#define DP_RSR 0x0c
+#define DP_RCR 0x0c // write
+#define DP_FER 0x0d
+#define DP_TCR 0x0d // write
+#define DP_CER 0x0e
+#define DP_DCR 0x0e // write
+#define DP_MISSED 0x0f
+#define DP_IMR 0x0f // write
+#define DP_DATAPORT 0x10 // "eprom" data port
+
+#define DP_P1_CR 0x00
+#define DP_P1_PAR0 0x01
+#define DP_P1_PAR1 0x02
+#define DP_P1_PAR2 0x03
+#define DP_P1_PAR3 0x04
+#define DP_P1_PAR4 0x05
+#define DP_P1_PAR5 0x06
+#define DP_P1_CURP 0x07
+#define DP_P1_MAR0 0x08
+#define DP_P1_MAR1 0x09
+#define DP_P1_MAR2 0x0a
+#define DP_P1_MAR3 0x0b
+#define DP_P1_MAR4 0x0c
+#define DP_P1_MAR5 0x0d
+#define DP_P1_MAR6 0x0e
+#define DP_P1_MAR7 0x0f
+
+#define DP_P2_CR 0x00
+#define DP_P2_PSTART 0x01
+#define DP_P2_CLDA0 0x01 // write
+#define DP_P2_PSTOP 0x02
+#define DP_P2_CLDA1 0x02 // write
+#define DP_P2_RNPP 0x03
+#define DP_P2_TPSR 0x04
+#define DP_P2_LNPP 0x05
+#define DP_P2_ACH 0x06
+#define DP_P2_ACL 0x07
+#define DP_P2_RCR 0x0c
+#define DP_P2_TCR 0x0d
+#define DP_P2_DCR 0x0e
+#define DP_P2_IMR 0x0f
+
+// Command register - common to all pages
+
+#define DP_CR_STOP 0x01 // Stop: software reset
+#define DP_CR_START 0x02 // Start: initialize device
+#define DP_CR_TXPKT 0x04 // Transmit packet
+#define DP_CR_RDMA 0x08 // Read DMA (recv data from device)
+#define DP_CR_WDMA 0x10 // Write DMA (send data to device)
+#define DP_CR_SEND 0x18 // Send packet
+#define DP_CR_NODMA 0x20 // Remote (or no) DMA
+#define DP_CR_PAGE0 0x00 // Page select
+#define DP_CR_PAGE1 0x40
+#define DP_CR_PAGE2 0x80
+#define DP_CR_PAGEMSK 0x3F // Used to mask out page bits
+
+// Data configuration register
+
+#define DP_DCR_WTS 0x01 // 1=16 bit word transfers
+#define DP_DCR_BOS 0x02 // 1=Little Endian
+#define DP_DCR_LAS 0x04 // 1=Single 32 bit DMA mode
+#define DP_DCR_LS 0x08 // 1=normal mode, 0=loopback
+#define DP_DCR_ARM 0x10 // 0=no send command (program I/O)
+#define DP_DCR_FIFO_1 0x00 // FIFO threshold
+#define DP_DCR_FIFO_2 0x20
+#define DP_DCR_FIFO_4 0x40
+#define DP_DCR_FIFO_6 0x60
+
+#ifdef CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+# ifdef BIGENDIAN
+# define DP_DCR_INIT (DP_DCR_BOS|DP_DCR_WTS|DP_DCR_LS|DP_DCR_FIFO_4)
+# else
+# define DP_DCR_INIT (DP_DCR_WTS|DP_DCR_LS|DP_DCR_FIFO_4)
+# endif
+#else
+# define DP_DCR_INIT (DP_DCR_LS|DP_DCR_FIFO_4)
+#endif
+
+// Interrupt status register
+
+#define DP_ISR_RxP 0x01 // Packet received
+#define DP_ISR_TxP 0x02 // Packet transmitted
+#define DP_ISR_RxE 0x04 // Receive error
+#define DP_ISR_TxE 0x08 // Transmit error
+#define DP_ISR_OFLW 0x10 // Receive overflow
+#define DP_ISR_CNT 0x20 // Tally counters need emptying
+#define DP_ISR_RDC 0x40 // Remote DMA complete
+#define DP_ISR_RESET 0x80 // Device has reset (shutdown, error)
+
+// Interrupt mask register
+
+#define DP_IMR_RxP 0x01 // Packet received
+#define DP_IMR_TxP 0x02 // Packet transmitted
+#define DP_IMR_RxE 0x04 // Receive error
+#define DP_IMR_TxE 0x08 // Transmit error
+#define DP_IMR_OFLW 0x10 // Receive overflow
+#define DP_IMR_CNT 0x20 // Tall counters need emptying
+#define DP_IMR_RDC 0x40 // Remote DMA complete
+
+#define DP_IMR_All 0x3F // Everything but remote DMA
+
+// Receiver control register
+
+#define DP_RCR_SEP 0x01 // Save bad(error) packets
+#define DP_RCR_AR 0x02 // Accept runt packets
+#define DP_RCR_AB 0x04 // Accept broadcast packets
+#define DP_RCR_AM 0x08 // Accept multicast packets
+#define DP_RCR_PROM 0x10 // Promiscuous mode
+#define DP_RCR_MON 0x20 // Monitor mode - 1=accept no packets
+
+// Receiver status register
+
+#define DP_RSR_RxP 0x01 // Packet received
+#define DP_RSR_CRC 0x02 // CRC error
+#define DP_RSR_FRAME 0x04 // Framing error
+#define DP_RSR_FO 0x08 // FIFO overrun
+#define DP_RSR_MISS 0x10 // Missed packet
+#define DP_RSR_PHY 0x20 // 0=pad match, 1=mad match
+#define DP_RSR_DIS 0x40 // Receiver disabled
+#define DP_RSR_DFR 0x80 // Receiver processing deferred
+
+// Transmitter control register
+
+#define DP_TCR_NOCRC 0x01 // 1=inhibit CRC
+#define DP_TCR_NORMAL 0x00 // Normal transmitter operation
+#define DP_TCR_LOCAL 0x02 // Internal NIC loopback
+#define DP_TCR_INLOOP 0x04 // Full internal loopback
+#define DP_TCR_OUTLOOP 0x08 // External loopback
+#define DP_TCR_ATD 0x10 // Auto transmit disable
+#define DP_TCR_OFFSET 0x20 // Collision offset adjust
+
+// Transmit status register
+
+#define DP_TSR_TxP 0x01 // Packet transmitted
+#define DP_TSR_COL 0x04 // Collision (at least one)
+#define DP_TSR_ABT 0x08 // Aborted because of too many collisions
+#define DP_TSR_CRS 0x10 // Lost carrier
+#define DP_TSR_FU 0x20 // FIFO underrun
+#define DP_TSR_CDH 0x40 // Collision Detect Heartbeat
+#define DP_TSR_OWC 0x80 // Collision outside normal window
+
+#define IEEE_8023_MAX_FRAME 1518 // Largest possible ethernet frame
+#define IEEE_8023_MIN_FRAME 64 // Smallest possible ethernet frame
+
diff --git a/ecos/packages/devs/eth/ns/dp83902a/current/src/if_dp83902a.c b/ecos/packages/devs/eth/ns/dp83902a/current/src/if_dp83902a.c
new file mode 100644
index 0000000..a1f187d
--- /dev/null
+++ b/ecos/packages/devs/eth/ns/dp83902a/current/src/if_dp83902a.c
@@ -0,0 +1,788 @@
+//==========================================================================
+//
+// dev/if_dp83902a.c
+//
+// Ethernet device driver for NS DP83902a ethernet controller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov, rsandifo
+// Date: 2001-06-13
+// Purpose:
+// Description:
+//
+// FIXME: Will fail if pinged with large packets (1520 bytes)
+// Add promisc config
+// Add SNMP
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/netdev.h>
+
+#include <cyg/io/dp83902a.h>
+
+#define __WANT_DEVS
+#include CYGDAT_DEVS_ETH_NS_DP83902A_INL
+#undef __WANT_DEVS
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+// This ISR is called when the ethernet interrupt occurs
+static cyg_uint32
+dp83902a_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *)data;
+
+ DEBUG_FUNCTION();
+// INCR_STAT( interrupts );
+
+ cyg_drv_interrupt_mask(dp->interrupt);
+ cyg_drv_interrupt_acknowledge(dp->interrupt);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+static void
+dp83902a_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ // This conditioning out is necessary because of explicit calls to this
+ // DSR - which would not ever be called in the case of a polled mode
+ // usage ie. in RedBoot.
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ dp83902a_priv_data_t* dp = (dp83902a_priv_data_t *)data;
+ struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(dp->tab);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ DEBUG_FUNCTION();
+
+ // but here, it must be a *sc:
+ eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+#else
+# ifndef CYGPKG_REDBOOT
+# error Empty DP83902A ethernet DSR is compiled. Is this what you want?
+# endif
+#endif
+}
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+// The deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+dp83902a_deliver(struct eth_drv_sc *sc)
+{
+ dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ // Service the interrupt:
+ dp83902a_poll(sc);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(dp->interrupt);
+}
+
+static bool
+dp83902a_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *)sc->driver_private;
+ cyg_uint8* base;
+ int i;
+
+ DEBUG_FUNCTION();
+
+ CYGHWR_NS_DP83902A_PLF_INIT(dp);
+ base = dp->base;
+ if (!base) return false; // No device found
+
+ dp->tab = tab;
+ dp->cr_lock = 0;
+
+ CYGHWR_NS_DP83902A_PLF_RESET(dp);
+
+ DEBUG_LINE();
+
+ // Prepare ESA
+ DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); // Select page 1
+ if (dp->hardwired_esa) {
+ // Force the NIC to use the specified ESA
+ for (i = 0; i < 6; i++)
+ DP_OUT(base, DP_P1_PAR0+i, dp->esa[i]);
+ } else {
+ // Use the address from the serial EEPROM
+ for (i = 0; i < 6; i++)
+ DP_IN(base, DP_P1_PAR0+i, dp->esa[i]);
+ }
+ DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); // Select page 0
+
+ diag_printf("DP83902A - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ (dp->hardwired_esa) ? "static" : "eeprom",
+ dp->esa[0],
+ dp->esa[1],
+ dp->esa[2],
+ dp->esa[3],
+ dp->esa[4],
+ dp->esa[5] );
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_create(
+ dp->interrupt,
+ 0, // Priority - unused
+ (cyg_addrword_t)dp,// Data item passed to ISR & DSR
+ dp83902a_isr, // ISR
+ dp83902a_dsr, // DSR
+ &dp->interrupt_handle, // handle to intr obj
+ &dp->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(dp->interrupt_handle);
+ cyg_drv_interrupt_unmask(dp->interrupt);
+#endif
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, dp->esa);
+
+ return true;
+}
+
+static void
+dp83902a_stop(struct eth_drv_sc *sc)
+{
+ dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *)sc->driver_private;
+ cyg_uint8 *base = dp->base;
+
+ DEBUG_FUNCTION();
+
+ CR_UP();
+ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); // Brutal
+ DP_OUT(base, DP_ISR, 0xFF); // Clear any pending interrupts
+ DP_OUT(base, DP_IMR, 0x00); // Disable all interrupts
+ CR_DOWN();
+
+ dp->running = false;
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+dp83902a_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *)sc->driver_private;
+ cyg_uint8 *base = dp->base;
+ int i;
+
+ DEBUG_FUNCTION();
+
+ CR_UP();
+ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); // Brutal
+ DP_OUT(base, DP_DCR, DP_DCR_INIT);
+ DP_OUT(base, DP_RBCH, 0); // Remote byte count
+ DP_OUT(base, DP_RBCL, 0);
+ DP_OUT(base, DP_RCR, DP_RCR_MON); // Accept no packets
+ DP_OUT(base, DP_TCR, DP_TCR_LOCAL); // Transmitter [virtually] off
+ DP_OUT(base, DP_TPSR, dp->tx_buf1); // Transmitter start page
+ dp->tx1 = dp->tx2 = 0;
+ dp->tx_next = dp->tx_buf1;
+ dp->tx_started = false;
+ DP_OUT(base, DP_PSTART, dp->rx_buf_start); // Receive ring start page
+ DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); // Receive ring boundary
+ DP_OUT(base, DP_PSTOP, dp->rx_buf_end); // Receive ring end page
+ dp->rx_next = dp->rx_buf_start-1;
+ DP_OUT(base, DP_ISR, 0xFF); // Clear any pending interrupts
+ DP_OUT(base, DP_IMR, DP_IMR_All); // Enable all interrupts
+ DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP); // Select page 1
+ DP_OUT(base, DP_P1_CURP, dp->rx_buf_start); // Current page - next free page for Rx
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
+ }
+ // Enable and start device
+ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+ DP_OUT(base, DP_TCR, DP_TCR_NORMAL); // Normal transmit operations
+ DP_OUT(base, DP_RCR, DP_RCR_AB); // Accept broadcast, no errors, no multicast
+ dp->running = true;
+ CR_DOWN();
+}
+
+//
+// This routine is called to perform special "control" opertions
+//
+static int
+dp83902a_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_len)
+{
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ return 0;
+ break;
+ default:
+ return 1;
+ break;
+ }
+}
+
+//
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+//
+static int
+dp83902a_can_send(struct eth_drv_sc *sc)
+{
+ dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ return ((dp->tx1 == 0) || (dp->tx2 == 0));
+}
+
+//
+// This routine is called to start the transmitter. It is split out from the
+// data handling routine so it may be called either when data becomes first
+// available or when an Tx interrupt occurs
+//
+
+static void
+dp83902a_start_xmit(struct eth_drv_sc *sc, int start_page, int len)
+{
+ dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *)sc->driver_private;
+ cyg_uint8 *base = dp->base;
+
+ DEBUG_FUNCTION();
+
+#if DEBUG & 1
+ diag_printf("Tx pkt %d len %d\n", start_page, len);
+ if (dp->tx_started)
+ diag_printf("TX already started?!?\n");
+#endif
+
+ CR_UP();
+ DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE));
+ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+ DP_OUT(base, DP_TBCL, len & 0xFF);
+ DP_OUT(base, DP_TBCH, len >> 8);
+ DP_OUT(base, DP_TPSR, start_page);
+ DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
+
+ CR_DOWN();
+ dp->tx_started = true;
+}
+
+//
+// This routine is called to send data to the hardware. It is known a-priori
+// that there is free buffer space (dp->tx_next).
+//
+static void
+dp83902a_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
+ cyg_uint8 *base = dp->base;
+ int i, len, start_page, pkt_len;
+ unsigned char *data;
+ cyg_uint8 isr;
+#if DEBUG & 4
+ int dx;
+#endif
+
+ DEBUG_FUNCTION();
+
+ pkt_len = total_len;
+ if (pkt_len < IEEE_8023_MIN_FRAME) pkt_len = IEEE_8023_MIN_FRAME;
+#ifdef CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+ // Make length even when using 16 bit transfers
+ if (pkt_len % 2) pkt_len++;
+#endif
+
+ start_page = dp->tx_next;
+ if (dp->tx_next == dp->tx_buf1) {
+ dp->tx1 = start_page;
+ dp->tx1_len = pkt_len;
+ dp->tx1_key = key;
+ dp->tx_next = dp->tx_buf2;
+ } else {
+ dp->tx2 = start_page;
+ dp->tx2_len = pkt_len;
+ dp->tx2_key = key;
+ dp->tx_next = dp->tx_buf1;
+ }
+ CR_UP();
+
+#if DEBUG & 5
+ diag_printf("TX prep page %d len %d\n", start_page, pkt_len);
+#endif
+
+ DP_OUT(base, DP_ISR, DP_ISR_RDC); // Clear end of DMA
+ {
+ // Dummy read. The manual sez something slightly different,
+ // but the code is extended a bit to do what Hitachi's monitor
+ // does (i.e., also read data).
+
+ cyg_uint16 tmp;
+#ifdef CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+ int len = 2;
+#else
+ int len = 1;
+#endif
+
+ DP_OUT(base, DP_RSAL, 0x100-len);
+ DP_OUT(base, DP_RSAH, (start_page-1) & 0xff);
+ DP_OUT(base, DP_RBCL, len);
+ DP_OUT(base, DP_RBCH, 0);
+ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
+ DP_IN_DATA(dp->data, tmp);
+ }
+
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
+ // Stall for a bit before continuing to work around random data
+ // corruption problems on some platforms.
+ CYGACC_CALL_IF_DELAY_US(1);
+#endif
+
+ // Send data to device buffer(s)
+ DP_OUT(base, DP_RSAL, 0);
+ DP_OUT(base, DP_RSAH, start_page);
+ DP_OUT(base, DP_RBCL, pkt_len & 0xFF);
+ DP_OUT(base, DP_RBCH, pkt_len >> 8);
+ DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START);
+
+ // Put data into buffer
+ for (i = 0; i < sg_len; i++) {
+ data = (unsigned char *)sg_list[i].buf;
+ len = sg_list[i].len;
+#if DEBUG & 4
+ diag_printf(" sg buf %08x len %08x\n ", data, len);
+ dx = 0;
+#endif
+ while (len > 0) {
+#ifdef CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+ cyg_uint16 tmp;
+ tmp = *data++ << 8;
+ len -= 2;
+ if (len >= 0)
+ tmp |= *data++;
+ DP_OUT_DATA(dp->data, tmp);
+#if DEBUG & 4
+ diag_printf(" %04x", tmp);
+ if (0 == (++dx % 8)) diag_printf("\n ");
+#endif
+#else
+#if DEBUG & 4
+ diag_printf(" %02x", *data);
+ if (0 == (++dx % 16)) diag_printf("\n ");
+#endif
+ DP_OUT_DATA(dp->data, *data++);
+ len--;
+#endif
+ }
+#if DEBUG & 4
+ diag_printf("\n");
+#endif
+ }
+ if (total_len < pkt_len) {
+#if DEBUG & 4
+ diag_printf(" + %d bytes of padding\n", pkt_len - total_len);
+#endif
+ // Padding to 802.3 length was required
+ for (i = total_len; i < pkt_len;) {
+#ifdef CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+ i += 2;
+#else
+ i++;
+#endif
+ DP_OUT_DATA(dp->data, 0);
+ }
+ }
+
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
+ // After last data write, delay for a bit before accessing the
+ // device again, or we may get random data corruption in the last
+ // datum (on some platforms).
+ CYGACC_CALL_IF_DELAY_US(1);
+#endif
+
+ // Wait for DMA to complete
+ do {
+ DP_IN(base, DP_ISR, isr);
+ } while ((isr & DP_ISR_RDC) == 0);
+ // Then disable DMA
+ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+ CR_DOWN();
+
+ // Start transmit if not already going
+ if (!dp->tx_started) {
+ if (start_page == dp->tx1) {
+ dp->tx_int = 1; // Expecting interrupt from BUF1
+ } else {
+ dp->tx_int = 2; // Expecting interrupt from BUF2
+ }
+ dp83902a_start_xmit(sc, start_page, pkt_len);
+ }
+}
+
+//
+// This function is called when a packet has been received. It's job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'dp83902a_recv' will be called to actually fetch it from the hardware.
+//
+static void
+dp83902a_RxEvent(struct eth_drv_sc *sc)
+{
+ struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
+ cyg_uint8 *base = dp->base;
+ unsigned char rsr;
+ unsigned char rcv_hdr[4];
+ int i, len, pkt, cur;
+
+ DEBUG_FUNCTION();
+
+ DP_IN(base, DP_RSR, rsr);
+ while (true) {
+ CR_UP();
+ // Read incoming packet header
+ DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START);
+ DP_IN(base, DP_P1_CURP, cur);
+ DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+ DP_IN(base, DP_BNDRY, pkt);
+
+ pkt += 1;
+ if (pkt == dp->rx_buf_end)
+ pkt = dp->rx_buf_start;
+
+ if (pkt == cur) {
+ CR_DOWN();
+ break;
+ }
+ DP_OUT(base, DP_RBCL, sizeof(rcv_hdr));
+ DP_OUT(base, DP_RBCH, 0);
+ DP_OUT(base, DP_RSAL, 0);
+ DP_OUT(base, DP_RSAH, pkt);
+ if (dp->rx_next == pkt) {
+ if (cur == dp->rx_buf_start)
+ DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
+ else
+ DP_OUT(base, DP_BNDRY, cur-1); // Update pointer
+ CR_DOWN();
+ return;
+ }
+ dp->rx_next = pkt;
+ DP_OUT(base, DP_ISR, DP_ISR_RDC); // Clear end of DMA
+ DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
+ CYGACC_CALL_IF_DELAY_US(10);
+#endif
+
+ for (i = 0; i < sizeof(rcv_hdr);) {
+#ifdef CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+ cyg_uint16 tmp;
+ DP_IN_DATA(dp->data, tmp);
+ rcv_hdr[i++] = (tmp >> 8) & 0xff;
+ rcv_hdr[i++] = tmp & 0xff;
+#else
+ DP_IN_DATA(dp->data, rcv_hdr[i++]);
+#endif
+ }
+ CR_DOWN();
+
+#if DEBUG & 5
+ diag_printf("rx hdr %02x %02x %02x %02x\n",
+ rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
+#endif
+ len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
+ (sc->funs->eth_drv->recv)(sc, len);
+ if (rcv_hdr[1] == dp->rx_buf_start)
+ DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
+ else
+ DP_OUT(base, DP_BNDRY, rcv_hdr[1]-1); // Update pointer
+ }
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// It's job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+dp83902a_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
+ cyg_uint8 *base = dp->base;
+ int i, mlen, len;
+ unsigned char *data;
+ cyg_uint8 saved_char = 0;
+ bool saved;
+#if DEBUG & 4
+ int dx;
+#endif
+
+ DEBUG_FUNCTION();
+
+ // Compute total packet length
+ len = 0;
+ for (i = 0; i < sg_len; i++) {
+ len += sg_list[i].len;
+ }
+
+#if DEBUG & 5
+ diag_printf("Rx packet %d length %d\n", dp->rx_next, len);
+#endif
+
+ CR_UP();
+
+ // Read incoming packet data
+ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+ DP_OUT(base, DP_RBCL, len & 0xFF);
+ DP_OUT(base, DP_RBCH, len >> 8);
+ DP_OUT(base, DP_RSAL, 4); // Past header
+ DP_OUT(base, DP_RSAH, dp->rx_next);
+ DP_OUT(base, DP_ISR, DP_ISR_RDC); // Clear end of DMA
+ DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
+ CYGACC_CALL_IF_DELAY_US(10);
+#endif
+
+ saved = false;
+ for (i = 0; i < sg_len; i++) {
+ data = (unsigned char *)sg_list[i].buf;
+ if (data) {
+ mlen = sg_list[i].len;
+#if DEBUG & 4
+ diag_printf(" sg buf %08x len %08x \n", data, mlen);
+ dx = 0;
+#endif
+ while (0 < mlen) {
+ // Saved byte from previous loop?
+ if (saved) {
+ *data++ = saved_char;
+ mlen--;
+ saved = false;
+ continue;
+ }
+
+#ifdef CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+ {
+ cyg_uint16 tmp;
+ DP_IN_DATA(dp->data, tmp);
+#if DEBUG & 4
+ diag_printf(" %04x", tmp);
+ if (0 == (++dx % 8)) diag_printf("\n ");
+#endif
+ *data++ = (tmp >> 8) & 0xff;
+ mlen--;
+ if (0 == mlen) {
+ saved_char = tmp & 0xff;
+ saved = true;
+ } else {
+ *data++ = tmp & 0xff;
+ mlen--;
+ }
+ }
+#else
+ {
+ cyg_uint8 tmp;
+ DP_IN_DATA(dp->data, tmp);
+#if DEBUG & 4
+ diag_printf(" %02x", tmp);
+ if (0 == (++dx % 16)) diag_printf("\n ");
+#endif
+ *data++ = tmp;;
+ mlen--;
+ }
+#endif
+ }
+#if DEBUG & 4
+ diag_printf("\n");
+#endif
+ }
+ }
+ CR_DOWN();
+}
+
+static void
+dp83902a_TxEvent(struct eth_drv_sc *sc)
+{
+ struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
+ cyg_uint8 *base = dp->base;
+ unsigned char tsr;
+ unsigned long key;
+
+ DEBUG_FUNCTION();
+
+ DP_IN(base, DP_TSR, tsr);
+ if (dp->tx_int == 1) {
+ key = dp->tx1_key;
+ dp->tx1 = 0;
+ } else {
+ key = dp->tx2_key;
+ dp->tx2 = 0;
+ }
+ // Start next packet if one is ready
+ dp->tx_started = false;
+ if (dp->tx1) {
+ dp83902a_start_xmit(sc, dp->tx1, dp->tx1_len);
+ dp->tx_int = 1;
+ } else if (dp->tx2) {
+ dp83902a_start_xmit(sc, dp->tx2, dp->tx2_len);
+ dp->tx_int = 2;
+ } else {
+ dp->tx_int = 0;
+ }
+ // Tell higher level we sent this packet
+ (sc->funs->eth_drv->tx_done)(sc, key, 0);
+}
+
+// Read the tally counters to clear them. Called in response to a CNT
+// interrupt.
+static void
+dp83902a_ClearCounters(struct eth_drv_sc *sc)
+{
+ struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
+ cyg_uint8 *base = dp->base;
+ cyg_uint8 cnt1, cnt2, cnt3;
+
+ DP_IN(base, DP_FER, cnt1);
+ DP_IN(base, DP_CER, cnt2);
+ DP_IN(base, DP_MISSED, cnt3);
+ DP_OUT(base, DP_ISR, DP_ISR_CNT);
+}
+
+// Deal with an overflow condition. This code follows the procedure set
+// out in section 7.0 of the datasheet.
+static void
+dp83902a_Overflow(struct eth_drv_sc *sc)
+{
+ struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
+ cyg_uint8 *base = dp->base;
+ cyg_uint8 isr;
+
+ // Issue a stop command and wait 1.6ms for it to complete.
+ CR_UP();
+ DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
+ CYGACC_CALL_IF_DELAY_US(1600);
+
+ // Clear the remote byte counter registers.
+ DP_OUT(base, DP_RBCL, 0);
+ DP_OUT(base, DP_RBCH, 0);
+
+ // Enter loopback mode while we clear the buffer.
+ DP_OUT(base, DP_TCR, DP_TCR_LOCAL);
+ DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
+ CR_DOWN();
+
+ // Read in as many packets as we can and acknowledge any and receive
+ // interrupts. Since the buffer has overflowed, a receive event of
+ // some kind will have occured.
+ dp83902a_RxEvent(sc);
+ DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
+
+ // Clear the overflow condition and leave loopback mode.
+ DP_OUT(base, DP_ISR, DP_ISR_OFLW);
+ DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
+
+ // If a transmit command was issued, but no transmit event has occured,
+ // restart it here.
+ DP_IN(base, DP_ISR, isr);
+ if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
+ CR_UP();
+ DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
+ CR_DOWN();
+ }
+}
+
+static void
+dp83902a_poll(struct eth_drv_sc *sc)
+{
+ struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
+ cyg_uint8 *base = dp->base;
+ unsigned char isr;
+
+// DEBUG_FUNCTION();
+
+ CR_UP();
+ DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
+ CR_DOWN();
+ DP_IN(base, DP_ISR, isr);
+ while (0 != isr) {
+ // The CNT interrupt triggers when the MSB of one of the error
+ // counters is set. We don't much care about these counters, but
+ // we should read their values to reset them.
+ if (isr & DP_ISR_CNT) {
+ dp83902a_ClearCounters(sc);
+ }
+ // Check for overflow. It's a special case, since there's a
+ // particular procedure that must be followed to get back into
+ // a running state.
+ if (isr & DP_ISR_OFLW) {
+ dp83902a_Overflow(sc);
+ } else {
+ // Other kinds of interrupts can be acknowledged simply by
+ // clearing the relevant bits of the ISR. Do that now, then
+ // handle the interrupts we care about.
+ DP_OUT(base, DP_ISR, isr); // Clear set bits
+ if (!dp->running) break; // Is this necessary?
+ // Check for tx_started on TX event since these may happen
+ // spuriously it seems.
+ if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
+ dp83902a_TxEvent(sc);
+ }
+ if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
+ dp83902a_RxEvent(sc);
+ }
+ }
+ DP_IN(base, DP_ISR, isr);
+ }
+
+ CYGHWR_NS_DP83902A_PLF_INT_CLEAR(dp);
+}
+
+static int
+dp83902a_int_vector(struct eth_drv_sc *sc)
+{
+ struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
+ return dp->interrupt;
+}
diff --git a/ecos/packages/devs/eth/phy/current/ChangeLog b/ecos/packages/devs/eth/phy/current/ChangeLog
new file mode 100644
index 0000000..66751bb
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/ChangeLog
@@ -0,0 +1,124 @@
+2011-07-22 Christophe Coutand <ecos@hotmail.co.uk> and sergeig
+
+ * cdl/phy_eth_drivers.cdl: Use CYGHWR_DEVS_ETH_PHY_DP8384X name
+ instead CYGHWR_DEVS_ETH_PHY_DP83847
+ * src/DP83847.c: Renamed stat() function, add new PHY DP83848C
+ Update due renaming CYGHWR_DEVS_ETH_PHY_DP83847 to
+ CYGHWR_DEVS_ETH_PHY_DP8384X. [ Bugzilla 1001235 ]
+
+2011-07-02 Ilija Kocho <ilijak@siva.com.mk>
+
+ * src/KSZ8041.c: More silicon revisions. [Bugzilla 1001274]
+
+2010-06-10 Christophe Coutand <ccoutand@stmi.com>
+
+ * doc/eth_phy.sgml, include/eth_phy.h: Add Ethernet Gigabit Mode
+ * cdl/phy_eth_drivers.cdl: Add new PHY support
+ * src/IP101A.c, src/IP101A.h: Contributed by Edgar Grimberg
+ * src/VSC8244.c, src/VSC8244.h: Contributed by Christophe Coutand
+ * src/VSC8641.c, src/VSC8641.h: Contributed by Sachin Sushil Chaddha
+
+2008-12-30 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/phy_eth_drivers.cdl: Reference per-package documentation.
+
+2008-10-28 Oliver Munz <munz@speag.ch>
+
+ * cdl/phy_eth_drivers.cdl:
+ * src/KSZ8041.c: Add support for Micrel KSZ8041 PHY
+
+2008-08-05 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/phy_eth_drivers.cdl:
+ * src/KSZ8001.c: Add support for Micrel KSZ8001 PHY
+
+2007-04-06 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/phy_eth_drivers.cdl:
+ * src/KS8721.c: Add support for Micrel KS8721 PHY
+
+2007-01-17 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * cdl/phy_eth_drivers.cdl:
+ * src/DM9161A.c: Add support for Davicom 9161A.
+
+2006-04-07 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * doc/eth_phy.sgml: Fixed a few typos
+
+2006-03-30 Jay Foster <jay@systech.com>
+ * include/eth_phy.h: Add default mode value for _eth_phy_cfg().
+ * cdl/phy_eth_drivers.cdl: Add support for ICS189x.
+ * include/eth_phy_dev.h:
+ * src/AM79C874.c:
+ * src/DP83847.c:
+ * src/INLXT972.c: Make debug output CDL configurable.
+ * src/eth_phy.c: Fix bug in _eth_phy_init() that prevented using
+ a PHY MII address other than 0.
+ * src/ics189x.c: New
+
+2005-08-25 Markus Schade <marks@peppercon.de>
+
+ * src/INLXT972.c:
+ * cdl/phy_eth_drivers.cdl: Add support for Intel LXT972
+
+2004-10-04 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/phy_eth_drivers.cdl: We call the delay function via VV so we
+ require VV support.
+
+2003-11-07 Gary Thomas <gary@mlbassoc.com>
+
+ * src/DP83847.c:
+ * src/AM79C874.c:
+ * cdl/phy_eth_drivers.cdl: Make auto-negotiation timeout configurable.
+
+2003-09-11 Gary Thomas <gary@mlbassoc.com>
+
+ * include/eth_phy.h: Minor improvement in status bitfield [comments]
+
+ * doc/eth_phy.sgml: New file - add basic documentation on PHY API.
+
+2003-08-26 Gary Thomas <gary@mlbassoc.com>
+
+ * src/DP83847.c:
+ * src/AM79C874.c: New file(s) - driver(s) for PHY devices.
+
+ * src/eth_phy.c:
+ * include/eth_phy_dev.h:
+ * include/eth_phy.h:
+ * cdl/phy_eth_drivers.cdl: Add device/chip specific drivers.
+
+2003-08-19 Gary Thomas <gary@mlbassoc.com>
+
+ * src/eth_phy.c:
+ * include/eth_phy.h:
+ * cdl/phy_eth_drivers.cdl: New file(s) - generic API for dealing
+ with ethernet PHY devices, allowing network drivers more flexibility.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2010 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/phy/current/cdl/phy_eth_drivers.cdl b/ecos/packages/devs/eth/phy/current/cdl/phy_eth_drivers.cdl
new file mode 100644
index 0000000..a0affe8
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/cdl/phy_eth_drivers.cdl
@@ -0,0 +1,198 @@
+#====================================================================
+#
+# phy_eth_drivers.cdl
+#
+# API support for ethernet transceivers (PHY)
+#
+#====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2010 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2003-08-01
+#
+#####DESCRIPTIONEND####
+#
+#====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_PHY {
+ display "Ethernet transciever (PHY) support"
+ doc ref/io-eth-phy-generic.html
+ description "API for ethernet PHY devices"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ requires CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+ include_dir cyg/io
+
+ compile eth_phy.c
+
+ cdl_option CYGDBG_DEVS_ETH_PHY {
+ display "Enable driver debugging"
+ flavor bool
+ default_value 0
+ description "Enables the diagnostic debug messages on the
+ console device."
+ }
+
+ cdl_option CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME {
+ display "Time period (seconds) to wait for auto-negotiation"
+ flavor data
+ default_value 5
+ description "
+ The length of time to wait for auto-negotiation to complete
+ before giving up and declaring the link dead/missing."
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_DP8384X {
+ display "NSDP8384X"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a DP83847.c
+ description "
+ Include support for National Semiconductor DP8384X DsPHYTER II"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_AM79C874 {
+ display "AMD 79C874"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a AM79C874.c
+ description "
+ Include support for AMD 79C874 NetPHY"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_INLXT972 {
+ display "Intel LXT972"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a INLXT972.c
+ description "
+ Include support for Intel LXT972xxx PHY"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_ICS1890 {
+ display "ICS 1890"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a ics189x.c
+ description "
+ Include support for ICS 1890 PHY"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_ICS1892 {
+ display "ICS 1892"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a ics189x.c
+ description "
+ Include support for ICS 1892 PHY"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_ICS1893 {
+ display "ICS 1893"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a ics189x.c
+ description "
+ Include support for ICS 1893 and 1893AF PHY"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_DM9161A {
+ display "Davicom DM9161A"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a DM9161A.c
+ description "
+ Include support for the Davicom DM9161A PHY"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_KS8721 {
+ display "Micrel KS8721"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a KS8721.c
+ description "
+ Include support for the Micrel KS8721 PHY"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_KSZ8001 {
+ display "Micrel KSZ8001"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a KSZ8001.c
+ description "
+ Include support for the Micrel KSZ8001 PHY"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_KSZ8041 {
+ display "Micrel KSZ8041"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a KSZ8041.c
+ description "
+ Include support for the Micrel KSZ8041 PHY"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_IP101A {
+ display "IC+ IP101A"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a IP101A.c
+ description "
+ Include support for IC+ IP101A"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_VSC8641 {
+ display "Vitesse VSC8641"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a VSC8641.c
+ description "
+ Include support for Vitesse VSC8641"
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_PHY_VSC8244 {
+ display "Vitesse VSC8244"
+ flavor bool
+ default_value 0
+ compile -library=libextras.a VSC8244.c
+ description "
+ Include support for Vitesse VSC8244"
+ }
+
+}
diff --git a/ecos/packages/devs/eth/phy/current/doc/eth_phy.sgml b/ecos/packages/devs/eth/phy/current/doc/eth_phy.sgml
new file mode 100644
index 0000000..35ccdda
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/doc/eth_phy.sgml
@@ -0,0 +1,172 @@
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- eth_phy.sgml -->
+<!-- -->
+<!-- eCos ethernet PHY device driver documentation -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2010 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="io-eth-phy-generic">
+<title>Ethernet PHY Device Support</title>
+<chapter id="io-eth-phy-generic1">
+<title>Ethernet PHY Device Support</title>
+<sect1 id="io-eth-phy-api">
+<title>Ethernet PHY Device API</title>
+<para>
+Modern ethernet subsystems are often separated into two pieces, the
+media access controller (sometimes known as a MAC) and the physical
+device or line interface (often referred to as a PHY). In this case,
+the MAC handles generating and parsing physical frames and the PHY
+handles how this data is actually moved to/from the wire. The MAC
+and PHY communicate via a special protocol, known as MII. This MII
+protocol can handle control over the PHY which allows for selection
+of such transmission criteria as line speed, duplex mode, etc.
+</para>
+<para>
+In most cases, ethernet drivers only need to bother with the PHY during
+system initialization. Since the details of the PHY are separate from
+the MAC, there are different drivers for each. The drivers for the PHY
+are described by a set of exported functions which are commonly used by
+the MAC. The primary use of these functions currently is to initialize
+the PHY and determine the status of the line connection.
+</para>
+<para>
+The connection between the MAC and the PHY differs from MAC to MAC, so
+the actual routines to manipulate this data channel are a property of
+the MAC instance. Furthermore, there are many PHY devices each with their
+own internal operations. A complete MAC/PHY driver setup will be comprised
+of the MAC MII access functions and the PHY internal driver.
+</para>
+<para>
+A driver instance is contained within a
+<type>eth_phy_access_t</type>:
+<programlisting>
+
+#define PHY_BIT_LEVEL_ACCESS_TYPE 0
+#define PHY_REG_LEVEL_ACCESS_TYPE 1
+
+typedef struct {
+ int ops_type; // 0 => bit level, 1 => register level
+ bool init_done;
+ void (*init)(void);
+ void (*reset)(void);
+ union {
+ struct {
+ void (*set_data)(int);
+ int (*get_data)(void);
+ void (*set_clock)(int);
+ void (*set_dir)(int);
+ } bit_level_ops;
+ struct {
+ void (*put_reg)(int reg, int unit, unsigned short data);
+ bool (*get_reg)(int reg, int unit, unsigned short *data);
+ } reg_level_ops;
+ } ops;
+ int phy_addr;
+ struct _eth_phy_dev_entry *dev; // Chip access functions
+} eth_phy_access_t;
+
+struct _eth_phy_dev_entry {
+ char *name;
+ unsigned long id;
+ bool (*stat)(eth_phy_access_t *f, int *stat);
+};
+
+</programlisting>
+The <varname>dev</varname> element points to the PHY specific support
+functions.
+Currently, the only function which must be defined is <function>stat()</function>.
+</para>
+<para>
+The MAC-MII-PHY interface is a narrow connection, with commands and status
+moving between the MAC and PHY using a bit-serial protocol.
+Some MAC devices contain the intelligence to run this protocol, exposing
+a mechanism to access PHY registers one at a time. Other MAC devices may only
+provide access to the MII data lines (or even still, this may be considered
+completely separate from the MAC). In these cases, the PHY support layer
+must handle the serial protocol.
+The choice between the access methods is in the
+<varname>ops_type</varname> field.
+If it has the value
+<varname>PHY_BIT_LEVEL_ACCESS_TYPE</varname>, then the PHY device layer will
+run the protocol, using the access functions
+<function>set_data()</function>,
+<function>get_data()</function>,
+<function>set_clock()</function>,
+<function>set_dir()</function> are used to control the MII signals and run
+the protocol.
+If <varname>ops_type</varname> has the value
+<varname>PHY_REG_LEVEL_ACCESS_TYPE</varname>,
+then the routines
+<function>put_reg()</function>, and
+<function>get_reg()</function>
+are used to access the PHY registers.
+</para>
+<para>
+Two additional functions may be defined.
+These are
+<function>init()</function>, and
+<function>reset()</function>.
+The purpose of these functions is for gross-level management of the
+MII interface.
+The
+<function>init()</function>
+function will be called once, at system initialization time.
+It should do whatever operations are necessary to prepare the
+MII channel.
+In the case of
+<varname>PHY_BIT_LEVEL_ACCESS_TYPE</varname> devices,
+<function>init()</function>
+should prepare the signals for use, i.e. set up the appropriate
+parallel port registers, etc.
+The
+<function>reset()</function>
+function may be called by a driver to cause the PHY device to
+be reset to a known state.
+Not all drivers will require this and this function may not even
+be possible, so it's use and behavior is somewhat target specific.
+</para>
+<para>
+Currently, the only function required of device specific drivers is
+<function>stat()</function>.
+This routine should query appropriate registers in the PHY and return
+a status bitmap indicating the state of the physical connection.
+In the case where the PHY can auto-negotiate a line speed and condition,
+this information may be useful to the MAC to indicate what speed it should
+provide data, etc.
+The status bitmask contains these bits:
+<programlisting>
+#define ETH_PHY_STAT_LINK 0x0001 // Link up/down
+#define ETH_PHY_STAT_100MB 0x0002 // Connection is 100Mb/10Mb
+#define ETH_PHY_STAT_FDX 0x0004 // Connection is full/half duplex
+#define ETH_PHY_STAT_1000MB 0x0008 // Connection is 1Gb
+</programlisting>
+Note: the usage here is that if the bit is set, then the condition
+exists. For example, if the
+<varname>ETH_PHY_STAT_LINK</varname>
+is set, then a physical link has been established.
+</para>
+</sect1>
+</chapter>
+</part>
diff --git a/ecos/packages/devs/eth/phy/current/include/eth_phy.h b/ecos/packages/devs/eth/phy/current/include/eth_phy.h
new file mode 100644
index 0000000..5628f1f
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/include/eth_phy.h
@@ -0,0 +1,103 @@
+#ifndef CYGONCE_DEVS_ETH_PHY_H_
+#define CYGONCE_DEVS_ETH_PHY_H_
+//==========================================================================
+//
+// eth_phy.h
+//
+// User API for ethernet transciever (PHY) support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2010 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2003-08-01
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define PHY_BIT_LEVEL_ACCESS_TYPE 0
+#define PHY_REG_LEVEL_ACCESS_TYPE 1
+
+// Physical device access - defined by hardware instance
+typedef struct {
+ int ops_type; // 0 => bit level, 1 => register level
+ bool init_done;
+ void (*init)(void);
+ void (*reset)(void);
+ union {
+ struct {
+ void (*set_data)(int);
+ int (*get_data)(void);
+ void (*set_clock)(int);
+ void (*set_dir)(int);
+ } bit_level_ops;
+ struct {
+ void (*put_reg)(int reg, int unit, unsigned short data);
+ bool (*get_reg)(int reg, int unit, unsigned short *data);
+ } reg_level_ops;
+ } ops;
+ int phy_addr;
+ struct _eth_phy_dev_entry *dev; // Chip access functions
+} eth_phy_access_t;
+
+#define ETH_PHY_BIT_LEVEL_ACCESS_FUNS(_l,_init,_reset,_set_data,_get_data,_set_clock,_set_dir) \
+static eth_phy_access_t _l = {PHY_BIT_LEVEL_ACCESS_TYPE, false, _init, _reset, \
+ {.bit_level_ops = {_set_data, _get_data, _set_clock, _set_dir}}}
+
+#define ETH_PHY_REG_LEVEL_ACCESS_FUNS(_l,_init,_reset,_put_reg,_get_reg) \
+static eth_phy_access_t _l = {PHY_REG_LEVEL_ACCESS_TYPE, false, _init, _reset, \
+ {.reg_level_ops = {_put_reg, _get_reg}}}
+
+#define ETH_PHY_STAT_LINK 0x0001 // Link up/down
+#define ETH_PHY_STAT_100MB 0x0002 // Connection is 100Mb/10Mb
+#define ETH_PHY_STAT_FDX 0x0004 // Connection is full/half duplex
+#define ETH_PHY_STAT_1000MB 0x0008 // Connection is 1Gb
+
+externC bool _eth_phy_init(eth_phy_access_t *f);
+externC void _eth_phy_reset(eth_phy_access_t *f);
+externC int _eth_phy_state(eth_phy_access_t *f);
+externC int _eth_phy_cfg(eth_phy_access_t *f, int mode);
+#define ETH_PHY_MODE_DEFAULT 0
+
+// Internal routines
+externC void _eth_phy_write(eth_phy_access_t *f, int reg, int unit, unsigned short data);
+externC bool _eth_phy_read(eth_phy_access_t *f, int reg, int unit, unsigned short *val);
+
+#endif // CYGONCE_DEVS_ETH_PHY_H_
+// ------------------------------------------------------------------------
diff --git a/ecos/packages/devs/eth/phy/current/include/eth_phy_dev.h b/ecos/packages/devs/eth/phy/current/include/eth_phy_dev.h
new file mode 100644
index 0000000..d36adb4
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/include/eth_phy_dev.h
@@ -0,0 +1,111 @@
+#ifndef CYGONCE_DEVS_ETH_PHY_DEV_H_
+#define CYGONCE_DEVS_ETH_PHY_DEV_H_
+//==========================================================================
+//
+// eth_phy_dev.h
+//
+// Device API for ethernet transciever (PHY) support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2003-08-01
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifdef CYGDBG_DEVS_ETH_PHY
+#include <cyg/infra/diag.h>
+#define eth_phy_printf(args...) diag_printf(args)
+#else
+#define eth_phy_printf(args...) /* NOOP */
+#endif
+
+// Transceiver mode
+#define PHY_BMCR 0x00 // Register number
+#define PHY_BMCR_RESET 0x8000
+#define PHY_BMCR_LOOPBACK 0x4000
+#define PHY_BMCR_100MB 0x2000
+#define PHY_BMCR_AUTO_NEG 0x1000
+#define PHY_BMCR_POWER_DOWN 0x0800
+#define PHY_BMCR_ISOLATE 0x0400
+#define PHY_BMCR_RESTART 0x0200
+#define PHY_BMCR_FULL_DUPLEX 0x0100
+#define PHY_BMCR_COLL_TEST 0x0080
+
+#define PHY_BMSR 0x01 // Status register
+#define PHY_BMSR_100T4 0x8000
+#define PHY_BMSR_100FDX 0x4000
+#define PHY_BMSR_100HDX 0x2000
+#define PHY_BMSR_10FDX 0x1000
+#define PHY_BMSR_10HDX 0x0800
+#define PHY_BMSR_AUTO_NEG 0x0020
+#define PHY_BMSR_LINK 0x0004
+
+#define PHY_ID1 0x02 // Chip ID register (high 16 bits)
+#define PHY_ID2 0x03 // Chip ID register (low 16 bits)
+
+#define PHY_AN_ADV 0x04 // Auto negotiation advertisement register
+#define PHY_AN_ADV_10HDX 0x0020
+#define PHY_AN_ADV_10FDX 0x0040
+#define PHY_AN_ADV_100HDX 0x0080
+#define PHY_AN_ADV_100FDX 0x0100
+#define PHY_AN_ADV_100_T4 0x0200
+
+#define PHY_AN_PAR 0x05 // Auto negotiation link partner ability
+#define PHY_AN_PAR_10HDX 0x0020
+#define PHY_AN_PAR_10FDX 0x0040
+#define PHY_AN_PAR_100HDX 0x0080
+#define PHY_AN_PAR_100FDX 0x0100
+#define PHY_AN_PAR_100_T4 0x0200
+
+struct _eth_phy_dev_entry {
+ char *name;
+ unsigned long id;
+ bool (*stat)(eth_phy_access_t *f, int *stat);
+} CYG_HAL_TABLE_TYPE;
+
+#define _eth_phy_dev(_name_,_id_,_stat_) \
+struct _eth_phy_dev_entry _eth_phy_dev_##_id_ \
+ CYG_HAL_TABLE_QUALIFIED_ENTRY(_eth_phy_devs,_id_) = \
+ { _name_, _id_, _stat_ };
+
+#endif // CYGONCE_DEVS_ETH_PHY_DEV_H_
+// ------------------------------------------------------------------------
diff --git a/ecos/packages/devs/eth/phy/current/src/AM79C874.c b/ecos/packages/devs/eth/phy/current/src/AM79C874.c
new file mode 100644
index 0000000..96514ba
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/AM79C874.c
@@ -0,0 +1,101 @@
+//==========================================================================
+//
+// dev/AM79C874.c
+//
+// Ethernet transceiver (PHY) support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors:
+// Date: 2003-08-01
+// Purpose:
+// Description: Support for ethernet NS AM79C874 PHY
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+static bool am79c874_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ int tries;
+
+ // Read negotiated state
+ if (_eth_phy_read(f, 0x1, f->phy_addr, &phy_state)) {
+ if ((phy_state & 0x20) == 0) {
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++) {
+ if (_eth_phy_read(f, 0x1, f->phy_addr, &phy_state)) {
+ if ((phy_state & 0x20) != 0) {
+ break;
+ }
+ }
+ CYGACC_CALL_IF_DELAY_US(1000000); // 1 second
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+ if ((phy_state & 0x20) != 0) {
+ *state = 0;
+ if ((phy_state & 0x0004) != 0) *state |= ETH_PHY_STAT_LINK;
+ if (_eth_phy_read(f, 0x5, f->phy_addr, &phy_state)) {
+ // Partner negotiated parameters
+ if ((phy_state & 0x0100) != 0) *state |= ETH_PHY_STAT_100MB | ETH_PHY_STAT_FDX;
+ if ((phy_state & 0x0080) != 0) *state |= ETH_PHY_STAT_100MB;
+ if ((phy_state & 0x0040) != 0) *state |= ETH_PHY_STAT_FDX;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+_eth_phy_dev("AMD AM79C874", 0x0022561B, am79c874_stat)
diff --git a/ecos/packages/devs/eth/phy/current/src/DM9161A.c b/ecos/packages/devs/eth/phy/current/src/DM9161A.c
new file mode 100644
index 0000000..45db76b
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/DM9161A.c
@@ -0,0 +1,133 @@
+//==========================================================================
+//
+// dev/DM9161A.c
+//
+// Ethernet transceiver (PHY) support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): John Eigelaar
+// Contributors: Gary Thomas
+// Date: 2006-12-07
+// Purpose:
+// Description: Support for Davicom DM9161A PHY
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+#define DM9161A_BMSR 0x01
+#define DM9161A_BMSR_ANEG_COMP (1<<5)
+#define DM9161A_BMSR_LINK (1<<2)
+
+#define DM9161A_BMCR 0x00
+
+#define DM9161A_DSCSR 17
+#define DM9161A_DSCSR_100FDX (1<<15)
+#define DM9161A_DSCSR_100HDX (1<<14)
+#define DM9161A_DSCSR_10FDX (1<<13)
+#define DM9161A_DSCSR_10HDX (1<<12)
+
+static bool dm9161a_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ int tries;
+
+ *state = 0;
+ // Read negotiated state
+
+ if (_eth_phy_read(f, DM9161A_BMSR, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & DM9161A_BMSR_ANEG_COMP) == 0)
+ {
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME;
+ tries++)
+ {
+ if (_eth_phy_read(f, DM9161A_BMSR, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & DM9161A_BMSR_ANEG_COMP) != 0)
+ {
+ break;
+ }
+ }
+ CYGACC_CALL_IF_DELAY_US(1000000); // 1 second
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+ if ((phy_state & DM9161A_BMSR_ANEG_COMP) != 0)
+ {
+ *state = 0;
+ if (!_eth_phy_read(f, DM9161A_DSCSR, f->phy_addr, &phy_state))
+ return false;
+
+ if (phy_state & 0xF000)
+ {
+ *state |= ETH_PHY_STAT_LINK;
+ }
+ if ((phy_state & DM9161A_DSCSR_100FDX) ||
+ (phy_state & DM9161A_DSCSR_100HDX))
+ {
+ *state |= ETH_PHY_STAT_100MB;
+ }
+ if ((phy_state & DM9161A_DSCSR_100FDX) ||
+ (phy_state & DM9161A_DSCSR_10FDX))
+ {
+ *state |= ETH_PHY_STAT_FDX;
+ }
+
+ return (true);
+ }
+ }
+ return (false);
+}
+
+_eth_phy_dev("Davicom DM9161A", 0x0181B8A0, dm9161a_stat)
diff --git a/ecos/packages/devs/eth/phy/current/src/DP83847.c b/ecos/packages/devs/eth/phy/current/src/DP83847.c
new file mode 100644
index 0000000..66f832a
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/DP83847.c
@@ -0,0 +1,98 @@
+//==========================================================================
+//
+// dev/DP83847.c
+//
+// Ethernet transceiver (PHY) support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: ccoutand
+// Date: 2003-08-01
+// Purpose:
+// Description: Support for ethernet NS DP8384X PHY
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+static bool dp8384x_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ int tries;
+
+ // Read negotiated state
+ if (_eth_phy_read(f, 0x10, f->phy_addr, &phy_state)) {
+ if ((phy_state & 0x10) == 0) {
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++) {
+ if (_eth_phy_read(f, 0x10, f->phy_addr, &phy_state)) {
+ if ((phy_state & 0x10) != 0) {
+ break;
+ }
+ }
+ CYGACC_CALL_IF_DELAY_US(1000000); // 1 second
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+ if ((phy_state & 0x10) != 0) {
+ *state = 0;
+ if ((phy_state & 0x0001) != 0) *state |= ETH_PHY_STAT_LINK;
+ if ((phy_state & 0x0002) == 0) *state |= ETH_PHY_STAT_100MB;
+ if ((phy_state & 0x0004) != 0) *state |= ETH_PHY_STAT_FDX;
+ return true;
+ }
+ }
+ return false;
+}
+
+_eth_phy_dev("National Semiconductor DP83847", 0x20005c30, dp8384x_stat)
+_eth_phy_dev("National Semiconductor DP83848C", 0x20005c90, dp8384x_stat)
diff --git a/ecos/packages/devs/eth/phy/current/src/INLXT972.c b/ecos/packages/devs/eth/phy/current/src/INLXT972.c
new file mode 100644
index 0000000..84575e1
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/INLXT972.c
@@ -0,0 +1,96 @@
+//==========================================================================
+//
+// dev/INLXT972.c
+//
+// Ethernet transceiver (PHY) support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Markus Schade <marks@peppercon.de>
+// Contributors:
+// Date: 2005-08­25
+// Purpose:
+// Description: Support for ethernet Intel LXT972xxx PHY
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+static bool inlxt972_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ int tries;
+
+ // Read negotiated state
+ if (_eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state)) {
+ if ((phy_state & PHY_BMSR_AUTO_NEG) == 0) {
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++) {
+ if (_eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state)) {
+ if ((phy_state & PHY_BMSR_AUTO_NEG) != 0) {
+ break;
+ }
+ }
+ CYGACC_CALL_IF_DELAY_US(1000000); // 1 second
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+ if ((phy_state & PHY_BMSR_AUTO_NEG) != 0) {
+ *state = 0;
+ if ((phy_state & PHY_BMSR_LINK) != 0) *state |= ETH_PHY_STAT_LINK;
+ if ((phy_state & PHY_BMSR_100FDX) != 0) *state |= ETH_PHY_STAT_100MB | ETH_PHY_STAT_FDX;
+ return true;
+ }
+ }
+ return false;
+}
+
+_eth_phy_dev("Intel LXT972", 0x001378E2, inlxt972_stat)
diff --git a/ecos/packages/devs/eth/phy/current/src/IP101A.c b/ecos/packages/devs/eth/phy/current/src/IP101A.c
new file mode 100644
index 0000000..c21bb55
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/IP101A.c
@@ -0,0 +1,117 @@
+//==========================================================================
+//
+// phy/ip101a.c
+//
+// Ethernet PHY driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+// 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Edgar Grimberg
+// Contributors:
+// Date: 2009-11-01
+// Purpose:
+// Description: hardware driver for Ethernet PHY IC+ IP101A
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+#include "IP101A.h"
+
+static bool ip101a_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ int tries;
+ int auto_completed = 1;
+
+ // Read negotiated state from the Quick Poll Detailed Status Register
+ if (_eth_phy_read(f, MII_STAT_REG, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & IP101A_AUTO_COMPLETED) == 0)
+ {
+ auto_completed = 0;
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++)
+ {
+ if (_eth_phy_read(f, MII_STAT_REG, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & IP101A_AUTO_COMPLETED) != 0)
+ {
+ auto_completed = 1;
+ break;
+ }
+ }
+ CYGACC_CALL_IF_DELAY_US(1000000); // 1 second
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+
+ if(auto_completed)
+ {
+ _eth_phy_read(f, MII_PHY_STAT_REG, f->phy_addr, &phy_state);
+
+ if(phy_state & IP101A_LINK_STATUS2)
+ *state |= ETH_PHY_STAT_LINK;
+ if(phy_state & IP101A_SPEED_100MB)
+ *state |= ETH_PHY_STAT_100MB;
+ if(phy_state & IP101A_DUPLEX_MODE)
+ *state |= ETH_PHY_STAT_FDX;
+ return true;
+ }
+
+ }
+ return false;
+}
+
+
+_eth_phy_dev("IC+ IP101A", 0x02430c54, ip101a_stat)
+
diff --git a/ecos/packages/devs/eth/phy/current/src/IP101A.h b/ecos/packages/devs/eth/phy/current/src/IP101A.h
new file mode 100644
index 0000000..cb2f912
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/IP101A.h
@@ -0,0 +1,92 @@
+#ifndef CYGONCE_PHY_IP101A_HEADER_
+#define CYGONCE_PHY_IP101A_HEADER_
+//==========================================================================
+//
+// phy/ip101a.h
+//
+// Ethernet PHY driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+// 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Edgar Grimberg
+// Contributors:
+// Date: 2009-11-01
+// Purpose:
+// Description: Hardware driver for Ethernet PHY IC+ IP101A
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define MII_CTRL_REG 0x00
+#define MII_STAT_REG 0x01
+#define MII_PHY_ID1_REG 0x02
+#define MII_PHY_ID2_REG 0x03
+#define MII_AUTO_NEG_ADV_REG 0x04
+#define MII_AUTO_NEG_LPA_REG 0x05
+#define MII_AUTO_NEG_EXP_REG 0x06
+#define MII_PHY_CTRL_REG 0x10
+#define MII_PHY_IRQ_REG 0x11
+#define MII_PHY_STAT_REG 0x12
+#define MII_PHY_CTRL2_REG 0x1E
+
+#define MII_PHY_IRQ_INTR 0x8000
+#define MII_PHY_IRQ_ALL_MASK 0x0800
+#define MII_PHY_IRQ_SPEED_MASK 0x0400
+#define MII_PHY_IRQ_DUPLEX_MASK 0x0200
+#define MII_PHY_IRQ_LINK_MASK 0x0100
+#define MII_PHY_IRQ_ARBITER_MASK 0x0080
+#define MII_PHY_IRQ_ARBITER_CHANGE 0x0040
+#define MII_PHY_IRQ_SPEED_CHANGE 0x0004
+#define MII_PHY_IRQ_DUPLEX_CHANGE 0x0002
+#define MII_PHY_IRQ_LINK_CHANGE 0x0001
+
+#define IP101A_CTRL_DUPLEX 0x0100
+#define IP101A_CTRL_100MB 0x2000
+#define IP101A_CTRL_AUTO_NEG 0x1000
+#define IP101A_CTRL_AUTO_NEG_RST 0x0200
+
+#define IP101A_LINK_STATUS 0x0004
+#define IP101A_AUTO_COMPLETED 0x20
+
+#define IP101A_DUPLEX_MODE 0x2000
+#define IP101A_SPEED_100MB 0x4000
+#define IP101A_LINK_STATUS2 0x0400
+
+#endif // CYGONCE_PHY_IP101A_HEADER_
+
diff --git a/ecos/packages/devs/eth/phy/current/src/KS8721.c b/ecos/packages/devs/eth/phy/current/src/KS8721.c
new file mode 100644
index 0000000..666a9ea
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/KS8721.c
@@ -0,0 +1,114 @@
+//==========================================================================
+//
+// dev/KS8721.c
+//
+// Ethernet transceiver (PHY) support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler <uwe_kindler@web.de>
+// Contributors: Markus Schade <marks@peppercon.de>
+// Date: 2007-04-04
+// Purpose:
+// Description: Support for ethernet Micrel KS8721 PHY
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+
+static bool ks8721_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ unsigned short phy_anadv_reg;
+ int tries;
+ int ms;
+
+ // Read negotiated state
+ if (_eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & PHY_BMSR_AUTO_NEG) == 0)
+ {
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++)
+ {
+ if (_eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & PHY_BMSR_AUTO_NEG) != 0)
+ {
+ break;
+ }
+ }
+
+ //
+ // Wait for 1 second
+ //
+ for (ms = 0; ms < 1000; ++ms)
+ {
+ CYGACC_CALL_IF_DELAY_US(1000); // 1 ms
+ }
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+ if ((phy_state & PHY_BMSR_AUTO_NEG) != 0)
+ {
+ _eth_phy_read(f, PHY_AN_ADV, f->phy_addr, &phy_anadv_reg);
+ eth_phy_printf("\nAuto negotiation advertisement: %x\n", phy_anadv_reg);
+ *state = 0;
+ if ((phy_state & PHY_BMSR_LINK) != 0) *state |= ETH_PHY_STAT_LINK;
+ if ((phy_anadv_reg & PHY_AN_ADV_100FDX) != 0) *state |= ETH_PHY_STAT_100MB | ETH_PHY_STAT_FDX;
+ return true;
+ }
+ }
+ return false;
+}
+
+_eth_phy_dev("Micrel KS8721", 0x00221619, ks8721_stat)
diff --git a/ecos/packages/devs/eth/phy/current/src/KSZ8001.c b/ecos/packages/devs/eth/phy/current/src/KSZ8001.c
new file mode 100644
index 0000000..f5638ec
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/KSZ8001.c
@@ -0,0 +1,160 @@
+//==========================================================================
+//
+// dev/KSZ8001.c
+//
+// Ethernet transceiver (PHY) support for Micrel KSZ8001
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler <uwe_kindler@web.de>
+// Contributors:
+// Date: 2008-08-05
+// Purpose:
+// Description: Support for ethernet PHY Micrel KSZ8001
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+
+//==========================================================================
+// DEFINES
+//==========================================================================
+#define PHY_100BASE_CTRL 0x1f // 100BASE-TX PHY Control Register
+#define PHY_100BASE_CTRL_OP_MODE_MASK (0x07 << 2)
+#define PHY_100BASE_CTRL_AN_MODE (0x00 << 2)
+#define PHY_100BASE_CTRL_10T_HDX (0x01 << 2)
+#define PHY_100BASE_CTRL_100T_HDX (0x02 << 2)
+#define PHY_100BASE_CTRL_DEFAULT (0x03 << 2)
+#define PHY_100BASE_CTRL_10T_FDX (0x05 << 2)
+#define PHY_100BASE_CTRL_100T_FDX (0x06 << 2)
+
+
+//==========================================================================
+// Query the 100BASE-TX PHY Control Register and return a status bitmap
+// indicating the state of the physical connection
+//==========================================================================
+static bool ksz8001_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ unsigned short phy_100ctrl_reg;
+ int tries;
+ int ms;
+
+ // Read negotiated state
+ if (_eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & PHY_BMSR_AUTO_NEG) == 0)
+ {
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++)
+ {
+ if (_eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & PHY_BMSR_AUTO_NEG) != 0)
+ {
+ break;
+ }
+ }
+
+ //
+ // Wait for 1 second
+ //
+ for (ms = 0; ms < 1000; ++ms)
+ {
+ CYGACC_CALL_IF_DELAY_US(1000); // 1 ms
+ }
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+ if ((phy_state & PHY_BMSR_AUTO_NEG) != 0)
+ {
+ *state = 0;
+ if ((phy_state & PHY_BMSR_LINK) != 0)
+ {
+ *state |= ETH_PHY_STAT_LINK;
+ }
+
+ _eth_phy_read(f, PHY_100BASE_CTRL, f->phy_addr, &phy_100ctrl_reg);
+ phy_100ctrl_reg &= PHY_100BASE_CTRL_OP_MODE_MASK;
+ switch (phy_100ctrl_reg)
+ {
+ case PHY_100BASE_CTRL_10T_HDX:
+ break;
+
+ case PHY_100BASE_CTRL_100T_HDX:
+ *state |= ETH_PHY_STAT_100MB;
+ break;
+
+ case PHY_100BASE_CTRL_10T_FDX:
+ *state |= ETH_PHY_STAT_FDX;
+ break;
+
+ case PHY_100BASE_CTRL_100T_FDX:
+ *state |= ETH_PHY_STAT_100MB | ETH_PHY_STAT_FDX;
+ break;
+
+ default:
+ // force to set default 100 Full Duplex
+ *state |= ETH_PHY_STAT_100MB | ETH_PHY_STAT_FDX;
+ } // switch (phy_100ctrl_reg)
+
+ return true;
+ }
+ }
+ return false;
+}
+
+_eth_phy_dev("Micrel KSZ8001", 0x00221613, ksz8001_stat)
diff --git a/ecos/packages/devs/eth/phy/current/src/KSZ8041.c b/ecos/packages/devs/eth/phy/current/src/KSZ8041.c
new file mode 100644
index 0000000..6818884
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/KSZ8041.c
@@ -0,0 +1,188 @@
+//==========================================================================
+//
+// dev/KSZ8041.c
+//
+// Ethernet transceiver (PHY) support for Micrel KSZ8041
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler <uwe_kindler@web.de>
+// Contributors: oli@snr.ch
+// Date: 2008-09-18
+// Purpose:
+// Description: Support for ethernet PHY Micrel KSZ8041
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+
+//==========================================================================
+// DEFINES
+//==========================================================================
+// 100BASE-TX PHY Control Register
+#define PHY_100BASE_CTRL 0x1f
+
+#define PHY_100BASE_CTRL_OP_MODE_MASK (0x07 << 2)
+#define PHY_100BASE_CTRL_AN_MODE (0x00 << 2)
+#define PHY_100BASE_CTRL_10T_HDX (0x01 << 2)
+#define PHY_100BASE_CTRL_100T_HDX (0x02 << 2)
+#define PHY_100BASE_CTRL_DEFAULT (0x03 << 2)
+#define PHY_100BASE_CTRL_10T_FDX (0x05 << 2)
+#define PHY_100BASE_CTRL_100T_FDX (0x06 << 2)
+
+//==========================================================================
+// Query the 100BASE-TX PHY Control Register and return a status bitmap
+// indicating the state of the physical connection
+//==========================================================================
+
+#ifdef CYGDBG_DEVS_ETH_PHY
+void
+ksz8041_diag (eth_phy_access_t * f)
+{
+
+ cyg_uint32 i;
+ cyg_uint16 reg;
+
+ eth_phy_printf ("KSZ8041 MIIM Register setings:\n");
+
+ for (i = 0; i < 0x20; i++) {
+ if (i % 2 == 0) {
+ _eth_phy_read (f, i, f->phy_addr, &reg);
+ eth_phy_printf ("r%02x: %04x ", i, reg);
+ } else {
+ _eth_phy_read (f, i, f->phy_addr, &reg);
+ eth_phy_printf ("%04x\n", reg);
+ }
+ }
+}
+#endif
+
+static bool
+ksz8041_stat (eth_phy_access_t * f, int *state)
+{
+
+ cyg_uint16 phy_state;
+ cyg_uint16 phy_100ctrl_reg;
+ cyg_uint32 tries;
+ cyg_uint32 ms;
+
+#ifdef CYGDBG_DEVS_ETH_PHY
+ ksz8041_diag (f);
+#endif
+
+ if (_eth_phy_read (f, PHY_BMSR, f->phy_addr, &phy_state)) {
+ if ((phy_state & PHY_BMSR_AUTO_NEG) == 0) {
+
+ eth_phy_printf ("... waiting for auto-negotiation");
+
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME;
+ tries++) {
+
+ if (_eth_phy_read (f, PHY_BMSR, f->phy_addr, &phy_state)) {
+ if ((phy_state & PHY_BMSR_AUTO_NEG) != 0) {
+ break;
+ }
+ } else {
+ eth_phy_printf ("error: _eth_phy_read()\n");
+ }
+
+ //
+ // Wait for 1 second
+ //
+ for (ms = 0; ms < 1000; ++ms) {
+ CYGACC_CALL_IF_DELAY_US (1000); // 1 ms
+ }
+ eth_phy_printf (".");
+ }
+ eth_phy_printf ("\n");
+ }
+
+ if ((phy_state & PHY_BMSR_AUTO_NEG) != 0) {
+ *state = 0;
+ if ((phy_state & PHY_BMSR_LINK) != 0) {
+ *state |= ETH_PHY_STAT_LINK;
+ }
+
+ _eth_phy_read (f, PHY_100BASE_CTRL, f->phy_addr, &phy_100ctrl_reg);
+ phy_100ctrl_reg &= PHY_100BASE_CTRL_OP_MODE_MASK;
+ switch (phy_100ctrl_reg) {
+ case PHY_100BASE_CTRL_10T_HDX:
+ break;
+
+ case PHY_100BASE_CTRL_100T_HDX:
+ *state |= ETH_PHY_STAT_100MB;
+ break;
+
+ case PHY_100BASE_CTRL_10T_FDX:
+ *state |= ETH_PHY_STAT_FDX;
+ break;
+
+ case PHY_100BASE_CTRL_100T_FDX:
+ *state |= ETH_PHY_STAT_100MB | ETH_PHY_STAT_FDX;
+ break;
+
+ default:
+ // force to set default 100 Full Duplex
+ *state |= ETH_PHY_STAT_100MB | ETH_PHY_STAT_FDX;
+ } // switch (phy_100ctrl_reg)
+
+ return true;
+ }
+ }
+ return false;
+}
+
+_eth_phy_dev ("Micrel KSZ8041", 0x00221512, ksz8041_stat)
+_eth_phy_dev ("Micrel KSZ8041", 0x00221513, ksz8041_stat)
diff --git a/ecos/packages/devs/eth/phy/current/src/VSC8244.c b/ecos/packages/devs/eth/phy/current/src/VSC8244.c
new file mode 100644
index 0000000..b167a59
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/VSC8244.c
@@ -0,0 +1,122 @@
+//==========================================================================
+//
+// phy/VSC8244.c
+//
+// Ethernet PHY driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+// 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Contributors:
+// Date: 2009-11-01
+// Purpose:
+// Description: Hardware driver for Ethernet PHY Vitesse VSC8244
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+#include "VSC8244.h"
+
+static bool VSC8244_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ int tries;
+ int auto_completed = 1;
+ int link_up = 0;
+
+ // Read negotiated state from the Quick Poll Detailed Status Register
+ if (_eth_phy_read(f, VSC8244_MII_STAT_REG, f->phy_addr, &phy_state))
+ {
+
+ if ((phy_state & VSC8244_AUTO_COMPLETED) == 0)
+ {
+ auto_completed = 0;
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++)
+ {
+ if (_eth_phy_read(f, VSC8244_MII_STAT_REG, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & VSC8244_AUTO_COMPLETED) != 0)
+ {
+ auto_completed = 1;
+ break;
+ }
+ }
+ CYGACC_CALL_IF_DELAY_US(1000000); // 1 second
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+
+ if(phy_state & VSC8244_MII_PHY_STAT_LINK_UP)
+ link_up = 1;
+
+ if(auto_completed)
+ {
+ _eth_phy_read(f, VSC8244_MII_PHY_STAT_REG, f->phy_addr, &phy_state);
+
+ if(link_up)
+ *state |= ETH_PHY_STAT_LINK;
+ if(phy_state & VSC8244_MII_PHY_STAT_1000MB )
+ *state |= ETH_PHY_STAT_1000MB;
+ if(phy_state & VSC8244_MII_PHY_STAT_100MB)
+ *state |= ETH_PHY_STAT_100MB;
+ if(phy_state & VSC8244_MII_PHY_STAT_DUPLEX_FULL)
+ *state |= ETH_PHY_STAT_FDX;
+ return true;
+ }
+
+ }
+ return false;
+}
+
+_eth_phy_dev("Vitesse VSC8244", 0x000FC6C2, VSC8244_stat)
diff --git a/ecos/packages/devs/eth/phy/current/src/VSC8244.h b/ecos/packages/devs/eth/phy/current/src/VSC8244.h
new file mode 100644
index 0000000..a824d32
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/VSC8244.h
@@ -0,0 +1,67 @@
+#ifndef CYGONCE_PHY_VSC8244_HEADER_
+#define CYGONCE_PHY_VSC8244_HEADER_
+//==========================================================================
+//
+// phy/VSC8244.h
+//
+// Ethernet PHY driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+// 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Contributors:
+// Date: 2009-11-01
+// Purpose:
+// Description: Hardware driver for Ethernet PHY Vitesse VSC8244
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define VSC8244_MII_PHY_STAT_DUPLEX_FULL 0x20
+#define VSC8244_MII_PHY_STAT_1000MB 0x10
+#define VSC8244_MII_PHY_STAT_100MB 0x08
+
+#define VSC8244_MII_PHY_STAT_LINK_UP 0x04
+
+#define VSC8244_MII_STAT_REG 0x01
+#define VSC8244_MII_PHY_STAT_REG 0x1C
+
+#define VSC8244_AUTO_COMPLETED 0x20
+
+#endif // CYGONCE_PHY_VSC8244_HEADER_
diff --git a/ecos/packages/devs/eth/phy/current/src/VSC8641.c b/ecos/packages/devs/eth/phy/current/src/VSC8641.c
new file mode 100644
index 0000000..39ef2df
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/VSC8641.c
@@ -0,0 +1,123 @@
+//==========================================================================
+//
+// phy/VSC8641.c
+//
+// Ethernet PHY driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+// 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Sachin Sushil Chaddha
+// Contributors:
+// Date: 2009-11-01
+// Purpose:
+// Description: Hardware driver for Ethernet PHY Vitesse VSC8641
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+#include "VSC8641.h"
+
+static bool VSC8641_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ int tries;
+ int auto_completed = 1;
+ int link_up = 0;
+
+ // Read negotiated state from the Quick Poll Detailed Status Register
+ if (_eth_phy_read(f, VSC8641_MII_STAT_REG, f->phy_addr, &phy_state))
+ {
+
+ if ((phy_state & VSC8641_AUTO_COMPLETED) == 0)
+ {
+ auto_completed = 0;
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++)
+ {
+ if (_eth_phy_read(f, VSC8641_MII_STAT_REG, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & VSC8641_AUTO_COMPLETED) != 0)
+ {
+ auto_completed = 1;
+ break;
+ }
+ }
+ CYGACC_CALL_IF_DELAY_US(1000000); // 1 second
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+
+ if(phy_state & VSC8641_MII_PHY_STAT_LINK_UP)
+ link_up = 1;
+
+ if(auto_completed)
+ {
+ _eth_phy_read(f, VSC8641_MII_PHY_STAT_REG, f->phy_addr, &phy_state);
+
+ if(link_up)
+ *state |= ETH_PHY_STAT_LINK;
+ if(phy_state & VSC8641_MII_PHY_STAT_1000MB )
+ *state |= ETH_PHY_STAT_1000MB;
+ if(phy_state & VSC8641_MII_PHY_STAT_100MB)
+ *state |= ETH_PHY_STAT_100MB;
+ if(phy_state & VSC8641_MII_PHY_STAT_DUPLEX_FULL)
+ *state |= ETH_PHY_STAT_FDX;
+ return true;
+ }
+
+ }
+ return false;
+}
+
+
+_eth_phy_dev("Vitesse VSC8641", 0x00070431, VSC8641_stat)
diff --git a/ecos/packages/devs/eth/phy/current/src/VSC8641.h b/ecos/packages/devs/eth/phy/current/src/VSC8641.h
new file mode 100644
index 0000000..5450f50
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/VSC8641.h
@@ -0,0 +1,86 @@
+#ifndef CYGONCE_PHY_VSC8641_HEADER_
+#define CYGONCE_PHY_VSC8641_HEADER_
+//==========================================================================
+//
+// phy/VSC8641.h
+//
+// Ethernet PHY driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+// 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Contributors:
+// Date: 2009-11-01
+// Purpose:
+// Description: Hardware driver for Ethernet PHY Vitesse VSC8641
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define VSC8641_MII_MDE_CTRL_REG 0x00
+#define VSC8641_MII_STAT_REG 0x01
+#define VSC8641_MII_AUTO_NEG_ADV_REG 0x04
+#define VSC8641_MII_AUTO_NEG_NXT_REG 0x07
+#define VSC8641_MII_PHY_IRQ_MSK_REG 0x19
+
+#define VSC8641_MII_PHY_STAT_REG 0x1C
+#define VSC8641_MII_INT_STAT_REG 0x1A
+
+#define VSC8641_MII_PHY_EPA 0x1F
+#define VSC8641_MII_PHY_RGMII_SKEW 0x1C
+
+#define VSC8641_AUTO_COMPLETED 0x20
+
+#define VSC8641_CTRL_AUTO_NEG 0x1000
+#define VSC8641_CTRL_AUTO_NEG_RST 0x0200
+#define VSC8641_CTRL_1000MB 0x0040
+#define VSC8641_CTRL_100MB 0x2000
+#define VSC8641_CTRL_FULL_DUPLEX 0x0100
+
+#define VSC8641_IRQ_SPEED_CHANGE 0x4000
+#define VSC8641_IRQ_FDX_STATE_CHANGE 0x1000
+#define VSC8641_IRQ_LINK_CHANGE 0x2000
+
+#define VSC8641_MII_PHY_STAT_DUPLEX_FULL 0x20
+#define VSC8641_MII_PHY_STAT_1000MB 0x10
+#define VSC8641_MII_PHY_STAT_100MB 0x08
+
+#define VSC8641_MII_PHY_STAT_LINK_UP 0x04
+
+#endif // CYGONCE_PHY_VSC8641_HEADER_
diff --git a/ecos/packages/devs/eth/phy/current/src/eth_phy.c b/ecos/packages/devs/eth/phy/current/src/eth_phy.c
new file mode 100644
index 0000000..03f12c6
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/eth_phy.c
@@ -0,0 +1,292 @@
+//==========================================================================
+//
+// dev/eth_phy.c
+//
+// Ethernet transciever (PHY) support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors:
+// Date: 2003-08-01
+// Purpose:
+// Description: API support for ethernet PHY
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_eth_drivers.h>
+#include <pkgconf/devs_eth_phy.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+// Define table boundaries
+CYG_HAL_TABLE_BEGIN( __ETH_PHY_TAB__, _eth_phy_devs );
+CYG_HAL_TABLE_END( __ETH_PHY_TAB_END__, _eth_phy_devs );
+extern struct _eth_phy_dev_entry __ETH_PHY_TAB__[], __ETH_PHY_TAB_END__;
+
+// MII interface
+#define MII_Start 0x40000000
+#define MII_Read 0x20000000
+#define MII_Write 0x10000000
+#define MII_Cmd 0x30000000
+#define MII_Phy(phy) (phy << 23)
+#define MII_Reg(reg) (reg << 18)
+#define MII_TA 0x00020000
+
+//
+// PHY unit access (via MII channel, using bit-level operations)
+//
+
+static cyg_uint32
+phy_cmd(eth_phy_access_t *f, cyg_uint32 cmd)
+{
+ cyg_uint32 retval;
+ int i, off;
+ bool is_read = ((cmd & MII_Cmd) == MII_Read);
+
+ // Set both bits as output
+ (f->ops.bit_level_ops.set_dir)(1);
+
+ // Preamble
+ for (i = 0; i < 32; i++) {
+ (f->ops.bit_level_ops.set_clock)(0);
+ (f->ops.bit_level_ops.set_data)(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ (f->ops.bit_level_ops.set_clock)(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ }
+
+ // Command/data
+ for (i = 0, off = 31; i < (is_read ? 14 : 32); i++, --off) {
+ (f->ops.bit_level_ops.set_clock)(0);
+ (f->ops.bit_level_ops.set_data)((cmd >> off) & 0x00000001);
+ CYGACC_CALL_IF_DELAY_US(1);
+ (f->ops.bit_level_ops.set_clock)(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ }
+
+ retval = cmd;
+
+ // If read, fetch data register
+ if (is_read) {
+ retval >>= 16;
+
+ (f->ops.bit_level_ops.set_clock)(0);
+ (f->ops.bit_level_ops.set_dir)(0);
+ CYGACC_CALL_IF_DELAY_US(1);
+ (f->ops.bit_level_ops.set_clock)(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ (f->ops.bit_level_ops.set_clock)(0);
+ CYGACC_CALL_IF_DELAY_US(1);
+
+ for (i = 0, off = 15; i < 16; i++, off--) {
+ (f->ops.bit_level_ops.set_clock)(1);
+ retval <<= 1;
+ retval |= (f->ops.bit_level_ops.get_data)();
+ CYGACC_CALL_IF_DELAY_US(1);
+ (f->ops.bit_level_ops.set_clock)(0);
+ CYGACC_CALL_IF_DELAY_US(1);
+ }
+ }
+
+ // Set both bits as output
+ (f->ops.bit_level_ops.set_dir)(1);
+
+ // Postamble
+ for (i = 0; i < 32; i++) {
+ (f->ops.bit_level_ops.set_clock)(0);
+ (f->ops.bit_level_ops.set_data)(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ (f->ops.bit_level_ops.set_clock)(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ }
+
+ return retval;
+}
+
+externC bool
+_eth_phy_init(eth_phy_access_t *f)
+{
+ int addr;
+ unsigned short state;
+ unsigned long id = 0;
+ struct _eth_phy_dev_entry *dev;
+
+ if (f->init_done) return true;
+ (f->init)();
+ // Scan to determine PHY address
+ f->init_done = true;
+ for (addr = 0; addr < 0x20; addr++) {
+ if (_eth_phy_read(f, PHY_ID1, addr, &state)) {
+ id = state << 16;
+ if (_eth_phy_read(f, PHY_ID2, addr, &state)) {
+ id |= state;
+ f->phy_addr = addr;
+ for (dev = __ETH_PHY_TAB__; dev != &__ETH_PHY_TAB_END__; dev++) {
+ if (dev->id == id) {
+ eth_phy_printf("PHY: %s at addr %x\n", dev->name, f->phy_addr);
+ f->dev = dev;
+ return true;
+ }
+ }
+ }
+ }
+ }
+ if (addr >= 0x20)
+ {
+ // Can't handle this PHY
+ eth_phy_printf("Unsupported PHY device - id: %x\n", id);
+ }
+ f->init_done = false;
+ return false;
+}
+
+externC void
+_eth_phy_reset(eth_phy_access_t *f)
+{
+ if (!f->init_done) {
+ eth_phy_printf("PHY reset without init on PHY: %x\n", f);
+ return;
+ }
+ (f->init)();
+}
+
+externC void
+_eth_phy_write(eth_phy_access_t *f, int reg, int addr, unsigned short data)
+{
+ if (!f->init_done) {
+ eth_phy_printf("PHY write without init on PHY: %x\n", f);
+ return;
+ }
+ if (f->ops_type == PHY_BIT_LEVEL_ACCESS_TYPE) {
+ phy_cmd(f, MII_Start | MII_Write | MII_Phy(addr) | MII_Reg(reg) | MII_TA | data);
+ } else {
+ (f->ops.reg_level_ops.put_reg)(reg, addr, data);
+ }
+}
+
+externC bool
+_eth_phy_read(eth_phy_access_t *f, int reg, int addr, unsigned short *val)
+{
+ cyg_uint32 ret;
+
+ if (!f->init_done) {
+ eth_phy_printf("PHY read without init on PHY: %x\n", f);
+ return false;
+ }
+ if (f->ops_type == PHY_BIT_LEVEL_ACCESS_TYPE) {
+ ret = phy_cmd(f, MII_Start | MII_Read | MII_Phy(addr) | MII_Reg(reg) | MII_TA);
+ *val = ret;
+ return true;
+ } else {
+ return (f->ops.reg_level_ops.get_reg)(reg, addr, val);
+ }
+}
+
+externC int
+_eth_phy_cfg(eth_phy_access_t *f, int mode)
+{
+ int phy_timeout = 5*1000; // Wait 5 seconds max for link to clear
+ bool phy_ok;
+ unsigned short reset_mode, phy_state;
+ int i;
+
+ if (!f->init_done) {
+ eth_phy_printf("PHY config without init on PHY: %x\n", f);
+ return 0;
+ }
+
+ // Reset PHY (transceiver)
+ phy_ok = false;
+ _eth_phy_reset(f);
+
+ _eth_phy_write(f, PHY_BMCR, f->phy_addr, PHY_BMCR_RESET);
+ for (i = 0; i < 5*100; i++) {
+ phy_ok = _eth_phy_read(f, PHY_BMCR, f->phy_addr, &phy_state);
+ eth_phy_printf("PHY: %x\n", phy_state);
+ if (phy_ok && !(phy_state & PHY_BMCR_RESET)) break;
+ CYGACC_CALL_IF_DELAY_US(10000); // 10ms
+ }
+ if (!phy_ok || (phy_state & PHY_BMCR_RESET)) {
+ eth_phy_printf("PPC405: Can't get PHY unit to soft reset: %x\n", phy_state);
+ return 0;
+ }
+
+ reset_mode = PHY_BMCR_RESTART | PHY_BMCR_AUTO_NEG;
+ _eth_phy_write(f, PHY_BMCR, f->phy_addr, reset_mode);
+ while (phy_timeout-- >= 0) {
+ phy_ok = _eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state);
+ if (phy_ok && (phy_state & PHY_BMSR_AUTO_NEG)) {
+ break;
+ } else {
+ CYGACC_CALL_IF_DELAY_US(10000); // 10ms
+ }
+ }
+ if (phy_timeout <= 0) {
+ eth_phy_printf("** PPC405 Warning: PHY LINK UP failed: %04x\n", phy_state);
+ return 0;
+ }
+
+ return _eth_phy_state(f);
+}
+
+externC int
+_eth_phy_state(eth_phy_access_t *f)
+{
+ int state = 0;
+
+ if (!f->init_done) {
+ eth_phy_printf("PHY state without init on PHY: %x\n", f);
+ return 0;
+ }
+ if ((f->dev->stat)(f, &state)) {
+ return state;
+ } else {
+ return 0;
+ }
+ return state;
+}
diff --git a/ecos/packages/devs/eth/phy/current/src/ics189x.c b/ecos/packages/devs/eth/phy/current/src/ics189x.c
new file mode 100644
index 0000000..ce52e0e
--- /dev/null
+++ b/ecos/packages/devs/eth/phy/current/src/ics189x.c
@@ -0,0 +1,118 @@
+//==========================================================================
+//
+// ics189x.c
+//
+// Ethernet transceiver (PHY) support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: Jay Foster
+// Date: 2006-03-17
+// Purpose:
+// Description: Support for ethernet ICS 189x PHYs
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+#define Bit(n) (1<<(n))
+
+static bool ics189x_stat(eth_phy_access_t *f, int *state)
+{
+ unsigned short phy_state;
+ int tries;
+
+ // Read negotiated state from the Quick Poll Detailed Status Register
+ if (_eth_phy_read(f, 17, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & Bit(4)) == 0)
+ {
+ eth_phy_printf("... waiting for auto-negotiation");
+ for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++)
+ {
+ if (_eth_phy_read(f, 17, f->phy_addr, &phy_state))
+ {
+ if ((phy_state & Bit(4)) != 0)
+ {
+ break;
+ }
+ }
+ CYGACC_CALL_IF_DELAY_US(1000000); // 1 second
+ eth_phy_printf(".");
+ }
+ eth_phy_printf("\n");
+ }
+ if ((phy_state & Bit(4)) != 0)
+ {
+ *state = 0;
+ if (phy_state & Bit(0))
+ *state |= ETH_PHY_STAT_LINK;
+ if (phy_state & Bit(14))
+ *state |= ETH_PHY_STAT_FDX;
+ if (phy_state & Bit(15))
+ *state |= ETH_PHY_STAT_100MB;
+ return true;
+ }
+ }
+ return false;
+}
+
+#ifdef CYGHWR_DEVS_ETH_PHY_ICS1890
+_eth_phy_dev("ICS 1890", 0x0015F422, ics189x_stat) // 1st general release
+_eth_phy_dev("ICS 1890", 0x0015F423, ics189x_stat) // 1890 "J" release
+#endif
+#ifdef CYGHWR_DEVS_ETH_PHY_ICS1892
+_eth_phy_dev("ICS 1892", 0x0015F430, ics189x_stat)
+#endif
+#ifdef CYGHWR_DEVS_ETH_PHY_ICS1893
+_eth_phy_dev("ICS 1893", 0x0015F441, ics189x_stat)
+#endif
+
diff --git a/ecos/packages/devs/eth/powerpc/adder/current/ChangeLog b/ecos/packages/devs/eth/powerpc/adder/current/ChangeLog
new file mode 100644
index 0000000..56be1de
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/adder/current/ChangeLog
@@ -0,0 +1,38 @@
+2003-03-24 Gary Thomas <gary@mlbassoc.com>
+
+ * cdl/adder_eth_drivers.cdl: Make sure this builds only for
+ the original Adder (PPC850)
+
+2002-11-25 Gary Thomas <gthomas@ecoscentric.com>
+
+ * src/adder_eth.c:
+ * include/adder_eth.inl:
+ * cdl/adder_eth_drivers.cdl: New package - platform specifics for
+ Analogue & Micro Adder (PowerPC 850) ethernet, using SCC2.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/adder/current/cdl/adder_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/adder/current/cdl/adder_eth_drivers.cdl
new file mode 100644
index 0000000..492b490
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/adder/current/cdl/adder_eth_drivers.cdl
@@ -0,0 +1,70 @@
+#====================================================================
+#
+# adder_eth_drivers.cdl
+#
+# Hardware specifics for A&M Adder ethernet
+#
+#====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-14
+#
+#####DESCRIPTIONEND####
+#
+#====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_ADDER {
+ display "A&M Adder (MPC8xxT) ethernet support"
+ description "Hardware specifics for A&M Adder ethernet"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_MPC8xx
+ active_if CYGPKG_HAL_POWERPC_ADDER
+
+ requires CYGPKG_DEVS_ETH_POWERPC_QUICC
+ requires CYGHWR_HAL_POWERPC_ADDER_I
+
+ compile adder_eth.c
+
+ include_dir cyg/io
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_QUICC_ETH_INL <cyg/io/adder_eth.inl>"
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/adder/current/include/adder_eth.inl b/ecos/packages/devs/eth/powerpc/adder/current/include/adder_eth.inl
new file mode 100644
index 0000000..550464d
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/adder/current/include/adder_eth.inl
@@ -0,0 +1,95 @@
+#ifndef CYGONCE_DEVS_ADDER_ETH_INL
+#define CYGONCE_DEVS_ADDER_ETH_INL
+//==========================================================================
+//
+// adder_eth.inl
+//
+// Hardware specifics for A&M Adder ethernet support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2002-11-19
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+extern int _adder_get_leds(void);
+extern void _adder_set_leds(int);
+extern bool _adder_reset_phy(void);
+
+#define _get_led() _adder_get_leds()
+#define _set_led(v) _adder_set_leds(v)
+
+#define LED_TxACTIVE 2
+#define LED_RxACTIVE 1
+
+// Reset the PHY - analagous to hardware reset
+#define QUICC_ETH_RESET_PHY() \
+ if (!_adder_reset_phy()) { \
+ diag_printf("Can't reset PHY or get link\n"); \
+ }
+
+// Port layout - uses SCC2
+#define QUICC_ETH_INT CYGNUM_HAL_INTERRUPT_CPM_SCC2
+#define QUICC_ETH_SCC 1 // SCC2
+#define QUICC_CPM_SCCx QUICC_CPM_SCC2
+
+// Fixed bits
+#define QUICC_ETH_PA_RXD 0x0004 // Rx Data on Port A
+#define QUICC_ETH_PA_TXD 0x0008 // Tx Data on Port A
+#define QUICC_ETH_PC_COLLISION 0x0040 // Collision detect
+#define QUICC_ETH_PC_Rx_ENABLE 0x0080 // Rx Enable (RENA)
+
+// These depend on how the PHY is wired to the CPU
+#define QUICC_ETH_PA_Tx_CLOCK 0x0200 // Tx Clock = CLK2
+#define QUICC_ETH_PA_Rx_CLOCK 0x0800 // Rx Clock = CLK4
+#define QUICC_ETH_SICR_MASK 0xFF00 // SI Clock Route - important bits
+#define QUICC_ETH_SICR_ENET (7<<11)|(5<<8) // Rx=CLK4, Tx=CLK2
+#define QUICC_ETH_SICR_ENABLE 0x4000 // Enable SCC2 to use NMSI
+
+// The TENA signal can appear on either port B or C
+//#define QUICC_ETH_PC_Tx_ENABLE 0x0002 // Tx Enable (TENA)
+#define QUICC_ETH_PB_Tx_ENABLE 0x2000 // Tx Enable (TENA)
+
+
+#endif // CYGONCE_DEVS_ADDER_ETH_INL
+// ------------------------------------------------------------------------
diff --git a/ecos/packages/devs/eth/powerpc/adder/current/src/adder_eth.c b/ecos/packages/devs/eth/powerpc/adder/current/src/adder_eth.c
new file mode 100644
index 0000000..36b4210
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/adder/current/src/adder_eth.c
@@ -0,0 +1,267 @@
+//==========================================================================
+//
+// adder_eth.c
+//
+// Ethernet device driver specifics for Analogue & Micro Adder (PPC850)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2002-11-25
+// Purpose:
+// Description: platform driver specifics for A&M Adder
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// Ethernet device driver support for PHY on Adder/MPC850
+
+#include <pkgconf/system.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/drv_api.h>
+
+#include CYGDAT_DEVS_QUICC_ETH_INL // Platform specifics
+#include <cyg/hal/quicc/ppc8xx.h> // QUICC structure definitions
+
+// MII interface
+#define MII_Start 0x40000000
+#define MII_Read 0x20000000
+#define MII_Write 0x10000000
+#define MII_Cmd 0x30000000
+#define MII_Phy(phy) (phy << 23)
+#define MII_Reg(reg) (reg << 18)
+#define MII_TA 0x00020000
+
+// Transceiver mode
+#define PHY_BMCR 0x00 // Register number
+#define PHY_BMCR_RESET 0x8000
+#define PHY_BMCR_LOOPBACK 0x4000
+#define PHY_BMCR_100MB 0x2000
+#define PHY_BMCR_AUTO_NEG 0x1000
+#define PHY_BMCR_POWER_DOWN 0x0800
+#define PHY_BMCR_ISOLATE 0x0400
+#define PHY_BMCR_RESTART 0x0200
+#define PHY_BMCR_FULL_DUPLEX 0x0100
+#define PHY_BMCR_COLL_TEST 0x0080
+
+#define PHY_BMSR 0x01 // Status register
+#define PHY_BMSR_AUTO_NEG 0x0020
+#define PHY_BMSR_LINK 0x0004
+
+// Bits in port D - used for 2 wire MII interface
+#define MII_DATA 0x1000
+#define MII_CLOCK 0x0800
+
+#define MII_SET_DATA(val) \
+ if (val) { \
+ eppc->pio_pddat |= MII_DATA; \
+ } else { \
+ eppc->pio_pddat &= ~MII_DATA; \
+ }
+
+#define MII_GET_DATA() \
+ ((eppc->pio_pddat & MII_DATA) != 0)
+
+#define MII_SET_CLOCK(val) \
+ if (val) { \
+ eppc->pio_pddat |= MII_CLOCK; \
+ } else { \
+ eppc->pio_pddat &= ~MII_CLOCK; \
+ }
+
+static cyg_uint32
+phy_cmd(cyg_uint32 cmd)
+{
+ volatile EPPC *eppc = (volatile EPPC *)eppc_base();
+ cyg_uint32 retval;
+ int i, off;
+ bool is_read = ((cmd & MII_Cmd) == MII_Read);
+
+ // Set both bits as output
+ eppc->pio_pddir |= MII_DATA | MII_CLOCK;
+
+ // Preamble
+ for (i = 0; i < 32; i++) {
+ MII_SET_CLOCK(0);
+ MII_SET_DATA(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ MII_SET_CLOCK(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ }
+
+ // Command/data
+ for (i = 0, off = 31; i < (is_read ? 14 : 32); i++, --off) {
+ MII_SET_CLOCK(0);
+ MII_SET_DATA((cmd >> off) & 0x00000001);
+ CYGACC_CALL_IF_DELAY_US(1);
+ MII_SET_CLOCK(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ }
+
+ retval = cmd;
+
+ // If read, fetch data register
+ if (is_read) {
+ retval >>= 16;
+
+ MII_SET_CLOCK(0);
+ eppc->pio_pddir &= ~MII_DATA; // Data bit is now input
+ CYGACC_CALL_IF_DELAY_US(1);
+ MII_SET_CLOCK(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ MII_SET_CLOCK(0);
+ CYGACC_CALL_IF_DELAY_US(1);
+
+ for (i = 0, off = 15; i < 16; i++, off--) {
+ MII_SET_CLOCK(1);
+ retval <<= 1;
+ retval |= MII_GET_DATA();
+ CYGACC_CALL_IF_DELAY_US(1);
+ MII_SET_CLOCK(0);
+ CYGACC_CALL_IF_DELAY_US(1);
+ }
+ }
+
+ // Set both bits as output
+ eppc->pio_pddir |= MII_DATA | MII_CLOCK;
+
+ // Postamble
+ for (i = 0; i < 32; i++) {
+ MII_SET_CLOCK(0);
+ MII_SET_DATA(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ MII_SET_CLOCK(1);
+ CYGACC_CALL_IF_DELAY_US(1);
+ }
+
+ return retval;
+}
+
+//
+// PHY unit access (via MII channel)
+//
+static void
+phy_write(int reg, int addr, unsigned short data)
+{
+ phy_cmd(MII_Start | MII_Write | MII_Phy(addr) | MII_Reg(reg) | MII_TA | data);
+}
+
+static bool
+phy_read(int reg, int addr, unsigned short *val)
+{
+ cyg_uint32 ret;
+
+ ret = phy_cmd(MII_Start | MII_Read | MII_Phy(addr) | MII_Reg(reg) | MII_TA);
+ *val = ret;
+ return true;
+}
+
+bool
+_adder_reset_phy(void)
+{
+ volatile EPPC *eppc = (volatile EPPC *)eppc_base();
+ int phy_timeout = 5*1000; // Wait 5 seconds max for link to clear
+ bool phy_ok;
+ unsigned short phy_state = 0;
+ int phy_unit = -1;
+ int i;
+
+ // Reset PHY (transceiver)
+ eppc->pip_pbdat &= ~0x00004000; // Reset PHY chip
+ CYGACC_CALL_IF_DELAY_US(15000); // > 10ms
+ eppc->pip_pbdat |= 0x00004000; // Enable PHY chip
+
+ phy_ok = false;
+
+ // Try and discover how this PHY is wired
+ for (i = 0; i < 0x20; i++) {
+ phy_read(PHY_BMCR, i, &phy_state);
+ if ((phy_state & PHY_BMCR_RESET) == 0) {
+ phy_unit = i;
+ break;
+ }
+ }
+ if (phy_unit < 0) {
+ diag_printf("QUICC ETH - Can't locate PHY\n");
+ return false;
+ } else {
+#if 0
+ diag_printf("QUICC ETH - using PHY %d\n", phy_unit);
+#endif
+ }
+ if (phy_read(PHY_BMSR, phy_unit, &phy_state)) {
+ if ((phy_state & PHY_BMSR_LINK) != PHY_BMSR_LINK) {
+ unsigned short reset_mode;
+ phy_write(PHY_BMCR, phy_unit, PHY_BMCR_RESET);
+ for (i = 0; i < 10; i++) {
+ phy_ok = phy_read(PHY_BMCR, phy_unit, &phy_state);
+ if (!phy_ok) break;
+ if (!(phy_state & PHY_BMCR_RESET)) break;
+ }
+ if (!phy_ok || (phy_state & PHY_BMCR_RESET)) {
+ diag_printf("QUICC/ETH: Can't get PHY unit to soft reset: %x\n", phy_state);
+ return false;
+ }
+ reset_mode = PHY_BMCR_RESTART | PHY_BMCR_AUTO_NEG | PHY_BMCR_FULL_DUPLEX;
+ phy_write(PHY_BMCR, phy_unit, reset_mode);
+ while (phy_timeout-- >= 0) {
+ phy_ok = phy_read(PHY_BMSR, phy_unit, &phy_state);
+ if (phy_ok && (phy_state & PHY_BMSR_LINK)) {
+ break;
+ } else {
+ CYGACC_CALL_IF_DELAY_US(10000); // 10ms
+ }
+ }
+ if (phy_timeout <= 0) {
+ diag_printf("** QUICC/ETH Warning: PHY LINK UP failed\n");
+ }
+ }
+ else {
+ diag_printf("** QUICC/ETH Info: PHY LINK already UP \n");
+ }
+ }
+
+ return phy_ok;
+}
+
diff --git a/ecos/packages/devs/eth/powerpc/adderII/current/ChangeLog b/ecos/packages/devs/eth/powerpc/adderII/current/ChangeLog
new file mode 100644
index 0000000..eda9eb0
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/adderII/current/ChangeLog
@@ -0,0 +1,38 @@
+2003-03-24 Gary Thomas <gary@mlbassoc.com>
+
+ * include/adderII_eth.inl:
+ * cdl/adderII_eth_drivers.cdl: New package - ethernet support on
+ AdderII using FEC.
+
+2002-09-03 Gary Thomas <gary@mlbassoc.com>
+
+ * include/viper_eth.inl:
+ * cdl/viper_eth_drivers.cdl: New package - platform specifics for
+ PowerPC/FEC ethernet driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/adderII/current/cdl/adderII_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/adderII/current/cdl/adderII_eth_drivers.cdl
new file mode 100644
index 0000000..e4755ca
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/adderII/current/cdl/adderII_eth_drivers.cdl
@@ -0,0 +1,68 @@
+#====================================================================
+#
+# adderII_eth_drivers.cdl
+#
+# Hardware specifics for A&M Adder-II ethernet
+#
+#====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt
+# Original data: gthomas
+# Contributors: gthomas, F.Robbins
+# Date: 2003-03-17
+#
+#####DESCRIPTIONEND####
+#
+#====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_ADDERII {
+ display "A&M AdderII (MPC852T) ethernet support"
+ description "Hardware specifics for A&M AdderII ethernet"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_MPC8xx
+
+ requires CYGPKG_DEVS_ETH_POWERPC_FEC
+ requires CYGHWR_HAL_POWERPC_ADDER_II
+
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FEC_ETH_INL <cyg/io/adderII_eth.inl>"
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/adderII/current/include/adderII_eth.inl b/ecos/packages/devs/eth/powerpc/adderII/current/include/adderII_eth.inl
new file mode 100644
index 0000000..d2ca29a
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/adderII/current/include/adderII_eth.inl
@@ -0,0 +1,77 @@
+#ifndef CYGONCE_DEVS_ADDERII_ETH_INL
+#define CYGONCE_DEVS_ADDERII_ETH_INL
+//==========================================================================
+//
+// adderii_eth.inl
+//
+// Hardware specifics for A&M AdderII ethernet support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas,F.Robbins
+// Date: 2002-09-03
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+extern int _adder_get_leds(void);
+extern void _adder_set_leds(int);
+
+#define _get_led() _adder_get_leds()
+#define _set_led(v) _adder_set_leds(v)
+
+#define LED_TxACTIVE 1
+#define LED_RxACTIVE 2
+#define LED_IntACTIVE 3
+
+// Interrupt generated by device
+#define FEC_ETH_INT CYGNUM_HAL_INTERRUPT_SIU_LVL1
+// Address of PHY (transceiver) device
+#define FEC_ETH_PHY 0
+
+// Reset the PHY - analagous to hardware reset
+#define FEC_ETH_RESET_PHY() \
+ eppc->pip_pbdat &= ~0x00010000; /* Reset PHY chip pb15 */ \
+ CYGACC_CALL_IF_DELAY_US(10000); /* 10ms */ \
+ eppc->pip_pbdat |= 0x00010000; /* Enable PHY chip pb15 */
+
+#endif // CYGONCE_DEVS_ADDERII_ETH_INL
+// ------------------------------------------------------------------------
diff --git a/ecos/packages/devs/eth/powerpc/csb281/current/ChangeLog b/ecos/packages/devs/eth/powerpc/csb281/current/ChangeLog
new file mode 100644
index 0000000..8280415
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/csb281/current/ChangeLog
@@ -0,0 +1,38 @@
+2003-01-20 Gary Thomas <gary@mlbassoc.com>
+
+ * include/devs_eth_csb281.inl: Add RedBoot management of ESA.
+
+2003-01-03 Gary Thomas <gary@mlbassoc.com>
+
+ * include/devs_eth_csb281.inl: PCI window is now in specially
+ mapped, uncacheable space.
+
+2002-12-24 Gary Thomas <gary@mlbassoc.com>
+
+ * include/devs_eth_csb281.inl:
+ * cdl/csb281_eth_drivers.cdl: New package - ethernet support
+ via i82559 on PCI for Cogent CSB281 board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/powerpc/csb281/current/cdl/csb281_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/csb281/current/cdl/csb281_eth_drivers.cdl
new file mode 100644
index 0000000..5a3d7df
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/csb281/current/cdl/csb281_eth_drivers.cdl
@@ -0,0 +1,199 @@
+# ====================================================================
+#
+# csb281_eth_drivers.cdl
+#
+# Ethernet drivers - support for i82559 ethernet controller
+# on the Cogent CSB281 (PowerPC 8245) board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov, hmt, gthomas
+# Date: 2001-02-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_CSB281 {
+ display "Cogent CSB281 ethernet driver"
+ description "
+ Ethernet driver for Cogent CSB281 with Intel
+ i82559 Ethernet controllers attached via the PCI"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC_CSB281
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the INTEL_I82559 package
+ cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
+ display "Intel i82559 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_csb281.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_csb281.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_CSB281_ETH0 {
+ display "CSB281 ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver on the
+ csb281 motherboard."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_CSB281_ETH0_NAME {
+ display "Device name for the ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ ethernet port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_CSB281_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value !CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA, and if RedBoot's
+ flash configuration support is not available."
+
+ cdl_option CYGDAT_DEVS_ETH_CSB281_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x11}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_CSB281_ETH1 {
+ display "CSB281 ethernet port 1 driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the ethernet device driver for the
+ additional i82559 devices plugged into a PCI slot."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH1
+ implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_CSB281_ETH1_NAME {
+ display "Device name for the ethernet port 1 driver"
+ flavor data
+ default_value {"\"eth1\""}
+ description "
+ This option sets the name of the ethernet device for the
+ ethernet port 1."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_CSB281_ETH1_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value !CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA, and if RedBoot's
+ flash configuration support is not available."
+
+ cdl_option CYGDAT_DEVS_ETH_CSB281_ETH1_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x12}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+
+ # note that this option's name is NOT csb281-specific, but i82559
+ # generic - other instantiations can set these also.
+ cdl_component CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA {
+ display "RedBoot manages ESA initialization data"
+ flavor bool
+ default_value 1
+
+ active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+ description "Enabling this option will allow the ethernet
+ station address to be acquired from RedBoot's configuration data,
+ stored in flash memory. It can be overridden individually by the
+ 'Set the ethernet station address' option for each interface."
+
+ cdl_component CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_VARS {
+ display "Build-in flash config fields for ESAs"
+ flavor bool
+ default_value 1
+
+ active_if CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT_FLASH
+ active_if CYGSEM_REDBOOT_FLASH_CONFIG
+ active_if CYGPKG_REDBOOT_NETWORKING
+
+ description "
+ This option controls the presence of RedBoot flash
+ configuration fields for the ESAs of the interfaces when you
+ are building RedBoot. It is independent of whether RedBoot
+ itself uses the network or any particular interface; this
+ support is more for the application to use than for RedBoot
+ itself, though the application gets at the data by vector
+ calls; this option cannot be enabled outside of building
+ RedBoot."
+
+ cdl_option CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0 {
+ display "RedBoot manages ESA for eth0"
+ flavor bool
+ default_value 1
+ }
+ }
+ }
+}
+
+# EOF csb281_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/powerpc/csb281/current/include/devs_eth_csb281.inl b/ecos/packages/devs/eth/powerpc/csb281/current/include/devs_eth_csb281.inl
new file mode 100644
index 0000000..2ab7d76
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/csb281/current/include/devs_eth_csb281.inl
@@ -0,0 +1,159 @@
+//==========================================================================
+//
+// devs/eth/powerpc/csb281/include/devs_eth_csb281.inl
+//
+// PCI i82559 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov, gthomas
+// Date: 2001-01-25
+// Purpose: PCI/i82559 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#ifdef CYGPKG_DEVS_ETH_CSB281_ETH0
+
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE CYGMEM_SECTION_pci_window
+#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE CYGMEM_SECTION_pci_window_SIZE
+#define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+#define CYGHWR_DEVS_ETH_INTEL_I82559_USE_MEMORY
+
+static I82559 i82559_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_CSB281_ETH0_SET_ESA
+ hardwired_esa: 1,
+ mac_address: CYGDAT_DEVS_ETH_CSB281_ETH0_ESA
+#else
+ hardwired_esa: 0,
+#endif
+};
+
+ETH_DRV_SC(i82559_sc0,
+ &i82559_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_CSB281_ETH0_NAME, // Name for device
+ i82559_start,
+ i82559_stop,
+ i82559_ioctl,
+ i82559_can_send,
+ i82559_send,
+ i82559_recv,
+ i82559_deliver,
+ i82559_poll,
+ i82559_int_vector
+ );
+
+NETDEVTAB_ENTRY(i82559_netdev0,
+ "i82559_" CYGDAT_DEVS_ETH_CSB281_ETH0_NAME,
+ i82559_init,
+ &i82559_sc0);
+
+#endif // CYGPKG_DEVS_ETH_CSB281_ETH0
+
+
+// These arrays are used for sanity checking of pointers
+I82559 *
+i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_CSB281_ETH0
+ &i82559_eth0_priv_data,
+#endif
+};
+
+#ifdef CYGDBG_USE_ASSERTS
+// These are only used when assertions are enabled
+cyg_netdevtab_entry_t *
+i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_CSB281_ETH0
+ &i82559_netdev0,
+#endif
+};
+
+struct eth_drv_sc *
+i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_CSB281_ETH0
+ &i82559_sc0,
+#endif
+};
+#endif // CYGDBG_USE_ASSERTS
+
+// --------------------------------------------------------------
+// RedBoot configuration options for managing ESAs for us
+
+// tell the driver there is no EEPROM on this board
+#define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
+
+// Decide whether to have redboot config vars for it...
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#ifdef CYGPKG_REDBOOT_NETWORKING
+#include <redboot.h>
+#include <flash_config.h>
+
+#ifdef CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0
+RedBoot_config_option("Network hardware address [MAC] for eth0",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif
+
+#endif
+#endif
+#endif
+
+// and initialization code to read them
+// - independent of whether we are building RedBoot right now:
+#ifdef CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+
+#include <cyg/hal/hal_if.h>
+
+#ifndef CONFIG_ESA
+#define CONFIG_ESA (6)
+#endif
+
+#define CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA( p_i82559, mac_address, ok ) \
+CYG_MACRO_START \
+ ok = false; \
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
+ "eth0_esa", mac_address, CONFIG_ESA); \
+CYG_MACRO_END
+
+#endif // CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
+
+// EOF devs_eth_csb281.inl
diff --git a/ecos/packages/devs/eth/powerpc/ec555/current/ChangeLog b/ecos/packages/devs/eth/powerpc/ec555/current/ChangeLog
new file mode 100644
index 0000000..b088bb4
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/ec555/current/ChangeLog
@@ -0,0 +1,39 @@
+2004-04-08 Bob Koninckx <bob.koninckx@o-3s.com>
+
+ * cdl/ec555_eth_drivers.cdl: Made
+ CYGNUM_DEVS_ETH_POWERPC_EC555_ETH0_BASE a calculated option that is
+ always consistent with the memory map. Added the possibility to set
+ the esa as a configuration option.
+
+ * include/devs_eth_powerpc_ec555.inl: Made hardware swapping or
+ software swapping of data bytes (mostly relevant to big endian
+ machines) a configuration option
+
+2003-11-05 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * include/devs_eth_powerpc_ec555.inl:
+ * cdl/ec555_eth_drivers.cdl: New package - support on PowerPC EC555
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/powerpc/ec555/current/cdl/ec555_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/ec555/current/cdl/ec555_eth_drivers.cdl
new file mode 100644
index 0000000..d477ae5
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/ec555/current/cdl/ec555_eth_drivers.cdl
@@ -0,0 +1,145 @@
+# ====================================================================
+#
+# ec555_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for ether555 on ec555
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Bob Koninckx
+# Contributors: Bob Koninckx
+# Date: 2002-11-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_EC555 {
+ display "Crystal LAN ethernet driver for ec555 boards"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC_EC555
+
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+ implements CYGINT_DEVS_ETH_CL_CS8900A_STATIC_ESA
+
+ requires CYGPKG_DEVS_ETH_CL_CS8900A
+
+ include_dir cyg/io
+
+ description "Ethernet driver for Crystal LAN based ether555 ethernet card for ec555"
+
+ # FIXME: This really belongs in the CL CS8900A package
+ cdl_interface CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED {
+ display "CS8900A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_INL <cyg/io/devs_eth_powerpc_ec555.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_CL_CS8900A_CFG <pkgconf/devs_eth_powerpc_ec555.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_POWERPC_EC555_ETH0 {
+ display "ec555 ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ ec555 port."
+
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_CL_CS8900A_REQUIRED
+ implements CYGINT_DEVS_ETH_CL_CS8900A_STATIC_ESA
+
+ cdl_option CYGDAT_DEVS_ETH_POWERPC_EC555_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_EC555_ETH0_CS {
+ display "Memory bank (CS2 / CS3) to use for accessing the device"
+ flavor data
+ default_value 2
+ legal_values 2 to 3
+ description "
+ This option controls which memory controller will be set up for access to
+ the ethernet card. The choise must correspond to the position of jumper
+ X3 on the device"
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_EC555_ETH0_BASE {
+ display "Base address to use for accessing the device"
+ flavor data
+ calculated { CYGNUM_DEVS_ETH_POWERPC_EC555_ETH0_CS == 2 ? 0x04000000 : 0x08000000 }
+ description "
+ This option determines the base address to use for the memory controller"
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_EC555_ETH0_IRQ {
+ display "Interrupt line on the ec555 to use"
+ flavor data
+ default_value 4
+ legal_values 4 to 7
+ description "
+ This option determines which interrupt line of the ec555 will be used by the
+ device. The choise must match the position of jumper X2."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_POWERPC_EC555_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_POWERPC_EC555_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+
+}
+
diff --git a/ecos/packages/devs/eth/powerpc/ec555/current/include/devs_eth_powerpc_ec555.inl b/ecos/packages/devs/eth/powerpc/ec555/current/include/devs_eth_powerpc_ec555.inl
new file mode 100644
index 0000000..4540ead
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/ec555/current/include/devs_eth_powerpc_ec555.inl
@@ -0,0 +1,256 @@
+//==========================================================================
+//
+// devs_eth_powerpc_ec555.inl
+//
+// ec555 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bob Koninckx
+// Contributors:Bob Koninckx
+// Date: 2002-11-20
+// Purpose: ec555 ethernet defintions
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_if.h>
+
+#ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+# endif
+#endif
+
+#ifdef __WANT_CONFIG
+# define CS8900A_step 2
+#endif
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_POWERPC_EC555_ETH0
+
+#ifndef CYGSEM_DEVS_ETH_POWERPC_EC555_ETH0_SET_ESA
+# if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_POWERPC_EC555_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_POWERPC_EC555_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+# endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+// Note that this section *is* active in an application, outside RedBoot,
+// where the above section is not included.
+
+# include <cyg/hal/hal_if.h>
+
+# ifndef CONFIG_ESA
+# define CONFIG_ESA (6)
+# endif
+# ifndef CONFIG_BOOL
+# define CONFIG_BOOL (1)
+# endif
+
+cyg_bool
+_ec555_provide_eth0_esa(struct cs8900a_priv_data* cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa", &set_esa, CONFIG_BOOL);
+ if (ok && set_esa) {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data", cpd->esa, CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+
+# endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+#endif // ! CYGSEM_DEVS_ETH_POWERPC_EC555_ETH0_SET_ESA
+
+// ------------------------------------------------------------------------
+// EEPROM access functions
+// These are byte swapped
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+#define PP_ECR 0x4000 // EEPROM Command Register
+#define PP_EE_READ_CMD 0x0002
+#define PP_EE_WRITE_CMD 0x0001
+#define PP_EE_DATA 0x4200
+#else
+#define PP_ECR 0x0040 // EEPROM Command Register
+#define PP_EE_READ_CMD 0x0200
+#define PP_EE_WRITE_CMD 0x0100
+#define PP_EE_DATA 0x0042
+#endif
+
+#define PP_EE_ADDR_W0 0x001C // Notice that the EEPROM is not programmed when you got the
+#define PP_EE_ADDR_W1 0x001D // Module from Wuerz. Make sure to program the address to these
+#define PP_EE_ADDR_W2 0x001E // locations before using the adapter. This is fairly easy using GDB
+
+// The example below programs the MAC address 0050 c4ff fc07 to the eeprom, supposed that the module
+// is mapped to adresses 0x0400 0000, and supposed that the data bus is _not_ byte swapped
+//
+// set *(unsigned short *)0x0400030a = 0x0040 Make the eeprom writable / erasable
+// set *(unsigned short *)0x0400030c = 0x0030
+//
+// set *(unsigned short *)0x0400030a = 0x0040 erase the old esa
+// set *(unsigned short *)0x0400030c = 0x031c
+// set *(unsigned short *)0x0400030c = 0x031d
+// set *(unsigned short *)0x0400030c = 0x031e
+//
+// set *(unsigned short *)0x0400030a = 0x0042 program the new esa
+// set *(unsigned short *)0x0400030c = 0x5000
+// set *(unsigned short *)0x0400030a = 0x0040
+// set *(unsigned short *)0x0400030c = 0x011c
+// set *(unsigned short *)0x0400030a = 0x0042
+// set *(unsigned short *)0x0400030c = 0xffc4
+// set *(unsigned short *)0x0400030a = 0x0040
+// set *(unsigned short *)0x0400030c = 0x011d
+// set *(unsigned short *)0x0400030a = 0x0042
+// set *(unsigned short *)0x0400030c = 0x07fc
+// set *(unsigned short *)0x0400030a = 0x0040
+// set *(unsigned short *)0x0400030c = 0x011e
+//
+// set *(unsigned short *)0x0400030a = 0x0040 Write protect the eeprom
+// set *(unsigned short *)0x0400030c = 0x0030
+
+static __inline__ cyg_uint16
+read_eeprom(cyg_addrword_t base, cyg_uint16 offset)
+{
+ while (get_reg(base, PP_SelfStat) & PP_SelfStat_SIBSY)
+ ;
+
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ put_reg(base, PP_ECR, (CYG_SWAP16(offset) | PP_EE_READ_CMD));
+#else
+ put_reg(base, PP_ECR, (offset | PP_EE_READ_CMD));
+#endif
+
+ while (get_reg(base, PP_SelfStat) & PP_SelfStat_SIBSY)
+ ;
+
+ return get_reg(base, PP_EE_DATA);
+}
+
+static __inline__ void
+copy_eeprom(cyg_addrword_t base)
+{
+ volatile cyg_uint16 esa_word;
+ cyg_uint16 i;
+ for (i = 0; i < 6; i += 2)
+ { // Offset in the eeprom is WORD oriented, in the packetpage BYTE oriented
+ esa_word = read_eeprom(base, PP_EE_ADDR_W0 + (i/2));
+#ifdef CYGIMP_DEVS_ETH_CL_CS8900A_DATABUS_BYTE_SWAPPED
+ put_reg(base, (PP_IA + CYG_SWAP16(i)), esa_word);
+#else
+ put_reg(base, (PP_IA + i), esa_word);
+#endif
+ }
+}
+
+// Not so nice, but reading these will never conflict on the ec555
+// They certainly differ in A18
+#define FIRSTRAM 0x01000000
+#define LASTRAM 0x010ffffe
+
+static __inline__ void
+post_reset(cyg_addrword_t base)
+{
+ cyg_uint16 tmp;
+
+ // The following must toggle Address line 18, connected to SBHE on the CS8900a
+ HAL_READ_UINT16( LASTRAM, tmp);
+ HAL_READ_UINT16( FIRSTRAM, tmp);
+ HAL_READ_UINT16( LASTRAM, tmp);
+ HAL_READ_UINT16( FIRSTRAM, tmp);
+}
+
+#undef CYGHWR_CL_CS8900A_PLF_POST_RESET
+#define CYGHWR_CL_CS8900A_PLF_POST_RESET(base) post_reset(base)
+
+#undef CYGHWR_CL_CS8900A_PLF_RESET
+#define CYGHWR_CL_CS8900A_PLF_RESET(base) copy_eeprom(base)
+
+static cs8900a_priv_data_t cs8900a_eth0_priv_data = {
+ base : (cyg_addrword_t) (CYGNUM_DEVS_ETH_POWERPC_EC555_ETH0_BASE + 0x300),
+ interrupt:((CYGNUM_DEVS_ETH_POWERPC_EC555_ETH0_IRQ*2)+1),
+#ifdef CYGSEM_DEVS_ETH_POWERPC_EC555_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_POWERPC_EC555_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &_ec555_provide_eth0_esa,
+# else
+ provide_esa : NULL,
+# endif
+#endif
+
+};
+
+
+ETH_DRV_SC(cs8900a_sc,
+ &cs8900a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_POWERPC_EC555_ETH0_NAME,
+ cs8900a_start,
+ cs8900a_stop,
+ cs8900a_control,
+ cs8900a_can_send,
+ cs8900a_send,
+ cs8900a_recv,
+ cs8900a_deliver, // "pseudoDSR" called from fast net thread
+ cs8900a_poll, // poll function, encapsulates ISR and DSR
+ cs8900a_int_vector);
+
+NETDEVTAB_ENTRY(cs8900a_netdev,
+ "cs8900a_" CYGDAT_DEVS_ETH_POWERPC_EC555_ETH0_NAME,
+ cs8900a_init,
+ &cs8900a_sc);
+
+#endif // CYGPKG_DEVS_ETH_POWERPC_EC555_ETH0
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_powerpc_ec555.inl
diff --git a/ecos/packages/devs/eth/powerpc/fcc/current/ChangeLog b/ecos/packages/devs/eth/powerpc/fcc/current/ChangeLog
new file mode 100644
index 0000000..ac37fd8
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/fcc/current/ChangeLog
@@ -0,0 +1,73 @@
+2004-02-04 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fcc.c:
+ * src/fcc.h: Only process error-free packets. Inspired by
+ Christoph Csebits.
+
+2004-02-03 Christoph Csebits <christoph.csebits@frequentis.com>
+
+ * src/if_fcc.c (fcc_eth_can_send): Fix: check also if
+ buffer was freed by the upper layer (txdone was called).
+
+2004-01-15 Tiphaine Billoir <tbilloir@elios-informatique.fr>
+
+ * src/if_fcc.c:
+ * src/fcc.h: Add support for FFC3. Only treat "link not found"
+ as an error when building for RedBoot.
+
+2003-11-07 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fcc.c (fcc_eth_init): Improve messages, add device name.
+
+2003-10-02 Gary Thomas <gary@mlbassoc.com>
+
+ * cdl/fcc_eth_drivers.cdl: Buffers need to be a multiple of cache
+ line size (typically 16 or 32).
+
+2003-09-08 Gary Thomas <gary@mlbassoc.com>
+
+ * cdl/fcc_eth_drivers.cdl: Force serial console during init (only
+ safe way to print during system initialization)
+
+2003-08-30 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fcc.c: Fix compile error.
+
+2003-08-26 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fcc.c: Use new PHY support.
+
+2003-08-19 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fcc.c:
+ * src/fcc.h:
+ * cdl/fcc_eth_drivers.cdl: New file(s) - generic ethernet driver
+ for Motorola QUICC-2 FCC controller. Roughly based on previously
+ contributed devs/eth/powerpc/quicc2 package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/fcc/current/cdl/fcc_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/fcc/current/cdl/fcc_eth_drivers.cdl
new file mode 100644
index 0000000..c2108c5
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/fcc/current/cdl/fcc_eth_drivers.cdl
@@ -0,0 +1,133 @@
+# ====================================================================
+#
+# fcc_eth_drivers.cdl
+#
+# Ethernet drivers - variant dependent support for PowerPC MPC8xxx
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data:
+# Contributors:
+# Date: 2003-08-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_FCC {
+ display "MPC8xxx FCC ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_MPC8XXX
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+
+ description "Fast ethernet driver for PowerPC MPC8xxx boards."
+ compile -library=libextras.a if_fcc.c
+
+ # Debug I/O during network stack initialization is not reliable
+ requires { !CYGPKG_NET || CYGPKG_NET_FORCE_SERIAL_CONSOLE == 1 }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_FCC_BUFSIZE {
+ display "Buffer size"
+ flavor data
+ default_value 1536
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC FCC/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM {
+ display "Number of output buffers"
+ flavor data
+ legal_values 2 to 64
+ default_value 8
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC FCC/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_FCC_RxNUM {
+ display "Number of input buffers"
+ flavor data
+ legal_values 2 to 64
+ default_value 8
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC FCC/ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_POWERPC_FCC_RESET_PHY {
+ display "Reset and reconfigure PHY"
+ flavor bool
+ default_value { CYG_HAL_STARTUP != "RAM" }
+ active_if CYGPKG_DEVS_ETH_PHY
+ description "
+ This option allows control over the physical transceiver"
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_FCC_LINK_MODE {
+ display "Initial link mode"
+ flavor data
+ legal_values { "10Mb" "100Mb" "Auto" }
+ default_value { "Auto" }
+ description "
+ This option specifies initial mode for the physical
+ link. The PHY will be reset and then set to this mode."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_POWERPC_FCC_OPTIONS {
+ display "MPC8xxx FCC ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_POWERPC_FCC_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the MPC8xxx FCC ethernet driver package.
+ These flags are used in addition to the set of global
+ flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/fcc/current/src/fcc.h b/ecos/packages/devs/eth/powerpc/fcc/current/src/fcc.h
new file mode 100644
index 0000000..4551d84
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/fcc/current/src/fcc.h
@@ -0,0 +1,182 @@
+//==========================================================================
+//
+// fcc.h
+//
+// PowerPC MPC8xxx fast ethernet (FCC)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: pfine, mtek
+// Date: 2003-08-19
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_eth_powerpc_fcc.h>
+// The port connected to the ethernet
+#define FCC1 0
+#define FCC2 1
+#define FCC3 2
+
+/* ------------------------ */
+/* FCC REGISTER CONSTANTS */
+/* ------------------------ */
+
+// GFMR masks (RESET: 0x00000000)
+#define FCC_GFMR_EN_Rx 0x00000020 // Receive enable
+#define FCC_GFMR_EN_Tx 0x00000010 // Transmit enable
+#define FCC_GFMR_INIT 0x0000000C // mode=ethernet
+
+//PSMR masks (RESET: 0x00000000)
+#define FCC_PSMR_INIT 0x00000080 // 32-bit CRC
+
+//TODR masks (RESET: 0x0000)
+#define FCC_TOD_INIT 0x0000
+#define FCC_TOD_SET 0x8000
+
+//DSR masks (RESET: 0x7E7E)
+#define FCC_DSR_INIT 0xD555
+
+//FCCE & FCCM (RESET: 0x0000)
+#define FCC_EV_GRA 0x0080 // Graceful stop
+#define FCC_EV_RXC 0x0040 // A control frame has been received
+#define FCC_EV_TXC 0x0020 // Out of sequence frame sent
+#define FCC_EV_TXE 0x0010 // Error in transmission channel
+#define FCC_EV_RXF 0x0008 // A complete frame received
+#define FCC_EV_BSY 0x0004 // A received frame discarded due to lack
+ // of buffers
+#define FCC_EV_TXB 0x0002 // A buffer sent to ethernet
+#define FCC_EV_RXB 0x0001 // A buffer that is a non-complete frame
+ // is received
+
+/* ------------------------------ */
+/* FCC PARAMETER RAM CONSTANTS */
+/* ------------------------------ */
+
+#define FCC_FCR_INIT 0x00000000 // Clear the reserved bits
+#define FCC_FCR_MOT_BO 0x10000000 // Motorola byte ordering
+#define FCC_PRAM_C_MASK 0xDEBB20E3 // Constant MASK for CRC
+#define FCC_PRAM_C_PRES 0xFFFFFFFF // CRC Preset
+#define FCC_PRAM_RETLIM 15 // Retry limit
+#define FCC_PRAM_PER_LO 5 // Persistance
+#define FCC_PRAM_PER_HI 0
+#define FCC_PRAM_MRBLR 1536
+#define FCC_MAX_FLR 1518 // Max frame length
+#define FCC_MIN_FLR 64 // Min frame length
+#define FCC_PRAM_PAD_CH 0x8888
+#define FCC_PRAM_MAXD 1520
+#define FCC1_PRAM_OFFSET 0x8400 // Offset of t_Fcc_Pram in 82xx
+#define FCC2_PRAM_OFFSET 0x8500 // Offset of t_Fcc_Pram in 82xx
+#define FCC3_PRAM_OFFSET 0x8600 // Offset of t_Fcc_Pram in 82xx
+
+/* ------------------------------ */
+/* BUFFER DESCRIPTOR CONSTANTS */
+/* ------------------------------ */
+#define FCC_BD_Rx_Empty 0x8000 // Buffer is empty, FCC can fill
+#define FCC_BD_Rx_Wrap 0x2000 // Wrap: Last buffer in ring
+#define FCC_BD_Rx_Int 0x1000 // Interrupt
+#define FCC_BD_Rx_Last 0x0800 // Last buffer in frame
+#define FCC_BD_Rx_Miss 0x0100 // Miss: promiscious mode
+#define FCC_BD_Rx_BC 0x0080 // Broadcast address
+#define FCC_BD_Rx_MC 0x0040 // Multicast address
+#define FCC_BD_Rx_LG 0x0020 // Frame length violation
+#define FCC_BD_Rx_NO 0x0010 // Non-octet aligned frame
+#define FCC_BD_Rx_SH 0x0008 // Short frame
+#define FCC_BD_Rx_CR 0x0004 // CRC error
+#define FCC_BD_Rx_OV 0x0002 // Overrun
+#define FCC_BD_Rx_TR 0x0001 // Frame truncated. late collision
+#define FCC_BD_Rx_ERRORS (FCC_BD_Rx_LG|FCC_BD_Rx_NO|FCC_BD_Rx_SH|FCC_BD_Rx_CR|FCC_BD_Rx_OV|FCC_BD_Rx_TR)
+
+#define FCC_BD_Tx_Ready 0x8000 // Frame ready
+#define FCC_BD_Tx_Pad 0x4000 // Pad short frames
+#define FCC_BD_Tx_Wrap 0x2000 // Wrap: Last buffer in ring
+#define FCC_BD_Tx_Int 0x1000 // Interrupt
+#define FCC_BD_Tx_Last 0x0800 // Last buffer in frame
+#define FCC_BD_Tx_TC 0x0400 // Send CRC after data
+#define FCC_BD_Tx_DEF 0x0200 // Defer indication
+#define FCC_BD_Tx_HB 0x0100 // Heartbeat
+#define FCC_BD_Tx_LC 0x0080 // Late collision
+#define FCC_BD_Tx_RL 0x0040 // Retransmission limit
+#define FCC_BD_Tx_RC 0x003C // Retry count
+#define FCC_BD_Tx_UN 0x0002 // Underrun
+#define FCC_BD_Tx_CSL 0x0001 // Carrier sense lost
+#define FCC_BD_Tx_ERRORS (FCC_BD_Tx_LC|FCC_BD_Tx_RL|FCC_BD_Tx_RC|FCC_BD_Tx_UN|FCC_BD_Tx_CSL)
+
+
+// Buffer descriptor
+struct fcc_bd {
+ volatile unsigned short ctrl;
+ volatile unsigned short length;
+ volatile unsigned char *buffer;
+};
+
+//
+// Info kept about each interface
+//
+struct fcc_eth_info {
+ // These fields should be defined by the implementation
+ int int_vector;
+ char *esa_key; // RedBoot 'key' for device ESA
+ unsigned char enaddr[6];
+ int rxnum; // Number of Rx buffers
+ unsigned char *rxbuf; // Rx buffer space
+ int txnum; // Number of Tx buffers
+ unsigned char *txbuf; // Tx buffer space
+#ifdef CYGPKG_DEVS_ETH_PHY
+ eth_phy_access_t *phy; // Routines to access PHY
+#endif
+ // The rest of the structure is set up at runtime
+ volatile struct fcc_regs *fcc_reg; // See "mpc8260.h"
+ struct fcc_bd *txbd, *rxbd; // Next Tx,Rx descriptor to use
+ struct fcc_bd *tbase, *rbase; // First Tx,Rx descriptor
+ struct fcc_bd *tnext, *rnext; // Next descriptor to check for interrupt
+ int txsize, rxsize; // Length of individual buffers
+ unsigned long txkey[CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM];
+#ifdef CYGPKG_NET
+ cyg_interrupt fcc_eth_interrupt;
+ cyg_handle_t fcc_eth_interrupt_handle;
+#endif
+};
+
+// CPM_CPCR masks
+#define CPCR_GRSTOP_TX 0x00000005
+#define CPCR_MCN_FCC 0x00000300
+#define CPCR_READY_TO_RX_CMD 0 /* Ready to receive a command */
diff --git a/ecos/packages/devs/eth/powerpc/fcc/current/src/if_fcc.c b/ecos/packages/devs/eth/powerpc/fcc/current/src/if_fcc.c
new file mode 100644
index 0000000..26caa79
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/fcc/current/src/if_fcc.c
@@ -0,0 +1,670 @@
+//==========================================================================
+//
+// dev/if_fcc.c
+//
+// Fast ethernet device driver for PowerPC MPC8xxx (QUICC-II) boards
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: mtek, pfine
+// Date: 2003-08-19
+// Purpose:
+// Description: hardware driver for MPC8xxx FCC
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_eth_powerpc_fcc.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/mpc8xxx.h>
+
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#endif
+
+#ifdef CYGPKG_DEVS_ETH_PHY
+#include <cyg/io/eth_phy.h>
+#endif
+
+#include "fcc.h"
+
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+#endif
+#endif
+
+#ifdef CYGDAT_DEVS_FCC_ETH_INL
+#include CYGDAT_DEVS_FCC_ETH_CDL // platform configury
+#include CYGDAT_DEVS_FCC_ETH_INL // platform details
+#else
+#error "No board instance defined!"
+#endif
+
+#define ALIGN_TO_CACHE_LINES(x) ( (long)((x) + 31) & 0xffffffe0 )
+
+// Buffer descriptors are in dual ported RAM, which is marked non-cached
+#define FCC_BDs_NONCACHED
+
+#define os_printf diag_printf
+
+// CONFIG_ESA and CONFIG_BOOL are defined in redboot/include/flash_config.h
+#ifndef CONFIG_ESA
+#define CONFIG_ESA 6 // ethernet address length ...
+#endif
+
+#ifndef CONFIG_BOOL
+#define CONFIG_BOOL 1
+#endif
+
+static void fcc_eth_int(struct eth_drv_sc *data);
+
+// This ISR is called when the ethernet interrupt occurs
+#ifdef CYGPKG_NET
+static int
+fcc_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+
+ cyg_drv_interrupt_mask(qi->int_vector);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+#endif
+
+// Deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+fcc_eth_deliver(struct eth_drv_sc * sc)
+{
+#ifdef CYGPKG_NET
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+#endif
+
+ fcc_eth_int(sc);
+#ifdef CYGPKG_NET
+ // Clearing the event register acknowledges FCC interrupt ...
+ cyg_drv_interrupt_unmask(qi->int_vector);
+#endif
+
+}
+
+
+// Initialize the interface - performed at system startup
+// This function must set up the interface, including arranging to
+// handle interrupts, etc, so that it may be "started" cheaply later.
+static bool
+fcc_eth_init(struct cyg_netdevtab_entry *dtp)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)dtp->device_instance;
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+ volatile t_Fcc_Pram *fcc = (volatile t_Fcc_Pram *)0;
+ volatile t_EnetFcc_Pram *E_fcc;
+ int i, fcc_chan;
+ bool esa_ok;
+ unsigned char *c_ptr;
+ unsigned char _enaddr[6];
+ unsigned long rxbase, txbase;
+ struct fcc_bd *rxbd, *txbd;
+ // The FCC seems rather picky about these...
+ static long rxbd_base = 0x3000;
+ static long txbd_base = 0xB000;
+#ifdef CYGPKG_DEVS_ETH_PHY
+ unsigned short phy_state = 0;
+#endif
+
+ // Set up pointers to FCC controller
+ switch (qi->int_vector) {
+ case CYGNUM_HAL_INTERRUPT_FCC1:
+ qi->fcc_reg = &(IMM->fcc_regs[FCC1]);
+ fcc = (volatile t_Fcc_Pram *)((unsigned long)IMM + FCC1_PRAM_OFFSET);
+ fcc_chan = FCC1_PAGE_SUBBLOCK;
+ break;
+ case CYGNUM_HAL_INTERRUPT_FCC2:
+ qi->fcc_reg = &(IMM->fcc_regs[FCC2]);
+ fcc = (volatile t_Fcc_Pram *)((unsigned long)IMM + FCC2_PRAM_OFFSET);
+ fcc_chan = FCC2_PAGE_SUBBLOCK;
+ break;
+ case CYGNUM_HAL_INTERRUPT_FCC3:
+ qi->fcc_reg = &(IMM->fcc_regs[FCC3]);
+ fcc = (volatile t_Fcc_Pram *)((unsigned long)IMM + FCC3_PRAM_OFFSET);
+ fcc_chan = FCC3_PAGE_SUBBLOCK;
+ break;
+ default:
+ os_printf("Can't initialize '%s' - unknown FCC!\n", dtp->name);
+ return false;
+ }
+
+ // just in case : disable Transmit and Receive
+ qi->fcc_reg->fcc_gfmr &= ~(FCC_GFMR_EN_Rx | FCC_GFMR_EN_Tx);
+
+ // Try to read the ethernet address of the transciever ...
+#ifdef CYGPKG_REDBOOT
+ esa_ok = flash_get_config(qi->esa_key, _enaddr, CONFIG_ESA);
+#else
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ qi->esa_key, _enaddr, CONFIG_ESA);
+#endif
+ if (esa_ok) {
+ memcpy(qi->enaddr, _enaddr, sizeof(qi->enaddr));
+ } else {
+ // No 'flash config' data available - use default
+ os_printf("FCC_ETH - Warning! Using default ESA for '%s'\n", dtp->name);
+ }
+
+ // Initialize Receive Buffer Descriptors
+ rxbase = rxbd_base;
+ fcc->riptr = rxbase; // temp work buffer
+ fcc->mrblr = FCC_PRAM_MRBLR; // Max Rx buffer
+ fcc->rstate &= FCC_FCR_INIT;
+ fcc->rstate |= FCC_FCR_MOT_BO;
+ rxbase += 64;
+ rxbd_base += sizeof(struct fcc_bd)*qi->rxnum + 64;
+ rxbd = (struct fcc_bd *)(CYGARC_IMM_BASE + rxbase);
+ fcc->rbase = (CYG_WORD)rxbd;
+ c_ptr = qi->rxbuf;
+ qi->rbase = rxbd;
+ qi->rxbd = rxbd;
+ qi->rnext = rxbd;
+
+ for (i = 0; i < qi->rxnum; i++, rxbd++) {
+ rxbd->ctrl = (FCC_BD_Rx_Empty | FCC_BD_Rx_Int);
+ rxbd->length = 0; // reset
+ c_ptr = (unsigned char *) ALIGN_TO_CACHE_LINES(c_ptr);
+ rxbd->buffer = (volatile unsigned char *)c_ptr;
+ c_ptr += CYGNUM_DEVS_ETH_POWERPC_FCC_BUFSIZE;
+ }
+ rxbd--;
+ rxbd->ctrl |= FCC_BD_Rx_Wrap;
+
+ // Initialize Transmit Buffer Descriptors
+ txbase = txbd_base;
+ fcc->tiptr = txbase; // in dual port RAM (see 28-11)
+ fcc->tstate &= FCC_FCR_INIT;
+ fcc->tstate |= FCC_FCR_MOT_BO;
+ txbase += 64;
+ txbd_base += sizeof(struct fcc_bd)*qi->txnum + 64;
+ txbd = (struct fcc_bd *)(CYGARC_IMM_BASE + txbase);
+ fcc->tbase = (CYG_WORD)txbd;
+ c_ptr = qi->txbuf;
+ qi->tbase = txbd;
+ qi->txbd = txbd;
+ qi->tnext = txbd;
+
+ for (i = 0; i < qi->txnum; i++, txbd++) {
+ txbd->ctrl = (FCC_BD_Tx_Pad | FCC_BD_Tx_Int);
+ txbd->length = 0; // reset : Write before send
+ c_ptr = (unsigned char *) ALIGN_TO_CACHE_LINES(c_ptr);
+ txbd->buffer = (volatile unsigned char *)c_ptr;
+ c_ptr += CYGNUM_DEVS_ETH_POWERPC_FCC_BUFSIZE;
+ }
+ txbd--;
+ txbd->ctrl |= FCC_BD_Tx_Wrap;
+
+ // Ethernet Specific FCC Parameter RAM Initialization
+ E_fcc = &(fcc->SpecificProtocol.e);
+ E_fcc->c_mask = FCC_PRAM_C_MASK; // (see 30-9)
+ E_fcc->c_pres = FCC_PRAM_C_PRES;
+ E_fcc->crcec = 0;
+ E_fcc->alec = 0;
+ E_fcc->disfc = 0;
+ E_fcc->ret_lim = FCC_PRAM_RETLIM;
+ E_fcc->p_per = FCC_PRAM_PER_LO;
+ E_fcc->gaddr_h = 0;
+ E_fcc->gaddr_l = 0;
+ E_fcc->tfcstat = 0;
+ E_fcc->mflr = FCC_MAX_FLR;
+
+ E_fcc->paddr1_h = ((short)qi->enaddr[5] << 8) | qi->enaddr[4];
+ E_fcc->paddr1_m = ((short)qi->enaddr[3] << 8) | qi->enaddr[2];
+ E_fcc->paddr1_l = ((short)qi->enaddr[1] << 8) | qi->enaddr[0];
+
+ E_fcc->iaddr_h = 0;
+ E_fcc->iaddr_l = 0;
+ E_fcc->minflr = FCC_MIN_FLR;
+ E_fcc->taddr_h = 0;
+ E_fcc->taddr_m = 0;
+ E_fcc->taddr_l = 0;
+ E_fcc->pad_ptr = fcc->tiptr; // No special padding char ...
+ E_fcc->cf_type = 0;
+ E_fcc->maxd1 = FCC_PRAM_MAXD;
+ E_fcc->maxd2 = FCC_PRAM_MAXD;
+
+ // FCC register initialization
+ qi->fcc_reg->fcc_gfmr = FCC_GFMR_INIT;
+ qi->fcc_reg->fcc_psmr = FCC_PSMR_INIT;
+ qi->fcc_reg->fcc_dsr = FCC_DSR_INIT;
+
+#ifdef CYGPKG_NET
+ // clear the events of FCCX
+ qi->fcc_reg->fcc_fcce = 0xFFFF;
+ qi->fcc_reg->fcc_fccm = FCC_EV_TXE | FCC_EV_TXB | FCC_EV_RXF;
+
+ // Set up to handle interrupts
+ cyg_drv_interrupt_create(qi->int_vector,
+ 0, // Highest //CYGARC_SIU_PRIORITY_HIGH,
+ (cyg_addrword_t)sc, // Data passed to ISR
+ (cyg_ISR_t *)fcc_eth_isr,
+ (cyg_DSR_t *)eth_drv_dsr,
+ &qi->fcc_eth_interrupt_handle,
+ &qi->fcc_eth_interrupt);
+ cyg_drv_interrupt_attach(qi->fcc_eth_interrupt_handle);
+ cyg_drv_interrupt_acknowledge(qi->int_vector);
+ cyg_drv_interrupt_unmask(qi->int_vector);
+#else
+
+ // Mask the interrupts
+ qi->fcc_reg->fcc_fccm = 0;
+#endif
+
+ // Issue Init RX & TX Parameters Command for FCCx
+ while ((IMM->cpm_cpcr & CPCR_FLG) != CPCR_READY_TO_RX_CMD);
+ IMM->cpm_cpcr = CPCR_INIT_TX_RX_PARAMS |
+ fcc_chan |
+ CPCR_MCN_FCC |
+ CPCR_FLG; /* ISSUE COMMAND */
+ while ((IMM->cpm_cpcr & CPCR_FLG) != CPCR_READY_TO_RX_CMD);
+
+ // Operating mode
+ if (!_eth_phy_init(qi->phy)) {
+ return false;
+ }
+#ifdef CYGSEM_DEVS_ETH_POWERPC_FCC_RESET_PHY
+ _eth_phy_reset(qi->phy);
+#endif
+ phy_state = _eth_phy_state(qi->phy);
+ os_printf("FCC %s: ", sc->dev_name);
+ if ((phy_state & ETH_PHY_STAT_LINK) != 0) {
+ if ((phy_state & ETH_PHY_STAT_100MB) != 0) {
+ // Link can handle 100Mb
+ os_printf("100Mb");
+ if ((phy_state & ETH_PHY_STAT_FDX) != 0) {
+ os_printf("/Full Duplex");
+ }
+ } else {
+ // Assume 10Mb, half duplex
+ os_printf("10Mb");
+ }
+ } else {
+ os_printf("/***NO LINK***\n");
+#ifdef CYGPKG_REDBOOT
+ return false;
+#endif
+ }
+ os_printf("\n");
+
+
+ // Initialize upper level driver for ecos
+ (sc->funs->eth_drv->init)(sc, (unsigned char *)&qi->enaddr);
+
+ return true;
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+fcc_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+
+ // Enable the device :
+ // Set the ENT/ENR bits in the GFMR -- Enable Transmit/Receive
+ qi->fcc_reg->fcc_gfmr |= (FCC_GFMR_EN_Rx | FCC_GFMR_EN_Tx);
+
+}
+
+//
+// This function is called to shut down the interface.
+//
+static void
+fcc_eth_stop(struct eth_drv_sc *sc)
+{
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+
+ // Disable the device :
+ // Clear the ENT/ENR bits in the GFMR -- Disable Transmit/Receive
+ qi->fcc_reg->fcc_gfmr &= ~(FCC_GFMR_EN_Rx | FCC_GFMR_EN_Tx);
+}
+
+
+//
+// This function is called for low level "control" operations
+//
+static int
+fcc_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int length)
+{
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ return 0;
+ break;
+ default:
+ return 1;
+ break;
+ }
+}
+
+
+//
+// This function is called to see if another packet can be sent.
+// It should return the number of packets which can be handled.
+// Zero should be returned if the interface is busy and can not send any more.
+//
+static int
+fcc_eth_can_send(struct eth_drv_sc *sc)
+{
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+ volatile struct fcc_bd *txbd = qi->txbd;
+#ifndef FCC_BDs_NONCACHED
+ int cache_state;
+#endif
+
+#ifndef FCC_BDs_NONCACHED
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(fcc_eth_txring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM);
+ }
+#endif
+
+ return ((txbd->ctrl & (FCC_BD_Tx_TC | FCC_BD_Tx_Ready)) == 0);
+}
+
+//
+// This routine is called to send data to the hardware.
+static void
+fcc_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+ struct fcc_bd *txbd, *txfirst;
+ volatile char *bp;
+ int i, txindex;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+#ifndef FCC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(fcc_eth_txring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM);
+ }
+#endif
+
+ // Find a free buffer
+ txbd = txfirst = qi->txbd;
+ while (txbd->ctrl & FCC_BD_Tx_Ready) {
+ // This buffer is busy, move to next one
+ if (txbd->ctrl & FCC_BD_Tx_Wrap) {
+ txbd = qi->tbase;
+ } else {
+ txbd++;
+ }
+ if (txbd == txfirst) {
+#ifdef CYGPKG_NET
+ panic ("No free xmit buffers");
+#else
+ os_printf("FCC Ethernet: No free xmit buffers\n");
+#endif
+ }
+ }
+
+ // Remember the next buffer to try
+ if (txbd->ctrl & FCC_BD_Tx_Wrap) {
+ qi->txbd = qi->tbase;
+ } else {
+ qi->txbd = txbd+1;
+ }
+
+ txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
+ qi->txkey[txindex] = key;
+
+ // Set up buffer
+ txbd->length = total_len;
+ bp = txbd->buffer;
+ for (i = 0; i < sg_len; i++) {
+ memcpy((void *)bp, (void *)sg_list[i].buf, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+
+ // Make sure no stale data buffer ...
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(txbd->buffer, txbd->length);
+ }
+
+ // Send it on it's way
+ txbd->ctrl |= FCC_BD_Tx_Ready | FCC_BD_Tx_Last | FCC_BD_Tx_TC;
+
+#ifndef FCC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(fcc_eth_txring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM);
+ }
+#endif
+
+}
+
+//
+// This function is called when a packet has been received. It's job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'fcc_eth_recv' will be called to actually fetch it from the hardware.
+//
+static void
+fcc_eth_RxEvent(struct eth_drv_sc *sc)
+{
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+ struct fcc_bd *rxbd;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+#ifndef FCC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(fcc_eth_rxring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_FCC_RxNUM);
+ }
+#endif
+
+ rxbd = qi->rnext;
+ while ((rxbd->ctrl & FCC_BD_Rx_Empty) == 0) {
+ qi->rxbd = rxbd; // Save for callback
+
+ // This is the right way of doing it, but dcbi has a bug ...
+ // if (cache_state) {
+ // HAL_DCACHE_INVALIDATE(rxbd->buffer, rxbd->length);
+ // }
+ if ((rxbd->ctrl & FCC_BD_Rx_ERRORS) == 0) {
+ (sc->funs->eth_drv->recv)(sc, rxbd->length);
+#if 1 // Coherent caches?
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(rxbd->buffer, rxbd->length);
+ }
+#endif
+ }
+ // Reset control flags to known [empty] state, clearing error bits
+ if (rxbd->ctrl & FCC_BD_Rx_Wrap) {
+ rxbd->ctrl = FCC_BD_Rx_Empty | FCC_BD_Rx_Int | FCC_BD_Rx_Wrap;
+ rxbd = qi->rbase;
+ } else {
+ rxbd->ctrl = FCC_BD_Rx_Empty | FCC_BD_Rx_Int;
+ rxbd++;
+ }
+ }
+ // Remember where we left off
+ qi->rnext = (struct fcc_bd *)rxbd;
+
+ // Make sure no stale data
+#ifndef FCC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(fcc_eth_rxring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_FCC_RxNUM);
+ }
+#endif
+
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// It's job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+fcc_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+ unsigned char *bp;
+ int i;
+
+ bp = (unsigned char *)qi->rxbd->buffer;
+
+ for (i = 0; i < sg_len; i++) {
+ if (sg_list[i].buf != 0) {
+ memcpy((void *)sg_list[i].buf, bp, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+ }
+
+}
+
+static void
+fcc_eth_TxEvent(struct eth_drv_sc *sc, int stat)
+{
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+ struct fcc_bd *txbd;
+ int txindex;
+#ifndef FCC_BDs_NONCACHED
+ int cache_state;
+#endif
+
+#ifndef FCC_BDs_NONCACHED
+ // Make sure no stale data
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(fcc_eth_txring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM);
+ }
+#endif
+
+ txbd = qi->tnext;
+ // Note: TC field is used to indicate the buffer has/had data in it
+ while ( (txbd->ctrl & (FCC_BD_Tx_TC | FCC_BD_Tx_Ready)) == FCC_BD_Tx_TC ) {
+ if ((txbd->ctrl & FCC_BD_Tx_ERRORS) != 0) {
+#if 0
+ diag_printf("FCC Tx error BD: %x/%x- ", txbd, txbd->ctrl);
+ if ((txbd->ctrl & FCC_BD_Tx_LC) != 0) diag_printf("Late Collision/");
+ if ((txbd->ctrl & FCC_BD_Tx_RL) != 0) diag_printf("Retry limit/");
+// if ((txbd->ctrl & FCC_BD_Tx_RC) != 0) diag_printf("Late Collision/");
+ if ((txbd->ctrl & FCC_BD_Tx_UN) != 0) diag_printf("Underrun/");
+ if ((txbd->ctrl & FCC_BD_Tx_CSL) != 0) diag_printf("Carrier Lost/");
+ diag_printf("\n");
+#endif
+ }
+
+ txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
+ (sc->funs->eth_drv->tx_done)(sc, qi->txkey[txindex], 0);
+ txbd->ctrl &= ~FCC_BD_Tx_TC;
+ if (txbd->ctrl & FCC_BD_Tx_Wrap) {
+ txbd = qi->tbase;
+ } else {
+ txbd++;
+ }
+ }
+ // Remember where we left off
+ qi->tnext = (struct fcc_bd *)txbd;
+
+ // Make sure no stale data
+#ifndef FCC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(fcc_eth_txring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM);
+ }
+#endif
+
+}
+
+//
+// Interrupt processing
+//
+static void
+fcc_eth_int(struct eth_drv_sc *sc)
+{
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+ unsigned short iEvent;
+
+ while ((iEvent = qi->fcc_reg->fcc_fcce) != 0){
+ // Clear pending interrupts (writing 1's to this register)
+ qi->fcc_reg->fcc_fcce = iEvent;
+ // Tx Done or Tx Error
+ if ( iEvent & (FCC_EV_TXB | FCC_EV_TXE) ) {
+ fcc_eth_TxEvent(sc, iEvent);
+ }
+ // Complete or non-complete frame receive
+ if (iEvent & (FCC_EV_RXF | FCC_EV_RXB) ) {
+ fcc_eth_RxEvent(sc);
+ }
+ }
+}
+
+//
+// Interrupt vector
+//
+static int
+fcc_eth_int_vector(struct eth_drv_sc *sc)
+{
+ struct fcc_eth_info *qi = (struct fcc_eth_info *)sc->driver_private;
+ return (qi->int_vector);
+}
+
diff --git a/ecos/packages/devs/eth/powerpc/fec/current/ChangeLog b/ecos/packages/devs/eth/powerpc/fec/current/ChangeLog
new file mode 100644
index 0000000..d253bed
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/fec/current/ChangeLog
@@ -0,0 +1,212 @@
+2005-06-22 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fec.c (fec_eth_int): Avoid race when handling interrupt
+ events - reported by Fernando Flores
+
+2004-10-11 Harald Kuethe <hkuethe@controlware.de>
+
+ * src/if_fec.c (fec_eth_RxEvent): remove crc from packet.
+
+2003-12-21 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fec.c (fec_eth_RxEvent): Clean up some unused variables.
+
+2003-10-06 Gary Thomas <gary@mlbassoc.com>
+
+ * cdl/fec_eth_drivers.cdl: Disable STATUS_LEDS by default since these
+ are mostly useful for debugging and get in the way of "normal" LED use.
+
+2003-05-14 Gary Thomas <gary@mlbassoc.com>
+
+ * cdl/fec_eth_drivers.cdl: Only force serial console for eCos
+ configurations (using actual network package).
+
+2003-05-04 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fec.c:
+ * cdl/fec_eth_drivers.cdl: Add control over use of LED display, since
+ it may interfere with some user programs. Also, debug I/O during
+ network intialization seems frail, so force it to be disabled.
+
+2003-03-28 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fec.c: Use new CPM/DPRAM buffer allocation scheme. Also,
+ better handling when aligning buffers to cache lines.
+
+2003-01-20 Gary Thomas <gary@mlbassoc.com>
+
+ * cdl/fec_eth_drivers.cdl: Increase number of allowed buffers.
+
+2002-11-14 Gary Thomas <gthomas@ecoscentric.com>
+
+ * cdl/fec_eth_drivers.cdl: Increase default number of buffers (to a
+ more reasonable amount).
+
+2002-10-18 Gary Thomas <gthomas@ecoscentric.com>
+
+ * src/if_fec.c: Reduce warnings when PHY code is not used.
+
+2002-10-11 Gary Thomas <gthomas@ecoscentric.com> [inspired by]
+2002-10-11 Wolfgang Heppner <hep@iis.fhg.de>
+
+ * src/if_fec.c:
+ * cdl/fec_eth_drivers.cdl: Make buffer descriptor use configurable.
+ Also, fix some issues where cache state wasn't being honored.
+
+2002-10-11 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fec.c:
+ * cdl/fec_eth_drivers.cdl: Add control over PHY - when to reset
+ and how to configure the link.
+
+2002-09-19 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fec.c (fec_eth_init): Check for availability of RedBoot
+ FLASH support.
+
+2002-09-03 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_fec.c: Make driver more generic - platform specifics are
+ now contained in an include file CYGDAT_DEVS_FEC_ETH_INL.
+
+2002-08-15 Gary Thomas <gthomas@ecoscentric.com>
+
+ * src/if_fec.c (fec_eth_send):
+ Clean up: remove unused variable _fec_eth_tx_count.
+
+2002-08-08 Gary Thomas <gthomas@ecoscentric.com>
+
+ * src/if_fec.c (fec_eth_RxEvent): Cache needs to be invalidated
+ to avoid any possible corruption.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_fec.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-05-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_fec.c: Use CYGINT_IO_ETH_INT_SUPPORT_REQUIRED where
+ appropriate.
+
+2002-05-30 Jesper Skov <jskov@redhat.com>
+
+ * src/if_fec.c: Initialized a variable and removed an unused
+ variable. Also made one volatile. All to remove warnings.
+ * src/fec.h: Made more pointers volatile to avoid compiler
+ warnings.
+
+2002-04-30 Nick Garnett <nickg@redhat.com>
+
+ * src/if_fec.c: Changed order of initialization and made code more
+ robust against hangups. Changed initialization of ESA from memcpy
+ to 32 bit assignments, since 855 seems fussy about this where 860
+ is not.
+
+2002-04-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_fec.c (fec_eth_control): Fix compile error (multicast).
+
+2002-04-19 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/fec_eth_drivers.cdl: Add [minimal] multicast support.
+
+ * src/if_fec.c: Cleaned out debug code.
+
+2002-04-18 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_fec.c: Finally working! Problem was that resetting the
+ interface is much more involved than simply set/reset the "enable".
+
+2002-04-17 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_fec.c:
+ * src/fec.h: Add code to poll PHY for link status on startup.
+ Still trying to get reliable results in general operation.
+
+2002-04-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/fec.h:
+ * src/if_fec.c: Lots of tinkering since this driver is somewhat
+ unreliable with the generic eCos stack (the RedBoot code seems
+ to work oddly enough).
+
+2002-02-19 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_fec.c (fec_eth_init): Args were backwards(!) getting
+ processor revision.
+
+2001-08-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_fec.c:
+ printf() is no longer a part of RedBoot. Thus all programs
+ must use diag_printf() and related functions instead.
+
+2001-06-26 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_fec.c (fec_eth_init): Use correct version register.
+
+2001-05-07 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_fec.c (fec_eth_init): Use RedBoot/fconfig data for ethernet
+ station address (ESA).
+
+2001-05-04 Gary Thomas <gthomas@redhat.com>
+
+ * src/fec.h (iEvent_all):
+ * src/if_fec.c (fec_eth_init): Enable interrupts.
+
+2001-05-01 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_fec.c (fec_eth_init): Force buffers to 32 byte boundary.
+
+2001-02-21 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_fec.c: Finally working! Lots of little changes
+ to get the setup just right.
+ (fec_eth_init): Need to set Tx high water mark high for proper
+ operation when code is run from FLASH. Also misc cleanups, removing
+ old debug code, etc.
+ (fec_eth_recv):
+ (fec_eth_TxEvent):
+ (fec_eth_RxEvent):
+ (fec_eth_send): Need to flush data cache - not snooped?
+
+ * src/fec.h: Add new defines for rev D of chip.
+
+ * cdl/fec_eth_drivers.cdl: Remove CDL for chip revision,
+ now handled automatically by driver.
+
+2001-01-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/fec.h:
+ * src/if_fec.c:
+ * cdl/fec_eth_drivers.cdl: New package/file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/fec/current/cdl/fec_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/fec/current/cdl/fec_eth_drivers.cdl
new file mode 100644
index 0000000..b52d939
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/fec/current/cdl/fec_eth_drivers.cdl
@@ -0,0 +1,155 @@
+# ====================================================================
+#
+# fec_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for PowerPC MPC8xx
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2001-01-21
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_FEC {
+ display "MPC8xx FEC ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_MPC8xx
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_IO_ETH_MULTICAST
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+
+ # Debug I/O during network stack initialization is not reliable
+ requires { !CYGPKG_NET || CYGPKG_NET_FORCE_SERIAL_CONSOLE == 1 }
+
+ description "Fast ethernet driver for PowerPC MPC8xxT boards."
+ compile -library=libextras.a if_fec.c
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_FEC_BD_OFFSET {
+ display "Buffer descriptors offset in PRAM"
+ flavor data
+ default_value 0x2C00
+ description "
+ This option specifies the address of the buffer descriptors
+ used by the PowerPC FEC/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE {
+ display "Buffer size"
+ flavor data
+ default_value 1520
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC FEC/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM {
+ display "Number of output buffers"
+ flavor data
+ legal_values 2 to 64
+ default_value 16
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC FEC/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM {
+ display "Number of input buffers"
+ flavor data
+ legal_values 2 to 64
+ default_value 16
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC FEC/ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY {
+ display "Reset and reconfigure PHY"
+ flavor bool
+ default_value { CYG_HAL_STARTUP != "RAM" }
+ description "
+ This option allows control over the physical transceiver"
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_FEC_LINK_MODE {
+ display "Initial link mode"
+ flavor data
+ legal_values { "10Mb" "100Mb" "Auto" }
+ default_value { "Auto" }
+ description "
+ This option specifies initial mode for the physical
+ link. The PHY will be reset and then set to this mode."
+ }
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_POWERPC_FEC_STATUS_LEDS {
+ display "Display I/O status via LEDs"
+ flavor bool
+ default_value 0
+ description "
+ If this option is set, and the platform defines LED access
+ functions, then I/O status will be displayed using the LEDs.
+ In particular, varying LEDs will be illuminated while the
+ device is busy transmitting a buffer, or handing an input
+ packet."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_POWERPC_FEC_OPTIONS {
+ display "MPC8xx FEC ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_POWERPC_FEC_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the MPC8xx FEC ethernet driver package. These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/fec/current/src/fec.h b/ecos/packages/devs/eth/powerpc/fec/current/src/fec.h
new file mode 100644
index 0000000..dd5826a
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/fec/current/src/fec.h
@@ -0,0 +1,188 @@
+//==========================================================================
+//
+// fec.h
+//
+// PowerPC MPC8xxT fast ethernet (FEC)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2001-01-21
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// PowerPC FEC (MPC8xxT) Fast Ethernet
+
+// Buffer descriptor
+struct fec_bd {
+ unsigned short ctrl;
+ unsigned short length;
+ unsigned char *buffer;
+};
+
+// control flags differ for Rx and Tx buffers
+#define FEC_BD_Rx_Empty 0x8000 // Buffer is empty [FEC can fill it]
+#define FEC_BD_Rx_Wrap 0x2000 // Last buffer in ring [wrap]
+#define FEC_BD_Rx_Last 0x0800 // Last buffer in frame
+#define FEC_BD_Rx_Miss 0x0100 //
+#define FEC_BD_Rx_BC 0x0080
+#define FEC_BD_Rx_MC 0x0040
+#define FEC_BD_Rx_LG 0x0020
+#define FEC_BD_Rx_NO 0x0010
+#define FEC_BD_Rx_SH 0x0008 // Short frame
+#define FEC_BD_Rx_CR 0x0004 // CRC error
+#define FEC_BD_Rx_OV 0x0002 // Overrun
+#define FEC_BD_Rx_TR 0x0001 // Frame truncated
+
+#define FEC_BD_Tx_Ready 0x8000 // Frame ready
+#define FEC_BD_Tx_Wrap 0x2000 // Last buffer in ring
+#define FEC_BD_Tx_Intr 0x1000 // Generate interrupt
+#define FEC_BD_Tx_Last 0x0800 // Last buffer in frame
+#define FEC_BD_Tx_TC 0x0400 // Send CRC after data
+#define FEC_BD_Tx_DEF 0x0200
+#define FEC_BD_Tx_HB 0x0100
+#define FEC_BD_Tx_LC 0x0080
+#define FEC_BD_Tx_RL 0x0040
+#define FEC_BD_Tx_RC 0x003C
+#define FEC_BD_Tx_UN 0x0002 // Underrun
+#define FEC_BD_Tx_CSL 0x0001 // Carrier sense lost
+
+#define FEC_BD_Tx_STATS 0x03FF // Status mask
+
+struct fec_eth_info {
+ volatile struct fec *fec;
+ volatile struct fec_bd *txbd, *rxbd; // Next Tx,Rx descriptor to use
+ volatile struct fec_bd *tbase, *rbase; // First Tx,Rx descriptor
+ volatile struct fec_bd *tnext, *rnext; // Next descriptor to check for interrupt
+ int txsize, rxsize; // Length of individual buffers
+ int txactive; // Count of active Tx buffers
+ unsigned long txkey[CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM];
+};
+
+// Fast Ethernet Controller [in PPC8xxT parameter RAM space]
+
+struct fec {
+ unsigned long addr[2]; // ESA
+ unsigned long hash[2]; // Address hash mask
+ volatile struct fec_bd *RxRing;
+ volatile struct fec_bd *TxRing;
+ unsigned long RxBufSize;
+ unsigned char _fill0[0x40-0x1C];
+ unsigned long eControl; // Master control register
+ unsigned long iEvent; // Interrupt event
+ unsigned long iMask; // Interrupt mask
+ unsigned long iVector; // Interrupt vector
+ unsigned long RxUpdate; // RxRing updated
+ unsigned long TxUpdate; // TxRing updated
+ unsigned char _fill1[0x80-0x58];
+ unsigned long MiiData;
+ unsigned long MiiSpeed;
+ unsigned char _fill2[0xCC-0x88];
+ unsigned long RxBound; // End of FIFO RAM
+ unsigned long RxStart; // Start of FIFO RAM
+ unsigned char _fill3[0xE4-0xD4];
+ unsigned long TxWater; // Transmit watermark
+ unsigned char _fill4[0xEC-0xE8];
+ unsigned long TxStart; // Start of Tx FIFO
+ unsigned char _fill5[0x134-0xF0];
+ unsigned long FunCode; // DMA function codes
+ unsigned char _fill6[0x144-0x138];
+ unsigned long RxControl; // Receiver control
+ unsigned long RxHash; // Receive hash
+ unsigned char _fill7[0x184-0x14C];
+ unsigned long TxControl; // Transmitter control
+};
+
+#define FEC_OFFSET 0x0E00 // Offset in 8xx parameter RAM
+
+// Master control register (eControl)
+#define eControl_MUX 0x0004 // Select proper pin MUX functions
+#define eControl_EN 0x0002 // Enable ethernet controller
+#define eControl_RESET 0x0001 // Reset controller
+
+// Receiver control register (RxControl)
+#define RxControl_BC_REJ 0x0010 // Reject broadcast frames
+#define RxControl_PROM 0x0008 // Promiscuous mode
+#define RxControl_MII 0x0004 // MII (1) or 7 wire (0) mode
+#define RxControl_DRT 0x0002 // Disable receive on transmit
+#define RxControl_LOOP 0x0001 // Internal loopback
+
+// Interrupt events
+#define iEvent_HBERR 0x80000000 // No heartbeat error
+#define iEvent_BABR 0x40000000 // Babling receiver
+#define iEvent_BABT 0x20000000 // Babling transmitter
+#define iEvent_GRA 0x10000000 // Graceful shutdown
+#define iEvent_TFINT 0x08000000 // Transmit frame interrupt
+#define iEvent_TXB 0x04000000 // Transmit buffer
+#define iEvent_RFINT 0x02000000 // Receive frame
+#define iEvent_RXB 0x01000000 // Receive buffer
+#define iEvent_MII 0x00800000 // MII complete
+#define iEvent_EBERR 0x00400000 // Ethernet BUS error
+#define iEvent_all 0xFFC00000 // Any interrupt
+
+// MII interface
+#define MII_Start 0x40000000
+#define MII_Read 0x20000000
+#define MII_Write 0x10000000
+#define MII_Phy(phy) (phy << 23)
+#define MII_Reg(reg) (reg << 18)
+#define MII_TA 0x00020000
+
+// Transceiver mode
+#define PHY_BMCR 0x00 // Register number
+#define PHY_BMCR_RESET 0x8000
+#define PHY_BMCR_LOOPBACK 0x4000
+#define PHY_BMCR_100MB 0x2000
+#define PHY_BMCR_AUTO_NEG 0x1000
+#define PHY_BMCR_POWER_DOWN 0x0800
+#define PHY_BMCR_ISOLATE 0x0400
+#define PHY_BMCR_RESTART 0x0200
+#define PHY_BMCR_FULL_DUPLEX 0x0100
+#define PHY_BMCR_COLL_TEST 0x0080
+
+#define PHY_BMSR 0x01 // Status register
+#define PHY_BMSR_AUTO_NEG 0x0020
+#define PHY_BMSR_LINK 0x0004
+
+#define IEEE_8023_MAX_FRAME 1518 // Largest possible ethernet frame
+#define IEEE_8023_MIN_FRAME 60 // Smallest possible ethernet frame
+
diff --git a/ecos/packages/devs/eth/powerpc/fec/current/src/if_fec.c b/ecos/packages/devs/eth/powerpc/fec/current/src/if_fec.c
new file mode 100644
index 0000000..c30412b
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/fec/current/src/if_fec.c
@@ -0,0 +1,797 @@
+//==========================================================================
+//
+// dev/if_fec.c
+//
+// Fast ethernet device driver for PowerPC MPC8xxT boards
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2001-01-21
+// Purpose:
+// Description: hardware driver for MPC8xxT FEC
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// Ethernet device driver for MPC8xx FEC
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_powerpc_fec.h>
+#include <pkgconf/io_eth_drivers.h>
+#include CYGDAT_DEVS_FEC_ETH_INL
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#endif
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/ppc_regs.h>
+
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#include "fec.h"
+
+// Align buffers on a cache boundary
+#define RxBUFSIZE CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM*CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE
+#define TxBUFSIZE CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM*CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE
+static unsigned char fec_eth_rxbufs[RxBUFSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char fec_eth_txbufs[TxBUFSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+static struct fec_eth_info fec_eth0_info;
+static unsigned char _default_enaddr[] = { 0x08, 0x00, 0x3E, 0x28, 0x7A, 0xBA};
+static unsigned char enaddr[6];
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+RedBoot_config_option("Network hardware address [MAC]",
+ fec_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif
+#endif
+
+#define os_printf diag_printf
+
+// For fetching the ESA from RedBoot
+#include <cyg/hal/hal_if.h>
+#ifndef CONFIG_ESA
+#define CONFIG_ESA 6
+#endif
+
+ETH_DRV_SC(fec_eth0_sc,
+ &fec_eth0_info, // Driver specific data
+ "eth0", // Name for this interface
+ fec_eth_start,
+ fec_eth_stop,
+ fec_eth_control,
+ fec_eth_can_send,
+ fec_eth_send,
+ fec_eth_recv,
+ fec_eth_deliver,
+ fec_eth_int,
+ fec_eth_int_vector);
+
+NETDEVTAB_ENTRY(fec_netdev,
+ "fec_eth",
+ fec_eth_init,
+ &fec_eth0_sc);
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+#define _FEC_USE_INTS
+#ifdef _FEC_USE_INTS
+static cyg_interrupt fec_eth_interrupt;
+static cyg_handle_t fec_eth_interrupt_handle;
+#else
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
+static char fec_fake_int_stack[STACK_SIZE];
+static cyg_thread fec_fake_int_thread_data;
+static cyg_handle_t fec_fake_int_thread_handle;
+static void fec_fake_int(cyg_addrword_t);
+#endif // _FEC_USE_INTS
+#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static void fec_eth_int(struct eth_drv_sc *data);
+
+#ifndef FEC_ETH_INT
+#error FEC_ETH_INT must be defined
+#endif
+
+#ifndef FEC_ETH_PHY
+#error FEC_ETH_PHY must be defined
+#endif
+
+#ifndef FEC_ETH_RESET_PHY
+#define FEC_ETH_RESET_PHY()
+#endif
+
+#ifndef FEC_EPPC_BD_OFFSET
+#define FEC_EPPC_BD_OFFSET CYGNUM_DEVS_ETH_POWERPC_FEC_BD_OFFSET
+#endif
+
+#ifdef CYGSEM_DEVS_ETH_POWERPC_FEC_STATUS_LEDS
+// LED activity [exclusive of hardware bits]
+#ifndef _get_led
+#define _get_led()
+#define _set_led(v)
+#endif
+#ifndef LED_TxACTIVE
+#define LED_TxACTIVE 7
+#define LED_RxACTIVE 6
+#define LED_IntACTIVE 5
+#endif
+
+static void
+set_led(int bit)
+{
+ _set_led(_get_led() | (1<<bit));
+}
+
+static void
+clear_led(int bit)
+{
+ _set_led(_get_led() & ~(1<<bit));
+}
+#else
+#define set_led(b)
+#define clear_led(b)
+#endif
+
+#ifdef _FEC_USE_INTS
+// This ISR is called when the ethernet interrupt occurs
+static int
+fec_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_drv_interrupt_mask(FEC_ETH_INT);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+#endif
+
+// Deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+fec_eth_deliver(struct eth_drv_sc * sc)
+{
+ fec_eth_int(sc);
+#ifdef _FEC_USE_INTS
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_acknowledge(FEC_ETH_INT);
+ cyg_drv_interrupt_unmask(FEC_ETH_INT);
+#endif
+}
+
+#ifdef CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY
+//
+// PHY unit access (via MII channel)
+//
+static void
+phy_write(int reg, int addr, unsigned short data)
+{
+ volatile EPPC *eppc = (volatile EPPC *)eppc_base();
+ volatile struct fec *fec = (volatile struct fec *)((unsigned char *)eppc + FEC_OFFSET);
+ int timeout = 0x100000;
+
+ fec->iEvent = iEvent_MII;
+ fec->MiiData = MII_Start | MII_Write | MII_Phy(addr) | MII_Reg(reg) | MII_TA | data;
+ while (!(fec->iEvent & iEvent_MII) && (--timeout > 0)) ;
+}
+
+static bool
+phy_read(int reg, int addr, unsigned short *val)
+{
+ volatile EPPC *eppc = (volatile EPPC *)eppc_base();
+ volatile struct fec *fec = (volatile struct fec *)((unsigned char *)eppc + FEC_OFFSET);
+ int timeout = 0x100000;
+
+ fec->iEvent = iEvent_MII;
+ fec->MiiData = MII_Start | MII_Read | MII_Phy(addr) | MII_Reg(reg) | MII_TA;
+ while (!(fec->iEvent & iEvent_MII)) {
+ if (--timeout <= 0) {
+ return false;
+ }
+ }
+ *val = fec->MiiData & 0x0000FFFF;
+ return true;
+}
+#endif // CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY
+
+//
+// [re]Initialize the ethernet controller
+// Done separately since shutting down the device requires a
+// full reconfiguration when re-enabling.
+// when
+static bool
+fec_eth_reset(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ volatile EPPC *eppc = (volatile EPPC *)eppc_base();
+ volatile struct fec *fec = (volatile struct fec *)((unsigned char *)eppc + FEC_OFFSET);
+ volatile struct fec_bd *rxbd, *txbd;
+ unsigned char *RxBUF, *TxBUF;
+ int cache_state, int_state;
+ int i;
+ int TxBD, RxBD;
+
+ // Ignore unless device is idle/stopped
+ if ((qi->fec->eControl & eControl_EN) != 0) {
+ return true;
+ }
+
+ // Make sure interrupts are off while we mess with the device
+ HAL_DISABLE_INTERRUPTS(int_state);
+
+ // Ensure consistent state between cache and what the FEC sees
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ }
+
+ // Shut down ethernet controller, in case it is already running
+ fec->eControl = eControl_RESET;
+ i = 0;
+ while ((fec->eControl & eControl_RESET) != 0) {
+ if (++i >= 500000) {
+ os_printf("FEC Ethernet does not reset\n");
+ if (cache_state)
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(int_state);
+ return false;
+ }
+ }
+
+ fec->iMask = 0x0000000; // Disables all interrupts
+ fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
+ fec->iVector = (1<<29); // Caution - must match FEC_ETH_INT above
+
+ TxBD = _mpc8xx_allocBd(CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM * sizeof(struct cp_bufdesc));
+ RxBD = _mpc8xx_allocBd(CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM * sizeof(struct cp_bufdesc));
+ txbd = (struct fec_bd *)(TxBD + (cyg_uint32)eppc);
+ rxbd = (struct fec_bd *)(RxBD + (cyg_uint32)eppc);
+ qi->tbase = qi->txbd = qi->tnext = txbd;
+ qi->rbase = qi->rxbd = qi->rnext = rxbd;
+ qi->txactive = 0;
+
+ RxBUF = &fec_eth_rxbufs[0];
+ TxBUF = &fec_eth_txbufs[0];
+
+ // setup buffer descriptors
+ for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM; i++) {
+ rxbd->length = 0;
+ rxbd->buffer = RxBUF;
+ rxbd->ctrl = FEC_BD_Rx_Empty;
+ RxBUF += CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE;
+ rxbd++;
+ }
+ rxbd--;
+ rxbd->ctrl |= FEC_BD_Rx_Wrap; // Last buffer
+ for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM; i++) {
+ txbd->length = 0;
+ txbd->buffer = TxBUF;
+ txbd->ctrl = 0;
+ TxBUF += CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE;
+ txbd++;
+ }
+ txbd--;
+ txbd->ctrl |= FEC_BD_Tx_Wrap; // Last buffer
+
+ // Reset interrupts
+ fec->iMask = 0x00000000; // No interrupts enabled
+ fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
+
+ // Initialize shared PRAM
+ fec->RxRing = qi->rbase;
+ fec->TxRing = qi->tbase;
+
+ // Size of receive buffers
+ fec->RxBufSize = CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE;
+
+ // Receiver control
+ fec->RxControl = RxControl_MII | RxControl_DRT;
+// fec->RxControl = RxControl_MII | RxControl_LOOP | RxControl_PROM;
+ fec->RxHash = IEEE_8023_MAX_FRAME; // Largest possible ethernet frame
+
+ // Transmit control
+ fec->TxControl = 4+0;
+
+ // Use largest possible Tx FIFO
+ fec->TxWater = 3;
+
+ // DMA control
+ fec->FunCode = ((2<<29) | (2<<27) | (0<<24));
+
+ // MII speed control (50MHz)
+ fec->MiiSpeed = 0x14;
+
+ // Group address hash
+ fec->hash[0] = 0;
+ fec->hash[1] = 0;
+
+ // Device physical address
+ fec->addr[0] = *(unsigned long *)&enaddr[0];
+ fec->addr[1] = *(unsigned long *)&enaddr[4];
+ // os_printf("FEC ESA = %08x/%08x\n", fec->addr[0], fec->addr[1]);
+
+ // Enable device
+ fec->eControl = eControl_EN | eControl_MUX;
+ fec->RxUpdate = 0x0F0F0F0F; // Any write tells machine to look for work
+
+#ifdef _FEC_USE_INTS
+ // Set up for interrupts
+ fec->iMask = iEvent_TFINT | iEvent_TXB |
+ iEvent_RFINT | iEvent_RXB;
+ fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
+#endif
+
+ if (cache_state)
+ HAL_DCACHE_ENABLE();
+
+ // Set LED state
+ clear_led(LED_TxACTIVE);
+ clear_led(LED_RxACTIVE);
+
+ HAL_RESTORE_INTERRUPTS(int_state);
+ return true;
+}
+
+//
+// Initialize the interface - performed at system startup
+// This function must set up the interface, including arranging to
+// handle interrupts, etc, so that it may be "started" cheaply later.
+//
+static bool
+fec_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ volatile EPPC *eppc = (volatile EPPC *)eppc_base();
+ volatile struct fec *fec = (volatile struct fec *)((unsigned char *)eppc + FEC_OFFSET);
+ int cache_state;
+ unsigned long proc_rev;
+ bool esa_ok;
+#ifdef CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY
+ int phy_timeout = 5*1000; // Wait 5 seconds max for link to clear
+ bool phy_ok;
+ unsigned short phy_state = 0;
+#endif
+
+ // Ensure consistent state between cache and what the FEC sees
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ }
+
+ qi->fec = fec;
+ fec_eth_stop(sc); // Make sure it's not running yet
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+#ifdef _FEC_USE_INTS
+ // Set up to handle interrupts
+ cyg_drv_interrupt_create(FEC_ETH_INT,
+ CYGARC_SIU_PRIORITY_HIGH,
+ (cyg_addrword_t)sc, // Data item passed to interrupt handler
+ (cyg_ISR_t *)fec_eth_isr,
+ (cyg_DSR_t *)eth_drv_dsr,
+ &fec_eth_interrupt_handle,
+ &fec_eth_interrupt);
+ cyg_drv_interrupt_attach(fec_eth_interrupt_handle);
+ cyg_drv_interrupt_acknowledge(FEC_ETH_INT);
+ cyg_drv_interrupt_unmask(FEC_ETH_INT);
+#else // _FEC_USE_INTS
+ // Hack - use a thread to simulate interrupts
+ cyg_thread_create(1, // Priority
+ fec_fake_int, // entry
+ (cyg_addrword_t)sc, // entry parameter
+ "CS8900 int", // Name
+ &fec_fake_int_stack[0], // Stack
+ STACK_SIZE, // Size
+ &fec_fake_int_thread_handle, // Handle
+ &fec_fake_int_thread_data // Thread data structure
+ );
+ cyg_thread_resume(fec_fake_int_thread_handle); // Start it
+#endif
+#endif
+
+ // Set up parallel port for connection to ethernet tranceiver
+ eppc->pio_pdpar = 0x1FFF;
+ CYGARC_MFSPR( CYGARC_REG_PVR, proc_rev );
+#define PROC_REVB 0x0020
+ if ((proc_rev & 0x0000FFFF) == PROC_REVB) {
+ eppc->pio_pddir = 0x1C58;
+ } else {
+ eppc->pio_pddir = 0x1FFF;
+ }
+
+ // Get physical device address
+#ifdef CYGPKG_REDBOOT
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+ esa_ok = flash_get_config("fec_esa", enaddr, CONFIG_ESA);
+#else
+ esa_ok = false;
+#endif
+#else
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "fec_esa", enaddr, CONFIG_ESA);
+#endif
+ if (!esa_ok) {
+ // Can't figure out ESA
+ os_printf("FEC_ETH - Warning! ESA unknown\n");
+ memcpy(&enaddr, &_default_enaddr, sizeof(enaddr));
+ }
+
+ // Configure the device
+ if (!fec_eth_reset(sc, enaddr, 0)) {
+ return false;
+ }
+
+ fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
+
+#ifdef CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY
+ // Reset PHY (transceiver)
+ FEC_ETH_RESET_PHY();
+
+ phy_ok = 0;
+ if (phy_read(PHY_BMSR, FEC_ETH_PHY, &phy_state)) {
+ if ((phy_state & PHY_BMSR_LINK) != PHY_BMSR_LINK) {
+ unsigned short reset_mode;
+ int i;
+ phy_write(PHY_BMCR, FEC_ETH_PHY, PHY_BMCR_RESET);
+ for (i = 0; i < 10; i++) {
+ phy_ok = phy_read(PHY_BMCR, FEC_ETH_PHY, &phy_state);
+ if (!phy_ok) break;
+ if (!(phy_state & PHY_BMCR_RESET)) break;
+ }
+ if (!phy_ok || (phy_state & PHY_BMCR_RESET)) {
+ os_printf("FEC: Can't get PHY unit to soft reset: %x\n", phy_state);
+ return false;
+ }
+
+ fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
+ reset_mode = PHY_BMCR_RESTART;
+#ifdef CYGNUM_DEVS_ETH_POWERPC_FEC_LINK_MODE_Auto
+ reset_mode |= PHY_BMCR_AUTO_NEG;
+#endif
+#ifdef CYGNUM_DEVS_ETH_POWERPC_FEC_LINK_MODE_100Mb
+ reset_mode |= PHY_BMCR_100MB;
+#endif
+ phy_write(PHY_BMCR, FEC_ETH_PHY, reset_mode);
+ while (phy_timeout-- >= 0) {
+ int ev = fec->iEvent;
+ unsigned short state;
+ fec->iEvent = ev;
+ if (ev & iEvent_MII) {
+ phy_ok = phy_read(PHY_BMSR, FEC_ETH_PHY, &state);
+ if (phy_ok && (state & PHY_BMSR_LINK)) {
+ break;
+ } else {
+ CYGACC_CALL_IF_DELAY_US(10000); // 10ms
+ }
+ }
+ }
+ if (phy_timeout <= 0) {
+ os_printf("** FEC Warning: PHY LINK UP failed\n");
+ }
+ }
+ else {
+ os_printf("** FEC Info: PHY LINK already UP \n");
+ }
+ }
+#endif // CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr);
+
+ if (cache_state)
+ HAL_DCACHE_ENABLE();
+
+ return true;
+}
+
+//
+// This function is called to shut down the interface.
+//
+static void
+fec_eth_stop(struct eth_drv_sc *sc)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+
+ // Disable the device!
+ qi->fec->eControl &= ~eControl_EN;
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+fec_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ // Enable the device!
+ fec_eth_reset(sc, enaddr, flags);
+}
+
+//
+// This function is called for low level "control" operations
+//
+static int
+fec_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int length)
+{
+#ifdef ETH_DRV_SET_MC_ALL
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ volatile struct fec *fec = qi->fec;
+#endif
+
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ return 0;
+ break;
+#ifdef ETH_DRV_SET_MC_ALL
+ case ETH_DRV_SET_MC_ALL:
+ case ETH_DRV_SET_MC_LIST:
+ fec->RxControl &= ~RxControl_PROM;
+ fec->hash[0] = 0xFFFFFFFF;
+ fec->hash[1] = 0xFFFFFFFF;
+ return 0;
+ break;
+#endif
+ default:
+ return 1;
+ break;
+ }
+}
+
+//
+// This function is called to see if another packet can be sent.
+// It should return the number of packets which can be handled.
+// Zero should be returned if the interface is busy and can not send any more.
+//
+static int
+fec_eth_can_send(struct eth_drv_sc *sc)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+
+ return (qi->txactive < CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM);
+}
+
+//
+// This routine is called to send data to the hardware.
+
+static void
+fec_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ volatile struct fec_bd *txbd, *txfirst;
+ volatile char *bp;
+ int i, txindex, cache_state;
+
+ // Find a free buffer
+ txbd = txfirst = qi->txbd;
+ while (txbd->ctrl & FEC_BD_Tx_Ready) {
+ // This buffer is busy, move to next one
+ if (txbd->ctrl & FEC_BD_Tx_Wrap) {
+ txbd = qi->tbase;
+ } else {
+ txbd++;
+ }
+ if (txbd == txfirst) {
+#ifdef CYGPKG_NET
+ panic ("No free xmit buffers");
+#else
+ os_printf("FEC Ethernet: No free xmit buffers\n");
+#endif
+ }
+ }
+ // Set up buffer
+ bp = txbd->buffer;
+ for (i = 0; i < sg_len; i++) {
+ memcpy((void *)bp, (void *)sg_list[i].buf, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+ txbd->length = total_len;
+ txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
+ qi->txkey[txindex] = key;
+ // Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(txbd->buffer, txbd->length); // Make sure no stale data
+ }
+ // Send it on it's way
+ txbd->ctrl |= FEC_BD_Tx_Ready | FEC_BD_Tx_Last | FEC_BD_Tx_TC;
+ qi->txactive++;
+ qi->fec->TxUpdate = 0x01000000; // Any write tells machine to look for work
+ set_led(LED_TxACTIVE);
+ // Remember the next buffer to try
+ if (txbd->ctrl & FEC_BD_Tx_Wrap) {
+ qi->txbd = qi->tbase;
+ } else {
+ qi->txbd = txbd+1;
+ }
+}
+
+//
+// This function is called when a packet has been received. It's job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'fec_eth_recv' will be called to actually fetch it from the hardware.
+//
+static void
+fec_eth_RxEvent(struct eth_drv_sc *sc)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ volatile struct fec_bd *rxbd, *rxfirst;
+
+ rxbd = rxfirst = qi->rnext;
+ while (true) {
+ if ((rxbd->ctrl & FEC_BD_Rx_Empty) == 0) {
+ qi->rxbd = rxbd; // Save for callback
+ set_led(LED_RxACTIVE); // Remove the CRC
+ (sc->funs->eth_drv->recv)(sc, rxbd->length - 4);
+ }
+ if (rxbd->ctrl & FEC_BD_Rx_Wrap) {
+ rxbd = qi->rbase;
+ } else {
+ rxbd++;
+ }
+ if (rxbd == rxfirst) {
+ break;
+ }
+ }
+ // Remember where we left off
+ qi->rnext = (struct fec_bd *)rxbd;
+ qi->fec->RxUpdate = 0x0F0F0F0F; // Any write tells machine to look for work
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// It's job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+fec_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ unsigned char *bp;
+ int i, cache_state;
+
+ bp = (unsigned char *)qi->rxbd->buffer;
+ // Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(qi->rxbd->buffer, qi->rxbd->length); // Make sure no stale data
+ }
+ for (i = 0; i < sg_len; i++) {
+ if (sg_list[i].buf != 0) {
+ memcpy((void *)sg_list[i].buf, bp, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+ }
+ qi->rxbd->ctrl |= FEC_BD_Rx_Empty;
+ clear_led(LED_RxACTIVE);
+}
+
+static void
+fec_eth_TxEvent(struct eth_drv_sc *sc)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ volatile struct fec_bd *txbd;
+ int key, txindex;
+
+ txbd = qi->tnext;
+ // Note: TC field is used to indicate the buffer has/had data in it
+ while ((txbd->ctrl & (FEC_BD_Tx_Ready|FEC_BD_Tx_TC)) == FEC_BD_Tx_TC) {
+ txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
+ if ((key = qi->txkey[txindex]) != 0) {
+ qi->txkey[txindex] = 0;
+ (sc->funs->eth_drv->tx_done)(sc, key, 0);
+ }
+ if (--qi->txactive == 0) {
+ clear_led(LED_TxACTIVE);
+ }
+ txbd->ctrl &= ~FEC_BD_Tx_TC;
+ if (txbd->ctrl & FEC_BD_Tx_Wrap) {
+ txbd = qi->tbase;
+ } else {
+ txbd++;
+ }
+ }
+ // Remember where we left off
+ qi->tnext = (struct fec_bd *)txbd;
+}
+
+//
+// Interrupt processing
+//
+static void
+fec_eth_int(struct eth_drv_sc *sc)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ unsigned long event;
+
+ while ((event = qi->fec->iEvent) != 0) {
+ qi->fec->iEvent = event; // Reset the bits we handled
+ if ((event & iEvent_TFINT) != 0) {
+ fec_eth_TxEvent(sc);
+ }
+ if ((event & iEvent_RFINT) != 0) {
+ fec_eth_RxEvent(sc);
+ }
+ }
+}
+
+//
+// Interrupt vector
+//
+static int
+fec_eth_int_vector(struct eth_drv_sc *sc)
+{
+ return (FEC_ETH_INT);
+}
+
+#if defined(CYGINT_IO_ETH_INT_SUPPORT_REQUIRED) && ~defined(_FEC_USE_INTS)
+void
+fec_fake_int(cyg_addrword_t param)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *) param;
+ int int_state;
+
+ while (true) {
+ cyg_thread_delay(1); // 10ms
+ HAL_DISABLE_INTERRUPTS(int_state);
+ fec_eth_int(sc);
+ HAL_RESTORE_INTERRUPTS(int_state);
+ }
+}
+#endif
diff --git a/ecos/packages/devs/eth/powerpc/mbx/current/ChangeLog b/ecos/packages/devs/eth/powerpc/mbx/current/ChangeLog
new file mode 100644
index 0000000..1e3111e
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/mbx/current/ChangeLog
@@ -0,0 +1,32 @@
+2002-11-25 Gary Thomas <gthomas@ecoscentric.com>
+
+ * include/mbx_eth.inl:
+ * cdl/mbx_eth_drivers.cdl: New package - platform specifics for
+ Motorola MBX (PowerPC 860) board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/mbx/current/cdl/mbx_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/mbx/current/cdl/mbx_eth_drivers.cdl
new file mode 100644
index 0000000..c3e3725
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/mbx/current/cdl/mbx_eth_drivers.cdl
@@ -0,0 +1,67 @@
+#====================================================================
+#
+# mbx_eth_drivers.cdl
+#
+# Hardware specifics for Motorola MBX ethernet
+#
+#====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-14
+#
+#####DESCRIPTIONEND####
+#
+#====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_MBX {
+ display "Motorola MBX (MPC8xxT) ethernet support"
+ description "Hardware specifics for Motorola MBX ethernet"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_MPC8xx
+ active_if CYGPKG_HAL_POWERPC_MBX
+
+ requires CYGPKG_DEVS_ETH_POWERPC_QUICC
+
+ include_dir cyg/io
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_QUICC_ETH_INL <cyg/io/mbx_eth.inl>"
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/mbx/current/include/mbx_eth.inl b/ecos/packages/devs/eth/powerpc/mbx/current/include/mbx_eth.inl
new file mode 100644
index 0000000..58f8719
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/mbx/current/include/mbx_eth.inl
@@ -0,0 +1,97 @@
+#ifndef CYGONCE_DEVS_MBX_ETH_INL
+#define CYGONCE_DEVS_MBX_ETH_INL
+//==========================================================================
+//
+// mbx_eth.inl
+//
+// Hardware specifics for Motorola MBX ethernet support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2002-11-19
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define _get_led()
+#define _set_led(v)
+
+#define LED_TxACTIVE 7
+#define LED_RxACTIVE 6
+#define LED_IntACTIVE 5
+
+#if 0
+// Fetch ESA from on-board EEPROM
+extern int _mbx_fetch_VPD(int, void *, int);
+#define QUICC_ETH_FETCH_ESA(_ok_) \
+ _ok_ = _mbx_fetch_VPD(VPD_ETHERNET_ADDRESS, enaddr, sizeof(enaddr));
+#endif
+
+// Reset/enable any external hardware
+#define QUICC_ETH_ENABLE() \
+ *MBX_CTL1 = MBX_CTL1_ETEN | MBX_CTL1_TPEN; /* Enable ethernet, TP mode */
+
+
+// Port layout - uses SCC1
+#define QUICC_ETH_PA_RXD 0x0001 // Rx Data on Port A
+#define QUICC_ETH_PA_TXD 0x0002 // Tx Data on Port A
+#define QUICC_ETH_PA_Tx_CLOCK 0x0200 // Tx Clock = CLK2
+#define QUICC_ETH_PA_Rx_CLOCK 0x0800 // Rx Clock = CLK4
+#define QUICC_ETH_PC_Tx_ENABLE 0x0001 // Tx Enable (TENA)
+#define QUICC_ETH_PC_COLLISION 0x0010 // Collision detect
+#define QUICC_ETH_PC_Rx_ENABLE 0x0020 // Rx Enable (RENA)
+#define QUICC_ETH_SICR_MASK 0x00FF // SI Clock Route - important bits
+#define QUICC_ETH_SICR_ENET (7<<3)|(5<<0) // Rx=CLK4, Tx=CLK2
+#define QUICC_ETH_SICR_ENABLE 0x0040 // Enable SCC1 to use NMSI
+#define QUICC_ETH_INT CYGNUM_HAL_INTERRUPT_CPM_SCC1
+#define QUICC_ETH_SCC 0 // SCC1
+#define QUICC_CPM_SCCx QUICC_CPM_SCC1
+
+#define MBX_CTL1 (cyg_uint8 *)0xFA100000 // System control register
+#define MBX_CTL1_ETEN 0x80 // 1 = Enable ethernet tranceiver
+#define MBX_CTL1_ELEN 0x40 // 1 = Enable ethernet loopback
+#define MBX_CTL1_EAEN 0x20 // 1 = Auto select ethernet interface
+#define MBX_CTL1_TPEN 0x10 // 0 = AUI, 1 = TPI
+#define MBX_CTL1_FDDIS 0x08 // 1 = Disable full duplex (if TP mode)
+
+
+#endif // CYGONCE_DEVS_MBX_ETH_INL
+// ------------------------------------------------------------------------
diff --git a/ecos/packages/devs/eth/powerpc/moab/current/ChangeLog b/ecos/packages/devs/eth/powerpc/moab/current/ChangeLog
new file mode 100644
index 0000000..be886d0
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/moab/current/ChangeLog
@@ -0,0 +1,57 @@
+2011-07-22 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * cdl/moab_eth_drivers.cdl:
+ Update due renaming CYGHWR_DEVS_ETH_PHY_DP83847 to
+ CYGHWR_DEVS_ETH_PHY_DP8384X. [ Bugzilla 1001235 ]
+
+2005-07-18 David Vrabel <dvrabel@arcom.com>
+
+ * include/moab_eth_dp83816.inl: Remove unneeded _h2le and _le2h
+ functions.
+
+2003-10-02 Gary Thomas <gary@mlbassoc.com>
+
+ * include/moab_eth_dp83816.inl:
+ * include/moab_eth.inl: Default ethernet station addresses are now
+ computed by system startup, based on CPU serial number.
+
+2003-09-30 Gary Thomas <gary@mlbassoc.com>
+
+ * include/moab_eth_dp83816.inl:
+ * include/moab_eth.inl: Change device names used by RedBoot to eth0/eth1
+ * include/moab_eth_dp83816.inl:
+ * cdl/moab_eth_drivers.cdl: Add support for 2nd LAN device, based
+ on National Semiconductor DP83816.
+
+2003-09-19 Gary Thomas <gary@mlbassoc.com>
+
+ * include/moab_eth.inl:
+ * cdl/moab_eth_drivers.cdl: New package - ethernet support for
+ TAMS MOAB (PowerPC 405GPr) board
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/moab/current/cdl/moab_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/moab/current/cdl/moab_eth_drivers.cdl
new file mode 100644
index 0000000..c96fbf9
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/moab/current/cdl/moab_eth_drivers.cdl
@@ -0,0 +1,126 @@
+#====================================================================
+#
+# moab_eth_drivers.cdl
+#
+# Hardware specifics for TAMS MOAB ethernet
+#
+#====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2003-08-19
+#
+#####DESCRIPTIONEND####
+#
+#====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_MOAB {
+ display "TAMS MOAB (PPC405GPr) ethernet support"
+ description "Hardware specifics for TAMS MOAB ethernet"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_PPC40x
+
+ requires CYGPKG_DEVS_ETH_POWERPC_PPC405
+ requires CYGHWR_DEVS_ETH_PHY_DP8384X
+ requires CYGPKG_HAL_POWERPC_MOAB
+
+ # FIXME: This really belongs in the NS DP83816 package
+ cdl_interface CYGINT_DEVS_ETH_NS_DP83816_REQUIRED {
+ display "NS DP83816 ethernet driver required"
+ }
+
+ cdl_component CYGHWR_DEVS_ETH_POWERPC_MOAB_ETH0 {
+ display "Include eth0 ethernet device"
+ default_value 1
+ description "
+ This option controls whether a driver for eth0
+ is included in the resulting system."
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGHWR_DEVS_ETH_POWERPC_PPC405_NET_DRIVERS
+ }
+
+ cdl_component CYGHWR_DEVS_ETH_POWERPC_MOAB_ETH1 {
+ display "Include eth1 ethernet device"
+ default_value 1
+ description "
+ This option controls whether a driver for eth1
+ is included in the resulting system."
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH1
+ requires CYGHWR_DEVS_ETH_POWERPC_MOAB_ETH0
+
+ implements CYGINT_DEVS_ETH_NS_DP83816_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83816_INL <cyg/io/moab_eth_dp83816.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83816_CFG <pkgconf/devs_eth_powerpc_moab.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_MOAB_DP83816_TxNUM {
+ display "Number of output buffers"
+ flavor data
+ legal_values 2 to 64
+ default_value 16
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the NS DP83816 ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_MOAB_DP83816_RxNUM {
+ display "Number of input buffers"
+ flavor data
+ legal_values 2 to 64
+ default_value 16
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the NS DP83816 ethernet device."
+ }
+ }
+
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_PPC405_ETH_CDL <pkgconf/devs_eth_powerpc_moab.h>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_PPC405_ETH_INL <cyg/io/moab_eth.inl>"
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/moab/current/include/moab_eth.inl b/ecos/packages/devs/eth/powerpc/moab/current/include/moab_eth.inl
new file mode 100644
index 0000000..0b00b67
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/moab/current/include/moab_eth.inl
@@ -0,0 +1,119 @@
+#ifndef CYGONCE_DEVS_MOAB_ETH_INL
+#define CYGONCE_DEVS_MOAB_ETH_INL
+//==========================================================================
+//
+// moab_eth.inl
+//
+// Hardware specifics for TAMS MOAB ethernet support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2003-08-19
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include CYGDAT_DEVS_PPC405_ETH_CDL
+
+#ifdef CYGHWR_DEVS_ETH_POWERPC_MOAB_ETH0
+ETH_PHY_REG_LEVEL_ACCESS_FUNS(eth0_phy,
+ ppc405_eth_phy_init,
+ NULL,
+ ppc405_eth_phy_put_reg,
+ ppc405_eth_phy_get_reg);
+
+// Align buffers on a cache boundary
+#define RxBUFSIZE CYGNUM_DEVS_ETH_POWERPC_PPC405_RxNUM*CYGNUM_DEVS_ETH_POWERPC_PPC405_BUFSIZE
+#define TxBUFSIZE CYGNUM_DEVS_ETH_POWERPC_PPC405_TxNUM*CYGNUM_DEVS_ETH_POWERPC_PPC405_BUFSIZE
+static unsigned char ppc405_eth_rxbufs[RxBUFSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char ppc405_eth_txbufs[TxBUFSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static mal_bd_t ppc405_eth_rxbd[CYGNUM_DEVS_ETH_POWERPC_PPC405_RxNUM] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static mal_bd_t ppc405_eth_txbd[CYGNUM_DEVS_ETH_POWERPC_PPC405_TxNUM] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+extern char _moab_eth0_ESA[];
+static struct ppc405_eth_info ppc405_eth0_info = {
+ 0, // Interrupt vector
+ "eth0_esa",
+ _moab_eth0_ESA,
+ CYGNUM_DEVS_ETH_POWERPC_PPC405_RxNUM, // Number of Rx buffers
+ ppc405_eth_rxbufs, // Rx buffer space
+ ppc405_eth_rxbd, // Rx buffer headers
+ CYGNUM_DEVS_ETH_POWERPC_PPC405_TxNUM, // Number of Tx buffers
+ ppc405_eth_txbufs, // Tx buffer space
+ ppc405_eth_txbd, // Tx buffer headers
+ &eth0_phy, // PHY access routines
+};
+
+ETH_DRV_SC(ppc405_eth0_sc,
+ &ppc405_eth0_info, // Driver specific data
+ "eth0", // Name for this interface
+ ppc405_eth_start,
+ ppc405_eth_stop,
+ ppc405_eth_control,
+ ppc405_eth_can_send,
+ ppc405_eth_send,
+ ppc405_eth_recv,
+ ppc405_eth_deliver,
+ ppc405_eth_int,
+ ppc405_eth_int_vector);
+
+NETDEVTAB_ENTRY(ppc405_netdev,
+ "eth0",
+ ppc405_eth_init,
+ &ppc405_eth0_sc);
+
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+RedBoot_config_option("eth0 network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, _moab_eth0_ESA
+ );
+#endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#endif // CYGPKG_REDBOOT
+
+#endif // CYGHWR_DEVS_ETH_POWERPC_MOAB_ETH0
+
+#endif // CYGONCE_DEVS_MOAB_ETH_INL
+// ------------------------------------------------------------------------
diff --git a/ecos/packages/devs/eth/powerpc/moab/current/include/moab_eth_dp83816.inl b/ecos/packages/devs/eth/powerpc/moab/current/include/moab_eth_dp83816.inl
new file mode 100644
index 0000000..9f1f187
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/moab/current/include/moab_eth_dp83816.inl
@@ -0,0 +1,137 @@
+//==========================================================================
+//
+// moab_eth_dp83816.inl
+//
+// MOAB ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors:
+// Date: 2003-09-29
+// Purpose: MOAB ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_cache.h>
+#include <cyg/io/pci.h>
+
+#undef DP_IN
+#undef DP_OUT
+#define DP_IN(_b_, _o_, _d_) HAL_READ_UINT32LE((cyg_addrword_t)(_b_)+(_o_), (_d_))
+#define DP_OUT(_b_, _o_, _d_) HAL_WRITE_UINT32LE((cyg_addrword_t)(_b_)+(_o_), (_d_))
+
+static cyg_bool
+find_rtl8381x_match_func(cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p)
+{
+ return ((v == 0x100B) && (d == 0x0020));
+}
+
+static void
+_moab_eth_init(dp83816_priv_data_t *dp)
+{
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+
+ devid = CYG_PCI_NULL_DEVID;
+ if (cyg_pci_find_matching( &find_rtl8381x_match_func, NULL, &devid )) {
+ cyg_pci_get_device_info(devid, &dev_info);
+ cyg_pci_translate_interrupt(&dev_info, &dp->interrupt);
+ dp->base = (cyg_uint8 *)(dev_info.base_map[0] & ~1);
+ diag_printf("DP83816 at %p, interrupt: %x\n", dp->base, dp->interrupt);
+ }
+}
+
+#undef CYGHWR_NS_DP83816_PLF_INIT
+#define CYGHWR_NS_DP83816_PLF_INIT(dp) _moab_eth_init(dp)
+
+// Align buffers on a cache boundary
+#define RxBUFSIZE CYGNUM_DEVS_ETH_MOAB_DP83816_RxNUM*_DP83816_BUFSIZE
+#define TxBUFSIZE CYGNUM_DEVS_ETH_MOAB_DP83816_TxNUM*_DP83816_BUFSIZE
+static unsigned char dp83816_eth_rxbufs[RxBUFSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char dp83816_eth_txbufs[TxBUFSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static dp83816_bd_t dp83816_eth_rxbd[CYGNUM_DEVS_ETH_MOAB_DP83816_RxNUM] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static dp83816_bd_t dp83816_eth_txbd[CYGNUM_DEVS_ETH_MOAB_DP83816_TxNUM] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+extern char _moab_eth1_ESA[];
+static dp83816_priv_data_t dp83816_eth1_priv_data = {
+ "eth1_esa",
+ _moab_eth1_ESA,
+ CYGNUM_DEVS_ETH_MOAB_DP83816_RxNUM, // Number of Rx buffers
+ dp83816_eth_rxbufs, // Rx buffer space
+ dp83816_eth_rxbd, // Rx buffer headers
+ CYGNUM_DEVS_ETH_MOAB_DP83816_TxNUM, // Number of Tx buffers
+ dp83816_eth_txbufs, // Tx buffer space
+ dp83816_eth_txbd, // Tx buffer headers
+};
+
+ETH_DRV_SC(dp83816_sc,
+ &dp83816_eth1_priv_data, // Driver specific data
+ "eth1",
+ dp83816_start,
+ dp83816_stop,
+ dp83816_control,
+ dp83816_can_send,
+ dp83816_send,
+ dp83816_recv,
+ dp83816_deliver, // "pseudoDSR" called from fast net thread
+ dp83816_poll, // poll function, encapsulates ISR and DSR
+ dp83816_int_vector);
+
+NETDEVTAB_ENTRY(dp83816_netdev,
+ "eth1",
+ dp83816_init,
+ &dp83816_sc);
+
+#if defined(CYGPKG_REDBOOT)
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+RedBoot_config_option("eth1 network hardware address [MAC]",
+ eth1_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, _moab_eth1_ESA
+ );
+#endif // CYGSEM_REDBOOT_FLASH_CONFIG
+#else
+#ifndef CONFIG_ESA
+#define CONFIG_ESA 6
+#endif
+#endif // CYGPKG_REDBOOT
+
+
+// EOF moab_eth_dp83816.inl
diff --git a/ecos/packages/devs/eth/powerpc/ppc405/current/ChangeLog b/ecos/packages/devs/eth/powerpc/ppc405/current/ChangeLog
new file mode 100644
index 0000000..b7cfbeb
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/ppc405/current/ChangeLog
@@ -0,0 +1,47 @@
+2005-08-25 Markus Schade <marks@peppercon.de>
+
+ * enabled build for PowerPC 405EP
+
+2005-02-03 Gary Thomas <gary@mlbassoc.com>
+
+ * src/ppc405_enet.h:
+ * src/if_ppc405.c: Improve error detection and recovery.
+
+2003-10-02 Gary Thomas <gary@mlbassoc.com>
+
+ * src/ppc405_enet.h: Let default ESA be a pointer so that platforms
+ may set/change it a runtime.
+
+2003-09-19 Gary Thomas <gary@mlbassoc.com>
+
+ * src/ppc405_enet.h:
+ * src/if_ppc405.c:
+ * cdl/ppc405_eth_drivers.cdl: New package - generic ethernet driver
+ for PowerPC 405GP based boards.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/ppc405/current/cdl/ppc405_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/ppc405/current/cdl/ppc405_eth_drivers.cdl
new file mode 100644
index 0000000..dc464e9
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/ppc405/current/cdl/ppc405_eth_drivers.cdl
@@ -0,0 +1,141 @@
+# ====================================================================
+#
+# ppc405_eth_drivers.cdl
+#
+# Ethernet drivers for PowerPC 405GP based platforms
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2003-08-15
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_PPC405 {
+ display "PPC405 ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_PPC40x
+ requires { (CYGHWR_HAL_POWERPC_PPC4XX == "405GP") || (CYGHWR_HAL_POWERPC_PPC4XX == "405EP") }
+ requires CYGPKG_DEVS_ETH_PHY
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_IO_ETH_MULTICAST
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+
+ # Debug I/O during network stack initialization is not reliable
+ requires { !CYGPKG_NET || CYGPKG_NET_FORCE_SERIAL_CONSOLE == 1 }
+
+ cdl_interface CYGHWR_DEVS_ETH_POWERPC_PPC405_NET_DRIVERS {
+ display "Network drivers"
+ }
+ requires { CYGHWR_DEVS_ETH_POWERPC_PPC405_NET_DRIVERS == 1 }
+
+ description "Ethernet driver for PowerPC 405GP/EP boards."
+ compile -library=libextras.a if_ppc405.c
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_PPC405_BUFSIZE {
+ display "Buffer size"
+ flavor data
+ default_value 1520
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC PPC405/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_PPC405_TxNUM {
+ display "Number of output buffers"
+ flavor data
+ legal_values 2 to 64
+ default_value 16
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC PPC405/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_PPC405_RxNUM {
+ display "Number of input buffers"
+ flavor data
+ legal_values 2 to 64
+ default_value 16
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC PPC405/ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_POWERPC_PPC405_RESET_PHY {
+ display "Reset and reconfigure PHY"
+ flavor bool
+ default_value { CYG_HAL_STARTUP != "RAM" }
+ description "
+ This option allows control over the physical transceiver"
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_PPC405_LINK_MODE {
+ display "Initial link mode"
+ flavor data
+ legal_values { "10Mb" "100Mb" "Auto" }
+ default_value { "Auto" }
+ description "
+ This option specifies initial mode for the physical
+ link. The PHY will be reset and then set to this mode."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_POWERPC_PPC405_OPTIONS {
+ display "PPC405 ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_POWERPC_PPC405_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the PPC405 ethernet driver package. These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/ppc405/current/src/if_ppc405.c b/ecos/packages/devs/eth/powerpc/ppc405/current/src/if_ppc405.c
new file mode 100644
index 0000000..09bd405
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/ppc405/current/src/if_ppc405.c
@@ -0,0 +1,685 @@
+//==========================================================================
+//
+// dev/if_ppc405.c
+//
+// Ethernet device driver for PowerPC PPC405 boards
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2003-08-15
+// Purpose:
+// Description: hardware driver for PPC405
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// Ethernet device driver for PPC405
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_powerpc_ppc405.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#endif
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/ppc_regs.h>
+
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth_phy.h>
+
+//
+// PHY access functions
+//
+static void ppc405_eth_phy_init(void);
+static void ppc405_eth_phy_put_reg(int reg, int phy, unsigned short data);
+static bool ppc405_eth_phy_get_reg(int reg, int phy, unsigned short *val);
+
+#include "ppc405_enet.h"
+#include CYGDAT_DEVS_PPC405_ETH_INL
+
+#define os_printf diag_printf
+
+// For fetching the ESA from RedBoot
+#include <cyg/hal/hal_if.h>
+#ifndef CONFIG_ESA
+#define CONFIG_ESA 6
+#endif
+
+static void ppc405_eth_int(struct eth_drv_sc *data);
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+
+static cyg_interrupt ppc405_emac_interrupt;
+static cyg_handle_t ppc405_emac_interrupt_handle;
+static cyg_interrupt ppc405_mal_txeob_interrupt;
+static cyg_handle_t ppc405_mal_txeob_interrupt_handle;
+static cyg_interrupt ppc405_mal_rxeob_interrupt;
+static cyg_handle_t ppc405_mal_rxeob_interrupt_handle;
+static cyg_interrupt ppc405_mal_txde_interrupt;
+static cyg_handle_t ppc405_mal_txde_interrupt_handle;
+static cyg_interrupt ppc405_mal_rxde_interrupt;
+static cyg_handle_t ppc405_mal_rxde_interrupt_handle;
+static cyg_interrupt ppc405_mal_serr_interrupt;
+static cyg_handle_t ppc405_mal_serr_interrupt_handle;
+
+#define EMAC_INTERRUPT_HANDLER(_int_,_hdlr_) \
+ cyg_drv_interrupt_create(_int_, \
+ 0, \
+ (cyg_addrword_t)sc, /* Data item passed to interrupt handler */ \
+ (cyg_ISR_t *)ppc405_eth_isr, \
+ (cyg_DSR_t *)eth_drv_dsr, \
+ &ppc405_##_hdlr_##_interrupt_handle, \
+ &ppc405_##_hdlr_##_interrupt); \
+ cyg_drv_interrupt_attach(ppc405_##_hdlr_##_interrupt_handle); \
+ cyg_drv_interrupt_acknowledge(_int_); \
+ cyg_drv_interrupt_unmask(_int_);
+
+// This ISR is called when the ethernet interrupt occurs
+static int
+ppc405_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_MAL_SERR);
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_MAL_TX_EOB);
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_MAL_RX_EOB);
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_MAL_TX_DE);
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_MAL_RX_DE);
+ cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_EMAC0);
+ qi->ints = vector;
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+#endif
+
+// Deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+ppc405_eth_deliver(struct eth_drv_sc *sc)
+{
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+ cyg_uint32 old_ints;
+#endif
+ ppc405_eth_int(sc);
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ // Allow interrupts to happen again
+ HAL_DISABLE_INTERRUPTS(old_ints);
+ cyg_drv_interrupt_acknowledge(qi->ints);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_MAL_SERR);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_MAL_TX_EOB);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_MAL_RX_EOB);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_MAL_TX_DE);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_MAL_RX_DE);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EMAC0);
+ HAL_RESTORE_INTERRUPTS(old_ints);
+#endif
+}
+
+//
+// PHY unit access
+//
+static void
+ppc405_eth_phy_init(void)
+{
+ // Set up MII hardware - nothing to do on this platform
+}
+
+static void
+ppc405_eth_phy_put_reg(int reg, int phy, unsigned short data)
+{
+ unsigned long reg_val;
+
+ reg_val = EMAC0_STACR_STAC_WRITE | EMAC0_STACR_OPBC_66;
+ reg_val |= (phy << EMAC0_STACR_PCDA_SHIFT) | reg;
+ reg_val |= (data << EMAC0_STACR_PHYD_SHIFT);
+#ifdef PHY_DEBUG
+ os_printf("PHY PUT - reg: %d, phy: %d, val: %04x [%08x]\n", reg, phy, data, reg_val);
+#endif
+ while ((EMAC0_STACR & EMAC0_STACR_OC) == 0) ; // Wait for MII free
+ EMAC0_STACR = reg_val;
+ while ((EMAC0_STACR & EMAC0_STACR_OC) == 0) ; // Wait for MII complete
+}
+
+static bool
+ppc405_eth_phy_get_reg(int reg, int phy, unsigned short *val)
+{
+ unsigned long reg_val;
+
+ reg_val = EMAC0_STACR_STAC_READ | EMAC0_STACR_OPBC_66;
+ reg_val |= (phy << EMAC0_STACR_PCDA_SHIFT) | reg;
+#ifdef PHY_DEBUG
+ os_printf("PHY GET - reg: %d, phy: %d [%08x] = ", reg, phy, reg_val);
+#endif
+ while ((EMAC0_STACR & EMAC0_STACR_OC) == 0) ; // Wait for MII free
+ EMAC0_STACR = reg_val;
+ while ((EMAC0_STACR & EMAC0_STACR_OC) == 0) ; // Wait for MII complete
+ if ((EMAC0_STACR & EMAC0_STACR_PHYE) == 0) {
+ // Operation completed with no error
+ *val = (EMAC0_STACR & EMAC0_STACR_PHYD) >> EMAC0_STACR_PHYD_SHIFT;
+#ifdef PHY_DEBUG
+ os_printf("%04x\n", *val);
+#endif
+ return true;
+ } else {
+ // No response
+#ifdef PHY_DEBUG
+ os_printf("***ERROR***\n");
+#endif
+ return false;
+ }
+}
+
+//
+// [re]Initialize the ethernet controller
+// Done separately since shutting down the device requires a
+// full reconfiguration when re-enabling.
+// when
+static bool
+ppc405_eth_reset(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+ volatile mal_bd_t *rxbd, *RxBD, *txbd, *TxBD;
+ unsigned char *RxBUF, *TxBUF;
+ int i, int_state;
+ unsigned long mal_status, mode;
+ unsigned short phy_state = 0;
+
+ // Ignore unless device is idle/stopped
+ if ((EMAC0_MR0 & (EMAC0_MR0_RXI|EMAC0_MR0_TXI)) != (EMAC0_MR0_RXI|EMAC0_MR0_TXI)) {
+ return true;
+ }
+
+ // Make sure interrupts are off while we mess with the device
+ HAL_DISABLE_INTERRUPTS(int_state);
+
+ // Reset EMAC controller
+ EMAC0_MR0 |= EMAC0_MR0_SRST;
+ i = 0;
+ while ((EMAC0_MR0 & EMAC0_MR0_SRST) != 0) {
+ if (++i >= 500000) {
+ os_printf("PPC405 Ethernet does not reset\n");
+ HAL_RESTORE_INTERRUPTS(int_state);
+ return false;
+ }
+ }
+
+ TxBD = qi->txbd_table;
+ txbd = (mal_bd_t *)CYGARC_UNCACHED_ADDRESS(TxBD);
+ RxBD = qi->rxbd_table;
+ rxbd = (mal_bd_t *)CYGARC_UNCACHED_ADDRESS(RxBD);
+ qi->tbase = qi->txbd = qi->tnext = txbd;
+ qi->rbase = qi->rxbd = qi->rnext = rxbd;
+ qi->txactive = 0;
+
+ RxBUF = qi->rxbuf;
+ TxBUF = qi->txbuf;
+
+ // setup buffer descriptors
+ for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_PPC405_RxNUM; i++) {
+ rxbd->length = 0;
+ rxbd->buffer = (unsigned long)RxBUF;
+ rxbd->status = MAL_BD_R | MAL_BD_I;
+ RxBUF += CYGNUM_DEVS_ETH_POWERPC_PPC405_BUFSIZE;
+ rxbd++;
+ }
+ rxbd--;
+ rxbd->status |= MAL_BD_W; // Last buffer
+ for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_PPC405_TxNUM; i++) {
+ txbd->length = 0;
+ txbd->buffer = (unsigned long)TxBUF;
+ txbd->status = 0;
+ TxBUF += CYGNUM_DEVS_ETH_POWERPC_PPC405_BUFSIZE;
+ txbd++;
+ }
+ txbd--;
+ txbd->status |= MAL_BD_W; // Last buffer
+
+ // Tell memory access layer where the buffer descriptors are
+ CYGARC_MTDCR(MAL0_TXCARR, MAL_CASR_C0|MAL_CASR_C1); // Disable/reset channel #0 & #1
+ CYGARC_MTDCR(MAL0_RXCARR, MAL_CASR_C0); // Disable/reset channel #0
+ CYGARC_MTDCR(MAL0_CFG, MAL_CFG_SR);
+ i = 0;
+ CYGARC_MFDCR(MAL0_CFG, mal_status);
+ while ((mal_status & MAL_CFG_SR) != 0) {
+ if (++i >= 500000) {
+ os_printf("PPC405 MAL does not reset\n");
+ HAL_RESTORE_INTERRUPTS(int_state);
+ return false;
+ }
+ }
+ CYGARC_MTDCR(MAL0_CFG, MAL_CFG_PLBB | MAL_CFG_OPBBL | MAL_CFG_LEA | MAL_CFG_PLBT_DEFAULT);
+ CYGARC_MTDCR(MAL0_TXCTP0R, TxBD);
+ CYGARC_MTDCR(MAL0_RXCTP0R, RxBD);
+ CYGARC_MTDCR(MAL0_RXBS0, (CYGNUM_DEVS_ETH_POWERPC_PPC405_BUFSIZE/16)); // Receive buffer size
+
+ // Set device physical address (ESA)
+ EMAC0_IAHR = (enaddr[0]<<8) | (enaddr[1]<<0);
+ EMAC0_IALR = (enaddr[2]<<24) | (enaddr[3]<<16) | (enaddr[4]<<8) | (enaddr[5]<<0);
+
+ // Operating mode
+ if (!_eth_phy_init(qi->phy)) {
+ return false;
+ }
+ phy_state = _eth_phy_state(qi->phy);
+ os_printf("PPC405 ETH: ");
+ mode = EMAC0_MR1_RFS_4096 | EMAC0_MR1_TFS_2048 | EMAC0_MR1_TR0_MULTI | EMAC0_MR1_APP;
+ if ((phy_state & ETH_PHY_STAT_LINK) != 0) {
+ if ((phy_state & ETH_PHY_STAT_100MB) != 0) {
+ // Link can handle 100Mb
+ mode |= EMAC0_MR1_MF_100MB;
+ os_printf("100Mb");
+ if ((phy_state & ETH_PHY_STAT_FDX) != 0) {
+ mode |= EMAC0_MR1_FDE | EMAC0_MR1_EIFC | EMAC0_MR1_IST;
+ os_printf("/Full Duplex");
+ }
+ } else {
+ // Assume 10Mb, half duplex
+ mode |= EMAC0_MR1_MF_10MB;
+ os_printf("10Mb");
+ }
+ } else {
+ os_printf("/***NO LINK***");
+ return false;
+ }
+ os_printf("\n");
+ EMAC0_MR1 = mode;
+
+ // Configure receiver
+ EMAC0_RMR = EMAC0_RMR_IAE | EMAC0_RMR_BAE | EMAC0_RMR_RRP | EMAC0_RMR_RFP;
+
+ // Transmit threshold to 256 bytes
+ EMAC0_TRTR = ((256/EMAC0_TRTR_TRT_SCALE)-1) << EMAC0_TRTR_TRT_SHIFT;
+
+ // Receive FIFO watermarks
+ EMAC0_RWMR = (0x1F<<EMAC0_RWMR_RLWM_SHIFT) | (0x10<<EMAC0_RWMR_RHWM_SHIFT);
+
+ // Frame gap
+ EMAC0_IPGVR = 8;
+
+ // Enable MAL
+ CYGARC_MTDCR(MAL0_TXCASR, MAL_CASR_C0);
+ CYGARC_MTDCR(MAL0_RXCASR, MAL_CASR_C0);
+
+ // Reset all interrupts
+ EMAC0_ISR = 0xFFFFFFFF;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ qi->ints = 0;
+#endif
+
+ // Enable interface
+ EMAC0_MR0 |= (EMAC0_MR0_RXE|EMAC0_MR0_TXE);
+
+ // Restore interrupts
+ HAL_RESTORE_INTERRUPTS(int_state);
+ return true;
+}
+
+//
+// Initialize the interface - performed at system startup
+// This function must set up the interface, including arranging to
+// handle interrupts, etc, so that it may be "started" cheaply later.
+//
+
+static bool
+ppc405_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+ bool esa_ok;
+ unsigned char enaddr[6];
+
+ ppc405_eth_stop(sc); // Make sure it's not running yet
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ // Set up to handle interrupts
+ EMAC_INTERRUPT_HANDLER(CYGNUM_HAL_INTERRUPT_MAL_SERR, mal_serr);
+ EMAC_INTERRUPT_HANDLER(CYGNUM_HAL_INTERRUPT_MAL_TX_EOB, mal_txeob);
+ EMAC_INTERRUPT_HANDLER(CYGNUM_HAL_INTERRUPT_MAL_RX_EOB, mal_rxeob);
+ EMAC_INTERRUPT_HANDLER(CYGNUM_HAL_INTERRUPT_MAL_TX_DE, mal_txde);
+ EMAC_INTERRUPT_HANDLER(CYGNUM_HAL_INTERRUPT_MAL_RX_DE, mal_rxde);
+ EMAC_INTERRUPT_HANDLER(CYGNUM_HAL_INTERRUPT_EMAC0, emac);
+#endif
+
+ // Get physical device address
+#ifdef CYGPKG_REDBOOT
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+ esa_ok = flash_get_config(qi->esa_key, enaddr, CONFIG_ESA);
+#else
+ esa_ok = false;
+#endif
+#else
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ qi->esa_key, enaddr, CONFIG_ESA);
+#endif
+ if (!esa_ok) {
+ // Can't figure out ESA
+ os_printf("PPC405_ETH - Warning! ESA unknown\n");
+ memcpy(&enaddr, qi->enaddr, sizeof(enaddr));
+ }
+ memcpy(qi->cfg_enaddr, enaddr, sizeof(enaddr));
+
+ // Configure the device
+ if (!ppc405_eth_reset(sc, enaddr, 0)) {
+ return false;
+ }
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr);
+
+ return true;
+}
+
+//
+// This function is called to shut down the interface.
+//
+static void
+ppc405_eth_stop(struct eth_drv_sc *sc)
+{
+ EMAC0_MR0 &= ~(EMAC0_MR0_RXE|EMAC0_MR0_TXE);
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+ppc405_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ EMAC0_MR0 |= (EMAC0_MR0_RXE|EMAC0_MR0_TXE);
+}
+
+//
+// This function is called for low level "control" operations
+//
+static int
+ppc405_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int length)
+{
+ os_printf("%s.%d\n", __FUNCTION__, __LINE__);
+ return 1;
+#if 0
+#ifdef ETH_DRV_SET_MC_ALL
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+ volatile struct ppc405 *ppc405 = qi->ppc405;
+#endif
+
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ return 0;
+ break;
+#ifdef ETH_DRV_SET_MC_ALL
+ case ETH_DRV_SET_MC_ALL:
+ case ETH_DRV_SET_MC_LIST:
+ ppc405->RxControl &= ~RxControl_PROM;
+ ppc405->hash[0] = 0xFFFFFFFF;
+ ppc405->hash[1] = 0xFFFFFFFF;
+ return 0;
+ break;
+#endif
+ default:
+ return 1;
+ break;
+ }
+#endif
+}
+
+//
+// This function is called to see if another packet can be sent.
+// It should return the number of packets which can be handled.
+// Zero should be returned if the interface is busy and can not send any more.
+//
+static int
+ppc405_eth_can_send(struct eth_drv_sc *sc)
+{
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+
+ return (qi->txactive < CYGNUM_DEVS_ETH_POWERPC_PPC405_TxNUM);
+}
+
+//
+// This routine is called to send data to the hardware.
+
+static void
+ppc405_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+ volatile mal_bd_t *txbd;
+ volatile char *bp;
+ int i, txindex;
+
+ // Find a free buffer
+ txbd = qi->txbd;
+ // Set up buffer
+ bp = (volatile char *)CYGARC_UNCACHED_ADDRESS(txbd->buffer);
+ for (i = 0; i < sg_len; i++) {
+ memcpy((void *)bp, (void *)sg_list[i].buf, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+ txbd->length = total_len;
+ txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
+ qi->txkey[txindex] = key;
+ // Send it on it's way
+ txbd->status = (txbd->status & MAL_BD_W) | MAL_BD_R | MAL_BD_L | MAL_BD_I |
+ MAL_BD_TX_GFCS | MAL_BD_TX_GPAD;
+ qi->txactive++;
+ EMAC0_TMR0 = EMAC0_TMR0_GNP0; // Start channel 0
+ // Remember the next buffer to try
+ if (txbd->status & MAL_BD_W) {
+ qi->txbd = qi->tbase;
+ } else {
+ qi->txbd = txbd+1;
+ }
+}
+
+//
+// This function is called when a packet has been received. It's job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'ppc405_eth_recv' will be called to actually fetch it from the hardware.
+//
+static void
+ppc405_eth_RxEvent(struct eth_drv_sc *sc)
+{
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+ volatile mal_bd_t *rxbd, *rxfirst;
+
+ rxbd = rxfirst = qi->rnext;
+ while ((rxbd->status & MAL_BD_R) == 0) {
+ qi->rxbd = rxbd; // Save for callback
+ (sc->funs->eth_drv->recv)(sc, rxbd->length-4); // Adjust for FCS
+ if (rxbd->status & MAL_BD_W) {
+ rxbd = qi->rbase;
+ } else {
+ rxbd++;
+ }
+ }
+ // Remember where we left off
+ qi->rnext = (mal_bd_t *)rxbd;
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// It's job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+ppc405_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+ unsigned char *bp;
+ int i;
+
+ bp = (unsigned char *)CYGARC_UNCACHED_ADDRESS(qi->rxbd->buffer);
+ for (i = 0; i < sg_len; i++) {
+ if (sg_list[i].buf != 0) {
+ memcpy((void *)sg_list[i].buf, bp, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+ }
+ qi->rxbd->status = (qi->rxbd->status & (MAL_BD_W|MAL_BD_I)) | MAL_BD_R;
+}
+
+static void
+ppc405_eth_TxEvent(struct eth_drv_sc *sc)
+{
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+ volatile mal_bd_t *txbd;
+ int key, txindex;
+
+ txbd = qi->tnext;
+ while ((txbd->status & (MAL_BD_R|MAL_BD_I)) == MAL_BD_I) {
+ txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
+ if ((key = qi->txkey[txindex]) != 0) {
+ qi->txkey[txindex] = 0;
+ (sc->funs->eth_drv->tx_done)(sc, key, 0);
+ }
+ qi->txactive -= 1;
+ txbd->status &= MAL_BD_W; // Only preserve wrap bit
+ if ((txbd->status & MAL_BD_W) != 0) {
+ txbd = qi->tbase;
+ } else {
+ txbd++;
+ }
+ if (txbd == qi->tnext) {
+ break; // Went through whole list
+ }
+ }
+ // Remember where we left off
+ qi->tnext = (mal_bd_t *)txbd;
+}
+
+//
+// Interrupt processing
+//
+int dump_mal0_esr = 0;
+
+static void
+ppc405_eth_int(struct eth_drv_sc *sc)
+{
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+ unsigned long event, tx_event, rx_event, tx_deir, rx_deir;
+ bool need_reset = false;
+
+ CYGARC_MFDCR(MAL0_TXEOBISR, tx_event);
+ if (tx_event != 0) {
+ ppc405_eth_TxEvent(sc);
+ CYGARC_MTDCR(MAL0_TXEOBISR, tx_event);
+ }
+ CYGARC_MFDCR(MAL0_RXEOBISR, rx_event);
+ if (rx_event != 0) {
+ ppc405_eth_RxEvent(sc);
+ CYGARC_MTDCR(MAL0_RXEOBISR, rx_event);
+ }
+ if ((event = EMAC0_ISR) != 0) {
+ if ((event & ~(EMAC0_ISR_SE0|EMAC0_ISR_SE1)) != 0) {
+ // Error other than signal quality
+ os_printf("EMAC0_ISR: %x\n", event);
+ if ((event & (EMAC0_ISR_TE0|EMAC0_ISR_TE1)) != 0) {
+ // Some problem with transmit - should be easily recoverable
+ CYGARC_MTDCR(MAL0_TXCASR, MAL_CASR_C0);
+ qi->tnext = qi->tbase;
+ }
+ if ((event & (EMAC0_ISR_OVR|EMAC0_ISR_BP|EMAC0_ISR_RP|EMAC0_ISR_ALE|EMAC0_ISR_BFCS)) != 0) {
+ // Rx errors - reset device
+ need_reset = true;
+ }
+ }
+ EMAC0_ISR = event; // Reset the bits we handled
+ }
+ CYGARC_MFDCR(MAL0_ESR, event);
+ if ((event & MAL_ESR_INT_MASK) != 0) {
+ CYGARC_MFDCR(MAL0_TXDEIR, tx_deir);
+ CYGARC_MFDCR(MAL0_RXDEIR, rx_deir);
+ if (dump_mal0_esr) {
+ os_printf("MAL0_ESR: %x, Tx: %x, Rx: %x\n", event, tx_deir, rx_deir);
+ os_printf("Tx buffer headers\n");
+ diag_dump_buf((void *)qi->tbase, qi->txnum*sizeof(mal_bd_t));
+ os_printf("Rx buffer headers\n");
+ diag_dump_buf((void *)qi->rbase, qi->rxnum*sizeof(mal_bd_t));
+ }
+ if (tx_deir != 0) {
+ // Fix Tx descriptor problems
+ CYGARC_MTDCR(MAL0_TXDEIR, tx_deir); // Clear interrupt indicator
+ CYGARC_MTDCR(MAL0_TXCASR, MAL_CASR_C0);
+ qi->tnext = qi->tbase;
+ }
+ if (rx_deir != 0) {
+ // Fix Rx descriptor problems
+ CYGARC_MTDCR(MAL0_RXDEIR, rx_deir); // Clear interrupt indicator
+ CYGARC_MTDCR(MAL0_RXCASR, MAL_CASR_C0);
+ qi->rnext = qi->rbase;
+ }
+ CYGARC_MTDCR(MAL0_ESR, event); // Clear events just handled
+ }
+ if (need_reset) {
+ // Something has gone awry - try resetting the device
+ os_printf("\n... PPC405 ethernet - hard reset after failure\n");
+ ppc405_eth_stop(sc);
+ if (!ppc405_eth_reset(sc, qi->cfg_enaddr, 0)) {
+ os_printf("!! Failed? !!\n");
+ }
+ }
+}
+
+//
+// Interrupt vector
+//
+static int
+ppc405_eth_int_vector(struct eth_drv_sc *sc)
+{
+ struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private;
+ return qi->int_vector;
+}
diff --git a/ecos/packages/devs/eth/powerpc/ppc405/current/src/ppc405_enet.h b/ecos/packages/devs/eth/powerpc/ppc405/current/src/ppc405_enet.h
new file mode 100644
index 0000000..3e555d1
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/ppc405/current/src/ppc405_enet.h
@@ -0,0 +1,360 @@
+//==========================================================================
+//
+// ppc405.h
+//
+// PowerPC PPC405GP Ethernet
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2003-08-15
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// PowerPC PPC405 Ethernet
+
+//
+// Ethernet MAC controller registers
+//
+#define EMAC0_MR0 *(volatile unsigned long *)0xEF600800
+#define EMAC0_MR1 *(volatile unsigned long *)0xEF600804
+#define EMAC0_TMR0 *(volatile unsigned long *)0xEF600808
+#define EMAC0_TMR1 *(volatile unsigned long *)0xEF60080C
+#define EMAC0_RMR *(volatile unsigned long *)0xEF600810
+#define EMAC0_ISR *(volatile unsigned long *)0xEF600814
+#define EMAC0_ISER *(volatile unsigned long *)0xEF600818
+#define EMAC0_IAHR *(volatile unsigned long *)0xEF60081C
+#define EMAC0_IALR *(volatile unsigned long *)0xEF600820
+#define EMAC0_VTPID *(volatile unsigned long *)0xEF600824
+#define EMAC0_VTCI *(volatile unsigned long *)0xEF600828
+#define EMAC0_PRT *(volatile unsigned long *)0xEF60082C
+#define EMAC0_IAHT1 *(volatile unsigned long *)0xEF600830
+#define EMAC0_IAHT2 *(volatile unsigned long *)0xEF600834
+#define EMAC0_IAHT3 *(volatile unsigned long *)0xEF600838
+#define EMAC0_IAHT4 *(volatile unsigned long *)0xEF60083C
+#define EMAC0_GAHT1 *(volatile unsigned long *)0xEF600840
+#define EMAC0_GAHT2 *(volatile unsigned long *)0xEF600844
+#define EMAC0_GAHT3 *(volatile unsigned long *)0xEF600848
+#define EMAC0_GAHT4 *(volatile unsigned long *)0xEF60084C
+#define EMAC0_LSAH *(volatile unsigned long *)0xEF600850
+#define EMAC0_LSAL *(volatile unsigned long *)0xEF600854
+#define EMAC0_IPGVR *(volatile unsigned long *)0xEF600858
+#define EMAC0_STACR *(volatile unsigned long *)0xEF60085C
+#define EMAC0_TRTR *(volatile unsigned long *)0xEF600860
+#define EMAC0_RWMR *(volatile unsigned long *)0xEF600864
+#define EMAC0_OCTX *(volatile unsigned long *)0xEF600868
+#define EMAC0_OCRX *(volatile unsigned long *)0xEF60086C
+
+//
+// Mode Register 0
+//
+#define EMAC0_MR0_RXI 0x80000000 // RX MAC Idle (1 = RX is idle)
+#define EMAC0_MR0_TXI 0x40000000 // TX MAC Idle (1 = TX is idle)
+#define EMAC0_MR0_SRST 0x20000000
+#define EMAC0_MR0_TXE 0x10000000
+#define EMAC0_MR0_RXE 0x08000000
+#define EMAC0_MR0_WKE 0x04000000
+
+//
+// Mode Register 1
+//
+#define EMAC0_MR1_FDE 0x80000000
+#define EMAC0_MR1_ILE 0x40000000
+#define EMAC0_MR1_VLE 0x20000000
+#define EMAC0_MR1_EIFC 0x10000000
+#define EMAC0_MR1_APP 0x08000000
+#define EMAC0_MR1_IST 0x01000000
+#define EMAC0_MR1_MF 0x00C00000
+#define EMAC0_MR1_MF_10MB 0x00000000
+#define EMAC0_MR1_MF_100MB 0x00400000
+#define EMAC0_MR1_RFS 0x00300000
+#define EMAC0_MR1_RFS_512 0x00000000
+#define EMAC0_MR1_RFS_1024 0x00100000
+#define EMAC0_MR1_RFS_2048 0x00200000
+#define EMAC0_MR1_RFS_4096 0x00300000
+#define EMAC0_MR1_TFS 0x000C0000
+#define EMAC0_MR1_TFS_1024 0x00040000
+#define EMAC0_MR1_TFS_2048 0x00080000
+#define EMAC0_MR1_TR0 0x00018000
+#define EMAC0_MR1_TR0_SINGLE 0x00000000
+#define EMAC0_MR1_TR0_MULTI 0x00008000
+#define EMAC0_MR1_TR0_DEP 0x00010000
+#define EMAC0_MR1_TR1 0x00006000
+#define EMAC0_MR1_TR1_SINGLE 0x00000000
+#define EMAC0_MR1_TR1_MULTI 0x00002000
+#define EMAC0_MR1_TR1_DEP 0x00004000
+
+//
+// Transmit mode register 0
+//
+#define EMAC0_TMR0_GNP0 0x80000000
+#define EMAC0_TMR0_GNP1 0x40000000
+#define EMAC0_TMR0_GNPD 0x20000000
+#define EMAC0_TMR0_FC 0x10000000
+
+//
+// Transmit mode register 1
+//
+#define EMAC0_TMR1_TLR 0xF8000000
+#define EMAC0_TMR1_TLR_SHIFT (32-5)
+#define EMAC0_TMR1_TUR 0x00FF0000
+#define EMAC0_TMR1_TUR_SHIFT (32-16)
+
+//
+// Receive mode register
+//
+#define EMAC0_RMR_SP 0x80000000
+#define EMAC0_RMR_SFCS 0x40000000
+#define EMAC0_RMR_RRP 0x20000000
+#define EMAC0_RMR_RFP 0x10000000
+#define EMAC0_RMR_ROP 0x08000000
+#define EMAC0_RMR_RPIR 0x04000000
+#define EMAC0_RMR_PPP 0x02000000
+#define EMAC0_RMR_PME 0x01000000
+#define EMAC0_RMR_PMME 0x00800000
+#define EMAC0_RMR_IAE 0x00400000
+#define EMAC0_RMR_MIAE 0x00200000
+#define EMAC0_RMR_BAE 0x00100000
+#define EMAC0_RMR_MAE 0x00080000
+
+//
+// Interrupt status
+//
+#define EMAC0_ISR_OVR 0x02000000 // Rx overrun
+#define EMAC0_ISR_PP 0x01000000 // Pause packet received
+#define EMAC0_ISR_BP 0x00800000 // Rx bad packet
+#define EMAC0_ISR_RP 0x00400000 // Rx runt packet
+#define EMAC0_ISR_SE 0x00200000 // Rx short event
+#define EMAC0_ISR_ALE 0x00100000 // Rx alignment error
+#define EMAC0_ISR_BFCS 0x00080000 // Rx bad FCS
+#define EMAC0_ISR_PTLE 0x00040000 // Rx packet too long
+#define EMAC0_ISR_ORE 0x00020000 // Rx packet out of range
+#define EMAC0_ISR_IRE 0x00010000 // Rx packet in range error
+#define EMAC0_ISR_DBDM 0x00000200
+#define EMAC0_ISR_DB0 0x00000100
+#define EMAC0_ISR_SE0 0x00000080
+#define EMAC0_ISR_TE0 0x00000040
+#define EMAC0_ISR_DB1 0x00000020
+#define EMAC0_ISR_SE1 0x00000010
+#define EMAC0_ISR_TE1 0x00000008
+#define EMAC0_ISR_MOS 0x00000002
+#define EMAC0_ISR_MOF 0x00000001
+
+//
+// Interrupt status enable - same as interrupt status
+//
+
+//
+// STA control register - MII interface
+//
+#define EMAC0_STACR_PHYD 0xFFFF0000
+#define EMAC0_STACR_PHYD_SHIFT (32-16)
+#define EMAC0_STACR_OC 0x00008000
+#define EMAC0_STACR_PHYE 0x00004000
+#define EMAC0_STACR_STAC 0x00003000
+#define EMAC0_STACR_STAC_READ 0x00001000
+#define EMAC0_STACR_STAC_WRITE 0x00002000
+#define EMAC0_STACR_OPBC 0x00000C00
+#define EMAC0_STACR_OPBC_50 0x00000000
+#define EMAC0_STACR_OPBC_66 0x00000400
+#define EMAC0_STACR_OPBC_83 0x00000800
+#define EMAC0_STACR_OPBC_100 0x00000C00
+#define EMAC0_STACR_PCDA 0x000003E0
+#define EMAC0_STACR_PCDA_SHIFT (32-27)
+#define EMAC0_STACR_PRA 0x0000001F
+
+//
+// Transmit request threshold
+//
+#define EMAC0_TRTR_TRT 0xF8000000 // 0=64, 1=128, 2=192, etc
+#define EMAC0_TRTR_TRT_SHIFT (32-5)
+#define EMAC0_TRTR_TRT_SCALE 64
+
+//
+// Receive high/low water marks
+//
+#define EMAC0_RWMR_RLWM 0xFF800000
+#define EMAC0_RWMR_RLWM_SHIFT (32-9)
+#define EMAC0_RWMR_RHWM 0x0000FF80
+#define EMAC0_RWMR_RHWM_SHIFT (32-25)
+
+//
+// Memory Access Layer (MAL) - in DCR space
+//
+#define MAL0_CFG 0x180
+#define MAL0_ESR 0x181
+#define MAL0_IER 0x182
+#define MAL0_TXCASR 0x184
+#define MAL0_TXCARR 0x185
+#define MAL0_TXEOBISR 0x186
+#define MAL0_TXDEIR 0x187
+#define MAL0_RXCASR 0x190
+#define MAL0_RXCARR 0x191
+#define MAL0_RXEOBISR 0x192
+#define MAL0_RXDEIR 0x193
+#define MAL0_TXCTP0R 0x1A0
+#define MAL0_TXCTP1R 0x1A1
+#define MAL0_RXCTP0R 0x1C0
+#define MAL0_RXBS0 0x1E0
+
+//
+// MAL configuration
+//
+#define MAL_CFG_SR 0x80000000
+#define MAL_CFG_PLBP 0x00C00000
+#define MAL_CFG_PLBP_0 0x00000000
+#define MAL_CFG_PLBP_1 0x00400000
+#define MAL_CFG_PLBP_2 0x00800000
+#define MAL_CFG_PLBP_3 0x00C00000
+#define MAL_CFG_GA 0x00200000
+#define MAL_CFG_OA 0x00100000
+#define MAL_CFG_PLBLE 0x00080000
+#define MAL_CFG_PLBLT 0x00078000
+#define MAL_CFG_PLBLT_SHIFT (32-17)
+#define MAL_CFG_PLBT_DEFAULT (0x07<<MAL_CFG_PLBLT_SHIFT)
+#define MAL_CFG_PLBB 0x00004000
+#define MAL_CFG_OPBBL 0x00000080
+#define MAL_CFG_EOPIE 0x00000004
+#define MAL_CFG_LEA 0x00000002
+#define MAL_CFG_SD 0x00000001
+
+//
+// Channel active set/reset
+//
+#define MAL_CASR_C0 0x80000000
+#define MAL_CASR_C1 0x40000000
+
+//
+// Error and interrupt status
+//
+#define MAL_ESR_EVB 0x80000000
+#define MAL_ESR_CID 0x7E000000
+#define MAL_ESR_CID_SHIFT (32-7)
+#define MAL_ESR_DE 0x00100000
+#define MAL_ESR_ONE 0x00080000
+#define MAL_ESR_OTE 0x00040000
+#define MAL_ESR_OSE 0x00020000
+#define MAL_ESR_PEIN 0x00010000
+#define MAL_ESR_DEI 0x00000010
+#define MAL_ESR_ONEI 0x00000008
+#define MAL_ESR_OTEI 0x00000004
+#define MAL_ESR_OSEI 0x00000002
+#define MAL_ESR_PBEI 0x00000001
+#define MAL_ESR_INT_MASK 0x0000001F
+
+
+//
+// MAL Buffer Descriptor
+//
+typedef struct mal_bd {
+ unsigned short status;
+ unsigned short length;
+ unsigned long buffer;
+} mal_bd_t;
+
+//
+// Status flags
+//
+#define MAL_BD_R 0x8000
+#define MAL_BD_W 0x4000
+#define MAL_BD_CM 0x2000
+#define MAL_BD_L 0x1000
+#define MAL_BD_F 0x0800
+#define MAL_BD_I 0x0400
+// EMAC TX bits (command - set before activating buffer)
+#define MAL_BD_TX_GFCS 0x0200
+#define MAL_BD_TX_GPAD 0x0100
+#define MAL_BD_TX_ISA 0x0080
+#define MAL_BD_TX_RSA 0x0040
+#define MAL_BD_TX_IVLA 0x0020
+#define MAL_BD_TX_RVLA 0x0010
+// EMAC TX bits (status - valid after buffer completes)
+#define MAL_BD_TX_BFCS 0x0200
+#define MAL_BD_TX_BPP 0x0100
+#define MAL_BD_TX_LOC 0x0080
+#define MAL_BD_TX_EDEF 0x0040
+#define MAL_BD_TX_ECOL 0x0020
+#define MAL_BD_TX_LATE 0x0010
+#define MAL_BD_TX_MULT 0x0008
+#define MAL_BD_TX_SNGL 0x0004
+#define MAL_BD_TX_URUN 0x0002
+#define MAL_BD_TX_SQE 0x0001
+// EMAC RX bits (only after buffer completes)
+#define MAL_BD_RX_ORUN 0x0200
+#define MAL_BD_RX_PP 0x0100
+#define MAL_BD_RX_BP 0x0080
+#define MAL_BD_RX_RP 0x0040
+#define MAL_BD_RX_SE 0x0020
+#define MAL_BD_RX_ALE 0x0010
+#define MAL_BD_RX_BFCS 0x0008
+#define MAL_BD_RX_PTL 0x0004
+#define MAL_BD_RX_ORNG 0x0002
+#define MAL_BD_RX_IRNG 0x0001
+
+//
+// Private information kept about interface
+//
+struct ppc405_eth_info {
+ // These fields should be defined by the implementation
+ int int_vector;
+ char *esa_key; // RedBoot 'key' for device ESA
+ unsigned char *enaddr;
+ int rxnum; // Number of Rx buffers
+ unsigned char *rxbuf; // Rx buffer space
+ mal_bd_t *rxbd_table; // Rx buffer headers
+ int txnum; // Number of Tx buffers
+ unsigned char *txbuf; // Tx buffer space
+ mal_bd_t *txbd_table; // Tx buffer headers
+ eth_phy_access_t *phy; // Routines to access PHY
+ // The following fields are maintained by the driver
+ volatile mal_bd_t *txbd, *rxbd; // Next Tx,Rx descriptor to use
+ volatile mal_bd_t *tbase, *rbase; // First Tx,Rx descriptor
+ volatile mal_bd_t *tnext, *rnext; // Next descriptor to check for interrupt
+ int txsize, rxsize; // Length of individual buffers
+ int txactive; // Count of active Tx buffers
+ unsigned long txkey[CYGNUM_DEVS_ETH_POWERPC_PPC405_TxNUM];
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ unsigned long ints; // Mask of interrupts in progress
+#endif
+ unsigned char cfg_enaddr[6]; // Last configured ESA
+};
+
diff --git a/ecos/packages/devs/eth/powerpc/quicc/current/ChangeLog b/ecos/packages/devs/eth/powerpc/quicc/current/ChangeLog
new file mode 100644
index 0000000..f3beaa4
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc/current/ChangeLog
@@ -0,0 +1,223 @@
+2004-10-11 Harald Kuethe <hkuethe@controlware.de>
+
+ * src/if_quicc.c (quicc_eth_RxEvent): remove CRC from the packet.
+
+2003-08-19 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_quicc.c (quicc_eth_init): Use 'quicc_eth_command()'
+ function instead of brute-force inline code.
+
+2003-07-14 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_quicc.c (quicc_eth_init): Only flush cache if enabled.
+
+ * cdl/quicc_eth_drivers.cdl: Force serial debug messages during
+ initialization (work around startup issues with RedBoot).
+
+2003-03-28 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_quicc.c: Align data buffers on cache boundary.
+
+2003-03-14 Nick Garnett <nickg@calivar.com>
+
+ * src/if_quicc.c: Fixed several bugs, mostly dealing with getting
+ the device restarted after certain failures such as collisions.
+
+ * src/quicc_eth.h: Added some statistics gathering.
+
+2003-03-06 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_quicc.c (quicc_eth_init): New name for CPM/DPRAM allocator.
+
+2002-11-25 Gary Thomas <gthomas@ecoscentric.com>
+
+ * src/quicc_eth.h:
+ * src/if_quicc.c: Split platform specifics into separate packages.
+
+2002-08-08 Gary Thomas <gthomas@ecoscentric.com>
+2002-08-08 Luoqi Chen <lchen@onetta.com>
+
+ * src/if_quicc.c (quicc_eth_send): Need to flush cache to force
+ out data, not invalidate it.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_quicc.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-05-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_quicc.c: Use CYGINT_IO_ETH_INT_SUPPORT_REQUIRED where
+ appropriate.
+
+2001-08-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c:
+ printf() is no longer a part of RedBoot. Thus all programs
+ must use diag_printf() and related functions instead.
+
+2001-05-07 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c (quicc_eth_init): Get ESA from RedBoot 'fconfig' data.
+ Improve interrupt interroperability when running with RedBoot and
+ sharing the network connection. Proper operation requires a new
+ RedBoot at least as new as this file.
+
+2001-01-30 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c: New RedBoot config data layout.
+
+2001-01-03 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c: Add support in RedBoot to keep ESA (since
+ the I2C interface is really broken).
+
+2000-10-20 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c: Changes to compile in stand-alone mode.
+
+2000-09-01 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/if_quicc.c (quicc_eth_init): Work with new fast net
+ thread to do all the copying work instead of loading up DSR time.
+ In detail:
+ o New "deliver" function in the interface record.
+ o The DSR changed to be that new function; its arg is now the sc
+ pointer already, no cast needed.
+ o In creating the interrupt, use eth_drv_dsr (from the logical
+ driver) instead of quicc_eth_dsr (which is gone).
+
+
+2000-08-23 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c: Add function to return interrupt vector used
+ by the interface.
+
+2000-08-03 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/quicc_eth_drivers.cdl: Ethernet driver package hierarchy changed.
+
+2000-07-26 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c: Update for new eth_drv interfaces.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-03-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c (quicc_eth_recv): Handle case where there were
+ no buffers (and thus the sg_list[] contains NULL pointers).
+
+2000-03-06 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c: New driver API.
+
+2000-03-05 Gary Thomas <gthomas@redhat.com>
+
+ * src/if_quicc.c: Cleanup to remove compiler warnings.
+
+2000-03-03 Gary Thomas <gthomas@redhat.com>
+
+ * src/quicc_eth.h: Move standard CPM defines to common (ppc8xx.h).
+
+ * src/if_quicc.c: Fetch ethernet hardware address (MAC) from the
+ board EEPROM. Also remove a bunch of diagnostic prints which aren't
+ needed any longer, now that the device is properly running.
+
+2000-03-01 Gary Thomas <gthomas@redhat.com>
+
+ * src/quicc_eth.h (MBX_CTL1):
+ * src/if_quicc.c (quicc_eth_init): Add intialization of board control
+ register which lets driver work when booted from eCos/GDB.
+
+2000-03-01 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/if_quicc.c: Lots of fixes. Now works, but only if application
+ is booted via PPCbug (some initialization is still missing).
+
+2000-02-29 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/quicc_eth.h:
+ * src/if_quicc.c: Some improvements. Almost works when booted via
+ PPCbug, but not from eCos/GDB.
+
+2000-02-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/quicc_eth_drivers.cdl:
+ * src/quicc_eth.h
+ * src/if_quicc.c: New file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/quicc/current/cdl/quicc_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/quicc/current/cdl/quicc_eth_drivers.cdl
new file mode 100644
index 0000000..9995b3b
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc/current/cdl/quicc_eth_drivers.cdl
@@ -0,0 +1,115 @@
+# ====================================================================
+#
+# quicc_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for PowerPC MPC8xx
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-01-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_QUICC {
+ display "MPC8xx QUICC ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_MPC8xx
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+
+ # Debug I/O during network stack initialization is not reliable
+ requires { !CYGPKG_NET || CYGPKG_NET_FORCE_SERIAL_CONSOLE == 1 }
+
+ description "Ethernet driver for PowerPC MPC8xx boards."
+ compile -library=libextras.a if_quicc.c
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE {
+ display "Buffer size"
+ flavor data
+ default_value 1520
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC QUICC/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM {
+ display "Number of output buffers"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC QUICC/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM {
+ display "Number of input buffers"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC QUICC/ethernet device."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_POWERPC_QUICC_OPTIONS {
+ display "MPC8xx QUICC ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_POWERPC_QUICC_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the MPC8xx QUICC ethernet driver package. These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c b/ecos/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c
new file mode 100644
index 0000000..e1b5090
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c
@@ -0,0 +1,815 @@
+//==========================================================================
+//
+// dev/if_quicc.c
+//
+// Ethernet device driver for PowerPC QUICC (MPC8xx) boards
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, nickg
+// Date: 2000-01-10
+// Purpose:
+// Description: hardware driver for MPC8xx QUICC
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// Ethernet device driver for MPC8xx QUICC
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_powerpc_quicc.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#endif
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#include "quicc_eth.h"
+
+static unsigned char quicc_eth_rxbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM]
+ [CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char quicc_eth_txbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM]
+ [CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+static struct quicc_eth_info quicc_eth0_info;
+static unsigned char _default_enaddr[] = { 0x08, 0x00, 0x3E, 0x28, 0x79, 0xB8};
+static unsigned char enaddr[6];
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+RedBoot_config_option("Network hardware address [MAC]",
+ quicc_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif
+#endif
+
+// For fetching the ESA from RedBoot
+#include <cyg/hal/hal_if.h>
+#ifndef CONFIG_ESA
+#define CONFIG_ESA 6
+#endif
+
+ETH_DRV_SC(quicc_eth0_sc,
+ &quicc_eth0_info, // Driver specific data
+ "eth0", // Name for this interface
+ quicc_eth_start,
+ quicc_eth_stop,
+ quicc_eth_control,
+ quicc_eth_can_send,
+ quicc_eth_send,
+ quicc_eth_recv,
+ quicc_eth_deliver,
+ quicc_eth_int,
+ quicc_eth_int_vector);
+
+NETDEVTAB_ENTRY(quicc_netdev,
+ "quicc_eth",
+ quicc_eth_init,
+ &quicc_eth0_sc);
+
+// LED activity [exclusive of hardware bits]
+#ifndef _get_led
+#define _get_led()
+#define _set_led(v)
+#endif
+#ifndef LED_TxACTIVE
+#define LED_TxACTIVE 7
+#define LED_RxACTIVE 6
+#define LED_IntACTIVE 5
+#endif
+
+static void
+set_led(int bit)
+{
+ _set_led(_get_led() | (1<<bit));
+}
+
+static void
+clear_led(int bit)
+{
+ _set_led(_get_led() & ~(1<<bit));
+}
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_interrupt quicc_eth_interrupt;
+static cyg_handle_t quicc_eth_interrupt_handle;
+#endif
+static void quicc_eth_int(struct eth_drv_sc *data);
+static void quicc_eth_command(struct eth_drv_sc *sc, unsigned long cmd);
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+// This ISR is called when the ethernet interrupt occurs
+static int
+quicc_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_drv_interrupt_mask(QUICC_ETH_INT);
+ cyg_drv_interrupt_acknowledge(QUICC_ETH_INT);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+#endif
+
+// Deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+quicc_eth_deliver(struct eth_drv_sc * sc)
+{
+ quicc_eth_int(sc);
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(QUICC_ETH_INT);
+#endif
+}
+
+//
+// Initialize the interface - performed at system startup
+// This function must set up the interface, including arranging to
+// handle interrupts, etc, so that it may be "started" cheaply later.
+//
+static bool
+quicc_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
+ volatile EPPC *eppc = (volatile EPPC *)eppc_base();
+ struct cp_bufdesc *rxbd, *txbd;
+ unsigned char *RxBUF, *TxBUF, *ep, *ap;
+ volatile struct ethernet_pram *enet_pram;
+ volatile struct scc_regs *scc;
+ int TxBD, RxBD;
+ int cache_state;
+ int i;
+ bool esa_ok = false;
+
+#ifdef QUICC_ETH_FETCH_ESA
+ QUICC_ETH_FETCH_ESA(esa_ok);
+#endif
+
+ if (!esa_ok) {
+#if defined(CYGPKG_REDBOOT) && \
+ defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+ esa_ok = flash_get_config("quicc_esa", enaddr, CONFIG_ESA);
+#else
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "quicc_esa", enaddr, CONFIG_ESA);
+#endif
+ if (!esa_ok) {
+ // Can't figure out ESA
+ diag_printf("QUICC_ETH - Warning! ESA unknown\n");
+ memcpy(&enaddr, &_default_enaddr, sizeof(enaddr));
+ }
+ }
+
+ // Ensure consistent state between cache and what the QUICC sees
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ }
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ // Set up to handle interrupts
+ cyg_drv_interrupt_create(QUICC_ETH_INT,
+ CYGARC_SIU_PRIORITY_HIGH,
+ (cyg_addrword_t)sc, // Data item passed to interrupt handler
+ (cyg_ISR_t *)quicc_eth_isr,
+ (cyg_DSR_t *)eth_drv_dsr,
+ &quicc_eth_interrupt_handle,
+ &quicc_eth_interrupt);
+ cyg_drv_interrupt_attach(quicc_eth_interrupt_handle);
+ cyg_drv_interrupt_acknowledge(QUICC_ETH_INT);
+ cyg_drv_interrupt_unmask(QUICC_ETH_INT);
+#endif
+
+ qi->pram = enet_pram = &eppc->pram[QUICC_ETH_SCC].enet_scc;
+ qi->ctl = scc = &eppc->scc_regs[QUICC_ETH_SCC]; // Use SCCx
+
+ // Shut down ethernet, in case it is already running
+ scc->scc_gsmr_l &= ~(QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT);
+
+ memset((void *)enet_pram, 0, sizeof(*enet_pram));
+
+ TxBD = _mpc8xx_allocBd(CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM * sizeof(struct cp_bufdesc));
+ RxBD = _mpc8xx_allocBd(CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM * sizeof(struct cp_bufdesc));
+
+ txbd = (struct cp_bufdesc *)((char *)eppc + TxBD);
+ rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD);
+ qi->tbase = txbd;
+ qi->txbd = txbd;
+ qi->tnext = txbd;
+ qi->rbase = rxbd;
+ qi->rxbd = rxbd;
+ qi->rnext = rxbd;
+ qi->txactive = 0;
+
+ RxBUF = &quicc_eth_rxbufs[0][0];
+ TxBUF = &quicc_eth_txbufs[0][0];
+
+ // setup buffer descriptors
+ for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM; i++) {
+ rxbd->length = 0;
+ rxbd->buffer = RxBUF;
+ rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;
+ RxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
+ rxbd++;
+ }
+ rxbd--;
+ rxbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer
+ for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM; i++) {
+ txbd->length = 0;
+ txbd->buffer = TxBUF;
+ txbd->ctrl = 0;
+ TxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
+ txbd++;
+ }
+ txbd--;
+ txbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer
+
+ // Set up parallel ports for connection to ethernet tranceiver
+ eppc->pio_papar |= (QUICC_ETH_PA_RXD | QUICC_ETH_PA_TXD);
+ eppc->pio_padir &= ~(QUICC_ETH_PA_RXD | QUICC_ETH_PA_TXD);
+ eppc->pio_paodr &= ~QUICC_ETH_PA_TXD;
+
+ eppc->pio_pcpar &= ~(QUICC_ETH_PC_COLLISION | QUICC_ETH_PC_Rx_ENABLE);
+ eppc->pio_pcdir &= ~(QUICC_ETH_PC_COLLISION | QUICC_ETH_PC_Rx_ENABLE);
+ eppc->pio_pcso |= (QUICC_ETH_PC_COLLISION | QUICC_ETH_PC_Rx_ENABLE);
+
+ eppc->pio_papar |= (QUICC_ETH_PA_Tx_CLOCK | QUICC_ETH_PA_Rx_CLOCK);
+ eppc->pio_padir &= ~(QUICC_ETH_PA_Tx_CLOCK | QUICC_ETH_PA_Rx_CLOCK);
+
+ // Set up clock routing
+ eppc->si_sicr &= ~QUICC_ETH_SICR_MASK;
+ eppc->si_sicr |= QUICC_ETH_SICR_ENET;
+ eppc->si_sicr &= ~QUICC_ETH_SICR_ENABLE;
+
+ // Set up DMA mode
+ eppc->dma_sdcr = 0x0001;
+
+ // Initialize shared PRAM
+ enet_pram->rbase = RxBD;
+ enet_pram->tbase = TxBD;
+
+ // Set Big Endian mode
+ enet_pram->rfcr = QUICC_SCC_FCR_BE;
+ enet_pram->tfcr = QUICC_SCC_FCR_BE;
+
+ // Size of receive buffers
+ enet_pram->mrblr = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
+
+ // Initialize CRC calculations
+ enet_pram->c_pres = 0xFFFFFFFF;
+ enet_pram->c_mask = 0xDEBB20E3; // Actual CRC formula
+ enet_pram->crcec = 0;
+ enet_pram->alec = 0;
+ enet_pram->disfc = 0;
+
+ // Frame padding
+ enet_pram->pads = 0x8888;
+ enet_pram->pads = 0x0000;
+
+ // Retries
+ enet_pram->ret_lim = 15;
+ enet_pram->ret_cnt = 0;
+
+ // Frame sizes
+ enet_pram->mflr = IEEE_8023_MAX_FRAME;
+ enet_pram->minflr = IEEE_8023_MIN_FRAME;
+ enet_pram->maxd1 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
+ enet_pram->maxd2 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
+
+ // Group address hash
+ enet_pram->gaddr1 = 0;
+ enet_pram->gaddr2 = 0;
+ enet_pram->gaddr3 = 0;
+ enet_pram->gaddr4 = 0;
+
+ // Device physical address
+ ep = &enaddr[sizeof(enaddr)];
+ ap = (unsigned char *)&enet_pram->paddr_h;
+ for (i = 0; i < sizeof(enaddr); i++) {
+ *ap++ = *--ep;
+ }
+
+ // Persistence counter
+ enet_pram->p_per = 0;
+
+ // Individual address filter
+ enet_pram->iaddr1 = 0;
+ enet_pram->iaddr2 = 0;
+ enet_pram->iaddr3 = 0;
+ enet_pram->iaddr4 = 0;
+
+ // Temp address
+ enet_pram->taddr_h = 0;
+ enet_pram->taddr_m = 0;
+ enet_pram->taddr_l = 0;
+
+ // Initialize the CPM (set up buffer pointers, etc).
+ quicc_eth_command(sc, QUICC_CPM_CR_INIT_TXRX);
+
+ // Clear any pending interrupt/exceptions
+ scc->scc_scce = 0xFFFF;
+
+ // Enable interrupts
+ scc->scc_sccm = QUICC_SCCE_INTS | QUICC_SCCE_GRC | QUICC_SCCE_BSY;
+
+ // Set up SCCx to run in ethernet mode
+ scc->scc_gsmr_h = 0;
+ scc->scc_gsmr_l = QUICC_SCC_GSML_TCI | QUICC_SCC_GSML_TPL_48 |
+ QUICC_SCC_GSML_TPP_01 | QUICC_SCC_GSML_MODE_ENET;
+
+ // Sync delimiters
+ scc->scc_dsr = 0xD555;
+
+ // Protocol specifics (as if GSML wasn't enough)
+ scc->scc_psmr = QUICC_PMSR_ENET_CRC | QUICC_PMSR_SEARCH_AFTER_22 |
+ QUICC_PMSR_RCV_SHORT_FRAMES;
+
+#ifdef QUICC_ETH_ENABLE
+ QUICC_ETH_ENABLE();
+#endif
+
+#ifdef QUICC_ETH_RESET_PHY
+ QUICC_ETH_RESET_PHY();
+#endif
+
+ // Enable ethernet interface
+#ifdef QUICC_ETH_PC_Tx_ENABLE
+ eppc->pio_pcpar |= QUICC_ETH_PC_Tx_ENABLE;
+ eppc->pio_pcdir &= ~QUICC_ETH_PC_Tx_ENABLE;
+#else
+ eppc->pip_pbpar |= QUICC_ETH_PB_Tx_ENABLE;
+ eppc->pip_pbdir |= QUICC_ETH_PB_Tx_ENABLE;
+#endif
+
+ if (cache_state)
+ HAL_DCACHE_ENABLE();
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr);
+
+ // Set LED state
+ clear_led(LED_TxACTIVE);
+ clear_led(LED_RxACTIVE);
+
+ return true;
+}
+
+//
+// This function is called to shut down the interface.
+//
+static void
+quicc_eth_stop(struct eth_drv_sc *sc)
+{
+ struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
+ volatile struct scc_regs *scc = qi->ctl;
+
+ // Disable the device!
+ scc->scc_gsmr_l &= ~(QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT);
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+quicc_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
+ volatile struct scc_regs *scc = qi->ctl;
+
+ // Enable the device!
+ scc->scc_gsmr_l |= QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT;
+}
+
+//
+// This function is called for low level "control" operations
+//
+static int
+quicc_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int length)
+{
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ return 0;
+ break;
+
+#ifdef ETH_DRV_GET_IF_STATS
+ case ETH_DRV_GET_IF_STATS:
+ {
+ struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+ struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
+
+ strcpy( p->description, "QUICC (MPC8xx) SCC Ethernet" );
+ CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+ // Really need to determine the following values properly, for
+ // now just assume the link is up, full duplex, unknown speed.
+
+ p->operational = 3; // LINK UP
+ p->duplex = 1;
+ p->speed = 0;
+
+ {
+ p->supports_dot3 = false;
+
+ // Those commented out are not available on this chip.
+
+ p->tx_good = qi->tx_good ;
+ //p->tx_max_collisions = qi->tx_max_collisions ;
+ p->tx_late_collisions = qi->tx_late_collisions ;
+ p->tx_underrun = qi->tx_underrun ;
+ p->tx_carrier_loss = qi->tx_carrier_loss ;
+ p->tx_deferred = qi->tx_deferred ;
+ //p->tx_sqetesterrors = qi->tx_sqetesterrors ;
+ //p->tx_single_collisions = qi->tx_single_collisions;
+ //p->tx_mult_collisions = qi->tx_mult_collisions ;
+ //p->tx_total_collisions = qi->tx_total_collisions ;
+ p->rx_good = qi->rx_good ;
+ p->rx_crc_errors = qi->rx_crc_errors ;
+ p->rx_align_errors = qi->rx_align_errors ;
+ p->rx_resource_errors = qi->rx_resource_errors ;
+ p->rx_overrun_errors = qi->rx_overrun_errors ;
+ p->rx_collisions = qi->rx_collisions ;
+ p->rx_short_frames = qi->rx_short_frames ;
+ p->rx_too_long_frames = qi->rx_long_frames ;
+ //p->rx_symbol_errors = qi->rx_symbol_errors ;
+
+ p->interrupts = qi->interrupts ;
+ p->rx_count = qi->rx_count ;
+ p->rx_deliver = qi->rx_deliver ;
+ p->rx_resource = qi->rx_resource ;
+ p->rx_restart = qi->rx_restart ;
+ p->tx_count = qi->tx_count ;
+ p->tx_complete = qi->tx_complete ;
+ p->tx_dropped = qi->tx_dropped ;
+ }
+
+ p->tx_queue_len = CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM;
+
+ return 0; // OK
+ }
+#endif
+
+
+ default:
+ return 1;
+ break;
+ }
+}
+
+//
+// This function is called to see if another packet can be sent.
+// It should return the number of packets which can be handled.
+// Zero should be returned if the interface is busy and can not send any more.
+//
+static int
+quicc_eth_can_send(struct eth_drv_sc *sc)
+{
+ struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
+
+ return (qi->txactive < CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM);
+}
+
+//
+// This routine is called to send data to the hardware.
+static void
+quicc_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
+ volatile struct cp_bufdesc *txbd, *txfirst;
+ volatile char *bp;
+ int i, txindex, cache_state;
+ unsigned int ctrl;
+
+ qi->tx_count++;
+
+ // Find a free buffer
+ txbd = txfirst = qi->txbd;
+ if ((txbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int )))
+#ifdef CYGPKG_NET
+ panic ("No free xmit buffers");
+#else
+ diag_printf("QUICC Ethernet: No free xmit buffers\n");
+#endif
+
+ // Remember the next buffer to try
+ if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
+ qi->txbd = qi->tbase;
+ } else {
+ qi->txbd = txbd+1;
+ }
+ txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
+ qi->txkey[txindex] = key;
+ // Set up buffer
+ txbd->length = total_len;
+ bp = txbd->buffer;
+ for (i = 0; i < sg_len; i++) {
+ memcpy((void *)bp, (void *)sg_list[i].buf, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+ // Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(txbd->buffer, txbd->length); // Make sure no stale data
+ }
+ // Send it on it's way
+ ctrl = txbd->ctrl & ~QUICC_BD_TX_PAD;
+ if (txbd->length < IEEE_8023_MIN_FRAME) {
+ ctrl |= QUICC_BD_TX_PAD;
+ }
+ txbd->ctrl = ctrl | QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int |
+ QUICC_BD_TX_LAST | QUICC_BD_TX_TC;
+ qi->txactive++;
+ set_led(LED_TxACTIVE);
+}
+
+//
+// This function is called when a packet has been received. It's job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'quicc_eth_recv' will be called to actually fetch it from the hardware.
+//
+static void
+quicc_eth_RxEvent(struct eth_drv_sc *sc)
+{
+ struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
+ volatile struct cp_bufdesc *rxbd;
+
+
+ rxbd = qi->rnext;
+ while ((rxbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) {
+
+ qi->rx_count++;
+
+ if( rxbd->ctrl & QUICC_BD_RX_MISS )
+ {
+ qi->rx_miss++;
+ }
+ if( rxbd->ctrl & QUICC_BD_RX_LG )
+ {
+ qi->rx_long_frames++;
+ }
+ if( rxbd->ctrl & QUICC_BD_RX_NO )
+ {
+ qi->rx_align_errors++;
+ }
+ if( rxbd->ctrl & QUICC_BD_RX_SH )
+ {
+ qi->rx_short_frames++;
+ }
+ if( rxbd->ctrl & QUICC_BD_RX_CR )
+ {
+ qi->rx_crc_errors++;
+ }
+ if( rxbd->ctrl & QUICC_BD_RX_OV )
+ {
+ qi->rx_overrun_errors++;
+ }
+
+ if( rxbd->ctrl & QUICC_BD_RX_CL )
+ {
+ qi->rx_collisions++;
+ }
+
+ if( (rxbd->ctrl & QUICC_BD_RX_ERRORS) == 0 )
+ {
+ qi->rx_good++;
+
+ // OK frame - Prepare for callback
+ qi->rxbd = rxbd; // Save for callback
+ set_led(LED_RxACTIVE);
+ // Remove the CRC from the end
+ (sc->funs->eth_drv->recv)(sc, rxbd->length - 4);
+
+ clear_led(LED_RxACTIVE);
+ }
+
+
+ // Clear flags and wrap if needed else step up BD pointer
+ if (rxbd->ctrl & QUICC_BD_CTL_Wrap)
+ {
+ rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int | QUICC_BD_CTL_Wrap;
+ rxbd = qi->rbase;
+ }
+ else
+ {
+ rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;
+ rxbd++;
+ }
+
+ }
+ // Remember where we left off
+ qi->rnext = (struct cp_bufdesc *)rxbd;
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// It's job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+quicc_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
+ unsigned char *bp;
+ int i, cache_state;
+ int sg_list_null_buffer = 0;
+
+ bp = (unsigned char *)qi->rxbd->buffer;
+ // Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(qi->rxbd->buffer, qi->rxbd->length); // Make sure no stale data
+ }
+ for (i = 0; i < sg_len; i++) {
+ if (sg_list[i].buf != 0) {
+ memcpy((void *)sg_list[i].buf, bp, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+ else
+ sg_list_null_buffer = 1;
+ }
+
+ // A NULL sg_list buffer usually means no mbufs, so we don't count
+ // it as a delivery, instead we count it as a resource error.
+
+ if (!sg_list_null_buffer)
+ qi->rx_deliver++;
+ else
+ qi->rx_resource++;
+
+}
+
+static void
+quicc_eth_command( struct eth_drv_sc *sc, unsigned long cmd)
+{
+ volatile EPPC *eppc = (volatile EPPC *)eppc_base();
+
+ eppc->cp_cr = QUICC_CPM_SCCx | cmd | QUICC_CPM_CR_BUSY;
+ while (eppc->cp_cr & QUICC_CPM_CR_BUSY )
+ continue;
+}
+
+static void
+quicc_eth_TxEvent(struct eth_drv_sc *sc, int stat)
+{
+ struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
+ volatile struct cp_bufdesc *txbd;
+ int txindex;
+ bool restart = false;
+
+ txbd = qi->tnext;
+
+ while ((txbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) {
+
+ txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
+
+ qi->tx_complete++;
+
+ (sc->funs->eth_drv->tx_done)(sc, qi->txkey[txindex], 0);
+ txbd->ctrl &= ~QUICC_BD_CTL_Int; // Reset int pending bit
+
+ if (txbd->ctrl & QUICC_BD_TX_LC )
+ qi->tx_late_collisions++, restart = true;
+ if (txbd->ctrl & QUICC_BD_TX_RL )
+ qi->tx_retransmit_error++, restart = true;
+ if (txbd->ctrl & QUICC_BD_TX_UN )
+ qi->tx_underrun++, restart = true;
+ if (txbd->ctrl & QUICC_BD_TX_CSL )
+ qi->tx_carrier_loss++;
+ if (txbd->ctrl & QUICC_BD_TX_HB )
+ qi->tx_heartbeat_loss++;
+ if (txbd->ctrl & QUICC_BD_TX_DEF )
+ qi->tx_deferred++;
+
+ if( (txbd->ctrl & QUICC_BD_TX_ERRORS) == 0 )
+ qi->tx_good++;
+
+
+ if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
+ txbd->ctrl = QUICC_BD_CTL_Wrap;
+ txbd = qi->tbase;
+ } else {
+ txbd->ctrl = 0;
+ txbd++;
+ }
+ qi->txactive--;
+ }
+
+ if (qi->txactive == 0) {
+ clear_led(LED_TxACTIVE);
+ }
+
+ // Remember where we left off
+ qi->tnext = (struct cp_bufdesc *)txbd;
+
+ if (restart)
+ {
+ quicc_eth_command(sc,QUICC_CPM_CR_RESTART_TX);
+ qi->tx_restart++;
+ }
+
+}
+
+//
+// Interrupt processing
+//
+static void
+quicc_eth_int(struct eth_drv_sc *sc)
+{
+ struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
+ volatile struct scc_regs *scc = qi->ctl;
+ unsigned short scce;
+
+ qi->interrupts++;
+
+ while ( (scce = scc->scc_scce) != 0 )
+ {
+ scc->scc_scce = scce;
+
+ if ( (scce & (QUICC_SCCE_TXE | QUICC_SCCE_TX)) != 0)
+ {
+ quicc_eth_TxEvent(sc, scce);
+ }
+ if ( (scce & ( QUICC_SCCE_RXF | QUICC_SCCE_RX )) != 0)
+ {
+ quicc_eth_RxEvent(sc);
+ }
+ if ( (scce & QUICC_SCCE_BSY) != 0)
+ {
+ qi->rx_resource_errors++;
+ }
+ if ( (scce & QUICC_SCCE_GRC) != 0 )
+ {
+ quicc_eth_command(sc, QUICC_CPM_CR_RESTART_TX);
+ qi->tx_restart++;
+ quicc_eth_command(sc, QUICC_CPM_CR_HUNT_MODE);
+ qi->rx_restart++;
+ }
+ }
+}
+
+//
+// Interrupt vector
+//
+static int
+quicc_eth_int_vector(struct eth_drv_sc *sc)
+{
+ return (QUICC_ETH_INT);
+}
diff --git a/ecos/packages/devs/eth/powerpc/quicc/current/src/quicc_eth.h b/ecos/packages/devs/eth/powerpc/quicc/current/src/quicc_eth.h
new file mode 100644
index 0000000..99f3c27
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc/current/src/quicc_eth.h
@@ -0,0 +1,190 @@
+//==========================================================================
+//
+// quicc_eth.h
+//
+// PowerPC QUICC (MPC8xx) ethernet
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, nickg
+// Date: 2000-01-10
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// PowerPC QUICC (MPC8xx) Ethernet
+
+#include <cyg/hal/quicc/ppc8xx.h> // QUICC structure definitions
+
+struct quicc_eth_info {
+ volatile struct ethernet_pram *pram; // Parameter RAM pointer
+ volatile struct scc_regs *ctl; // SCC control registers
+ volatile struct cp_bufdesc *txbd, *rxbd; // Next Tx,Rx descriptor to use
+ struct cp_bufdesc *tbase, *rbase; // First Tx,Rx descriptor
+ struct cp_bufdesc *tnext, *rnext; // Next descriptor to check for interrupt
+ int txsize, rxsize; // Length of individual buffers
+ int txactive; // Count of active Tx buffers
+ unsigned long txkey[CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM];
+
+ // Keep some statistics
+ cyg_uint32 interrupts;
+
+ cyg_uint32 rx_count;
+ cyg_uint32 rx_deliver;
+ cyg_uint32 rx_resource;
+ cyg_uint32 rx_restart;
+ cyg_uint32 rx_good;
+ cyg_uint32 rx_crc_errors;
+ cyg_uint32 rx_align_errors;
+ cyg_uint32 rx_resource_errors;
+ cyg_uint32 rx_overrun_errors;
+ cyg_uint32 rx_collisions;
+ cyg_uint32 rx_short_frames;
+ cyg_uint32 rx_long_frames;
+ cyg_uint32 rx_miss;
+
+ cyg_uint32 tx_count;
+ cyg_uint32 tx_complete;
+ cyg_uint32 tx_restart;
+ cyg_uint32 tx_good;
+ cyg_uint32 tx_dropped;
+ cyg_uint32 tx_underrun;
+ cyg_uint32 tx_late_collisions;
+ cyg_uint32 tx_carrier_loss;
+ cyg_uint32 tx_retransmit_error;
+ cyg_uint32 tx_heartbeat_loss;
+ cyg_uint32 tx_deferred;
+};
+
+// SCC registers - ethernet mode
+
+// General SCC mode register
+#define QUICC_SCC_GSMH_IRP 0x00040000 // Infared polarity
+#define QUICC_SCC_GSMH_GDE 0x00010000 // Glitch detect enable
+#define QUICC_SCC_GSMH_TCRC 0x00008000 // Transparent CRC
+#define QUICC_SCC_GSMH_REVD 0x00004000 // Reverse data (transparent)
+#define QUICC_SCC_GSMH_TRX 0x00002000 // Transparent Rx
+#define QUICC_SCC_GSMH_TTX 0x00001000 // Transparent Tx
+
+#define QUICC_SCC_GSML_TCI 0x10000000 // Transmit clock invert
+#define QUICC_SCC_GSML_TPL 0x00E00000 // Tx preamble bits
+#define QUICC_SCC_GSML_TPL_8 0x00200000 // 8 bits
+#define QUICC_SCC_GSML_TPL_16 0x00400000 // 16 bits
+#define QUICC_SCC_GSML_TPL_32 0x00600000 // 32 bits
+#define QUICC_SCC_GSML_TPL_48 0x00800000 // 48 bits (used for ethernet)
+#define QUICC_SCC_GSML_TPL_64 0x00A00000 // 64 bits
+#define QUICC_SCC_GSML_TPL_128 0x00C00000 // 128 bits
+#define QUICC_SCC_GSML_TPP 0x00180000 // Tx preamble pattern
+#define QUICC_SCC_GSML_TPP_00 0x00000000 // all zeroes
+#define QUICC_SCC_GSML_TPP_01 0x00080000 // 10 repeats (ethernet)
+#define QUICC_SCC_GSML_TPP_10 0x00100000 // 01 repeats
+#define QUICC_SCC_GSML_TPP_11 0x00180000 // all ones (localtalk)
+#define QUICC_SCC_GSML_ENR 0x00000020 // Enable receiver
+#define QUICC_SCC_GSML_ENT 0x00000010 // Enable transmitter
+#define QUICC_SCC_GSML_MODE 0x0000000F // Operating mode
+#define QUICC_SCC_GSML_MODE_HDLC 0x00000000
+#define QUICC_SCC_GSML_MODE_ATALK 0x00000002
+#define QUICC_SCC_GSML_MODE_ENET 0x0000000C
+
+// Function code
+#define QUICC_SCC_FCR_BE 0x0010 // Big Endian operation
+
+// Event register
+#define QUICC_SCCE_GRC 0x0080 // Gracefull stop complete
+#define QUICC_SCCE_TXE 0x0010 // Transmit error
+#define QUICC_SCCE_RXF 0x0008 // Received full frame
+#define QUICC_SCCE_BSY 0x0004 // No free receive buffers
+#define QUICC_SCCE_TX 0x0002 // Buffer transmit complete
+#define QUICC_SCCE_RX 0x0001 // Buffer received
+#define QUICC_SCCE_INTS (QUICC_SCCE_TXE | QUICC_SCCE_RXF | QUICC_SCCE_TX)
+
+// Protocol specific mode register
+#define QUICC_PMSR_HEARTBEAT 0x8000 // Enable heartbeat
+#define QUICC_PMSR_FORCE_COLLISION 0x4000 // Force a collision
+#define QUICC_PMSR_RCV_SHORT_FRAMES 0x2000 // Accept short frames
+#define QUICC_PMSR_INDIV_ADDR_MODE 0x1000 // Check individual address (hash)
+#define QUICC_PMSR_ENET_CRC 0x0800 // Enable ethernet CRC mode
+#define QUICC_PMSR_PROMISCUOUS 0x0200 // Enable promiscuous mode
+#define QUICC_PMSR_BROADCAST 0x0100 // Accept broadcast packets
+#define QUICC_PMSR_SPECIAL_BACKOFF 0x0080 // Enable special backoff timer
+#define QUICC_PMSR_LOOPBACK 0x0040 // Enable loopback mode
+#define QUICC_PMSR_SAMPLE_INPUTS 0x0020 // Discretely look at input pins
+#define QUICC_PMSR_LATE_COLLISION 0x0010 // Enable late collision window
+#define QUICC_PMSR_SEARCH_AFTER_22 0x000A // Start frame search after 22 bits
+#define QUICC_PMSR_FULL_DUPLEX 0x0001 // Full duplex mode
+
+// Receive buffer status
+#define QUICC_BD_RX_LAST 0x0800 // Last buffer in chain
+#define QUICC_BD_RX_FIRST 0x0400 // First buffer in chain
+#define QUICC_BD_RX_MISS 0x0100 // Missed data
+#define QUICC_BD_RX_LG 0x0020 // Rx frame too long
+#define QUICC_BD_RX_NO 0x0010 // Rx frame not properly aligned
+#define QUICC_BD_RX_SH 0x0008 // Rx frame too short
+#define QUICC_BD_RX_CR 0x0004 // Bad CRC
+#define QUICC_BD_RX_OV 0x0002 // Rx overrun
+#define QUICC_BD_RX_CL 0x0001 // Collision during frame
+
+#define QUICC_BD_RX_ERRORS ( QUICC_BD_RX_CL | QUICC_BD_RX_OV | \
+ QUICC_BD_RX_CR | QUICC_BD_RX_SH | \
+ QUICC_BD_RX_NO | QUICC_BD_RX_LG | \
+ QUICC_BD_RX_MISS )
+
+// Transmit buffer status
+#define QUICC_BD_TX_PAD 0x4000 // Pad short packets
+#define QUICC_BD_TX_LAST 0x0800 // Last buffer in chain
+#define QUICC_BD_TX_TC 0x0400 // Transmit CRC after buffer
+#define QUICC_BD_TX_DEF 0x0200 // Transmission was deferred
+#define QUICC_BD_TX_HB 0x0100 // Heartbeat detected
+#define QUICC_BD_TX_LC 0x0080 // Late collision
+#define QUICC_BD_TX_RL 0x0040 // Retransmit limit exceeded
+#define QUICC_BD_TX_RC 0x003C // Retry count
+#define QUICC_BD_TX_UN 0x0002 // Tx underrun
+#define QUICC_BD_TX_CSL 0x0001 // Carrier lost
+
+#define QUICC_BD_TX_ERRORS (QUICC_BD_TX_CSL | QUICC_BD_TX_UN | \
+ QUICC_BD_TX_RL | QUICC_BD_TX_LC | \
+ QUICC_BD_TX_HB | QUICC_BD_TX_DEF )
+
+#include CYGDAT_DEVS_QUICC_ETH_INL // Platform specifics
+
+#define IEEE_8023_MAX_FRAME 1518 // Largest possible ethernet frame
+#define IEEE_8023_MIN_FRAME 64 // Smallest possible ethernet frame
+
diff --git a/ecos/packages/devs/eth/powerpc/quicc2/current/ChangeLog b/ecos/packages/devs/eth/powerpc/quicc2/current/ChangeLog
new file mode 100644
index 0000000..7d8cabc
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc2/current/ChangeLog
@@ -0,0 +1,50 @@
+2004-02-03 Christoph Csebits <christoph.csebits@frequentis.com>
+
+ * src/if_fcc.c (fcc_eth_can_send): Fix: check also if
+ buffer was freed by the upper layer (txdone was called).
+
+2003-03-04 Paul Fine <pfine@delcomsys.com>
+
+ * src/EnetPHY.c : Added PHY reset function for the ts6 platform.
+ Changed delay to use HAL_DELAY_US instead of a nop for loop.
+ * src/if_fec.c : Invoke PHY reset function for ts6 platform, as
+ well as VADS platform. Remove unneeded and incorrect invocation
+ data cache macros.
+
+2002-12-12 Gary Thomas <gthomas@ecoscentric.com>
+2002-12-12 Patrick Doyle <wpd@delcomsys.com>
+
+ * src/types.h:
+ * src/if_fec.c:
+ * src/fec.h:
+ * src/EnetPHY.h:
+ * src/EnetPHY.c:
+ * cdl/quicc2_eth_drivers.cdl: New package; ethernet drivers for
+ PowerPC/QUICC2 based systems (like MPC8260).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/quicc2/current/cdl/quicc2_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/quicc2/current/cdl/quicc2_eth_drivers.cdl
new file mode 100644
index 0000000..a89ed93
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc2/current/cdl/quicc2_eth_drivers.cdl
@@ -0,0 +1,113 @@
+# ====================================================================
+#
+# fec_eth_drivers.cdl
+#
+# Ethernet drivers - platform dependent support for PowerPC MPC8260
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): mtek
+# Original data: gthomas
+# Contributors:
+# Date: 2002-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_QUICC2 {
+ display "MPC8260 FEC ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_MPC8260
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+
+ description "Fast ethernet driver for PowerPC MPC8260 boards."
+ compile -library=libextras.a if_fec.c EnetPHY.c
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE {
+ display "Buffer size"
+ flavor data
+ default_value 1540
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC FEC/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM {
+ display "Number of output buffers"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC FEC/ethernet device."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM {
+ display "Number of input buffers"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC FEC/ethernet device."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_POWERPC_QUICC2_OPTIONS {
+ display "MPC8260 FEC ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_POWERPC_QUICC2_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the MPC8260 FEC ethernet driver package.
+ These flags are used in addition to the set of global
+ flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/quicc2/current/src/EnetPHY.c b/ecos/packages/devs/eth/powerpc/quicc2/current/src/EnetPHY.c
new file mode 100644
index 0000000..6d58049
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc2/current/src/EnetPHY.c
@@ -0,0 +1,378 @@
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+/*-------------------------------------------------------------------
+*
+* FILE: enetPHY.c
+*
+* DESCRIPTION: GPIO Management Pins driver for the LXT970a
+*
+*
+* Modified for the mpc8260 VADS board
+*--------------------------------------------------------------------*/
+#include "types.h"
+#include <cyg/hal/hal_intr.h> /* HAL_DELAY_US */
+#include "EnetPHY.h"
+
+/* Internal functions */
+void MdioSend(UINT32, UINT16);
+UINT16 MdioReceive(UINT16);
+UINT16 MdioFrame(MDIORW, UINT16, UINT16, UINT32);
+
+VUINT32 * pPortDir;
+VUINT32 * pPortData;
+
+/*-------------------------------------------------------------------
+*
+* FUNCTION NAME:
+*
+* DESCRIPTION:
+*
+* EXTERNAL EFFECT: Turns on the LXT970 transciever
+*
+* PARAMETERS:
+*
+* RETURNS: None
+*
+* ASSUMPTIONS:
+*
+*-------------------------------------------------------------------*/
+void
+EnableResetPHY(volatile t_BCSR *pBCSR)
+{
+#ifdef CYGPKG_HAL_POWERPC_TS6
+#define ETH_RST_MASK 0x20
+ /* The FPGA control register on the TS6 board uses the same memory
+ * location as the BCSR register on the VADS board.
+ */
+ volatile cyg_uint32 *fpga_ctrl = (cyg_uint32 *) pBCSR;
+ volatile cyg_uint32 *fpga_vers;
+ cyg_uint32 value;
+ fpga_vers = fpga_ctrl + 1;
+ value = *fpga_vers;
+ if(value >= 6){ /* version 06 of the FPGA added PHY reset control */
+ value = *fpga_ctrl;
+ /* Set the PHY reset bit */
+ value |= ETH_RST_MASK;
+ *fpga_vers = value;
+
+ /* Give the PHY time to reset */
+ HAL_DELAY_US(10000);
+
+ /* Clear the reset bit */
+ *fpga_vers = value & ~ETH_RST_MASK;
+ }
+#else
+ // active low FETHIEN on BSCR1, assert reset low
+ pBCSR->bcsr1 &= ~(FETHIEN_ | FETHRST_);
+ // de-assert reset
+ pBCSR->bcsr1 |= FETHRST_;
+#endif
+}
+
+
+/*-------------------------------------------------------------------
+*
+* FUNCTION NAME:
+*
+* DESCRIPTION: Writes parameters to the control registers of LXT970
+*
+* EXTERNAL EFFECT:
+*
+* PARAMETERS:
+*
+* RETURNS: None
+*
+* ASSUMPTIONS:
+*
+*-------------------------------------------------------------------*/
+UINT16
+InitEthernetPHY(VUINT32* pdir, VUINT32* pdat, UINT16 link)
+{
+
+ VUINT16 FrameValue;
+
+ /* 8101 Ethernet Management Pin Assignments */
+ pPortDir = pdir;
+ pPortData = pdat;
+
+ (*pPortDir) |= MDC_PIN_MASK; /* MD_Clock will always be output only */
+
+ /* Test MDC & MDIO Pin Connection to PHY */
+ MdioFrame(WRITE, 0, MIRROR_REG, MD_TEST_FRAME); //send test frame
+ MdioFrame(WRITE, 0, MIRROR_REG, MD_TEST_FRAME); //send test frame
+ FrameValue = MdioFrame(READ, 0, MIRROR_REG, 0); //read test frame
+
+ if (FrameValue != MD_TEST_FRAME)
+ return LINKERROR; //test data integrity
+
+ /* General Configuration */
+ MdioFrame(WRITE, 0, CONFIG_REG, 0x0000);
+
+ if(link == HUNDRED_HD)
+ MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0081); //100 Mbps Half, 802.3
+ else
+ MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0021); //10 Mbps Half, 802.3
+
+ // 100 Mbps full duplex not supported
+ // MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0101); //100 Mbps Full, 802.3
+
+ MdioFrame(WRITE, 0, CONTROL_REG, 0x1300);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------
+*
+* FUNCTION NAME:
+*
+* DESCRIPTION:
+*
+* EXTERNAL EFFECT:
+*
+* PARAMETERS:
+*
+* RETURNS: None
+*
+* ASSUMPTIONS:
+*
+*-------------------------------------------------------------------*/
+UINT16
+EthernetPHYInterruptHandler()
+{
+ // Reading registers 1 and 18 in sequence
+ // clears the transceiver interrupt
+
+ MdioFrame(READ, 0, STATUS_REG, 0);
+ MdioFrame(READ, 0, INT_STAT_REG, 0);
+
+ return LinkTestPHY();
+} /* end EthernetPHYInterruptHandler */
+
+/*-------------------------------------------------------------------
+*
+* FUNCTION NAME:
+*
+* DESCRIPTION:
+*
+* EXTERNAL EFFECT:
+*
+* PARAMETERS:
+*
+* RETURNS: None
+*
+* ASSUMPTIONS:
+*
+*-------------------------------------------------------------------*/
+UINT16
+LinkTestPHY()
+{
+ UINT32 j;
+ UINT16 FrameValue = 0;
+
+ for (j = 0; j < 50; j++) {
+
+ HAL_DELAY_US(100000);
+
+ FrameValue = MdioFrame(READ,0,CHIP_STAT_REG,0);
+
+ if ( (FrameValue & 0x0200) != 0 )
+ break;
+ }
+
+ FrameValue &= 0x3800;
+
+ switch (FrameValue) {
+
+ case 0x3800: return HUNDRED_FD;
+ case 0x2800: return HUNDRED_HD;
+ case 0x3000: return TEN_FD;
+ case 0x2000: return TEN_HD;
+ default: return NOTLINKED;
+ }
+
+}
+
+/*-------------------------------------------------------------------
+*
+* FUNCTION NAME:
+*
+* DESCRIPTION:
+*
+* EXTERNAL EFFECT:
+*
+* PARAMETERS:
+*
+* RETURNS: None
+*
+* ASSUMPTIONS:
+*
+*-------------------------------------------------------------------*/
+void EnablePHYinterrupt(UINT8 enable)
+{
+ MdioFrame(WRITE, 0, INT_EN_REG, enable?0x2:0x0);
+}
+
+/*----------------------------------------------------------------------
+*
+* FUNCTION NAME:
+*
+* DESCRIPTION: generic READ/WRITE function of LXT970
+* through the MDC/MDIO interface.
+*
+* EXTERNAL EFFECT:
+*
+* PARAMETERS:
+*
+* RETURNS: None
+*
+* ASSUMPTIONS:
+*
+*---------------------------------------------------------------------*/
+UINT16
+MdioFrame(MDIORW R_W, UINT16 PhyAddr, UINT16 RegAddr, UINT32 PutData) {
+
+ UINT16 GetData;
+
+ *pPortDir |= MDIO_PIN_MASK; //set to output mode
+
+ MdioSend(0xFFFFFFFF,32); //PreAmble
+ MdioSend(0x1,2); //Start Frame Delimiter
+ if (R_W==READ)
+ MdioSend(0x2,2); //Read OpCode
+ else
+ MdioSend(0x1,2); //Write OpCode
+
+ MdioSend(PhyAddr,5); //Send PHY transciever Address
+ MdioSend(RegAddr,5); //Send Register Address
+
+ if (R_W==READ) {
+ *pPortDir &= ~MDIO_PIN_MASK; //set to input mode
+ GetData = MdioReceive(17); //Drive TurnAround and Data
+ MdioReceive(2);
+ }
+ else {
+ MdioSend(0x2,2); //Drive TurnAround
+ MdioSend(PutData, 16); //Send Data
+ GetData = 0;
+ *pPortDir &= ~MDIO_PIN_MASK; //set to input mode
+ }
+
+ return GetData;
+
+}
+/*----------------------------------------------------------------------
+*
+* FUNCTION NAME:
+*
+* DESCRIPTION: Shift out bits of data
+*
+* EXTERNAL EFFECT:
+*
+* PARAMETERS:
+*
+* RETURNS: None
+*
+* ASSUMPTIONS:
+*
+*----------------------------------------------------------------------*/
+void
+MdioSend(UINT32 txF, UINT16 size) {
+
+ UINT32 dmask;
+ INT_NATIVE i, j;
+
+ dmask = 1 << (size-1); // msbit out first
+
+ for (i = 0; i < size; i++) { // for "size" bits
+
+ if ( txF & dmask ) //output data bit high
+ *pPortData |= MDIO_PIN_MASK;
+ else //output data bit low > 400ns
+ *pPortData &= ~MDIO_PIN_MASK;
+ // >10ns
+ *pPortData |= MDC_PIN_MASK; // clock rise
+
+ txF = (UINT32)(txF << 1); // >160ns
+
+ for (j=0; j<MDC_HOLD_TIME; j++);
+
+ *pPortData &= ~MDC_PIN_MASK; // clock fall
+
+ for (j=0; j<MDC_HOLD_TIME; j++);
+
+ }
+
+ return;
+}
+
+
+/*---------------------------------------------------------------------
+*
+* FUNCTION NAME:
+*
+* DESCRIPTION: Shifts in bits of data
+*
+* EXTERNAL EFFECT:
+*
+* PARAMETERS:
+*
+* RETURNS:
+*
+* ASSUMPTIONS:
+*
+*---------------------------------------------------------------------*/
+UINT16
+MdioReceive(UINT16 size) {
+
+ UINT16 i,j, rxF = 0;
+
+ for (i = 0; i < size; i++) { // 16 bits
+
+ *pPortData |= MDC_PIN_MASK; // clock rise
+
+ if ( *pPortData & MDIO_PIN_MASK ) // if read in a high bit
+ rxF = ( (UINT16)(rxF << 1) | 1 ); // shift in a one
+ else // if read in a low bit
+ rxF = ( (UINT16)(rxF << 1) & ~(UINT16)1 ); // shift in a zero
+
+
+ for (j=0; j<MDC_HOLD_TIME; j++);
+
+ *pPortData &= ~MDC_PIN_MASK; // clock fall
+
+ for (j=0; j<MDC_HOLD_TIME; j++);
+
+ }
+
+ return rxF;
+}
+
diff --git a/ecos/packages/devs/eth/powerpc/quicc2/current/src/EnetPHY.h b/ecos/packages/devs/eth/powerpc/quicc2/current/src/EnetPHY.h
new file mode 100644
index 0000000..33a500f
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc2/current/src/EnetPHY.h
@@ -0,0 +1,109 @@
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+/*------------------------------------------------------------------
+*
+* FILE: EnetPHY.c
+*
+* DESCRIPTION: LXT970a driver header file
+*
+*
+* Modified for MPC8260 VADS board
+*-------------------------------------------------------------------*/
+
+#ifndef _EnetPHY_H
+#define _EnetPHY_H
+
+#include "types.h"
+
+// Board control and status registers
+typedef struct bcsr {
+ UINT32 bcsr0;
+ UINT32 bcsr1;
+ UINT32 bcsr2;
+ UINT32 bcsr3;
+} t_BCSR;
+
+// Fast ethernet enable/reset pins on bcsr
+#define FETHIEN_ 0x08000000
+#define FETHRST_ 0x04000000
+
+
+/**************************/
+/* The API for PHY Device */
+/**************************/
+
+void EnableResetPHY(volatile t_BCSR *pBCSR);
+UINT16 InitEthernetPHY(VUINT32* pdir, VUINT32* pdat, UINT16 link);
+UINT16 EthernetPHYInterruptHandler(void);
+void EnablePHYinterrupt(UINT8 enable);
+UINT16 LinkTestPHY(void);
+
+
+typedef enum MDIORW {READ, WRITE} MDIORW;
+
+
+#define LINKERROR 0xFFFF
+#define NOTLINKED 0x0000
+#define TEN_HD 0x0020
+#define TEN_FD 0x0040
+#define HUNDRED_HD 0x0080
+#define HUNDRED_FD 0x0100
+
+#define MD_TEST_FRAME 0xDEAD
+
+//8260 VADS Pin Connections
+#define MDIO_PIN_MASK 0x00400000 //PC9 for 8260 VADS
+#define MDC_PIN_MASK 0x00200000 //PC10 for 8260 VADS
+
+//#define MDIO_PIN_MASK 0x00000200 //PC9 for 8260 VADS
+//#define MDC_PIN_MASK 0x00000400 //PC10 for 8260 VADS
+
+//IEEE 802.3 PHY Register Definitions
+#define CONTROL_REG 0
+#define STATUS_REG 1
+#define PHY_ID_REG_A 2
+#define PHY_ID_REG_B 3
+#define AUTONEG_AD_REG 4
+#define AUTONEG_LINKPARTNER_REG 5
+#define AUTONEG_EXP_REG 6
+
+//LXT970a Specific Register Definitions
+#define MIRROR_REG 16
+#define INT_EN_REG 17
+#define INT_STAT_REG 18
+#define CONFIG_REG 19
+#define CHIP_STAT_REG 20
+
+//Clock Timing Control
+#define MDC_HOLD_TIME 50
+
+#endif
diff --git a/ecos/packages/devs/eth/powerpc/quicc2/current/src/fec.h b/ecos/packages/devs/eth/powerpc/quicc2/current/src/fec.h
new file mode 100644
index 0000000..8d82c44
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc2/current/src/fec.h
@@ -0,0 +1,171 @@
+//==========================================================================
+//
+// fec.h
+//
+// PowerPC MPC8260 fast ethernet (FEC)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): mtek
+// Contributors: pfine
+// Date: 2002-02-20
+// Purpose:
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// The port connected to the ethernet
+#define QUICC2_VADS_IMM_BASE 0x04700000
+#define FCC2 1
+
+/* ------------------------ */
+/* FCC REGISTER CONSTANTS */
+/* ------------------------ */
+
+// GFMR masks (RESET: 0x00000000)
+#define FEC_GFMR_EN_Rx 0x00000020 // Receive enable
+#define FEC_GFMR_EN_Tx 0x00000010 // Transmit enable
+#define FEC_GFMR_INIT 0x0000000C // mode=ethernet
+#define FEC_GFMR_OFFSET 0x11320
+
+//PSMR masks (RESET: 0x00000000)
+#define FEC_PSMR_INIT 0x00000080 // 32-bit CRC
+#define FEC_PSMR_OFFSET 0x11324
+
+//TODR masks (RESET: 0x0000)
+#define FEC_TOD_INIT 0x0000
+#define FEC_TOD_SET 0x8000
+#define FEC_TOD_OFFSET 0x11328
+
+//DSR masks (RESET: 0x7E7E)
+#define FEC_DSR_INIT 0xD555
+#define FEC_DSR_OFFSET 0x1132C
+
+//FCCE & FCCM (RESET: 0x0000)
+#define FEC_EV_GRA 0x00800000 // Graceful stop
+#define FEC_EV_RXC 0x00400000 // A control frame has been received
+#define FEC_EV_TXC 0x00200000 // Out of sequence frame sent
+#define FEC_EV_TXE 0x00100000 // Error in transmission channel
+#define FEC_EV_RXF 0x00080000 // A complete frame received
+#define FEC_EV_BSY 0x00040000 // A received frame discarded due to lack
+ // of buffers
+#define FEC_EV_TXB 0x00020000 // A buffer sent to ethernet
+#define FEC_EV_RXB 0x00010000 // A buffer that is a non-complete frame
+ // is received
+#define FEC_FCCE_OFFSET 0x11330
+#define FEC_FCCM_OFFSET 0x11334
+
+/* ------------------------------ */
+/* FCC PARAMETER RAM CONSTANTS */
+/* ------------------------------ */
+
+#define FEC_PRAM_RIPTR 0x3000 // 32 byte buffer in dual port RAM
+#define FEC_PRAM_TIPTR 0xB000 // 32 byte buffer in dual port RAM
+#define FEC_FCR_INIT 0x00000000 // Clear the reserved bits
+#define FEC_FCR_MOT_BO 0x10000000 // Motorola byte ordering
+#define FEC_PRAM_C_MASK 0xDEBB20E3 // Constant MASK for CRC
+#define FEC_PRAM_C_PRES 0xFFFFFFFF // CRC Preset
+#define FEC_PRAM_RETLIM 15 // Retry limit
+#define FEC_PRAM_PER_LO 5 // Persistance
+#define FEC_PRAM_PER_HI 0
+#define FEC_PRAM_MRBLR 1536
+#define FEC_MAX_FLR 1518 // Max frame length
+#define FEC_MIN_FLR 64 // Min frame length
+#define FEC_PRAM_PAD_CH 0x8888
+#define FEC_PRAM_MAXD 1520
+#define FEC_PRAM_OFFSET 0x8500 // Offset of t_Fcc_Pram in 82xx
+
+/* ------------------------------ */
+/* BUFFER DESCRIPTOR CONSTANTS */
+/* ------------------------------ */
+#define FEC_PRAM_RxBD_Base (FEC_PRAM_RIPTR + 0x400)
+#define FEC_BD_Rx_Empty 0x8000 // Buffer is empty, FEC can fill
+#define FEC_BD_Rx_Wrap 0x2000 // Wrap: Last buffer in ring
+#define FEC_BD_Rx_Int 0x1000 // Interrupt
+#define FEC_BD_Rx_Last 0x0800 // Last buffer in frame
+#define FEC_BD_Rx_Miss 0x0100 // Miss: promiscious mode
+#define FEC_BD_Rx_BC 0x0080 // Broadcast address
+#define FEC_BD_Rx_MC 0x0040 // Multicast address
+#define FEC_BD_Rx_LG 0x0020 // Frame length violation
+#define FEC_BD_Rx_NO 0x0010 // Non-octet aligned frame
+#define FEC_BD_Rx_SH 0x0008 // Short frame
+#define FEC_BD_Rx_CR 0x0004 // CRC error
+#define FEC_BD_Rx_OV 0x0002 // Overrun
+#define FEC_BD_Rx_TR 0x0001 // Frame truncated. late collision
+
+#define FEC_PRAM_TxBD_Base (FEC_PRAM_TIPTR + 0x400)
+#define FEC_BD_Tx_Ready 0x8000 // Frame ready
+#define FEC_BD_Tx_Pad 0x4000 // Pad short frames
+#define FEC_BD_Tx_Wrap 0x2000 // Wrap: Last buffer in ring
+#define FEC_BD_Tx_Int 0x1000 // Interrupt
+#define FEC_BD_Tx_Last 0x0800 // Last buffer in frame
+#define FEC_BD_Tx_TC 0x0400 // Send CRC after data
+#define FEC_BD_Tx_DEF 0x0200 // Defer indication
+#define FEC_BD_Tx_HB 0x0100 // Heartbeat
+#define FEC_BD_Tx_LC 0x0080 // Late collision
+#define FEC_BD_Tx_RL 0x0040 // Retransmission limit
+#define FEC_BD_Tx_RC 0x003C // Retry count
+#define FEC_BD_Tx_UN 0x0002 // Underrun
+#define FEC_BD_Tx_CSL 0x0001 // Carrier sense lost
+
+
+// Buffer descriptor
+struct fec_bd {
+ volatile unsigned short ctrl;
+ volatile unsigned short length;
+ volatile unsigned char *buffer;
+};
+
+
+struct fec_eth_info {
+ volatile struct fcc_regs *fcc_reg; // See "mpc8260.h"
+ struct fec_bd *txbd, *rxbd; // Next Tx,Rx descriptor to use
+ struct fec_bd *tbase, *rbase; // First Tx,Rx descriptor
+ struct fec_bd *tnext, *rnext; // Next descriptor to check for interrupt
+ int txsize, rxsize; // Length of individual buffers
+ unsigned long txkey[CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM];
+};
+
+// CPM_CPCR masks
+#define CPCR_FLG 0x00010000
+#define CPCR_FCC2_CH 0x16200000
+#define CPCR_GRSTOP_TX 0x00000005
+#define CPCR_INIT_TX_RX_PARAMS 0x00000000
+#define CPCR_MCN_FEC 0x00000300
+#define CPCR_READY_TO_RX_CMD 0 /* Ready to receive a command */
diff --git a/ecos/packages/devs/eth/powerpc/quicc2/current/src/if_fec.c b/ecos/packages/devs/eth/powerpc/quicc2/current/src/if_fec.c
new file mode 100644
index 0000000..7a50db8
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc2/current/src/if_fec.c
@@ -0,0 +1,708 @@
+//==========================================================================
+//
+// dev/if_fec.c
+//
+// Fast ethernet device driver for PowerPC MPC8260 boards
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): mtek
+// Contributors: pfine
+// Date: 2002-02-20
+// Purpose:
+// Description: hardware driver for MPC8260 FEC
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_eth_powerpc_quicc2.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/var_intr.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/mpc8260.h>
+
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#endif
+
+#include "fec.h"
+#include "EnetPHY.h"
+
+#define ALIGN_TO_CACHE_LINES(x) ( (long)((x) + 31) & 0xffffffe0 )
+
+static unsigned char fec_eth_rxbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM *
+ (CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE + 32)];
+static unsigned char fec_eth_txbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM *
+ (CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE + 32)];
+
+// Buffer descriptors are in dual ported RAM, which is marked non-cached
+#define FEC_BDs_NONCACHED
+static struct fec_bd *const fec_eth_rxring = (struct fec_bd *)
+ (QUICC2_VADS_IMM_BASE + FEC_PRAM_RxBD_Base);
+static struct fec_bd *const fec_eth_txring = (struct fec_bd *)
+ (QUICC2_VADS_IMM_BASE + FEC_PRAM_TxBD_Base);
+
+static struct fec_eth_info fec_eth0_info;
+
+static unsigned short _default_enaddr[] = {0x1234, 0x5678, 0x90a1};
+static unsigned char enaddr[6];
+
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+RedBoot_config_option("Network hardware address [MAC]",
+ fec_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+RedBoot_config_option("Attempt to find 100 Mbps Ethernet",
+ fec_100,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, 0
+ );
+#endif
+#endif
+
+#define os_printf diag_printf
+
+// CONFIG_ESA and CONFIG_BOOL are defined in redboot/include/flash_config.h
+#ifndef CONFIG_ESA
+#define CONFIG_ESA 6 // ethernet address length ...
+#endif
+
+#ifndef CONFIG_BOOL
+#define CONFIG_BOOL 1
+#endif
+
+ETH_DRV_SC(fec_eth0_sc,
+ &fec_eth0_info, // Driver specific data
+ "eth0", // Name for this interface
+ fec_eth_start,
+ fec_eth_stop,
+ fec_eth_control,
+ fec_eth_can_send,
+ fec_eth_send,
+ fec_eth_recv,
+ fec_eth_deliver,
+ fec_eth_int,
+ fec_eth_int_vector);
+
+NETDEVTAB_ENTRY(fec_netdev,
+ "fec_eth",
+ fec_eth_init,
+ &fec_eth0_sc);
+
+#ifdef CYGPKG_NET
+static cyg_interrupt fec_eth_interrupt;
+static cyg_handle_t fec_eth_interrupt_handle;
+#endif
+static void fec_eth_int(struct eth_drv_sc *data);
+
+#define FEC_ETH_INT CYGNUM_HAL_INTERRUPT_FCC2
+
+// This ISR is called when the ethernet interrupt occurs
+#ifdef CYGPKG_NET
+static int
+fec_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_drv_interrupt_mask(FEC_ETH_INT);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+#endif
+
+// Deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+fec_eth_deliver(struct eth_drv_sc * sc)
+{
+ fec_eth_int(sc);
+#ifdef CYGPKG_NET
+ // Clearing the event register acknowledges FCC2 interrupt ...
+ // cyg_drv_interrupt_acknowledge(FEC_ETH_INT);
+ cyg_drv_interrupt_unmask(FEC_ETH_INT);
+#endif
+
+}
+
+
+// Initialize the interface - performed at system startup
+// This function must set up the interface, including arranging to
+// handle interrupts, etc, so that it may be "started" cheaply later.
+static bool
+fec_eth_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+
+ volatile t_PQ2IMM *IMM = (volatile t_PQ2IMM *) QUICC2_VADS_IMM_BASE;
+ volatile t_Fcc_Pram *fcc = (volatile t_Fcc_Pram *) (QUICC2_VADS_IMM_BASE + FEC_PRAM_OFFSET);
+ volatile t_EnetFcc_Pram *E_fcc = &(fcc->SpecificProtocol.e);
+#if defined(CYGPKG_HAL_POWERPC_VADS) || defined(CYGPKG_HAL_POWERPC_TS6)
+ volatile t_BCSR *CSR = (t_BCSR *) 0x04500000;
+#endif
+
+ int i;
+ bool esa_ok;
+ bool fec_100;
+ unsigned char *c_ptr;
+ UINT16 link_speed;
+
+ // Link the memory to the driver control memory
+ qi->fcc_reg = & (IMM->fcc_regs[FCC2]);
+
+ // just in case : disable Transmit and Receive
+ qi->fcc_reg->fcc_gfmr &= ~(FEC_GFMR_EN_Rx | FEC_GFMR_EN_Tx);
+
+ // Via BCSR, (re)start LXT970
+#if defined(CYGPKG_HAL_POWERPC_VADS) || defined(CYGPKG_HAL_POWERPC_TS6)
+ EnableResetPHY(CSR);
+#endif
+
+ // Try to read the ethernet address of the transciever ...
+#ifdef CYGPKG_REDBOOT
+ esa_ok = flash_get_config("fec_100", &fec_100, CONFIG_BOOL);
+#else
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "fec_100", &fec_100, CONFIG_BOOL);
+#endif
+
+ link_speed = NOTLINKED;
+ if(esa_ok && fec_100){
+ // Via MII Management pins, tell LXT970 to initialize
+ os_printf("Attempting to acquire 100 Mbps half_duplex link ...");
+ InitEthernetPHY((VUINT32 *) &(IMM->io_regs[PORT_C].pdir),
+ (VUINT32 *) &(IMM->io_regs[PORT_C].pdat),
+ HUNDRED_HD);
+
+ link_speed = LinkTestPHY();
+ os_printf("\n");
+ if(link_speed == NOTLINKED){
+ os_printf("Failed to get 100 Mbps half_duplex link.\n");
+ }
+ }
+ if(link_speed == NOTLINKED){
+ os_printf("Attempting to acquire 10 Mbps half_duplex link ...");
+ InitEthernetPHY((VUINT32 *) &(IMM->io_regs[PORT_C].pdir),
+ (VUINT32 *) &(IMM->io_regs[PORT_C].pdat),
+ TEN_HD);
+ link_speed = LinkTestPHY();
+ os_printf("\n");
+ if(link_speed == NOTLINKED){
+ link_speed = LinkTestPHY();
+ os_printf("Failed to get 10 Mbps half_duplex link.\n");
+ }
+
+ }
+ switch ( link_speed ) {
+
+ case HUNDRED_FD:
+ os_printf("100 MB full-duplex ethernet link \n");
+ break;
+ case HUNDRED_HD:
+ os_printf("100 MB half-duplex ethernet link \n");
+ break;
+ case TEN_FD:
+ os_printf("10 MB full-duplex ethernet link \n");
+ break;
+ case TEN_HD:
+ os_printf("10 MB half-duplex ethernet link \n");
+ break;
+ default:
+ os_printf("NO ethernet link \n");
+ }
+
+ // Connect PORTC pins: (C19) to clk13, (C18) to clk 14
+ IMM->io_regs[PORT_C].ppar |= 0x00003000;
+ IMM->io_regs[PORT_C].podr &= ~(0x00003000);
+ IMM->io_regs[PORT_C].psor &= ~(0x00003000);
+ IMM->io_regs[PORT_C].pdir &= ~(0x00003000);
+
+ // Connect clk13 to RxClk and clk14 to TxClk on FCC2
+ IMM->cpm_mux_cmxfcr &= 0x7f007f00; // clear fcc2 clocks
+ IMM->cpm_mux_cmxfcr |= 0x00250000; // set fcc2 clocks (see 15-14)
+ IMM->cpm_mux_cmxuar = 0x0000; // Utopia address reg, just clear
+
+ // Initialize parallel port registers to connect FCC2 to MII
+ IMM->io_regs[PORT_B].podr &= 0xffffc000; // clear bits 18-31
+ IMM->io_regs[PORT_B].psor &= 0xffffc000;
+ IMM->io_regs[PORT_B].pdir &= 0xffffc000;
+
+ IMM->io_regs[PORT_B].psor |= 0x00000004;
+ IMM->io_regs[PORT_B].pdir |= 0x000003c5;
+ IMM->io_regs[PORT_B].ppar |= 0x00003fff;
+
+ // Initialize Receive Buffer Descriptors
+ qi->rbase = fec_eth_rxring;
+ qi->rxbd = fec_eth_rxring;
+ qi->rnext = fec_eth_rxring;
+ c_ptr = fec_eth_rxbufs;
+
+ for(i=0; i<CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM; i++) {
+
+ fec_eth_rxring[i].ctrl = (FEC_BD_Rx_Empty | FEC_BD_Rx_Int);
+ fec_eth_rxring[i].length = 0; // reset
+ c_ptr = (unsigned char *) ALIGN_TO_CACHE_LINES(c_ptr);
+ fec_eth_rxring[i].buffer = (volatile unsigned char *)c_ptr;
+ c_ptr += CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE;
+ }
+
+ fec_eth_rxring[CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM-1].ctrl |= FEC_BD_Rx_Wrap;
+
+ // Initialize Transmit Buffer Descriptors
+ qi->tbase = fec_eth_txring;
+ qi->txbd = fec_eth_txring;
+ qi->tnext = fec_eth_txring;
+ c_ptr = fec_eth_txbufs;
+
+ for(i=0; i<CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM; i++) {
+
+ fec_eth_txring[i].ctrl = (FEC_BD_Tx_Pad | FEC_BD_Tx_Int);
+ fec_eth_txring[i].length = 0; // reset : Write before send
+ c_ptr = (unsigned char *) ALIGN_TO_CACHE_LINES(c_ptr);
+ fec_eth_txring[i].buffer = (volatile unsigned char *)c_ptr;
+ c_ptr += CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE;
+ }
+
+ fec_eth_txring[CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM-1].ctrl |= FEC_BD_Tx_Wrap;
+
+ // Common FCC Parameter RAM initialization
+ fcc->riptr = FEC_PRAM_RIPTR; // in dual port RAM (see 28-11)
+ fcc->tiptr = FEC_PRAM_TIPTR; // in dual port RAM (see 28-11)
+ fcc->mrblr = FEC_PRAM_MRBLR; // ?? FROM 8101 code ...
+ fcc->rstate &= FEC_FCR_INIT;
+ fcc->rstate |= FEC_FCR_MOT_BO;
+ fcc->rbase = (long) fec_eth_rxring;
+ fcc->tstate &= FEC_FCR_INIT;
+ fcc->tstate |= FEC_FCR_MOT_BO;
+ fcc->tbase = (long) fec_eth_txring;
+
+ // Ethernet Specific FCC Parameter RAM Initialization
+ E_fcc->c_mask = FEC_PRAM_C_MASK; // (see 30-9)
+ E_fcc->c_pres = FEC_PRAM_C_PRES;
+ E_fcc->crcec = 0;
+ E_fcc->alec = 0;
+ E_fcc->disfc = 0;
+ E_fcc->ret_lim = FEC_PRAM_RETLIM;
+ E_fcc->p_per = FEC_PRAM_PER_LO;
+ E_fcc->gaddr_h = 0;
+ E_fcc->gaddr_l = 0;
+ E_fcc->tfcstat = 0;
+ E_fcc->mflr = FEC_MAX_FLR;
+
+ // Try to read the ethernet address of the transciever ...
+#ifdef CYGPKG_REDBOOT
+ esa_ok = flash_get_config("fec_esa", enaddr, CONFIG_ESA);
+#else
+ esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "fec_esa", enaddr, CONFIG_ESA);
+#endif
+ if (!esa_ok) {
+ // If can't use the default ...
+ os_printf("FEC_ETH - Warning! ESA unknown\n");
+ memcpy(enaddr, _default_enaddr, sizeof(enaddr));
+ }
+
+ E_fcc->paddr1_h = ((short)enaddr[5] << 8) | enaddr[4]; // enaddr[2];
+ E_fcc->paddr1_m = ((short)enaddr[3] << 8) | enaddr[2]; // enaddr[1];
+ E_fcc->paddr1_l = ((short)enaddr[1] << 8) | enaddr[0]; // enaddr[0];
+
+ E_fcc->iaddr_h = 0;
+ E_fcc->iaddr_l = 0;
+ E_fcc->minflr = FEC_MIN_FLR;
+ E_fcc->taddr_h = 0;
+ E_fcc->taddr_m = 0;
+ E_fcc->taddr_l = 0;
+ E_fcc->pad_ptr = FEC_PRAM_TIPTR; // No special padding char ...
+ E_fcc->cf_type = 0;
+ E_fcc->maxd1 = FEC_PRAM_MAXD;
+ E_fcc->maxd2 = FEC_PRAM_MAXD;
+
+ // FCC register initialization
+ IMM->fcc_regs[FCC2].fcc_gfmr = FEC_GFMR_INIT;
+ IMM->fcc_regs[FCC2].fcc_psmr = FEC_PSMR_INIT;
+ IMM->fcc_regs[FCC2].fcc_dsr = FEC_DSR_INIT;
+
+#ifdef CYGPKG_NET
+ // clear the events of FCC2
+ IMM->fcc_regs[FCC2].fcc_fcce = 0xFFFF0000;
+ IMM->fcc_regs[FCC2].fcc_fccm = FEC_EV_TXE | FEC_EV_TXB | FEC_EV_RXF;
+
+ // Set up to handle interrupts
+ cyg_drv_interrupt_create(FEC_ETH_INT,
+ 0, // Highest //CYGARC_SIU_PRIORITY_HIGH,
+ (cyg_addrword_t)sc, // Data passed to ISR
+ (cyg_ISR_t *)fec_eth_isr,
+ (cyg_DSR_t *)eth_drv_dsr,
+ &fec_eth_interrupt_handle,
+ &fec_eth_interrupt);
+ cyg_drv_interrupt_attach(fec_eth_interrupt_handle);
+ cyg_drv_interrupt_acknowledge(FEC_ETH_INT);
+ cyg_drv_interrupt_unmask(FEC_ETH_INT);
+#else
+
+ // Mask the interrupts
+ IMM->fcc_regs[FCC2].fcc_fccm = 0;
+#endif
+
+ // Issue Init RX & TX Parameters Command for FCC2
+ while ((IMM->cpm_cpcr & CPCR_FLG) != CPCR_READY_TO_RX_CMD);
+
+ IMM->cpm_cpcr = CPCR_INIT_TX_RX_PARAMS |
+ CPCR_FCC2_CH |
+ CPCR_MCN_FEC |
+ CPCR_FLG; /* ISSUE COMMAND */
+
+ while ((IMM->cpm_cpcr & CPCR_FLG) != CPCR_READY_TO_RX_CMD);
+
+ // Initialize upper level driver for ecos
+ (sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr);
+
+ return true;
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+fec_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+
+ // Enable the device :
+ // Set the ENT/ENR bits in the GFMR -- Enable Transmit/Receive
+ qi->fcc_reg->fcc_gfmr |= (FEC_GFMR_EN_Rx | FEC_GFMR_EN_Tx);
+
+}
+
+//
+// This function is called to shut down the interface.
+//
+static void
+fec_eth_stop(struct eth_drv_sc *sc)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+
+ // Disable the device :
+ // Clear the ENT/ENR bits in the GFMR -- Disable Transmit/Receive
+ qi->fcc_reg->fcc_gfmr &= ~(FEC_GFMR_EN_Rx | FEC_GFMR_EN_Tx);
+}
+
+
+//
+// This function is called for low level "control" operations
+//
+static int
+fec_eth_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int length)
+{
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ return 0;
+ break;
+ default:
+ return 1;
+ break;
+ }
+}
+
+
+//
+// This function is called to see if another packet can be sent.
+// It should return the number of packets which can be handled.
+// Zero should be returned if the interface is busy and can not send any more.
+//
+static int
+fec_eth_can_send(struct eth_drv_sc *sc)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ volatile struct fec_bd *txbd = qi->txbd;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+#ifndef FEC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(fec_eth_txring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM);
+ }
+#endif
+
+ return ((txbd->ctrl & (FCC_BD_Tx_TC | FCC_BD_Tx_Ready)) == 0);
+}
+
+//
+// This routine is called to send data to the hardware.
+static void
+fec_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ struct fec_bd *txbd, *txfirst;
+ volatile char *bp;
+ int i, txindex, cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+#ifndef FEC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(fec_eth_txring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM);
+ }
+#endif
+
+ // Find a free buffer
+ txbd = txfirst = qi->txbd;
+ while (txbd->ctrl & FEC_BD_Tx_Ready) {
+ // This buffer is busy, move to next one
+ if (txbd->ctrl & FEC_BD_Tx_Wrap) {
+ txbd = qi->tbase;
+ } else {
+ txbd++;
+ }
+ if (txbd == txfirst) {
+#ifdef CYGPKG_NET
+ panic ("No free xmit buffers");
+#else
+ os_printf("FEC Ethernet: No free xmit buffers\n");
+#endif
+ }
+ }
+
+ // Remember the next buffer to try
+ if (txbd->ctrl & FEC_BD_Tx_Wrap) {
+ qi->txbd = qi->tbase;
+ } else {
+ qi->txbd = txbd+1;
+ }
+
+ txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
+ qi->txkey[txindex] = key;
+
+ // Set up buffer
+ txbd->length = total_len;
+ bp = txbd->buffer;
+ for (i = 0; i < sg_len; i++) {
+ memcpy((void *)bp, (void *)sg_list[i].buf, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+
+ // Make sure no stale data buffer ...
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(txbd->buffer, txbd->length);
+ }
+ // Send it on it's way
+ txbd->ctrl |= FEC_BD_Tx_Ready | FEC_BD_Tx_Last | FEC_BD_Tx_TC;
+#ifndef FEC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(fec_eth_txring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM);
+ }
+#endif
+
+}
+
+//
+// This function is called when a packet has been received. It's job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'fec_eth_recv' will be called to actually fetch it from the hardware.
+//
+static void
+fec_eth_RxEvent(struct eth_drv_sc *sc)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ struct fec_bd *rxbd;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+#ifndef FEC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(fec_eth_rxring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM);
+ }
+#endif
+
+ rxbd = qi->rnext;
+ while ((rxbd->ctrl & FEC_BD_Rx_Empty) == 0) {
+ qi->rxbd = rxbd; // Save for callback
+
+ // This is the right way of doing it, but dcbi has a bug ...
+ // if (cache_state) {
+ // HAL_DCACHE_INVALIDATE(rxbd->buffer, rxbd->length);
+ // }
+ (sc->funs->eth_drv->recv)(sc, rxbd->length);
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(rxbd->buffer, rxbd->length);
+ }
+
+ rxbd->ctrl |= FEC_BD_Rx_Empty;
+ if (rxbd->ctrl & FEC_BD_Rx_Wrap) {
+ rxbd = qi->rbase;
+ } else {
+ rxbd++;
+ }
+ }
+ // Remember where we left off
+ qi->rnext = (struct fec_bd *)rxbd;
+
+ // Make sure no stale data
+#ifndef FEC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(fec_eth_rxring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM);
+ }
+#endif
+
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// It's job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+fec_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ unsigned char *bp;
+ int i;
+
+ bp = (unsigned char *)qi->rxbd->buffer;
+
+ for (i = 0; i < sg_len; i++) {
+ if (sg_list[i].buf != 0) {
+ memcpy((void *)sg_list[i].buf, bp, sg_list[i].len);
+ bp += sg_list[i].len;
+ }
+ }
+
+}
+
+static void
+fec_eth_TxEvent(struct eth_drv_sc *sc, int stat)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ struct fec_bd *txbd;
+ int txindex, cache_state;
+
+ // Make sure no stale data
+ HAL_DCACHE_IS_ENABLED(cache_state);
+#ifndef FEC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(fec_eth_txring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM);
+ }
+#endif
+
+ txbd = qi->tnext;
+ // Note: TC field is used to indicate the buffer has/had data in it
+ while ( (txbd->ctrl & (FEC_BD_Tx_TC | FEC_BD_Tx_Ready)) == FEC_BD_Tx_TC ) {
+ txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
+ (sc->funs->eth_drv->tx_done)(sc, qi->txkey[txindex], 0);
+ txbd->ctrl &= ~FEC_BD_Tx_TC;
+ if (txbd->ctrl & FEC_BD_Tx_Wrap) {
+ txbd = qi->tbase;
+ } else {
+ txbd++;
+ }
+ }
+ // Remember where we left off
+ qi->tnext = (struct fec_bd *)txbd;
+
+ // Make sure no stale data
+#ifndef FEC_BDs_NONCACHED
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(fec_eth_txring,
+ 8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM);
+ }
+#endif
+
+}
+
+//
+// Interrupt processing
+//
+static void
+fec_eth_int(struct eth_drv_sc *sc)
+{
+ struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
+ unsigned long iEvent;
+
+ while ((iEvent = qi->fcc_reg->fcc_fcce) != 0){
+
+ // Writing 1's clear fcce, Writing 0's have no effect
+ qi->fcc_reg->fcc_fcce = iEvent;
+
+ // Tx Done or Tx Error
+ if ( iEvent & (FEC_EV_TXB | FEC_EV_TXE) ) {
+ fec_eth_TxEvent(sc, iEvent);
+ }
+
+ // Complete or non-complete frame receive
+ if (iEvent & (FEC_EV_RXF | FEC_EV_RXB) ) {
+ fec_eth_RxEvent(sc);
+ }
+
+ }
+
+
+}
+
+//
+// Interrupt vector
+//
+static int
+fec_eth_int_vector(struct eth_drv_sc *sc)
+{
+ return (FEC_ETH_INT);
+}
+
diff --git a/ecos/packages/devs/eth/powerpc/quicc2/current/src/types.h b/ecos/packages/devs/eth/powerpc/quicc2/current/src/types.h
new file mode 100644
index 0000000..c3628f9
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/quicc2/current/src/types.h
@@ -0,0 +1,98 @@
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+/**********************************************************************
+ * Copyright (c) 1999 Delphi Communication Systems
+ * Maynard, MA. ALL RIGHTS RESERVED
+ ***********************************************************************/
+/**********************************************************************
+ * File:
+ * $RCSfile: types.h,v $
+ * $Revision: 1.1.1.2 $
+ * $Date: 2002/03/14 17:54:24 $
+ *
+ * Purpose:
+ * This file defines basic types used in the ITU-T G.729A Speech
+ * codec. These are defined here so that we may control
+ * how many bits of precision a type has on a particular
+ * platform.
+ *
+ * Operation:
+ * We define the following in this file:
+ *
+ * typedef ... INT16
+ * This type definition defines the data type used for
+ * variables that must hold exactly 16 bits (signed).
+ *
+ * typedef ... INT32
+ * This type definition defines the data type used for
+ * variables that must hold exactly 32 bits (signed).
+ *
+ * Notes/Issues:
+ * This file is correct for the following platforms (so far):
+ *
+ * GNUWIN32 compiled with GCC
+ *
+ * $Log: types.h,v $
+ * Revision 1.1.1.2 2002/03/14 17:54:24 pfine
+ * Fixed CR/LF Problem
+ *
+ * Revision 1.1.1.1 2002/03/13 18:20:24 pfine
+ * DCS Ecos with Device Drivers
+ *
+ *
+ ***********************************************************************/
+#ifndef TYPES_H
+#define TYPES_H
+
+typedef char INT8;
+typedef unsigned char UINT8;
+typedef short INT16;
+typedef unsigned short UINT16;
+typedef long INT32;
+typedef unsigned long UINT32;
+
+typedef volatile char VINT8;
+typedef volatile unsigned char VUINT8;
+typedef volatile short VINT16;
+typedef volatile unsigned short VUINT16;
+typedef volatile long VINT32;
+typedef volatile unsigned long VUINT32;
+
+typedef char OCTET;
+typedef int INT_NATIVE;
+typedef unsigned int UINT_NATIVE;
+
+#endif /* TYPES_H */
+
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/rattler/current/ChangeLog b/ecos/packages/devs/eth/powerpc/rattler/current/ChangeLog
new file mode 100644
index 0000000..3bde9b4
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/rattler/current/ChangeLog
@@ -0,0 +1,37 @@
+2003-08-26 Gary Thomas <gary@mlbassoc.com>
+
+ * include/rattler_eth.inl:
+ * cdl/rattler_eth_drivers.cdl: Update PHY support, using AMD AM79C874.
+
+2003-08-19 Gary Thomas <gary@mlbassoc.com>
+
+ * include/rattler_eth.inl:
+ * cdl/rattler_eth_drivers.cdl: New file(s) - platform specifics
+ for ethernet drivers on Analogue & Micro Rattler (MPC8250) board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/rattler/current/cdl/rattler_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/rattler/current/cdl/rattler_eth_drivers.cdl
new file mode 100644
index 0000000..9426aef
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/rattler/current/cdl/rattler_eth_drivers.cdl
@@ -0,0 +1,91 @@
+#====================================================================
+#
+# rattler_eth_drivers.cdl
+#
+# Hardware specifics for A&M Rattler ethernet
+#
+#====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt
+# Original data: gthomas
+# Contributors: gthomas, F.Robbins
+# Date: 2003-08-19
+#
+#####DESCRIPTIONEND####
+#
+#====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_RATTLER {
+ display "A&M Rattler (MPC8250) ethernet support"
+ description "Hardware specifics for A&M Rattler ethernet"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_MPC8XXX
+
+ requires CYGPKG_DEVS_ETH_POWERPC_FCC
+ requires CYGPKG_HAL_POWERPC_RATTLER
+ requires CYGHWR_DEVS_ETH_PHY_AM79C874
+
+ cdl_option CYGHWR_DEVS_ETH_POWERPC_RATTLER_FCC1 {
+ display "Include fcc1/eth0 ethernet device"
+ default_value 1
+ description "
+ This option controls whether a driver for FCC1/eth0
+ is included in the resulting system."
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ }
+
+ cdl_option CYGHWR_DEVS_ETH_POWERPC_RATTLER_FCC2 {
+ display "Include fcc2/eth1 ethernet device"
+ default_value 1
+ description "
+ This option controls whether a driver for FCC2/eth1
+ is included in the resulting system."
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH1
+ requires CYGHWR_DEVS_ETH_POWERPC_RATTLER_FCC1
+ }
+
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FCC_ETH_CDL <pkgconf/devs_eth_powerpc_rattler.h>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FCC_ETH_INL <cyg/io/rattler_eth.inl>"
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/rattler/current/include/rattler_eth.inl b/ecos/packages/devs/eth/powerpc/rattler/current/include/rattler_eth.inl
new file mode 100644
index 0000000..5a0a00a
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/rattler/current/include/rattler_eth.inl
@@ -0,0 +1,331 @@
+#ifndef CYGONCE_DEVS_RATTLER_ETH_INL
+#define CYGONCE_DEVS_RATTLER_ETH_INL
+//==========================================================================
+//
+// rattler_eth.inl
+//
+// Hardware specifics for A&M Rattler ethernet support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas,F.Robbins
+// Date: 2003-08-19
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//
+// Pin layout for PHY connections
+//
+#define FCC1_PHY_RESET 0x01000000
+#define FCC1_PHY_DATA 0x10000000
+#define FCC1_PHY_CLOCK 0x20000000
+#define FCC2_PHY_RESET 0x02000000
+#define FCC2_PHY_DATA 0x04000000
+#define FCC2_PHY_CLOCK 0x08000000
+
+#ifdef CYGHWR_DEVS_ETH_POWERPC_RATTLER_FCC1
+//
+// Initialize the PHY associated with FCC1/eth0
+//
+static void
+fcc1_phy_init(void)
+{
+ // Set up PHY reset line
+ IMM->io_regs[PORT_B].pdat |= FCC1_PHY_RESET;
+ IMM->io_regs[PORT_C].pdir |= FCC1_PHY_CLOCK;
+}
+
+//
+// Reset the PHY associated with FCC1/eth0
+//
+static void
+fcc1_phy_reset(void)
+{
+ // Toggle PHY reset line
+ IMM->io_regs[PORT_B].pdat &= ~FCC1_PHY_RESET;
+ IMM->io_regs[PORT_B].pdat |= FCC1_PHY_RESET;
+}
+
+//
+// Set up a particular data bit for FCC1/eth0
+//
+static void
+fcc1_phy_set_data(int val)
+{
+ if (val) {
+ // Output
+ IMM->io_regs[PORT_C].pdat |= FCC1_PHY_DATA;
+ } else {
+ // Input
+ IMM->io_regs[PORT_C].pdat &= ~FCC1_PHY_DATA;
+ }
+}
+
+//
+// Read the current data bit for FCC1/eth0
+//
+static int
+fcc1_phy_get_data(void)
+{
+ if ((IMM->io_regs[PORT_C].pdat & FCC1_PHY_DATA) != 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+//
+// Set the clock bit for FCC1/eth0
+//
+static void
+fcc1_phy_set_clock(int val)
+{
+ if (val) {
+ // Output
+ IMM->io_regs[PORT_C].pdat |= FCC1_PHY_CLOCK;
+ } else {
+ // Input
+ IMM->io_regs[PORT_C].pdat &= ~FCC1_PHY_CLOCK;
+ }
+}
+
+//
+// Set the clock/data direction for FCC1/eth0
+// Note: always forces clock to be an output
+//
+static void
+fcc1_phy_set_dir(int data_dir)
+{
+ if (data_dir) {
+ // Output
+ IMM->io_regs[PORT_C].pdir |= FCC1_PHY_DATA;
+ } else {
+ // Input
+ IMM->io_regs[PORT_C].pdir &= ~FCC1_PHY_DATA;
+ }
+}
+
+ETH_PHY_BIT_LEVEL_ACCESS_FUNS(fcc1_phy,
+ fcc1_phy_init,
+ fcc1_phy_reset,
+ fcc1_phy_set_data,
+ fcc1_phy_get_data,
+ fcc1_phy_set_clock,
+ fcc1_phy_set_dir);
+
+static unsigned char fcc_eth0_rxbufs[CYGNUM_DEVS_ETH_POWERPC_FCC_RxNUM *
+ (CYGNUM_DEVS_ETH_POWERPC_FCC_BUFSIZE + 32)];
+static unsigned char fcc_eth0_txbufs[CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM *
+ (CYGNUM_DEVS_ETH_POWERPC_FCC_BUFSIZE + 32)];
+
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+RedBoot_config_option("FCC1/eth0 Network hardware address [MAC]",
+ fcc1_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif
+
+static struct fcc_eth_info fcc_eth0_info = {
+ CYGNUM_HAL_INTERRUPT_FCC1, // Interrupt
+ "fcc1_esa", // ESA 'key'
+ { 0x00, 0x08, 0xe5, 0x11, 0x22, 0x33 }, // Fallback ESA
+ CYGNUM_DEVS_ETH_POWERPC_FCC_RxNUM, // Number of Rx buffers
+ fcc_eth0_rxbufs, // Pointer to buffers
+ CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM, // Number of Tx buffers
+ fcc_eth0_txbufs, // Pointer to buffers
+ &fcc1_phy,
+};
+
+ETH_DRV_SC(fcc_eth0_sc,
+ &fcc_eth0_info, // Driver specific data
+ "eth0", // Name for this interface
+ fcc_eth_start,
+ fcc_eth_stop,
+ fcc_eth_control,
+ fcc_eth_can_send,
+ fcc_eth_send,
+ fcc_eth_recv,
+ fcc_eth_deliver,
+ fcc_eth_int,
+ fcc_eth_int_vector);
+
+NETDEVTAB_ENTRY(fcc_eth0_netdev,
+ "fcc_eth0",
+ fcc_eth_init,
+ &fcc_eth0_sc);
+#endif // CYGHWR_DEVS_ETH_POWERPC_RATTLER_FCC1
+
+#ifdef CYGHWR_DEVS_ETH_POWERPC_RATTLER_FCC2
+//
+// Initialize the PHY associated with FCC2/eth1
+//
+static void
+fcc2_phy_init(void)
+{
+ // Set up PHY reset line
+ IMM->io_regs[PORT_B].pdat |= FCC2_PHY_RESET;
+ IMM->io_regs[PORT_C].pdir |= FCC2_PHY_CLOCK;
+}
+
+//
+// Reset the PHY associated with FCC2/eth1
+//
+static void
+fcc2_phy_reset(void)
+{
+ // Toggle the PHY reset line
+ IMM->io_regs[PORT_B].pdat &= ~FCC2_PHY_RESET;
+ IMM->io_regs[PORT_B].pdat |= FCC2_PHY_RESET;
+}
+
+//
+// Set up a particular data bit for FCC2/eth1
+//
+static void
+fcc2_phy_set_data(int val)
+{
+ if (val) {
+ // Output
+ IMM->io_regs[PORT_C].pdat |= FCC2_PHY_DATA;
+ } else {
+ // Input
+ IMM->io_regs[PORT_C].pdat &= ~FCC2_PHY_DATA;
+ }
+}
+
+//
+// Read the current data bit for FCC2/eth1
+//
+static int
+fcc2_phy_get_data(void)
+{
+ if ((IMM->io_regs[PORT_C].pdat & FCC2_PHY_DATA) != 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+//
+// Set the clock bit for FCC2/eth1
+//
+static void
+fcc2_phy_set_clock(int val)
+{
+ if (val) {
+ // Output
+ IMM->io_regs[PORT_C].pdat |= FCC2_PHY_CLOCK;
+ } else {
+ // Input
+ IMM->io_regs[PORT_C].pdat &= ~FCC2_PHY_CLOCK;
+ }
+}
+
+//
+// Set the clock/data direction for FCC2/eth1
+// Note: always forces clock to be an output
+//
+static void
+fcc2_phy_set_dir(int data_dir)
+{
+ if (data_dir) {
+ // Output
+ IMM->io_regs[PORT_C].pdir |= FCC2_PHY_DATA;
+ } else {
+ // Input
+ IMM->io_regs[PORT_C].pdir &= ~FCC2_PHY_DATA;
+ }
+}
+
+ETH_PHY_BIT_LEVEL_ACCESS_FUNS(fcc2_phy,
+ fcc2_phy_init,
+ fcc2_phy_reset,
+ fcc2_phy_set_data,
+ fcc2_phy_get_data,
+ fcc2_phy_set_clock,
+ fcc2_phy_set_dir);
+
+static unsigned char fcc_eth1_rxbufs[CYGNUM_DEVS_ETH_POWERPC_FCC_RxNUM *
+ (CYGNUM_DEVS_ETH_POWERPC_FCC_BUFSIZE + 32)];
+static unsigned char fcc_eth1_txbufs[CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM *
+ (CYGNUM_DEVS_ETH_POWERPC_FCC_BUFSIZE + 32)];
+
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+RedBoot_config_option("FCC2/eth1 Network hardware address [MAC]",
+ fcc2_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_ESA, 0
+ );
+#endif
+
+static struct fcc_eth_info fcc_eth1_info = {
+ CYGNUM_HAL_INTERRUPT_FCC2, // Interrupt
+ "fcc2_esa", // ESA 'key'
+ { 0x00, 0x08, 0xe5, 0x11, 0x22, 0x33 }, // Fallback ESA
+ CYGNUM_DEVS_ETH_POWERPC_FCC_RxNUM, // Number of Rx buffers
+ fcc_eth1_rxbufs, // Pointer to buffers
+ CYGNUM_DEVS_ETH_POWERPC_FCC_TxNUM, // Number of Tx buffers
+ fcc_eth1_txbufs, // Pointer to buffers
+ &fcc2_phy,
+};
+
+ETH_DRV_SC(fcc_eth1_sc,
+ &fcc_eth1_info, // Driver specific data
+ "eth1", // Name for this interface
+ fcc_eth_start,
+ fcc_eth_stop,
+ fcc_eth_control,
+ fcc_eth_can_send,
+ fcc_eth_send,
+ fcc_eth_recv,
+ fcc_eth_deliver,
+ fcc_eth_int,
+ fcc_eth_int_vector);
+
+NETDEVTAB_ENTRY(fcc_eth1_netdev,
+ "fcc_eth1",
+ fcc_eth_init,
+ &fcc_eth1_sc);
+#endif // CYGHWR_DEVS_ETH_POWERPC_RATTLER_FCC2
+
+#endif // CYGONCE_DEVS_RATTLER_ETH_INL
+// ------------------------------------------------------------------------
diff --git a/ecos/packages/devs/eth/powerpc/ts1000/current/ChangeLog b/ecos/packages/devs/eth/powerpc/ts1000/current/ChangeLog
new file mode 100644
index 0000000..f2252fb
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/ts1000/current/ChangeLog
@@ -0,0 +1,31 @@
+2002-09-03 Gary Thomas <gary@mlbassoc.com>
+
+ * include/ts1000_eth.inl:
+ * cdl/ts1000_eth_drivers.cdl: New package - platform ethernet specifics.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/ts1000/current/cdl/ts1000_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/ts1000/current/cdl/ts1000_eth_drivers.cdl
new file mode 100644
index 0000000..974c068
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/ts1000/current/cdl/ts1000_eth_drivers.cdl
@@ -0,0 +1,65 @@
+#====================================================================
+#
+# ts1000_eth_drivers.cdl
+#
+# Hardware specifics for Allied Telesyn Ts1000 ethernet
+#
+#====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2002-09-03
+#
+#####DESCRIPTIONEND####
+#
+#====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_TS1000 {
+ display "Allied Telesyn TS1000 (MPC855T) ethernet support"
+ description "Hardware specifics for Allied Telesyn TS1000 ethernet"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_MPC8xx
+
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FEC_ETH_INL <cyg/io/ts1000_eth.inl>"
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/ts1000/current/include/ts1000_eth.inl b/ecos/packages/devs/eth/powerpc/ts1000/current/include/ts1000_eth.inl
new file mode 100644
index 0000000..599fc8d
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/ts1000/current/include/ts1000_eth.inl
@@ -0,0 +1,77 @@
+#ifndef CYGONCE_DEVS_TS1000_ETH_INL
+#define CYGONCE_DEVS_TS1000_ETH_INL
+//==========================================================================
+//
+// ts1000_eth.inl
+//
+// Hardware specifics for Allied Telesyn TS1000 ethernet support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2002-09-03
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+extern int hal_ts1000_get_led(void);
+extern void hal_ts1000_set_led(int);
+
+#define _get_led()
+#define _set_led(v)
+
+#define LED_TxACTIVE 2
+#define LED_RxACTIVE 1
+#define LED_IntACTIVE 0
+
+// Interrupt generated by device
+#define FEC_ETH_INT CYGNUM_HAL_INTERRUPT_SIU_LVL1
+// Address of PHY (transceiver) device
+#define FEC_ETH_PHY 1
+
+// Reset the PHY - analagous to hardware reset
+#define FEC_ETH_RESET_PHY() \
+ eppc->pio_padat |= 0x00008000; /* Reset PHY chip */ \
+ CYGACC_CALL_IF_DELAY_US(10000); /* 10ms */ \
+ eppc->pio_padat &= ~0x00008000; /* Enable PHY chip */
+
+#endif // CYGONCE_DEVS_TS1000_ETH_INL
+// ------------------------------------------------------------------------
diff --git a/ecos/packages/devs/eth/powerpc/viper/current/ChangeLog b/ecos/packages/devs/eth/powerpc/viper/current/ChangeLog
new file mode 100644
index 0000000..22f58ad
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/viper/current/ChangeLog
@@ -0,0 +1,37 @@
+2003-03-24 Gary Thomas <gary@mlbassoc.com>
+
+ * cdl/viper_eth_drivers.cdl: Add constraint to make sure this is
+ only used with a Viper board.
+
+2002-09-03 Gary Thomas <gary@mlbassoc.com>
+
+ * include/viper_eth.inl:
+ * cdl/viper_eth_drivers.cdl: New package - platform specifics for
+ PowerPC/FEC ethernet driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
diff --git a/ecos/packages/devs/eth/powerpc/viper/current/cdl/viper_eth_drivers.cdl b/ecos/packages/devs/eth/powerpc/viper/current/cdl/viper_eth_drivers.cdl
new file mode 100644
index 0000000..20f1523
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/viper/current/cdl/viper_eth_drivers.cdl
@@ -0,0 +1,67 @@
+#====================================================================
+#
+# viper_eth_drivers.cdl
+#
+# Hardware specifics for A&M Viper ethernet
+#
+#====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-14
+#
+#####DESCRIPTIONEND####
+#
+#====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_POWERPC_VIPER {
+ display "A&M Viper (MPC8xxT) ethernet support"
+ description "Hardware specifics for A&M Viper ethernet"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_POWERPC
+ active_if CYGPKG_HAL_POWERPC_MPC8xx
+
+ requires CYGPKG_DEVS_ETH_POWERPC_FEC
+
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FEC_ETH_INL <cyg/io/viper_eth.inl>"
+ }
+}
diff --git a/ecos/packages/devs/eth/powerpc/viper/current/include/viper_eth.inl b/ecos/packages/devs/eth/powerpc/viper/current/include/viper_eth.inl
new file mode 100644
index 0000000..9a65b99
--- /dev/null
+++ b/ecos/packages/devs/eth/powerpc/viper/current/include/viper_eth.inl
@@ -0,0 +1,77 @@
+#ifndef CYGONCE_DEVS_VIPER_ETH_INL
+#define CYGONCE_DEVS_VIPER_ETH_INL
+//==========================================================================
+//
+// viper_eth.inl
+//
+// Hardware specifics for A&M Viper ethernet support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2002-09-03
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+extern int hal_viper_get_led(void);
+extern void hal_viper_set_led(int);
+
+#define _get_led() hal_viper_get_led()
+#define _set_led(v) hal_viper_set_led(v)
+
+#define LED_TxACTIVE 7
+#define LED_RxACTIVE 6
+#define LED_IntACTIVE 5
+
+// Interrupt generated by device
+#define FEC_ETH_INT CYGNUM_HAL_INTERRUPT_SIU_LVL1
+// Address of PHY (transceiver) device
+#define FEC_ETH_PHY 0
+
+// Reset the PHY - analagous to hardware reset
+#define FEC_ETH_RESET_PHY() \
+ eppc->pip_pbdat &= ~0x00004000; /* Reset PHY chip */ \
+ CYGACC_CALL_IF_DELAY_US(10000); /* 10ms */ \
+ eppc->pip_pbdat |= 0x00004000; /* Enable PHY chip */
+
+#endif // CYGONCE_DEVS_VIPER_ETH_INL
+// ------------------------------------------------------------------------
diff --git a/ecos/packages/devs/eth/rltk/8139/current/ChangeLog b/ecos/packages/devs/eth/rltk/8139/current/ChangeLog
new file mode 100644
index 0000000..60f4101
--- /dev/null
+++ b/ecos/packages/devs/eth/rltk/8139/current/ChangeLog
@@ -0,0 +1,84 @@
+2009-07-15 John Dallaway <john@dallaway.org.uk>
+
+ * src/if_8139.c: Add 0x1186/0x1300 for D-Link DFE-530TX+ PCI card.
+
+2007-05-30 Hajime Ishitani <pigmon@mail.snd.co.jp>
+
+ * src/if_8139.c:
+ * cdl/rltk_8139_eth_drivers.cdl
+ add write in MAC address at EEPROM by SIOCSIFHWADDR.
+
+2006-12-17 Hajime Ishitani <pigmon@mail.snd.co.jp>
+
+ * src/if_8139.c:
+ added 0x10ec/0x8129 for RTL8139C(L) of a known device.
+
+2006-11-13 Hajime Ishitani <pigmon@mail.snd.co.jp>
+
+ * src/if_8139.c: Enabled "PUN/LinkChg" interrupt.
+
+2005-12-02 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/if_8139.c (rltk8139_deliver): Fix the compiler warnings by
+ adding some casts.
+
+2005-11-25 Hajime Ishitani <pigmon@mail.snd.co.jp>
+
+ * src/if_8139.h:
+ * src/if_8139.c: Added a priority level field
+
+2005-03-03 Bob Koninckx <bob.koninckx@fmtc.be>
+
+ * src/if_8139.c: fixed bug that prevented rltk8139_find to find
+ anything but first device.
+
+2004-10-18 Andrew Dyer <adyer@righthandtech.com>
+
+ * src/if_8139.c (rltk8139_recv): if eth_drv_recv() wants to
+ discard an incoming packet it sets the buffer address == 0. Add a
+ check for this and skip the memcpy if found.
+
+2004-04-21 Yoshinori Sato <ysato@users.sourceforge.jp>
+
+ * src/if_8139.c:
+ add known device 0x11db/0x1234 from Dreamcast Broadband Adapter.
+ add Platform depend Initialize entry.
+
+2003-11-21 Gary Thomas <gary@mlbassoc.com>
+
+ * src/if_8139.c: Use cyg_drv_isr_lock/unlock functions for ISR
+ critical sections - much better than calling cyg_interrupt_enable
+ directly.
+
+2003-07-09 Eric Doenges <Eric.Doenges@DynaPel.com>
+
+ * src/if_8139.h:
+ * src/if_8139.c:
+ * doc/README:
+ * cdl/rltk_8139_eth_drivers.cdl:
+ New package - PCI ethernet driver for RTL8139 cards,
+ (using the Intel 82259 driver as inspiration).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/rltk/8139/current/cdl/rltk_8139_eth_drivers.cdl b/ecos/packages/devs/eth/rltk/8139/current/cdl/rltk_8139_eth_drivers.cdl
new file mode 100644
index 0000000..0630ff8
--- /dev/null
+++ b/ecos/packages/devs/eth/rltk/8139/current/cdl/rltk_8139_eth_drivers.cdl
@@ -0,0 +1,170 @@
+# ====================================================================
+#
+# rltk_8139_eth_drivers.cdl
+#
+# RealTek 8139 ethernet driver
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Eric Doenges
+# Original data:
+# Contributors:
+# Date: 2003-07-16
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_RLTK_8139 {
+ display "RealTek 8139 ethernet driver"
+ description "Ethernet driver for RealTek 8139 controller."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGINT_DEVS_ETH_RLTK_8139_REQUIRED
+
+ implements CYGINT_IO_ETH_MULTICAST
+
+ include_dir cyg/devs/eth
+
+ # SNMP demands to know stuff; this sadly makes us break the neat
+ # abstraction of the device having nothing exported.
+ # include_files include/8139_info.h
+ # and tell them that it is available
+ define_proc {
+ puts $::cdl_system_header \
+ "#define CYGBLD_DEVS_ETH_DEVICE_H <pkgconf/devs_eth_rltk_8139.h>"
+
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_RLTK_8139_CFG";
+ }
+
+ compile -library=libextras.a if_8139.c
+
+ cdl_component CYGPKG_DEVS_ETH_RLTK_8139_SHARE_INTERRUPTS {
+ display "Share interrupt with other devices"
+ default_value 1
+ description "
+ If this option is enabled, the driver does not assume that it is
+ in sole possession of the interrupt pin used by the 8139."
+
+ cdl_option CYGPKG_DEVS_ETH_RLTK_8139_MASK_INTERRUPTS_IN_8139 {
+ display "Mask 8139 interrupts on chip"
+ default_value 1
+ description "
+ If this option is enabled, the driver masks interrupts in the 8139's
+ status register, and does not mask the interrupt vector. This is
+ only useful if the 8139 must share it's interrupt line with other
+ devices."
+ }
+ }
+
+ cdl_option CYGDBG_DEVS_ETH_RLTK_8139_CHATTER {
+ display "Print debugging messages"
+ default_value 0
+ description "
+ If this option is set, a lot of debugging messages are printed
+ to the console to help debug the driver."
+ }
+
+# cdl_component CYGDBG_DEVS_ETH_RLTK_8139_KEEP_STATISTICS {
+# display "Keep Ethernet statistics"
+# default_value 1
+# description "
+# The ethernet device can maintain statistics about the network,
+# specifically a great variety of error rates which are useful
+# for network management. SNMP for example uses this
+# information. There is some performance cost in maintaining
+# this information; disable this option to recoup that."
+
+# cdl_option CYGDBG_DEVS_ETH_RLTK_8139_KEEP_8139_STATISTICS {
+# display "Keep RealTek 8139 internal statistics"
+# default_value 1
+# description "
+# The i82559 keeps internal counters, and it is possible to
+# acquire these. But the i82559 (reputedly) does not service
+# the network whilst uploading the data to RAM from its
+# internal registers. If throughput is a problem, disable
+# this option to acquire only those statistics gathered by
+# software, so that the i82559 never sleeps."
+# }
+# }
+
+ cdl_component CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM {
+ display "SIOCSIFHWADDR records MAC address in EEPROM"
+ default_value 0
+ description "
+ The ioctl() socket call with operand SIOCSIFHWADDR sets the
+ interface hardware address - the MAC address or ethernet
+ address. This option causes the new MAC address to be written
+ into the EEPROM associated with the interface, so that the new
+ MAC address is permanently recorded. Doing this should be a
+ carefully chosen decision, hence this option."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_RLTK_8139_RX_BUF_LEN_IDX {
+ display "Size of the receive ring"
+ flavor data
+ legal_values 0 to 2
+ default_value { CYGPKG_REDBOOT ? 0 : 2 }
+ define RX_BUF_LEN_IDX
+ description "
+ The 8139 stores all received packets in a single 'rx ring'
+ located somewhere in physical memory. The size of this ring
+ can be varied from ~8k to ~64k; however the driver currently
+ supports a maximum buffer size of only ~32k (so we can use
+ the 8139's WRAP mode). The actual buffer size is
+ 8192<<x + 16 + 1536 bytes, with x being the value of this
+ option."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_RLTK_8139_OPTIONS {
+ display "RealTek 8139 ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_RLTK_8139_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the RealTek 8139 ethernet driver package. These
+ flags are used in addition to the set of global flags."
+ }
+ }
+}
+# EOF rltk_8139_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/rltk/8139/current/doc/README b/ecos/packages/devs/eth/rltk/8139/current/doc/README
new file mode 100644
index 0000000..6b815b2
--- /dev/null
+++ b/ecos/packages/devs/eth/rltk/8139/current/doc/README
@@ -0,0 +1,164 @@
+Some notes on the RealTek 8139 driver
+
+
+1. Using the driver
+
+This driver follows the customization model used by many other drivers
+to separate those parts of the code that are device specific from those
+that are platform specific by requiring two packages to actually use the
+driver -- the driver itself and a platform glue package that contains
+only a .cdl and an .inl file (see the devs/i386/pc/rltk8139 package for
+an example).
+
+Both the driver and the glue packages must be added to the package
+database before you can use them. My entries look like this:
+
+package CYGPKG_DEVS_ETH_RLTK_8139 {
+ alias { "RealTek 8139 ethernet driver"
+ devs_eth_rltk_8139 8139_eth_driver }
+ hardware
+ directory devs/eth/rltk/8139
+ script rltk_8139_eth_drivers.cdl
+ description "Ethernet driver for RealTek 8139 NIC."
+}
+
+and
+
+package CYGPKG_DEVS_ETH_I386_RLTK8139 {
+ alias { "Standard PC with RealTek 8139 ethernet device"
+ devs_eth_i386_pc_rltk8139 }
+ hardware
+ directory devs/eth/i386/pc/rltk8139
+ script i386_pc_rltk8139_eth_drivers.cdl
+ description "Ethernet driver for the RealTek 8139 family of chips."
+}
+
+Finally, you will need to create a new target that includes the RealTek
+driver. The easiest way to this is copy an existing target and add the
+two packages defined above (and removing the Intel 82259 packages in case
+of an i386 pc target).
+
+
+2. Cache Coherency
+
+Since the 8139 reads data directly from memory via the PCI bus, you may
+have to worry about data cache coherency. For eCos, there are basically
+three cases (turning the data cache off is not considered a serious solution):
+
+a. Either the CPU has no data cache, or the CPU has cache snooping logic
+that will detect memory accesses by PCI bus master devices and flush the cache
+when necessary. In this case, nothing special needs to be done.
+
+b. The MMU is configured to access memory uncached in a certain address space.
+In this case, the macro CYGARC_UNCACHED_ADDRESS() can be used to convert
+normal (cached) into uncached accesses. The driver always uses this macro for
+accessing the transmit and receive buffers, since if the HAL doesn't
+support this mechanism, the macro does nothing and no harm is done.
+
+c. The data cache needs to be flushed/invalidated by the driver. In this case,
+you must define CYGPKG_DEVS_ETH_RLTK_8139_SOFTWARE_CACHE_COHERENCY in the
+platform specific .inl file. Furthermore, the HAL macros HAL_DCACHE_INVALIDATE
+and HAL_DCACHE_FLUSH must be defined. Next, you must ensure that the buffers
+are aligned to cache line boundaries; otherwise, the code could fail in
+mysterious ways.
+
+One way to do this is to define the following in the .inl file:
+
+#define CACHE_ALIGNED __attribute__ ((aligned (HAL_DCACHE_LINE_SIZE)))
+
+Then, use this attribute on the transmit and receive buffer definitions:
+
+static cyg_uint8 rltk8139_eth0_rx_ring[RX_BUF_TOT_LEN] CACHE_ALIGNED;
+
+Note that this may fail for long cache lines, since the 'aligned' attribute
+does not allow arbitrarily large alignment parameters. Unfortunately, the gcc
+documentation does not say what the maximum alignment that can be specified
+is. Additionally, the linker may also be limited in the maximum alignment that
+can be used. In such cases, you'll have to bite the bullet and define more
+space than would be strictly necessary, and ensure the necessary alignment
+like this:
+
+static cyg_uint8 rltk8139_eth0_rx_ring[RX_BUF_TOT_LEN + HAL_DCACHE_LINE_SIZE];
+
+Then, reference the buffers in the Rltk8139 definition like this:
+
+(cyg_uint8 *)((int)(&rltk8139_eth0_rx_ring[0] + HAL_DCACHE_LINE_SIZE)
+ & ~(HAL_DCACHE_LINE_SIZE - 1))
+
+This assumes the cache line size is a power of 2; this is the case for all
+CPUs I know of. It also assumes an int can hold a pointer; if this is
+not true for your platform, use an integral type that can.
+
+Another thing to watch out for is that the buffers should also end on
+a cache line boundary. If your linker places the buffers sequentially in
+memory, you will only have to do this for the last buffer defined (since
+all buffers will start on cache line boundaries):
+
+static cyg_uint8
+rltk8139_eth0_tx_buffer[(TX_BUF_TOT_LEN + HAL_DCACHE_LINE_SIZE - 1)
+ & ~(HAL_DCACHE_LINE_SIZE - 1)] CACHE_ALIGNED;
+
+
+3. Interrupt sharing
+
+If the 8139 must share it's interrupt request line with other devices, the
+HAL option 'chained interrupts' must be enabled. The 8139 driver does not
+support IRQ muxing like the Intel 82559 driver does (see also *Limitations*).
+
+The driver's ISR does not clear the interrupt status bits since I believe this
+should only be done after the conditions that caused those bits to be set
+have been handled by the '_deliver' routine. Instead, the interrupt is masked.
+There are two ways to do this (configurable with a CDL option):
+
+a. The interrupt vector is masked. Personally I think this is a bad idea
+ because this will also block interrupts from all other devices sharing
+ this interrupt until the network thread gets around to calling the
+ '_deliver' routine.
+
+b. Mask the interrupt request using the 8139's interrupt mask register. This
+ way, other devices' interrupt requests can still be serviced. Enable the
+ CYGPKG_DEVS_ETH_RLTK_8139_MASK_INTERRUPTS_IN_8139 option to use this.
+
+
+4. Limitations
+
+There are a number of limitations associated with this driver:
+
+a. The configuration of the NIC (MAC address, media selection, etc.) is
+ loaded from the serial EEPROM (which is assumed to exist) and cannot be
+ changed either at compile or run time.
+
+b. The 'twister' cannot be tuned. As far as I can make out, the 'twister'
+ can be tuned to improve signal quality over long lines. The RealTek
+ data sheet does not document the twister; and the code in the Linux
+ driver that does this is totally incomprehensible to me.
+
+c. If multiple 8139s share the same interrupt, chained interrupts have to
+ be used. No IRQ MUXing (like the Intel 82559 driver has) is supported.
+
+d. Programming the multicast acceptance filter is now implemented, but not
+ tested because eCos doesn't have such a test program (or at least I
+ couldn't find any). Since I have never used multicasting myself, I don't
+ feel competent to write one. Someone suggested setting up an IPv6 network
+ for testing, since it seems IPv6 makes use of multicasting in normal
+ operation, but I haven't got around to doing that.
+
+e. It's fairly slow. This is not really the driver's fault - the 8139 requires
+ a fast CPU to get anything approaching decent speed because all messages
+ have to be copied around in memory.
+
+
+5. Credits
+
+The 8139's data sheet is not really all that helpful, since it contains
+a lot of omissions and some data that is simply incorrect. As such, I am
+indebted to Bill Paul for his well-documented OpenBSD driver, which was
+invaluable for figuring out how the chip is supposed to work. The idea of
+using 'enum' instead of '#define' came from the Linux 8139 driver, which I
+initially wanted to port to eCos, but didn't because I found it extremely
+hard to read and understand. (Note that I didn't copy any code from those
+drivers to avoid tainting eCos' license). The basic structure of the driver
+and .cdl files was taken from the eCos i82559 driver.
+
+I'd also like all the people who have downloaded and tested the driver, and
+contributed bug reports and fixes.
diff --git a/ecos/packages/devs/eth/rltk/8139/current/src/if_8139.c b/ecos/packages/devs/eth/rltk/8139/current/src/if_8139.c
new file mode 100644
index 0000000..b574fe6
--- /dev/null
+++ b/ecos/packages/devs/eth/rltk/8139/current/src/if_8139.c
@@ -0,0 +1,1516 @@
+//==========================================================================
+//
+// if_8139.c
+//
+// RealTek 8139 ethernet driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Eric Doenges
+// Contributors: Chris Nimmers, Gary Thomas, Andy Dyer
+// Date: 2003-07-09
+// Purpose:
+// Description: hardware driver for RealTek 8139 ethernet
+// Notes: This is a very basic driver that will send and receive
+// packets and not much else. A lot of features of the 8139
+// are not supported (power management, MII interface,
+// access to the serial eeprom, 'twister tuning', etc.).
+//
+// Many of the configuration options (like media type and
+// speed) the 8139 has are taken directly from the serial
+// eeprom and are not currently configurable from this driver.
+//
+// I've tentatively added some code to handle cache coherency
+// issues for platforms that do not have a separate address
+// space for uncached memory access and do not do cache
+// snooping for PCI bus masters. This code can be activated by
+// defining CYGPKG_DEVS_ETH_RLTK_8139_SOFTWARE_CACHE_COHERENCY
+// in the platform specific .inl file. Note that if
+// CYGPKG_DEVS_ETH_RLTK_8139_SOFTWARE_CACHE_COHERENCY is
+// defined, the .inl file is also responsible for making sure
+// the receive and transmit buffers are located in memory in
+// such a way that flushing or invalidating cache lines for
+// these buffers will not affect any other buffers. See the
+// README in the doc directory for some suggestions on how
+// to do this.
+//
+// Since the official data sheet for this chip is a bit
+// vague, I had to look at the Linux and OpenBSD drivers to
+// understand the basic workings of the chip; however, I have
+// not copied any code from those drivers to avoid tainting
+// eCos' license.
+//
+// FIXME:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+#include <pkgconf/system.h>
+#ifdef CYGPKG_IO_ETH_DRIVERS
+#include <pkgconf/io_eth_drivers.h>
+#endif
+#include <pkgconf/devs_eth_rltk_8139.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#include <string.h> /* for memset */
+
+#ifdef CYGPKG_IO_PCI
+#include <cyg/io/pci.h>
+#else
+#error "This driver requires the PCI package (CYGPKG_IO_PCI)"
+#endif
+
+#include <cyg/io/pci.h>
+
+/* Necessary for memory mapping macros */
+#include CYGHWR_MEMORY_LAYOUT_H
+
+/* Check if we should be dumping debug information or not */
+#if defined CYGDBG_DEVS_ETH_RLTK_8139_CHATTER \
+ && (CYGDBG_DEVS_ETH_RLTK_8139_CHATTER > 0)
+#define DEBUG_RLTK8139_DRIVER
+#endif
+
+#include "if_8139.h"
+
+/* Which interrupts we will handle */
+#define RLTK8139_IRQ (IR_SERR|IR_FOVW|IR_RXOVW|IR_TER|IR_TOK|IR_RER|IR_ROK|IR_FUN)
+
+/* Allow platform-specific configuration of the driver */
+#ifndef CYGDAT_DEVS_ETH_RLTK_8139_INL
+#error "CYGDAT_DEVS_ETH_RLTK_8139_INL not defined"
+#else
+#include CYGDAT_DEVS_ETH_RLTK_8139_INL
+#endif
+
+#ifndef CYGHWR_RLTK_8139_PLF_INIT
+#define CYGHWR_RLTK_8139_PLF_INIT(sc) do {} while(0)
+#endif
+
+/*
+ * If software cache coherency is required, the HAL_DCACHE_INVALIDATE
+ * hal macro must be defined as well.
+ */
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_SOFTWARE_CACHE_COHERENCY
+#if !defined HAL_DCACHE_INVALIDATE || !defined HAL_DCACHE_FLUSH
+#error "HAL_DCACHE_INVALIDATE/HAL_DCACHE_FLUSH not defined for this platform but CYGPKG_DEVS_ETH_RLTK_8139_CACHE_COHERENCY was defined."
+#endif
+#endif
+
+/* Local driver function declarations */
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+static cyg_uint32 rltk8139_isr(cyg_vector_t vector, cyg_addrword_t data);
+#endif
+
+#ifdef ETH_DRV_SET_MC_LIST
+static cyg_uint32 ether_crc(cyg_uint8 *data, int length);
+static void rltk8139_set_multicast_list(Rltk8139_t *rltk8139_info,
+ struct eth_drv_mc_list *mc_list);
+#endif
+
+static void rltk8139_reset(struct eth_drv_sc *sc);
+static bool rltk8139_init(struct cyg_netdevtab_entry *tab);
+static void rltk8139_start(struct eth_drv_sc *sc, unsigned char *enaddr,
+ int flags);
+static void rltk8139_stop(struct eth_drv_sc *sc);
+static int rltk8139_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length);
+static int rltk8139_can_send(struct eth_drv_sc *sc);
+static void rltk8139_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
+ int sg_len, int total_len, unsigned long key);
+static void rltk8139_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
+ int sg_len);
+static void rltk8139_deliver(struct eth_drv_sc *sc);
+static void rltk8139_poll(struct eth_drv_sc *sc);
+static int rltk8139_int_vector(struct eth_drv_sc *sc);
+
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM
+static cyg_uint16 rltk8139_eeprom_read( char *cpErAddr, cyg_uint8 Cmd, cyg_uint8 RomAdr );
+static void rltk8139_eeprom_write( char *cpErAddr, cyg_uint8 Cmd, cyg_uint8 RomAdr, cyg_uint16 SrcData );
+#endif
+
+#ifdef DEBUG_RLTK8139_DRIVER
+void rltk8139_print_state(struct eth_drv_sc *sc);
+#endif
+
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM
+#define EEPROM_CMD_READ 0x06 // eeprom read command
+#define EEPROM_CMD_WRITE 0x05 // eeprom write command
+#define EEPROM_PG_ON 0x80
+#define EEPROM_PG_EECS 0x08
+#define EEPROM_PG_EESK 0x04
+#define EEPROM_PG_EEDI 0x02
+#define EEPROM_PG_EEDO 0x01
+#define EEPROM_WR_BUSY_RETRIES 100 // ready wait re-try count
+
+#define EEPROM_MASK(_param0_,_param1_) ((_param0_ & _param1_) ? EEPROM_PG_EEDI : 0 )
+
+
+#define EEPROM_WR_DATA(_addr_,_txdata_) HAL_WRITE_UINT8(_addr_,_txdata_);
+
+#define EEPROM_WR_DATAPULSE(_addr_,_txdata_) HAL_WRITE_UINT8(_addr_,_txdata_); \
+ cyg_thread_delay(0); \
+ HAL_WRITE_UINT8(_addr_,_txdata_ | EEPROM_PG_EESK);
+
+#define EEPROM_RD_DATA(_addr_,_txdata_,_rxdata_) { \
+ cyg_uint16 read_data; \
+ HAL_WRITE_UINT8(_addr_,_txdata_); \
+ cyg_thread_delay(1); \
+ HAL_READ_UINT8(_addr_, read_data); \
+ _rxdata_ <<= 1; \
+ _rxdata_ |= ((read_data & EEPROM_PG_EEDO) ? 0x0001 : 0x0000 ); \
+ HAL_WRITE_UINT8(_addr_,_txdata_ | EEPROM_PG_EESK); }
+#endif
+
+/*
+ * Define inline functions to access the card. This will also handle
+ * endianess issues in one place. This code was lifted from the eCos
+ * i82559 driver.
+ */
+#if (CYG_BYTEORDER == CYG_MSBFIRST)
+#define HAL_CTOLE32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))
+#define HAL_LE32TOC(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))
+
+#define HAL_CTOLE16(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+#define HAL_LE16TOC(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+
+static inline void
+OUTB(cyg_uint8 value,
+ cyg_uint32 io_address)
+{
+ HAL_WRITE_UINT8( io_address, value);
+}
+
+static inline void
+OUTW(cyg_uint16 value, cyg_uint32 io_address)
+{
+ HAL_WRITE_UINT16(io_address,
+ (((value & 0xff) << 8) | ((value & 0xff00) >> 8)) );
+}
+
+static inline void
+OUTL(cyg_uint32 value, cyg_uint32 io_address)
+{
+ HAL_WRITE_UINT32(io_address,
+ ((((value) & 0xff) << 24) | (((value) & 0xff00) << 8)
+ | (((value) & 0xff0000) >> 8)
+ | (((value) >> 24) & 0xff)) );
+}
+
+static inline cyg_uint8
+INB(cyg_uint32 io_address)
+{
+ cyg_uint8 d;
+ HAL_READ_UINT8(io_address, d);
+ return d;
+}
+
+static inline cyg_uint16
+INW(cyg_uint32 io_address)
+{
+ cyg_uint16 d;
+ HAL_READ_UINT16( io_address, d );
+ return (((d & 0xff) << 8) | ((d & 0xff00) >> 8));
+}
+
+static inline cyg_uint32
+INL(cyg_uint32 io_address)
+{
+ cyg_uint32 d;
+ HAL_READ_UINT32(io_address, d);
+ return ((((d) & 0xff) << 24) | (((d) & 0xff00) << 8)
+ | (((d) & 0xff0000) >> 8) | (((d) >> 24) & 0xff));
+}
+#else
+
+// Maintaining the same styleee as above...
+#define HAL_CTOLE32(x) ((((x))))
+#define HAL_LE32TOC(x) ((((x))))
+
+#define HAL_CTOLE16(x) ((((x))))
+#define HAL_LE16TOC(x) ((((x))))
+
+static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address)
+{ HAL_WRITE_UINT8( io_address, value ); }
+
+static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)
+{ HAL_WRITE_UINT16( io_address, value ); }
+
+static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address)
+{ HAL_WRITE_UINT32( io_address, value ); }
+
+static inline cyg_uint8 INB(cyg_uint32 io_address)
+{ cyg_uint8 _t_; HAL_READ_UINT8( io_address, _t_ ); return _t_; }
+
+static inline cyg_uint16 INW(cyg_uint32 io_address)
+{ cyg_uint16 _t_; HAL_READ_UINT16( io_address, _t_ ); return _t_; }
+
+static inline cyg_uint32 INL(cyg_uint32 io_address)
+{ cyg_uint32 _t_; HAL_READ_UINT32( io_address, _t_ ); return _t_; }
+
+#endif // byteorder
+
+
+/*
+ * Table of all known PCI device/vendor ID combinations for the RealTek 8139.
+ * Add them as you get to know them.
+ */
+#define CYGNUM_DEVS_ETH_RLTK_8139_KNOWN_ALIASES 4
+static pci_identifier_t
+known_8139_aliases[CYGNUM_DEVS_ETH_RLTK_8139_KNOWN_ALIASES] = {
+ { 0x1186, 0x1300, NULL }, /* D-Link DFE-530TX+ PCI card */
+ { 0x10ec, 0x8139, NULL }, /* This is the official RealTek vendor/device code of 8139D(L) */
+ { 0x11db, 0x1234, NULL}, /* SEGA DreamCast BroadBandAdapter */
+ { 0x10ec, 0x8129, NULL } /* This is the official RealTek vendor/device code of 8139C(L) */
+};
+
+
+/*
+ * Check if the device description matches a known 8139 alias.
+ */
+static cyg_bool
+rltk8139_find_match_func(cyg_uint16 vendor_id, cyg_uint16 device_id,
+ cyg_uint32 class_id, void *p)
+{
+ int i;
+
+
+ for (i = 0; i < CYGNUM_DEVS_ETH_RLTK_8139_KNOWN_ALIASES; ++i) {
+ if (((known_8139_aliases[i].vendor_id == PCI_ANY_ID) ||
+ (known_8139_aliases[i].vendor_id == vendor_id)) &&
+ ((known_8139_aliases[i].device_id == PCI_ANY_ID) ||
+ (known_8139_aliases[i].device_id == device_id)))
+ return true;
+ }
+
+ return false;
+}
+
+
+/*
+ * Find the Nth 8139 device on all attached PCI busses and do some initial
+ * PCI-type initialization. Also setup the interrupt for use in eCos.
+ */
+static bool
+rltk8139_find(int n_th, struct eth_drv_sc *sc)
+{
+ Rltk8139_t *rltk8139_info;
+ cyg_pci_device_id pci_device_id;
+ cyg_pci_device pci_device_info;
+ cyg_uint16 command;
+ int found = -1;
+
+
+ /* Go through all PCI devices until we find the Nth 8139 chip */
+ pci_device_id = CYG_PCI_NULL_DEVID;
+ do {
+ if (!cyg_pci_find_matching(&rltk8139_find_match_func, NULL,
+ &pci_device_id))
+ return false;
+ else
+ found += 1;
+ } while (found != n_th);
+
+ /* Save device ID in driver private data in case we ever need it again */
+ rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+ rltk8139_info->pci_device_id = pci_device_id;
+
+ /* Now that we have found the device, we can extract some data about it */
+ cyg_pci_get_device_info(pci_device_id, &pci_device_info);
+
+ /* Get the assigned interrupt and set up ISR and DSR for it. */
+ if (cyg_pci_translate_interrupt(&pci_device_info, &rltk8139_info->vector)) {
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf(" Wired to HAL interrupt vector %d\n", rltk8139_info->vector);
+#endif
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ /*
+ * Note that we use the generic eth_drv_dsr routine instead of
+ * our own.
+ */
+ cyg_drv_interrupt_create(rltk8139_info->vector,
+ rltk8139_info->isr_priority,
+ (CYG_ADDRWORD)sc,
+ rltk8139_isr,
+ eth_drv_dsr,
+ &rltk8139_info->interrupt_handle,
+ &rltk8139_info->interrupt);
+ cyg_drv_interrupt_attach(rltk8139_info->interrupt_handle);
+#endif
+ }
+ else {
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf(" Does not generate interrupts.\n");
+#endif
+ }
+
+ /*
+ * Call 'cyg_pci_configure_device' for those platforms that do not
+ * configure the PCI bus during HAL initialization. According to Nick
+ * Garnett, there are good reasons to not configure PCI devices during HAL
+ * initialization. Also according to Nick, calling
+ * 'cyg_pci_configure_device' for devices already configured should have no
+ * effect and thus is safe to do.
+ */
+ if (cyg_pci_configure_device(&pci_device_info)) {
+#ifdef DEBUG_RLTK8139_DRIVER
+ int i;
+ diag_printf("Found device #%d on bus %d, devfn 0x%02x:\n", n_th,
+ CYG_PCI_DEV_GET_BUS(pci_device_id),
+ CYG_PCI_DEV_GET_DEVFN(pci_device_id));
+
+ if (pci_device_info.command & CYG_PCI_CFG_COMMAND_ACTIVE)
+ diag_printf(" Note that board is active. Probed"
+ " sizes and CPU addresses are invalid!\n");
+
+ diag_printf(" Vendor 0x%04x", pci_device_info.vendor);
+ diag_printf("\n Device 0x%04x", pci_device_info.device);
+ diag_printf("\n Command 0x%04x, Status 0x%04x\n",
+ pci_device_info.command, pci_device_info.status)
+ ;
+
+ diag_printf(" Class/Rev 0x%08x", pci_device_info.class_rev);
+ diag_printf("\n Header 0x%02x\n", pci_device_info.header_type);
+
+ diag_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+ pci_device_info.header.normal.sub_vendor,
+ pci_device_info.header.normal.sub_id);
+
+ for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
+ diag_printf(" BAR[%d] 0x%08x /", i, pci_device_info.base_address[i]);
+ diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
+ pci_device_info.base_size[i], pci_device_info.base_map[i]);
+ }
+#endif
+ }
+ else {
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("Failed to configure 8139 device #%d\n", n_th);
+#endif
+ return false;
+ }
+
+ /*
+ * Enable memory mapped and port based I/O and busmastering. We currently
+ * only support IO space accesses; memory mapping is enabled so that bit
+ * DVRLOAD in CONFIG1 is cleared automatically.
+ *
+ * NOTE: it seems that for some configurations/HALs, the device is already
+ * activated at this point, even though eCos' documentation suggests
+ * it shouldn't be. At least in my case, this is not a problem.
+ */
+ cyg_pci_read_config_uint16(pci_device_info.devid, CYG_PCI_CFG_COMMAND,
+ &command);
+ command |= (CYG_PCI_CFG_COMMAND_IO | CYG_PCI_CFG_COMMAND_MEMORY
+ | CYG_PCI_CFG_COMMAND_MASTER);
+ cyg_pci_write_config_uint16(pci_device_info.devid, CYG_PCI_CFG_COMMAND,
+ command);
+
+ /*
+ * This is the base address used to talk to the device. The 8139's IOAR
+ * and MEMAR registers are BAR0 and BAR1, respectively.
+ */
+ rltk8139_info->base_address = pci_device_info.base_map[0];
+
+ /*
+ * Read the MAC address. The RealTek data sheet seems to claim this should
+ * only be read in 4 byte accesses, but the code below works just fine.
+ */
+ for (found = 0; found < 6; ++found)
+ rltk8139_info->mac[found] = INB(rltk8139_info->base_address + IDR0 + found);
+
+ /*
+ * This is the indicator for "uses an interrupt". The code was lifted
+ * from the eCos Intel 82559 driver.
+ */
+ if (rltk8139_info->interrupt_handle != 0) {
+ cyg_drv_interrupt_acknowledge(rltk8139_info->vector);
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ cyg_drv_interrupt_unmask(rltk8139_info->vector);
+#endif
+ }
+
+ return true;
+}
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+/*
+ * Interrupt service routine. We do not clear the interrupt status bits
+ * (since this should really only be done after handling whatever caused
+ * the interrupt, and that is done in the '_deliver' routine), but instead
+ * clear the interrupt mask.
+ *
+ * If we are sharing interrupts with other devices, we have two options
+ * (configurable):
+ *
+ * 1. Mask the interrupt vector completly. Personally I think this is a bad
+ * idea because the other devices sharing this interrupt are also masked
+ * until the network thread gets around to calling the '_deliver' routine.
+ *
+ * 2. Use the interrupt mask register in the 8139 to mask just the interrupt
+ * request coming from the 8139. This way, the other devices' requests
+ * can still be serviced.
+ */
+static cyg_uint32
+rltk8139_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ Rltk8139_t *rltk8139_info;
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_SHARE_INTERRUPTS
+ cyg_uint16 isr;
+#endif
+
+ rltk8139_info = (Rltk8139_t *)(((struct eth_drv_sc *)data)->driver_private);
+
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_SHARE_INTERRUPTS
+ /*
+ * If interrupt sharing is enabled, check if the interrupt is really
+ * intended for us. Note that while the RealTek data sheet claims that
+ * reading the interrupt status register will clear all it's bits,
+ * this is not true, so we can read it without problems.
+ */
+ if (!(isr = INW(rltk8139_info->base_address + ISR)))
+ return 0;
+#endif
+
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_MASK_INTERRUPTS_IN_8139
+ /* Clear the interrupt mask to stop the current request. */
+ OUTW(0, rltk8139_info->base_address + IMR);
+#else
+ /* Mask the interrupt */
+ cyg_interrupt_mask(vector);
+#endif
+
+ /* Acknowledge the interrupt for those platforms were this is necessary */
+ cyg_interrupt_acknowledge(vector);
+
+ return (CYG_ISR_HANDLED | CYG_ISR_CALL_DSR);
+}
+#endif /* ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE */
+
+/*
+ * Reset the chip. This function is not exported to higher level software.
+ */
+static void
+rltk8139_reset(struct eth_drv_sc *sc)
+{
+ rltk8139_stop(sc);
+ rltk8139_start(sc, NULL, 0);
+}
+
+#ifdef ETH_DRV_SET_MC_LIST
+/*
+ * I assume (hope !) that this is identical to Ethernet's CRC algorithm
+ * specified in IEEE 802.3. It does seem to calculate the same CRC that
+ * the 8139 itself does, so I think it is correct.
+ * Note that while Ethernet's polynomial is usually specified as 04C11DB7,
+ * we must use EDB88320 because we shift the bits to the left, not the right.
+ * (See ftp://ftp.rocksoft.com/papers/crc_v3.txt for a good description of
+ * CRC algorithms).
+ */
+static cyg_uint32
+ether_crc(cyg_uint8 *data, int length)
+{
+ int bit;
+ cyg_uint32 crc = 0xFFFFFFFFU;
+
+ while (length-- > 0) {
+ crc ^= *data++;
+ for (bit = 0; bit < 8; ++bit) {
+ if (crc & 1)
+ crc = (crc >> 1) ^ 0xEDB88320U;
+ else
+ crc = (crc >> 1);
+ }
+ }
+
+ return crc ^ 0xFFFFFFFFU;
+}
+
+
+/*
+ * Set up multicast filtering. The way I understand existing driver code
+ * (Linux and OpenBSD), the 8139 calculates the ethernet CRC of
+ * incoming addresses and uses the top 6 bits as an index into a hash
+ * table. If the corresponding bit is set in MAR0..7, the address is
+ * accepted.
+ */
+static void
+rltk8139_set_multicast_list(Rltk8139_t *rltk8139_info,
+ struct eth_drv_mc_list *mc_list)
+{
+ cyg_uint32 mar[2], hash;
+ int i;
+
+ /* If 'mc_list' is NULL, accept all multicast packets. */
+ if (!mc_list) {
+ mar[0] = 0xFFFFFFFFU;
+ mar[1] = 0xFFFFFFFFU;
+ }
+ else {
+ mar[0] = 0;
+ mar[1] = 0;
+
+ for (i = 0; i < mc_list->len; ++i) {
+ hash = ether_crc(&mc_list->addrs[i][0], ETHER_ADDR_LEN) >> 26;
+ mar[hash >> 5] |= (1 << (hash & 0x1F));
+ }
+ }
+
+ /* Program the new filter values */
+ OUTL(mar[0], rltk8139_info->base_address + MAR0);
+ OUTL(mar[1], rltk8139_info->base_address + MAR4);
+}
+#endif /* ifdef ETH_DRV_SET_MC_LIST */
+
+
+/*
+ * Initialize the network interface. Since the chips is reset by calling
+ * _stop() and _start(), any code that will never need to be executed more
+ * than once after system startup should go here.
+ */
+static bool
+rltk8139_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc;
+ Rltk8139_t *rltk8139_info;
+
+
+ sc = (struct eth_drv_sc *)(tab->device_instance);
+ rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+
+ /*
+ * Initialize the eCos PCI library. According to the documentation, it
+ * is safe to call this function multiple times, so we call it just to
+ * be sure it has been done.
+ */
+ cyg_pci_init();
+
+ /*
+ * Scan the PCI bus for the specified chip. The '_find' function will also
+ * do some basic PCI initialization.
+ */
+ if (!rltk8139_find(rltk8139_info->device_num, sc)) {
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_init: could not find RealTek 8139 chip #%d.\n",
+ rltk8139_info->device_num);
+#endif
+ return false;
+ }
+
+ /* platform depends initialize */
+ CYGHWR_RLTK_8139_PLF_INIT(sc);
+
+ /*
+ * The initial tx threshold is set here to prevent it from being reset
+ * with every _start().
+ */
+ rltk8139_info->tx_threshold = 3;
+
+ /* Initialize upper level driver */
+ (sc->funs->eth_drv->init)(sc, rltk8139_info->mac);
+
+ return true;
+}
+
+
+/*
+ * (Re)Start the chip, initializing data structures and enabling the
+ * transmitter and receiver. Currently, 'flags' is unused by eCos.
+ */
+static void
+rltk8139_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ Rltk8139_t *rltk8139_info;
+ int i;
+
+
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_start(%s)\n", sc->dev_name);
+#endif
+
+ rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+
+ /*
+ * Reset the chip. Existing driver code implies that this may take up
+ * to 10ms; since I don't know under what exact circumstances this code may
+ * be called I busy wait here regardless.
+ */
+ OUTB(RST, rltk8139_info->base_address + CR);
+ while (INB(rltk8139_info->base_address + CR) & RST);
+
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_start(%s): 8139 was successfully reset.\n",
+ sc->dev_name);
+#endif
+
+ /*
+ * Clear the key storage area. These keys are used by the eCos networking
+ * support code to keep track of individual packets.
+ */
+ for (i = 0; i < NUM_TX_DESC; ++i)
+ rltk8139_info->tx_desc_key[i] = 0;
+
+ /* Initialize transmission buffer control */
+ rltk8139_info->tx_free_desc = 0;
+ rltk8139_info->tx_num_free_desc = NUM_TX_DESC;
+
+ /*
+ * Set the requested MAC address if enaddr != NULL. This is a special
+ * feature of my '_start' function since it's used to reset the chip after
+ * errors as well.
+ */
+ if (enaddr != NULL) {
+ for (i = 0; i < 6; ++i) {
+ rltk8139_info->mac[i] = enaddr[i];
+ OUTB(enaddr[i], rltk8139_info->base_address + IDR0 + i);
+ }
+ }
+
+ /*
+ * Now setup the transmission and reception buffers. These could be done
+ * in _init() and kept around, but putting them here fits better logically.
+ */
+ OUTL(CYGARC_PCI_DMA_ADDRESS((cyg_uint32)(rltk8139_info->tx_buffer
+ + 0 * TX_BUF_SIZE)),
+ rltk8139_info->base_address + TSAD0);
+ OUTL(CYGARC_PCI_DMA_ADDRESS((cyg_uint32)(rltk8139_info->tx_buffer
+ + 1 * TX_BUF_SIZE)),
+ rltk8139_info->base_address + TSAD1);
+ OUTL(CYGARC_PCI_DMA_ADDRESS((cyg_uint32)(rltk8139_info->tx_buffer
+ + 2 * TX_BUF_SIZE)),
+ rltk8139_info->base_address + TSAD2);
+ OUTL(CYGARC_PCI_DMA_ADDRESS((cyg_uint32)(rltk8139_info->tx_buffer
+ + 3 * TX_BUF_SIZE)),
+ rltk8139_info->base_address + TSAD3);
+ OUTL(CYGARC_PCI_DMA_ADDRESS((cyg_uint32)rltk8139_info->rx_ring),
+ rltk8139_info->base_address + RBSTART);
+
+ /*
+ * Enable the transmitter and receiver, then clear the missed packet
+ * counter.
+ */
+ OUTB(INB(rltk8139_info->base_address + CR) | (TE|RE),
+ rltk8139_info->base_address + CR);
+ OUTL(0, rltk8139_info->base_address + MPC);
+
+ /*
+ * It seems the receiver and transmitter configuration can only
+ * be set after the transmitter/receiver have been enabled.
+ */
+ OUTL(TXCFG, rltk8139_info->base_address + TCR);
+ OUTL(RXCFG | AM, rltk8139_info->base_address + RCR);
+
+ /*
+ * Enable the transmitter and receiver again. I'm not sure why this is
+ * necessary; the Linux driver does it so we do it here just to be on
+ * the safe side.
+ */
+ OUTB(INB(rltk8139_info->base_address + CR) | (TE|RE),
+ rltk8139_info->base_address + CR);
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ /*
+ * If this driver was not compiled in stand alone (without interrupts)
+ * mode, enable interrupts.
+ */
+ OUTW(RLTK8139_IRQ, rltk8139_info->base_address + IMR);
+#endif
+
+#ifdef DEBUG_RLTK8139_DRIVER
+ rltk8139_print_state(sc);
+#endif
+}
+
+
+/*
+ * Stop the chip, disabling the transmitter and receiver.
+ */
+static void
+rltk8139_stop(struct eth_drv_sc *sc)
+{
+ Rltk8139_t *rltk8139_info;
+
+
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_stop(%s)\n", sc->dev_name);
+#endif
+
+ rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+
+ /* Disable receiver and transmitter */
+ OUTB(INB(rltk8139_info->base_address + CR) & ~(TE|RE),
+ rltk8139_info->base_address + CR);
+
+ /* Mask all interrupts */
+ OUTW(0, rltk8139_info->base_address + IMR);
+}
+
+
+/*
+ * 8139 control function. Unlike a 'real' ioctl function, this function is
+ * not required to tell the caller why a request failed, only that it did
+ * (see the eCos documentation).
+ */
+static int
+rltk8139_control(struct eth_drv_sc *sc, unsigned long key, void *data,
+ int data_length)
+{
+ int i;
+ Rltk8139_t *rltk8139_info;
+
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM
+ cyg_uint16 WrData, RdData;
+ cyg_uint8 *pSrcData;
+ int iRetry;
+#endif
+
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_control(%08x, %lx)\n", sc, key);
+#endif
+
+ rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+
+ switch (key) {
+#ifdef ETH_DRV_SET_MAC_ADDRESS
+ case ETH_DRV_SET_MAC_ADDRESS:
+ if ( 6 != data_length )
+ return 1;
+
+ /* Set the mac address */
+ for (i = 0; i < 6; ++i) {
+ rltk8139_info->mac[i] = *(((cyg_uint8 *)data) + i);
+ OUTB(rltk8139_info->mac[i], rltk8139_info->base_address + IDR0 + i);
+ }
+
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM
+ pSrcData = (cyg_uint8 *)data;
+ for(i = 0; i < 3; i++){
+ WrData = ((cyg_uint16)(*pSrcData++)) & 0xff;
+ WrData |= ((cyg_uint16)(*pSrcData++)) << 8;
+ for( iRetry = 0; iRetry < 3; iRetry++){
+ rltk8139_eeprom_write(
+ (char *)(rltk8139_info->base_address + CR9346),
+ EEPROM_CMD_WRITE, i + 7, WrData);
+ RdData = rltk8139_eeprom_read(
+ (char *)(rltk8139_info->base_address + CR9346),
+ EEPROM_CMD_READ, i + 7);
+ if( RdData == WrData ){
+ break;
+ }
+ }
+ }
+#endif
+
+ return 0;
+#endif
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ if (6 != data_length)
+ return 1;
+
+ memcpy(data, rltk8139_info->mac, 6);
+ return 0;
+#endif
+
+#ifdef ETH_DRV_GET_IF_STATS_UD
+ case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+ //ETH_STATS_INIT( sc ); // so UPDATE the statistics structure
+#endif
+ // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+ case ETH_DRV_GET_IF_STATS:
+#endif
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+ break;
+#endif
+
+#ifdef ETH_DRV_SET_MC_LIST
+ case ETH_DRV_SET_MC_LIST:
+ /*
+ * Program the 8139's multicast filter register. If the eth_drv_mc_list
+ * contains at least one element, set the accept multicast bit in the
+ * receive config register.
+ */
+ rltk8139_set_multicast_list(rltk8139_info, (struct eth_drv_mc_list *)data);
+ if (((struct eth_drv_mc_list *)data)->len > 0)
+ OUTL(INL(rltk8139_info->base_address + RCR) | AM,
+ rltk8139_info->base_address + RCR);
+ else
+ OUTL(INL(rltk8139_info->base_address + RCR) & ~AM,
+ rltk8139_info->base_address + RCR);
+
+ return 0;
+#endif // ETH_DRV_SET_MC_LIST
+
+#ifdef ETH_DRV_SET_MC_ALL
+ case ETH_DRV_SET_MC_ALL:
+ /*
+ * Set the accept multicast bit in the receive config register and
+ * program the multicast filter to accept all addresses.
+ */
+ rltk8139_set_multicast_list(rltk8139_info, NULL);
+ OUTL(INL(rltk8139_info->base_address + RCR) | AM,
+ rltk8139_info->base_address + RCR);
+ return 0;
+#endif // ETH_DRV_SET_MC_ALL
+
+ default:
+ return 1;
+ }
+
+ return 1;
+}
+
+
+/*
+ * Check if a new packet can be sent.
+ */
+static int
+rltk8139_can_send(struct eth_drv_sc *sc)
+{
+ return ((Rltk8139_t *)(sc->driver_private))->tx_num_free_desc;
+}
+
+
+/*
+ * Send a packet over the wire.
+ */
+static void
+rltk8139_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ Rltk8139_t *rltk8139_info;
+ cyg_uint8 *tx_buffer;
+ struct eth_drv_sg *last_sg;
+ int desc;
+
+ rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_send(%s, %08x, %d, %d, %08lx)\n",
+ sc->dev_name, sg_list, sg_len, total_len, key);
+#endif
+
+ CYG_ASSERT(total_len <= TX_BUF_SIZE, "packet too long");
+
+ /*
+ * Get the next free descriptor to send. We lock out all interrupts
+ * and scheduling because we really, really do not want to be interrupted
+ * at this point.
+ *
+ * IMPORTANT NOTE: the RealTek data sheet does not really make this clear,
+ * but when they talk about a 'ring' of transmit descriptors, they
+ * _really_ mean it, i.e. you _must_ use descriptor #1 after descriptor
+ * #0 even if transmission of descriptor #0 has already completed.
+ */
+ cyg_drv_isr_lock();
+
+ /*
+ * Sanity check to see if '_send' was called even though there is no free
+ * descriptor. This is probably unnecessary.
+ */
+ if (rltk8139_info->tx_num_free_desc == 0) {
+ cyg_drv_isr_unlock();
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_send(%s): no free descriptor available\n",
+ sc->dev_name);
+#endif
+ return;
+ }
+
+ /*
+ * Get the free descriptor and advance the descriptor counter modulo
+ * TX_NUM_DESC. We assume that TX_NUM_DESC will always be a power of 2.
+ */
+ desc = rltk8139_info->tx_free_desc;
+ rltk8139_info->tx_free_desc = (rltk8139_info->tx_free_desc + 1)
+ & (NUM_TX_DESC - 1);
+
+ /* Decrement the number of free descriptors */
+ rltk8139_info->tx_num_free_desc -= 1;
+
+ /* Reenable interrupts at this point */
+ cyg_drv_isr_unlock();
+
+ /*
+ * Determine the buffer memory to use and tell the hardware about it.
+ * Since we use fixed buffer addresses, we do not need to set up TSADx.
+ * Memorize the key so we can call the tx_done callback correctly.
+ *
+ * While it would be possible to set TSADx to the packet directly if
+ * it is stored in a linear memory area with 32 bit alignment, it seems
+ * this happens so seldomly that it's simply not worth the extra
+ * runtime check.
+ */
+ tx_buffer = (cyg_uint8 *)CYGARC_UNCACHED_ADDRESS(rltk8139_info->tx_buffer
+ + TX_BUF_SIZE * desc);
+ rltk8139_info->tx_desc_key[desc] = key;
+
+ /*
+ * Copy the data to the designated position. Note that unlike the eCos
+ * Intel 82559 driver, we simply assume that all the scatter/gather list
+ * elements' lengths will add up to total_len exactly, and don't check
+ * to make sure.
+ */
+ for (last_sg = &sg_list[sg_len]; sg_list < last_sg; ++sg_list) {
+ memcpy(tx_buffer, (void *)(sg_list->buf), sg_list->len);
+ tx_buffer += sg_list->len;
+ }
+
+ /*
+ * Make sure the packet has the minimum ethernet packet size, padding
+ * with zeros if necessary.
+ */
+ if (total_len < MIN_ETH_FRAME_SIZE) {
+ memset(tx_buffer, 0, MIN_ETH_FRAME_SIZE - total_len);
+ total_len = MIN_ETH_FRAME_SIZE;
+ }
+
+ /*
+ * Flush the data cache here if necessary. This ensures the 8139 can
+ * read the correct data from the transmit buffer.
+ */
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_SOFTWARE_CACHE_COHERENCY
+ HAL_DCACHE_FLUSH(rltk8139_info->tx_buffer + TX_BUF_SIZE * desc, total_len);
+#endif
+
+ /*
+ * Now setup the correct transmit descriptor to actually send the data.
+ * The early TX threshold is incremented by the driver until we reach a
+ * size that prevents transmit underruns. (An earlier attempt to calculate
+ * this parameter from the packet size didn't work).
+ */
+ OUTL((rltk8139_info->tx_threshold << ERTXTH_SHIFT) | (total_len & SIZE),
+ rltk8139_info->base_address + TSD0 + (desc<<2));
+}
+
+
+/*
+ * This routine actually retrieves data from the receive ring by
+ * copying it into the specified scatter/gather buffers. Again,
+ * we assume the scatter/gather list is OK and don't check against
+ * total length.
+ */
+static void
+rltk8139_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list,
+ int sg_len)
+{
+ Rltk8139_t *rltk8139_info;
+ struct eth_drv_sg *last_sg;
+ cyg_uint8 *rx_buffer;
+
+
+ rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+ rx_buffer = rltk8139_info->rx_current;
+
+ /*
+ * Invalidate the cache line(s) mapped to the receive buffer
+ * if necessary.
+ */
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_SOFTWARE_CACHE_COHERENCY
+ HAL_DCACHE_INVALIDATE(rx_buffer, rltk8139_info->rx_size);
+#endif
+
+ for (last_sg = &sg_list[sg_len]; sg_list < last_sg; ++sg_list) {
+ if (sg_list->buf != (CYG_ADDRESS)0) {
+ memcpy((void *)(sg_list->buf), rx_buffer, sg_list->len);
+ rx_buffer += sg_list->len;
+ }
+ }
+}
+
+
+/*
+ * This function does all the heavy lifting associated with interrupts.
+ */
+static void
+rltk8139_deliver(struct eth_drv_sc *sc)
+{
+ Rltk8139_t *rltk8139_info;
+ cyg_uint16 status, pci_status;
+ cyg_uint32 tsd;
+ int desc;
+
+
+ rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+
+ /*
+ * The RealTek data sheet claims that reading the ISR will clear
+ * it. This is incorrect; to clear a bit in the ISR, a '1' must be
+ * written to the ISR instead. We immediately clear the interrupt
+ * bits at this point.
+ */
+ status = INW(rltk8139_info->base_address + ISR);
+ OUTW(status, rltk8139_info->base_address + ISR);
+
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_deliver(%s): %04x\n", sc->dev_name, status);
+#endif
+
+ /*
+ * Check for a PCI error. This seems like a very serious error to
+ * me, so we will reset the chip and hope for the best.
+ */
+ if (status & IR_SERR) {
+ cyg_pci_read_config_uint16(rltk8139_info->pci_device_id,
+ CYG_PCI_CFG_STATUS, &pci_status);
+ cyg_pci_write_config_uint16(rltk8139_info->pci_device_id,
+ CYG_PCI_CFG_STATUS, pci_status);
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_deliver(%s): PCI error %04x\n",
+ sc->dev_name, pci_status);
+#endif
+
+ rltk8139_reset(sc);
+ return;
+ }
+
+ /* Check for transmission complete (with errors or not) */
+ if ((status & IR_TER) || (status & IR_TOK)) {
+ /*
+ * Figure out which descriptors' status must be checked. We lock out
+ * interrupts while manipulating the descriptor list because we do not
+ * want to be interrupted at this point.
+ */
+ while (1) {
+ cyg_drv_isr_lock();
+
+ /* Check if all descriptors are ready, in which case we are done. */
+ if (rltk8139_info->tx_num_free_desc >= NUM_TX_DESC) {
+ cyg_drv_isr_unlock();
+ break;
+ }
+
+ desc = (rltk8139_info->tx_free_desc
+ - (NUM_TX_DESC - rltk8139_info->tx_num_free_desc))
+ & (NUM_TX_DESC - 1);
+ cyg_drv_isr_unlock();
+
+ /* Get the current status of the descriptor */
+ tsd = INL(rltk8139_info->base_address + TSD0 + (desc<<2));
+
+ /*
+ * If a transmit FIFO underrun occurred, increment the threshold
+ * value.
+ */
+ if ((tsd & TUN) && (rltk8139_info->tx_threshold < 64))
+ rltk8139_info->tx_threshold += 1;
+
+ /*
+ * Check if a transmission completed OK. RealTek's data sheet implies
+ * that a successful transmission that experiences underrun will only
+ * set TUN. This is not true; TOK is set for all successful
+ * transmissions.
+ */
+ if (tsd & TOK) {
+ (sc->funs->eth_drv->tx_done)(sc, rltk8139_info->tx_desc_key[desc], 0);
+ }
+ else if (tsd & TABT) {
+ /*
+ * Set the CLRABT bit in TCR. Since I haven't encountered any
+ * transmission aborts so far, I don't really know if this code
+ * will work or not.
+ */
+ OUTL(INL(rltk8139_info->base_address + TCR) & CLRABT,
+ rltk8139_info->base_address + TCR);
+ (sc->funs->eth_drv->tx_done)(sc, rltk8139_info->tx_desc_key[desc], -1);
+ }
+ else {
+ /*
+ * This descriptor is not ready. Since the descriptors are used
+ * in a ring, this means that no more descriptors are ready.
+ */
+ break;
+ }
+
+ /*
+ * Clear the saved key value. This is not really necessary, since
+ * the key value is never used to determine if a descriptor is
+ * valid or not. However, clearing it is a tidier IMO.
+ */
+ rltk8139_info->tx_desc_key[desc] = 0;
+
+ /*
+ * Increment the free descriptor count and go through the loop again
+ * to see if more descriptors are ready.
+ */
+ cyg_drv_isr_lock();
+ rltk8139_info->tx_num_free_desc += 1;
+ cyg_drv_isr_unlock();
+ }
+ }
+
+ if (status & IR_ROK) {
+ /*
+ * Received a frame. Note that '_deliver' does not actually copy any
+ * data; it just determines how many bytes are available and tells
+ * the generic ethernet driver about it, which then calls into
+ * the '_recv' function to copy the data.
+ */
+ cyg_uint16 rx_pos;
+ cyg_uint32 header, length;
+
+ /*
+ * CAPR contains the index into the receive buffer. It is controlled
+ * completely in software. For some reason, CAPR points 16 bytes
+ * before the actual start of the packet.
+ */
+ rx_pos = (INW(rltk8139_info->base_address + CAPR) + 16) % RX_BUF_LEN;
+
+ /*
+ * Loop until the rx buffer is empty. I have no idea how the 8139
+ * determines if the buffer still contains a packet; it may check
+ * that CAPR points 16 bytes before CBR.
+ */
+ while (!(INB(rltk8139_info->base_address + CR) & BUFE)) {
+ /*
+ * Invalidate the data cache for the cache line containing the header
+ * if necessary.
+ */
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_SOFTWARE_CACHE_COHERENCY
+ HAL_DCACHE_INVALIDATE(&rltk8139_info->rx_ring[rx_pos],
+ sizeof(cyg_uint32));
+#endif
+
+ /*
+ * The 8139 prepends each packet with a 32 bit packet header that
+ * contains a 16 bit length and 16 bit status field, in little-endian
+ * byte order.
+ */
+ header = HAL_LE32TOC(*((volatile cyg_uint32 *)CYGARC_UNCACHED_ADDRESS(&rltk8139_info->rx_ring[rx_pos])));
+
+ /*
+ * If the 8139 is still copying data for this packet into the
+ * receive ring, it will set packet length to 0xfff0. This shouldn't
+ * ever happen because we do not use early receive.
+ */
+ if ((header >> 16) == 0xFFF0)
+ break;
+
+ /*
+ * Since the 8139 appends the ethernet CRC to every packet, we
+ * must subtract 4 from the length to get the true packet length.
+ */
+ length = (header >> 16) - 4;
+
+ /*
+ * Check if the packet was received correctly. The OpenBSD driver
+ * resets the chip if this is not the case; we attempt to salvage
+ * following packets by doing nothing.
+ */
+ if (!(header & HDR_ROK)) {
+ }
+ else {
+ /*
+ * Packet was received OK. Determine from where to start copying
+ * bytes. This is saved in the driver private area so rlt8139_recv
+ * doesn't have to redetermine this information. Then, inform
+ * the generic ethernet driver about the packet.
+ */
+ rltk8139_info->rx_current =
+ (cyg_uint8 *)CYGARC_UNCACHED_ADDRESS(rltk8139_info->rx_ring +
+ rx_pos + 4);
+ rltk8139_info->rx_size = length;
+
+ /* Tell eCos about the packet */
+ (sc->funs->eth_drv->recv)(sc, length);
+ }
+
+ /*
+ * Update CAPR. CAPR must be aligned to a 32 bit boundary, and should
+ * point 16 bytes before it's actual position.
+ */
+ rx_pos = ((rx_pos + length + 8 + 3) & ~3) % RX_BUF_LEN;
+ OUTW((rx_pos - 16) % RX_BUF_LEN, rltk8139_info->base_address + CAPR);
+ }
+ }
+
+ if (status & IR_RXOVW) {
+ /*
+ * In case of a receive buffer overflow, the RealTek data sheet claims we
+ * should update CAPR and then write a '1' to ROK in ISR. However, none of
+ * the other 8139 drivers I have looked at do this, so we will just reset
+ * the chip instead.
+ */
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_deliver(%s): receive buffer overflow\n",
+ sc->dev_name);
+#endif
+ rltk8139_reset(sc);
+ return;
+ }
+
+ if (status & IR_FOVW) {
+ /*
+ * Rx FIFO overflow. According to RealTek's data sheet, this is cleared
+ * by writing a '1' to RXOVW. Again, none of the 8139 drivers I have
+ * seen actually do this, so we reset the chip instead.
+ */
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_deliver(%s): receive FIFO overflow\n",
+ sc->dev_name);
+#endif
+ rltk8139_reset(sc);
+ return;
+ }
+
+ if (status & IR_FUN) {
+ /*
+ * Packet underrun or link change interrupt.
+ * A cable was packet underrun or re-connected ?
+ */
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_deliver(%s): packet underrun or link change\n",
+ sc->dev_name);
+#endif
+ }
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ /* Finally, reenable interrupts */
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_MASK_INTERRUPTS_IN_8139
+ OUTW(RLTK8139_IRQ, rltk8139_info->base_address + IMR);
+#else
+ cyg_interrupt_unmask(rltk8139_info->vector);
+#endif
+#endif
+}
+
+
+/*
+ * '_poll' does the same thing as '_deliver'. It is called periodically when
+ * the ethernet driver is operated in non-interrupt mode, for instance by
+ * RedBoot.
+ */
+static void
+rltk8139_poll(struct eth_drv_sc *sc)
+{
+ Rltk8139_t *rltk8139_info;
+ cyg_uint16 isr;
+
+
+#ifdef DEBUG_RLTK8139_DRIVER
+ diag_printf("rltk8139_poll(%s)\n", sc->dev_name);
+#endif
+
+ rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+
+ /*
+ * Get the current interrupt status. If anything changed, call
+ * _deliver.
+ */
+ if ((isr = INW(rltk8139_info->base_address + ISR)))
+ rltk8139_deliver(sc);
+}
+
+
+/*
+ * Return the interrupt vector used by this device.
+ */
+static int
+rltk8139_int_vector(struct eth_drv_sc *sc)
+{
+ return ((Rltk8139_t *)(sc->driver_private))->vector;
+}
+
+
+/*
+ * Quick and dirty register dump. This is somewhat dangerous, since
+ * we read the register space 32 bits at a time, regardless of actual
+ * register sizes.
+ */
+#ifdef DEBUG_RLTK8139_DRIVER
+void
+rltk8139_print_state(struct eth_drv_sc *sc) {
+ int i;
+ Rltk8139_t *rltk8139_info;
+
+
+ rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+
+ for (i = IDR0; i < FFER; i += 16) {
+ diag_printf("8139 reg address 0x%02x = 0x%08x", i,
+ INL(rltk8139_info->base_address + i));
+ diag_printf(" 0x%08x", INL(rltk8139_info->base_address + i + 4));
+ diag_printf(" 0x%08x", INL(rltk8139_info->base_address + i + 8));
+ diag_printf(" 0x%08x\n", INL(rltk8139_info->base_address + i + 12));
+ }
+}
+#endif
+
+
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM
+/*
+ * Read mac_address from EEPROM.
+ */
+static cyg_uint16
+rltk8139_eeprom_read( char *rtl_addr, cyg_uint8 eeprom_cmd, cyg_uint8 eeprom_addr )
+{
+cyg_uint8 read_data; // read from eeprom bit data
+cyg_uint8 org_param; // original register parameter
+cyg_uint8 mask_bit8; // mask bit
+int icount; // for loop counter
+
+ // get old parameter
+ HAL_READ_UINT8( rtl_addr, org_param );
+
+ // ready
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON );
+
+ // set command
+ mask_bit8 = 0x04;
+ for(icount = 0; icount < 3; icount++){
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_MASK( mask_bit8, eeprom_cmd ));
+ mask_bit8 >>= 1;
+ }
+
+ // set address
+ mask_bit8 = 0x20;
+ for(icount = 0; icount < 6; icount++){
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_MASK( mask_bit8, eeprom_addr ));
+ mask_bit8 >>= 1;
+ }
+
+ // read data
+ read_data = 0;
+ for(icount = 0; icount < 16; icount++){
+ EEPROM_RD_DATA( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS, read_data );
+ }
+
+ // close
+ EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+ EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON );
+
+ // put old parameter
+ HAL_WRITE_UINT8(rtl_addr, org_param);
+
+ return(read_data);
+}
+
+
+/*
+ * Write in mac_address at EEPROM.
+ */
+static void
+rltk8139_eeprom_write( char *rtl_addr, cyg_uint8 eeprom_cmd, cyg_uint8 eeprom_addr, cyg_uint16 src_data )
+{
+cyg_uint8 read_data; // read from eeprom bit data
+cyg_uint8 org_param; // original register parameter
+cyg_uint8 mask_bit8; // mask bit
+cyg_uint16 mask_bit16; // mask bit for write data
+int icount; // for loop counter
+
+ // get old parameter
+ HAL_READ_UINT8( rtl_addr, org_param );
+
+ // ready
+ EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON );
+ EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EESK );
+ EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON );
+
+ // set EWEN (eeprom write enable)
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_PG_EEDI );
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_PG_EEDI );
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_PG_EEDI );
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON );
+
+ // set command
+ mask_bit8 = 0x04;
+ for(icount = 0; icount < 3; icount++){
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_MASK( mask_bit8, eeprom_cmd ));
+ mask_bit8 >>= 1;
+ }
+
+ // set address
+ mask_bit8 = 0x20;
+ for(icount = 0; icount < 6; icount++){
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_MASK( mask_bit8, eeprom_addr ));
+ mask_bit8 >>= 1;
+ }
+
+ // set data
+ mask_bit16 = 0x8000;
+ for(icount = 0; icount < 16; icount++){
+ EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_MASK( mask_bit16, src_data ));
+ mask_bit16 >>= 1;
+ }
+
+ // close
+ EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON );
+ EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EESK );
+ EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON );
+
+ // write ready check
+ EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+
+ // wait busy disable
+ icount = 0;
+ while( 1 ){
+ cyg_thread_delay( 1 );
+ HAL_WRITE_UINT8( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_PG_EESK );
+ HAL_WRITE_UINT8( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+ HAL_READ_UINT8( rtl_addr, read_data );
+ if(( read_data & EEPROM_PG_EEDO ) != 0 ){
+ break;
+ }
+ if( icount++ >= EEPROM_WR_BUSY_RETRIES ){
+ diag_printf("EEPROM write wait error adr=0x%02x data=0x%04x\n", eeprom_addr, src_data );
+ break;
+ }
+ }
+ HAL_WRITE_UINT8( rtl_addr, EEPROM_PG_ON );
+
+ // put old parameter
+ HAL_WRITE_UINT8( rtl_addr, org_param );
+}
+
+#endif
diff --git a/ecos/packages/devs/eth/rltk/8139/current/src/if_8139.h b/ecos/packages/devs/eth/rltk/8139/current/src/if_8139.h
new file mode 100644
index 0000000..6635c2e
--- /dev/null
+++ b/ecos/packages/devs/eth/rltk/8139/current/src/if_8139.h
@@ -0,0 +1,369 @@
+#ifndef CYGONCE_DEVS_ETH_REALTEK_8139_INFO_H
+#define CYGONCE_DEVS_ETH_REALTEK_8139_INFO_H
+/*==========================================================================
+//
+// 8139_info.h
+//
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Eric Doenges
+// Contributors: Chris Nimmers, Gary Thomas, Andy Dyer
+// Date: 2003-07-09
+// Description:
+//
+//####DESCRIPTIONEND####
+*/
+#include <pkgconf/devs_eth_rltk_8139.h>
+
+
+/*
+ * Used to define all vendor/device ID combinations we know about to find
+ * the chip.
+ */
+typedef struct {
+ cyg_uint16 vendor_id;
+ cyg_uint16 device_id;
+ void *data;
+} pci_identifier_t;
+
+#define PCI_ANY_ID (0xFFFF)
+
+/*
+ * Valid receive buffer sizes are 8k+16, 16k+16, 32k+16, or 64k+16.
+ * For the last case, WRAP mode should not be enabled. Since we do not
+ * currently want to support unwrapped mode, do not use 64k+16 at this
+ * point. The buffer length is set via the configuration mechanism.
+ */
+#if (CYGNUM_DEVS_ETH_RLTK_8139_RX_BUF_LEN_IDX < 0) |\
+ (CYGNUM_DEVS_ETH_RLTK_8139_RX_BUF_LEN_IDX > 2)
+#error "The receive ring size index must be in the range of 0 to 2"
+#endif
+#define RX_BUF_LEN (8192 << (CYGNUM_DEVS_ETH_RLTK_8139_RX_BUF_LEN_IDX))
+#define RX_BUF_PAD 16
+#define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
+#define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
+
+/* Number of Tx descriptor registers. */
+#define NUM_TX_DESC 4
+
+/*
+ * Max supported ethernet frame size. The 8139 cannot transmit packets more
+ * than 1792 bytes long. Also, since transmit buffers must be 32-bit
+ * aligned, MAX_ETH_FRAME_SIZE should always be a multiple of 4.
+ */
+#define MIN_ETH_FRAME_SIZE 60 /* without FCS */
+#define MAX_ETH_FRAME_SIZE 1536 /* is this with/without FCS ? */
+
+/* Size of the Tx buffers. */
+#define TX_BUF_SIZE MAX_ETH_FRAME_SIZE
+#define TX_BUF_TOT_LEN (TX_BUF_SIZE * NUM_TX_DESC)
+
+/* Rx buffer level before first PCI transfer ('5' is 512 bytes) */
+#define RX_FIFO_THRESH 5
+
+/*
+ * Maximum PCI rx and tx bursts. This value ranges from '0' (16 bytes)
+ * to '7' (unlimited), with MXDMA = 2^(4 + 'value').
+ */
+#define RX_DMA_BURST 6
+#define TX_DMA_BURST 6
+
+/*
+ * Device driver private data
+ */
+typedef struct {
+ /* Device number. Used for actually finding the device */
+ cyg_uint32 device_num;
+
+ /* Receive buffer ring area */
+ cyg_uint8 *rx_ring;
+
+ /* Transmit buffer area */
+ cyg_uint8 *tx_buffer;
+
+ /* PCI device ID */
+ cyg_pci_device_id pci_device_id;
+
+ /* Address for memory mapped I/O */
+ cyg_uint32 base_address;
+
+ /* Our current MAC address */
+ unsigned char mac[6];
+
+ /* tx FIFO threshold. */
+ cyg_uint8 tx_threshold;
+
+ /* This is the first free descriptor. */
+ int tx_free_desc;
+
+ /* This is the number of currently free descriptors */
+ int tx_num_free_desc;
+
+ /* Keys to match _send calls with the tx_done callback */
+ unsigned long tx_desc_key[NUM_TX_DESC];
+
+ /*
+ * This is used to (temporarily) store the address of the current
+ * received packet. We save it here to avoid having to calculate it
+ * several times.
+ */
+ cyg_uint8 *rx_current;
+ cyg_uint32 rx_size;
+
+ /* Interrupt handling stuff */
+ cyg_vector_t vector;
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt;
+
+ /* device ISR priority */
+ cyg_priority_t isr_priority;
+
+} Rltk8139_t;
+
+
+/*
+ * Register offsets and bit definitions. These use the names in the 8139
+ * data sheet, not those found e.g. in the Linux driver for the 8139.
+ */
+enum {
+ IDR0 = 0x0, /* mac address, seemingly in big-endian order */
+ IDR1 = 0x1,
+ IDR2 = 0x2,
+ IDR3 = 0x3,
+ IDR4 = 0x4,
+ IDR5 = 0x5,
+ MAR0 = 0x8, /* multicast registers (0-7) */
+ MAR1 = 0x9,
+ MAR2 = 0xA,
+ MAR3 = 0xB,
+ MAR4 = 0xC,
+ MAR5 = 0xD,
+ MAR6 = 0xE,
+ MAR7 = 0xF,
+ TSD0 = 0x10, /* L, transmit status of descriptor 0 */
+ TSD1 = 0x14,
+ TSD2 = 0x18,
+ TSD3 = 0x1C,
+ TSAD0 = 0x20, /* L, transmit start address of descriptor 0 */
+ TSAD1 = 0x24,
+ TSAD2 = 0x28,
+ TSAD3 = 0x2C,
+ RBSTART = 0x30, /* L, receive buffer start address */
+ ERBCR = 0x34, /* W, early receive byte count register */
+ ERSR = 0x36, /* B, early receive status register */
+ CR = 0x37, /* B, command register */
+ CAPR = 0x38, /* W, current address of packet read */
+ CBR = 0x3A, /* W, current buffer address */
+ IMR = 0x3C, /* W, interrupt mask register */
+ ISR = 0x3E, /* W, interrupt status register */
+ TCR = 0x40, /* L, transmit configuration register */
+ RCR = 0x44, /* L, receive configuration register */
+ TCTR = 0x48, /* L, timer count register */
+ MPC = 0x4C, /* L, missed packet counter */
+ CR9346 = 0x50, /* B, 93C46 (serial eeprom) command register */
+ CONFIG0 = 0x51, /* B, configuration register 0 */
+ CONFIG1 = 0x52, /* B, configuration register 1 */
+ TIMERINT= 0x54, /* L, timer interrupt register */
+ MSR = 0x58, /* B, media status register */
+ CONFIG3 = 0x59, /* B, configuration register 0 */
+ CONFIG4 = 0x5A, /* B, configuration register 1 */
+ MULINT = 0x5C, /* W, multiple interrupt select */
+ RERID = 0x5E, /* B, PCI revision ID; should be 0x10 */
+ TSAD = 0x60, /* W, transmit status of all descriptors */
+ BMCR = 0x62, /* W, basic mode control register */
+ BMSR = 0x64, /* W, basic mode status register */
+ ANAR = 0x66, /* W, auto-negotiation advertisement register */
+ ANLPAR = 0x68, /* W, auto-negotiation link partner register */
+ ANER = 0x6A, /* W, auto-negotiation expansion register */
+ DIS = 0x6C, /* W, disconnect counter */
+ FCSC = 0x6E, /* W, false carrier sense counter */
+ NWAYTR = 0x70, /* W, N-way test register */
+ REC = 0x72, /* W, RX_ER counter */
+ CSCR = 0x74, /* W, CS configuration register */
+ PHY1_PARM = 0x78, /* L, PHY parameter 1 */
+ TW_PARM = 0x7C, /* L, twister parameter */
+ PHY2_PARM = 0x80, /* B, PHY parameter 2 */
+ CRC0 = 0x84, /* B, power management CRC register for wakeup frame 0 */
+ CRC1 = 0x85, /* B, power management CRC register for wakeup frame 1 */
+ CRC2 = 0x86, /* B, power management CRC register for wakeup frame 2 */
+ CRC3 = 0x87, /* B, power management CRC register for wakeup frame 3 */
+ CRC4 = 0x88, /* B, power management CRC register for wakeup frame 4 */
+ CRC5 = 0x89, /* B, power management CRC register for wakeup frame 5 */
+ CRC6 = 0x8A, /* B, power management CRC register for wakeup frame 6 */
+ CRC7 = 0x8B, /* B, power management CRC register for wakeup frame 7 */
+ WAKEUP0 = 0x8C, /* Q, power management wakeup frame 0 (64 bits) */
+ WAKEUP1 = 0x94, /* Q, power management wakeup frame 1 (64 bits) */
+ WAKEUP2 = 0x9C, /* Q, power management wakeup frame 2 (64 bits) */
+ WAKEUP3 = 0xA4, /* Q, power management wakeup frame 3 (64 bits) */
+ WAKEUP4 = 0xAC, /* Q, power management wakeup frame 4 (64 bits) */
+ WAKEUP5 = 0xB4, /* Q, power management wakeup frame 5 (64 bits) */
+ WAKEUP6 = 0xBC, /* Q, power management wakeup frame 6 (64 bits) */
+ WAKEUP7 = 0xC4, /* Q, power management wakeup frame 7 (64 bits) */
+ LSBCRC0 = 0xCC, /* B, LSB of mask byte of wakeup frame 0 offset 12 to 75 */
+ LSBCRC1 = 0xCD, /* B, LSB of mask byte of wakeup frame 1 offset 12 to 75 */
+ LSBCRC2 = 0xCE, /* B, LSB of mask byte of wakeup frame 2 offset 12 to 75 */
+ LSBCRC3 = 0xCF, /* B, LSB of mask byte of wakeup frame 3 offset 12 to 75 */
+ LSBCRC4 = 0xD0, /* B, LSB of mask byte of wakeup frame 4 offset 12 to 75 */
+ LSBCRC5 = 0xD1, /* B, LSB of mask byte of wakeup frame 5 offset 12 to 75 */
+ LSBCRC6 = 0xD2, /* B, LSB of mask byte of wakeup frame 6 offset 12 to 75 */
+ LSBCRC7 = 0xD3, /* B, LSB of mask byte of wakeup frame 7 offset 12 to 75 */
+ FLASH = 0xD4, /* L, flash memory read/write register */
+ CONFIG5 = 0xD8, /* B, configuration register #5 */
+ FER = 0xF0, /* L, function event register (CardBus only) */
+ FEMR = 0xF4, /* L, function event mask register (CardBus only) */
+ FPSR = 0xF8, /* L, function present state register (CardBus only) */
+ FFER = 0xFC /* L, function force event register (CardBus only) */
+};
+
+/* Receive status register in Rx packet header */
+enum {
+ MAR = (1<<15), /* multicast address received */
+ PAM = (1<<14), /* physical address matched */
+ BAR = (1<<13), /* broadcast address received */
+ ISE = (1<<5), /* invalid symbol error */
+ RUNT = (1<<4), /* runt packet (<64 bytes) received */
+ LONG = (1<<3), /* long packet (>4K bytes) received */
+ CRC = (1<<2), /* CRC error */
+ FAE = (1<<1), /* frame alignment error */
+ ROK = (1<<0) /* receive OK */
+};
+
+/* Transmit status register */
+enum {
+ CRS = (1<<31), /* carrier sense lost */
+ TABT = (1<<30), /* transmit abort */
+ OWC = (1<<29), /* out of window collision */
+ CDH = (1<<28), /* CD heart beat */
+ NCC_SHIFT = 24,
+ NCC = (0xF<<24), /* number of collision count */
+ ERTXTH_SHIFT = 16,
+ ERTXTH = (0x1F<<16), /* early tx threshold, in multiples of 32 bytes */
+ TOK = (1<<15), /* transmission OK */
+ TUN = (1<<14), /* transmit FIFO underrun */
+ OWN = (1<<13), /* own */
+ SIZE = 0xFFF /* descriptor size */
+};
+
+/* Command register */
+enum {
+ RST = (1<<4), /* reset */
+ RE = (1<<3), /* receiver enable */
+ TE = (1<<2), /* transmitter enable */
+ BUFE = (1<<0) /* buffer empty */
+};
+
+/* Transmit configuration register */
+enum {
+ CLRABT = (1<<0) /* clear abort */
+};
+
+/* Receive configuration register */
+enum {
+ ERTH_SHIFT = 24, /* Early Rx threshold bits (4) */
+ MULERINT = (1<<17), /* multiple early interrupt */
+ RER8 = (1<<16), /* ? */
+ RXFTH_SHIFT= 13, /* Rx FIFO threshold */
+ RBLEN_SHIFT= 11, /* Rx buffer length */
+ MXDMA_SHIFT= 8, /* max DMA burst size per Rx DMA burst */
+ WRAP = (1<<7), /* WRAP mode */
+ SEL9356 = (1<<6), /* EEPROM select */
+ AER = (1<<5), /* accept error packets */
+ AR = (1<<4), /* accept runt packets */
+ AB = (1<<3), /* accept broadcast packets */
+ AM = (1<<2), /* accept multicast packets */
+ APM = (1<<1), /* accept physical match packets (our MAC) */
+ AAP = (1<<0), /* accept physical address packets (any MAC) */
+};
+
+/* TSAD (transmit status of all descriptors */
+enum {
+ TOK3 = (1<<15),
+ TOK2 = (1<<14),
+ TOK1 = (1<<13),
+ TOK0 = (1<<12),
+ TUN3 = (1<<11),
+ TUN2 = (1<<10),
+ TUN1 = (1<<9),
+ TUN0 = (1<<8),
+ TABT3 = (1<<7),
+ TABT2 = (1<<6),
+ TABT1 = (1<<5),
+ TABT0 = (1<<4),
+ OWN3 = (1<<3),
+ OWN2 = (1<<2),
+ OWN1 = (1<<1),
+ OWN0 = (1<<0)
+};
+
+/* Interrupt mask/status register */
+enum {
+ IR_SERR = (1<<15), /* system error interrupt */
+ IR_TIMEOUT = (1<<14), /* time out interrupt */
+ IR_LENCHG = (1<<13), /* cable length change interrupt */
+ IR_FOVW = (1<<6), /* Rx FIFO overflow */
+ IR_FUN = (1<<5), /* Packet underrun or link change interrupt */
+ IR_RXOVW = (1<<4), /* Rx buffer overflow */
+ IR_TER = (1<<3), /* transmit error interrupt */
+ IR_TOK = (1<<2), /* transmit OK interrupt */
+ IR_RER = (1<<1), /* receive error interrupt */
+ IR_ROK = (1<<0) /* receive OK interrupt */
+};
+
+/* Packet header bits */
+enum {
+ HDR_MAR = (1<<15), /* multicast address received */
+ HDR_PAM = (1<<14), /* physical address matched */
+ HDR_BAR = (1<<13), /* broadcast address matched */
+ HDR_ISE = (1<<5), /* invalid symbol error */
+ HDR_RUNT = (1<<4), /* runt packet received (packet < 64 bytes) */
+ HDR_LONG = (1<<3), /* long packet (>4k) */
+ HDR_CRC = (1<<2), /* CRC error */
+ HDR_FAE = (1<<1), /* frame alignment error */
+ HDR_ROK = (1<<0) /* receive OK */
+};
+
+
+/*
+ * Define some options to use
+ */
+#define TXCFG ((0x3 << 24) | (TX_DMA_BURST << MXDMA_SHIFT))
+#define RXCFG ((RX_FIFO_THRESH << RXFTH_SHIFT) |\
+ (RX_BUF_LEN_IDX << RBLEN_SHIFT) |\
+ (RX_DMA_BURST << MXDMA_SHIFT) |\
+ WRAP | AB | APM)
+
+#endif /* ifndef CYGONCE_DEVS_ETH_REALTEK_8139_INFO_H */
diff --git a/ecos/packages/devs/eth/sh/dreamcast/current/ChangeLog b/ecos/packages/devs/eth/sh/dreamcast/current/ChangeLog
new file mode 100644
index 0000000..2772b4e
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/dreamcast/current/ChangeLog
@@ -0,0 +1,35 @@
+2005-12-02 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/sh_dreamcast_rltk8139_eth_drivers.cdl: Add compiler
+ flags "-D_KERNEL -D__ECOS" so the code compiles.
+
+2004-04-21 Yoshinori Sato <ysato@users.sourceforge.jp>
+
+ * src/if_dreamcast.c
+ * include/devs_eth_sh_dreamcast_rltk8139.inl
+ * cdl/sh_dreamcast_rltk_8139_eth_drivers.cdl:
+ New package - SEGA Dreamcast Broadband Adapter Support.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/sh/dreamcast/current/cdl/sh_dreamcast_rltk8139_eth_drivers.cdl b/ecos/packages/devs/eth/sh/dreamcast/current/cdl/sh_dreamcast_rltk8139_eth_drivers.cdl
new file mode 100644
index 0000000..bd2d8a6
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/dreamcast/current/cdl/sh_dreamcast_rltk8139_eth_drivers.cdl
@@ -0,0 +1,109 @@
+# ====================================================================
+#
+# sh_dreamcast_rltk8139_eth_drivers.cdl
+#
+# Ethernet drivers - support for Dreamcast BroadBandAdapter
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Yoshinori Sato
+# Contributors:
+# Date: 2004-04-22
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_SH_DREAMCAST_RLTK8139 {
+ display "Dreamcast BbA driver"
+ description "Ethernet driver for Dreamcast Broadband Adapter"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_SH_SH7750_DREAMCAST
+ compile -library=libextras.a if_dreamcast.c
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the RealTek_8139 package ?
+ cdl_interface CYGINT_DEVS_ETH_RLTK_8139_REQUIRED {
+ display "RealTek 8139 ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_RLTK_8139_INL <cyg/io/devs_eth_sh_dreamcast_rltk8139.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_RLTK_8139_CFG <pkgconf/devs_eth_sh_dreamcast_rltk8139.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_SH_DREAMCAST_RLTK8139_ETH0 {
+ display "Ethernet port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_RLTK_8139_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_SH_DREAMCAST_RLTK8139_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ RealTek 8139 ethernet port 0."
+ }
+ }
+ cdl_component CYGPKG_DEVS_ETH_SH_DREAMCAST_RLTK8139_OPTIONS {
+ display "RealTek 8139 ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_SH_DREAMCAST_RLTK8139_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the RealTek 8139 ethernet driver package. These
+ flags are used in addition to the set of global flags."
+ }
+ }
+}
+
+# EOF sh_dreamcast_rltk8139_eth_drivers.cdl
diff --git a/ecos/packages/devs/eth/sh/dreamcast/current/include/devs_eth_sh_dreamcast_rltk8139.inl b/ecos/packages/devs/eth/sh/dreamcast/current/include/devs_eth_sh_dreamcast_rltk8139.inl
new file mode 100644
index 0000000..cb9e8b3
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/dreamcast/current/include/devs_eth_sh_dreamcast_rltk8139.inl
@@ -0,0 +1,79 @@
+//==========================================================================
+//
+// devs/eth/sh/dreamcast/include/devs_eth_sh_dreamcast_rltk8139.inl
+//
+// SEGA Dreamcast Broadband Adapter I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Yoshinori Sato
+// Contributors:
+// Date: 2004-04-22
+// Purpose: SEGA Dreamcast Broadband Adapter definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#ifdef CYGPKG_DEVS_ETH_SH_DREAMCAST_RLTK8139_ETH0
+
+static Rltk8139_t rltk8139_eth0_priv_data = {
+ 0, 0, 0
+};
+
+ETH_DRV_SC(rltk8139_sc0,
+ &rltk8139_eth0_priv_data,
+ CYGDAT_DEVS_ETH_SH_DREAMCAST_RLTK8139_ETH0_NAME,
+ rltk8139_start,
+ rltk8139_stop,
+ rltk8139_control,
+ rltk8139_can_send,
+ rltk8139_send,
+ rltk8139_recv,
+ rltk8139_deliver,
+ rltk8139_poll,
+ rltk8139_int_vector
+ );
+
+NETDEVTAB_ENTRY(rltk8139_netdev0,
+ "rltk8139_" CYGDAT_DEVS_ETH_SH_DREAMCAST_RLTK8139_ETH0_NAME,
+ rltk8139_init,
+ &rltk8139_sc0);
+
+void __dreamcast_bba_init(struct eth_drv_sc *sc);
+#define CYGHWR_RLTK_8139_PLF_INIT(sc) __dreamcast_bba_init(sc);
+
+#endif // CYGPKG_DEVS_ETH_SH_DREAMCAST_RLTK8139_ETH0
+
+// EOF devs_eth_sh_dreamcast_rltk8139.inl
diff --git a/ecos/packages/devs/eth/sh/dreamcast/current/src/if_dreamcast.c b/ecos/packages/devs/eth/sh/dreamcast/current/src/if_dreamcast.c
new file mode 100644
index 0000000..5ba7218
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/dreamcast/current/src/if_dreamcast.c
@@ -0,0 +1,92 @@
+//==========================================================================
+//
+// devs/eth/sh/dreamcast/src/devs_eth_sh_dreamcast_rltk8139.c
+//
+// Dreamcast Broadband Adapter initialize functions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Yoshiori Sato
+// Contributors:
+// Date: 2004-04-21
+// Purpose: dreamcast BbA initialize functions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/pci.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/devs/eth/src/if_8139.h>
+
+/* DMA BASE address */
+#define GAPSPCI_DMA_BASE 0x01840000
+#define GAPSPCI_DMA_SIZE 32768
+#define BBA_BASE 0x01001700
+
+#define P2BASE 0xa0000000
+
+static cyg_uint32 gapspci_dma_alloc(int size)
+{
+ static cyg_uint32 top = GAPSPCI_DMA_BASE;
+ cyg_uint32 r;
+ if ((GAPSPCI_DMA_SIZE - (top - GAPSPCI_DMA_BASE)) < size)
+ r = 0;
+ else {
+ r = top;
+ top += size;
+ }
+ return r;
+}
+
+void __dreamcast_bba_init(struct eth_drv_sc *sc)
+{
+ Rltk8139_t *rltk8139_info = (Rltk8139_t *)(sc->driver_private);
+ int i;
+
+ rltk8139_info->base_address = (BBA_BASE | P2BASE);
+
+ rltk8139_info->tx_buffer = (cyg_uint8 *)(gapspci_dma_alloc(TX_BUF_TOT_LEN) | P2BASE);
+ rltk8139_info->rx_ring = (cyg_uint8 *)(gapspci_dma_alloc(RX_BUF_TOT_LEN) | P2BASE);
+
+ for (i = 0; i < 6; ++i)
+ HAL_READ_UINT8(rltk8139_info->base_address + IDR0 + i, rltk8139_info->mac[i]);
+}
+
+// EOF if_dreamcast.c
diff --git a/ecos/packages/devs/eth/sh/etherc/current/ChangeLog b/ecos/packages/devs/eth/sh/etherc/current/ChangeLog
new file mode 100644
index 0000000..51497aa
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/etherc/current/ChangeLog
@@ -0,0 +1,105 @@
+2004-08-12 Jani Monoses <jani@iv.ro>
+
+ * src/if_etherc.c: Fix builing with lwip.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_etherc.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2002-03-18 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/if_etherc.c (etherc_RxEvent): ensure Receive Request is always
+ enabled.
+
+2002-03-18 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_etherc.h: Removed some unused definitions.
+
+ * src/if_etherc.c (etherc_poll): Move the bit of code that ensures RX
+ enabling down to the exit of the function so it is always executed.
+
+2002-03-07 Jesper Skov <jskov@redhat.com>
+
+ * src/if_etherc.c: Initialize interrupt field. Skip tests for
+ suspended device - they are wrong.
+
+ * src/phyter.inl (_MII_RENEGOTIATE): split delay out in new
+ _MII_RENEGOTIATION_WAIT macro.
+ (_MII_SPEED_FORCE_10MB): Added.
+
+ * src/if_etherc.c (sh_etherc_init): Added forced-10Mbit
+ option. Cleaned up some fix mes.
+
+2002-03-06 Jesper Skov <jskov@redhat.com>
+
+ * src/if_etherc.c: Disabled PHY errata workaround. Make sure
+ promisuous mode is disabled per default. Don't clear the wrap-bit
+ of the RD table.
+
+ * src/sh_etherc.h: Added a definition.
+
+2002-02-21 Jesper Skov <jskov@redhat.com>
+
+ * src/if_etherc.c (_MII_HAS_EXTENDED): define.
+
+2002-02-20 Jesper Skov <jskov@redhat.com>
+
+ * src/if_etherc.c: Pad packets to minimum ethernet frame
+ length. Added PHY erratum workaround.
+
+ * src/sh_etherc.h: Remove debug setting.
+
+ * src/phyter.inl: Added here for now.
+
+ * src/if_etherc.c: Include phyter.inl.
+ (sh_etherc_init): Fix ring initialization. Set to continuous
+ reception.
+ (etherc_start): Tell FIFO to dump data in memory.
+ (etherc_control): Use _MII functions to gather necessary
+ information.
+ (etherc_can_send): Same.
+ Added _MII accessor macros and some extra debug code.
+
+2002-02-19 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_etherc.h: Moved debug print code here. Tweak debug
+ functions.
+ * src/if_etherc.c: Tweaked the init and TX code some. Don't check
+ for CYGARC_REG_EESR_ECI in the poll function as it does not appear
+ to get set when other requests are. Moved debug print code to
+ header file.
+
+ * src/sh_etherc.h: More definitions.
+
+ * src/if_etherc.c: Fix typos. Add interrupt attach code. Update
+ remaining functions to support this controller.
+
+2002-01-30 Jesper Skov <jskov@redhat.com>
+
+ * File structure cloned from PCNet driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/sh/etherc/current/cdl/sh_etherc_eth_drivers.cdl b/ecos/packages/devs/eth/sh/etherc/current/cdl/sh_etherc_eth_drivers.cdl
new file mode 100644
index 0000000..a1863ce
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/etherc/current/cdl/sh_etherc_eth_drivers.cdl
@@ -0,0 +1,104 @@
+# ====================================================================
+#
+# sh_etherc_eth_drivers.cdl
+#
+# Ethernet drivers - support for SH EtherC ethernet controllers
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2002-01-30
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_SH_ETHERC {
+ display "SH EtherC CPU module ethernet driver"
+ description "Ethernet driver for SH EtherC CPU module controller."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ active_if CYGINT_DEVS_ETH_SH_ETHERC_REQUIRED
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ compile -library=libextras.a if_etherc.c
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_SH_ETHERC_CFG";
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_SH_ETHERC_DEV_COUNT {
+ display "Number of supported interfaces."
+ calculated { CYGINT_DEVS_ETH_SH_ETHERC_REQUIRED }
+ flavor data
+ description "
+ This option selects the number of ethernet interfaces to
+ be supported by the driver."
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_SH_ETHERC_FORCE_10MBPS {
+ display "Force negotiation of a 10Mbps link"
+ flavor bool
+ default_value 0
+ description "
+ If this option is enabled then the driver will force the chipset
+ to negotiate only for a 10Mbps link (rather than a 100Mbps
+ link)."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_SH_ETHERC_OPTIONS {
+ display "ETHERC ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_SH_ETHERC_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the EtherC ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/sh/etherc/current/src/if_etherc.c b/ecos/packages/devs/eth/sh/etherc/current/src/if_etherc.c
new file mode 100644
index 0000000..1f6563d
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/etherc/current/src/if_etherc.c
@@ -0,0 +1,1126 @@
+//==========================================================================
+//
+// dev/if_etherc.c
+//
+// Ethernet device driver for SH EtherC CPU module controller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2002-01-30
+// Purpose:
+// Description: Hardware driver for SH EtherC CPU module controller
+//
+// Notes: The KEEP_STATISTICS code is not implemented yet. Look
+// for FIXME macro.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_sh_etherc.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h> // delays
+#include <string.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <cyg/kernel/kapi.h>
+#include <net/if.h> /* Needed for struct ifnet */
+#include <pkgconf/io_eth_drivers.h>
+#endif
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#define FIXME 0
+
+// Set size so it is 16-byte aligned
+#define _BUF_SIZE (1544+8)
+
+#define IEEE_8023_MIN_FRAME 64 // Smallest possible ethernet frame
+
+#ifdef CYGPKG_INFRA_DEBUG
+// Then we log, OOI, the number of times we get a bad packet number
+// from the tx done fifo.
+int etherc_txfifo_good = 0;
+int etherc_txfifo_bad = 0;
+#endif
+
+#include "sh_etherc.h"
+#define __WANT_DEVS
+#include CYGDAT_DEVS_ETH_SH_ETHERC_INL
+#undef __WANT_DEVS
+
+static void etherc_poll(struct eth_drv_sc *sc);
+
+static cyg_uint16 etherc_read_MII(struct etherc_priv_data *cpd, int id, int reg);
+static void etherc_write_MII(struct etherc_priv_data *cpd, int id, int reg, cyg_uint16 value);
+#define _MII_READ(_priv_, _id_, _reg_) etherc_read_MII(_priv_, _id_, _reg_)
+#define _MII_WRITE(_priv_, _id_, _reg_, _val_) etherc_write_MII(_priv_, _id_, _reg_, _val_)
+#define _MII_HAS_EXTENDED
+#include "phyter.inl"
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+// This ISR is called when the ethernet interrupt occurs
+static cyg_uint32
+etherc_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct etherc_priv_data *cpd = (struct etherc_priv_data *)data;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( interrupts );
+
+ cyg_drv_interrupt_mask(cpd->interrupt);
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+static void
+etherc_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ // This conditioning out is necessary because of explicit calls to this
+ // DSR - which would not ever be called in the case of a polled mode
+ // usage ie. in RedBoot.
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ struct etherc_priv_data* cpd = (struct etherc_priv_data *)data;
+ struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->ndp);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ // but here, it must be a *sc:
+ eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+#else
+# ifndef CYGPKG_REDBOOT
+# error Empty Etherc ethernet DSR is compiled. Is this what you want?
+# endif
+#endif
+}
+#endif // CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+
+
+// The deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+etherc_deliver(struct eth_drv_sc *sc)
+{
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ // Service the interrupt:
+ etherc_poll(sc);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+}
+
+static int
+etherc_int_vector(struct eth_drv_sc *sc)
+{
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+
+ return (cpd->interrupt);
+}
+
+
+static bool
+sh_etherc_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+ cyg_uint8 *p, *d;
+ cyg_uint32 reg;
+ int i;
+ bool esa_configured = true;
+
+ DEBUG_FUNCTION();
+
+ cpd->txbusy = 0;
+
+ // Ensure that addresses of ring descriptors and buffers are properly aligned
+ // and in uncached memory.
+ cpd->rx_buffers = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS(((cyg_uint32)cpd->rx_buffers+16-1) & ~(16-1));
+ cpd->rx_ring = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS(((cyg_uint32)cpd->rx_ring+16-1) & ~(16-1));
+ cpd->tx_buffers = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS(((cyg_uint32)cpd->tx_buffers+16-1) & ~(16-1));
+ cpd->tx_ring = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS(((cyg_uint32)cpd->tx_ring+16-1) & ~(16-1));
+
+#if DEBUG & 8
+ db_printf("Etherc at base 0x%08x\n", cpd->base);
+#endif
+
+ // Find ESA - check possible sources in sequence and stop when
+ // one provides the ESA:
+ // RedBoot option (via provide_esa)
+ // Compile-time configuration
+ // EEPROM
+ // <fail configuration of device>
+ if (NULL != cpd->provide_esa) {
+ esa_configured = cpd->provide_esa(cpd);
+# if DEBUG & 8
+ if (esa_configured)
+ diag_printf("Got ESA from RedBoot option\n");
+# endif
+ }
+ if (!esa_configured && cpd->hardwired_esa) {
+ // ESA is already set in cpd->esa[]
+ esa_configured = true;
+ }
+ if (!esa_configured) {
+# if DEBUG & 8
+ diag_printf("EtherC - no EEPROM, static ESA or RedBoot config option.\n");
+# endif
+ return false;
+ }
+
+#if DEBUG & 9
+ db_printf("ETHERC ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ cpd->esa[0], cpd->esa[1], cpd->esa[2],
+ cpd->esa[3], cpd->esa[4], cpd->esa[5] );
+#endif
+
+ // Prepare RX and TX rings
+ p = cpd->rx_ring;
+ d = cpd->rx_buffers;
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ _SU32(p, ETHERC_RD_STAT) = ETHERC_RD_STAT_RACT | ETHERC_RD_STAT_RFP_OTO;
+ _SU16(p, ETHERC_RD_RBL) = _BUF_SIZE;
+ _SU16(p, ETHERC_RD_RDL) = 0;
+ _SU32(p, ETHERC_RD_RBA) = (cyg_uint32)d;
+ _SU32(p, ETHERC_RD_PAD) = 0;
+ p += ETHERC_RD_SIZE;
+ d += _BUF_SIZE;
+ }
+ // Set ring-end marker
+ p -= ETHERC_RD_SIZE;
+ _SU32(p, ETHERC_RD_STAT) |= ETHERC_RD_STAT_RDLE;
+ cpd->rx_ring_next = 0;
+
+ p = cpd->tx_ring;
+ d = cpd->tx_buffers;
+ for (i = 0; i < cpd->tx_ring_cnt; i++) {
+ _SU32(p, ETHERC_TD_STAT) = ETHERC_TD_STAT_TFP_OTO;
+ _SU16(p, ETHERC_TD_TDL) = 0;
+ _SU16(p, ETHERC_TD_PAD0) = 0;
+ _SU32(p, ETHERC_TD_TBA) = (cyg_uint32)d;
+ _SU32(p, ETHERC_TD_PAD1) = 0;
+ p += ETHERC_TD_SIZE;
+ d += _BUF_SIZE;
+ }
+ // Set ring-end marker
+ p -= ETHERC_RD_SIZE;
+ _SU32(p, ETHERC_TD_STAT) |= ETHERC_TD_STAT_TDLE;
+ cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;
+
+ // Reset ethernet module, then wait for (at least) 16 clocks.
+ put_reg(cpd, _REG_EDMR, CYGARC_REG_EDMR_SWR | CYGARC_REG_EDMR_DL16);
+ for (i = 0; i < 16; i++);
+ put_reg(cpd, _REG_EDMR, CYGARC_REG_EDMR_DL16);
+
+ // Program ring data into controller
+ put_reg(cpd, _REG_RDLAR, (cyg_uint32)cpd->rx_ring);
+ put_reg(cpd, _REG_TDLAR, (cyg_uint32)cpd->tx_ring);
+
+ // Set ESA
+ put_reg(cpd, _REG_MAHR, (cpd->esa[0] << 24) | (cpd->esa[1] << 16) | (cpd->esa[2] << 8) | cpd->esa[3]);
+ put_reg(cpd, _REG_MALR, (cpd->esa[4] << 8) | cpd->esa[5]);
+
+ // Set receive mode: receive continuously
+ put_reg(cpd, _REG_RCR, CYGARC_REG_RCR_RNC);
+
+ // Stop controller, set duplex mode
+ put_reg(cpd, _REG_ECMR, CYGARC_REG_ECMR_DM);
+ cpd->active = 0;
+
+ // Clear pending interrupt flags
+ reg = get_reg(cpd, _REG_EESR);
+ put_reg(cpd, _REG_EESR, reg);
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ // Attach ISR/DSRs.
+ cpd->interrupt = CYGNUM_HAL_INTERRUPT_EDMAC_EINT;
+ cyg_drv_interrupt_create(cpd->interrupt,
+ 1, // Priority
+ (cyg_addrword_t)cpd, // Data item passed to ISR & DSR
+ etherc_isr, // ISR
+ etherc_dsr, // DSR
+ &cpd->interrupt_handle, // handle to intr obj
+ &cpd->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(cpd->interrupt_handle);
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+ put_reg(cpd, _REG_EESIPR, CYGARC_REG_EESIPR_TCIP|CYGARC_REG_EESIPR_FRIP);
+#if DEBUG & 8
+ db_printf("Attached interrupt on vector %d\n", cpd->interrupt);
+#endif
+#endif
+
+ // Record the net dev pointer
+ cpd->ndp = (void *)tab;
+
+
+ // Initialize the PHY
+#ifdef CYGSEM_DEVS_ETH_SH_ETHERC_FORCE_10MBPS
+#if DEBUG & 8
+ db_printf("Forcing 10Mb link\n");
+#endif
+ _MII_SPEED_FORCE_10MB(cpd, 1);
+ _MII_RENEGOTIATE(cpd, 1);
+#else
+ // Wait for automatic negotiation to complete
+ _MII_RENEGOTIATION_WAIT(cpd, 1);
+#endif
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, cpd->esa);
+
+#if DEBUG & 9
+ db_printf("Done\n");
+#endif
+ return true;
+}
+
+static void
+etherc_suspend(struct etherc_priv_data *cpd)
+{
+ cyg_uint32 reg;
+#if 0
+ bool still_active;
+#endif
+
+ reg = get_reg(cpd, _REG_ECMR);
+ reg &= ~(CYGARC_REG_ECMR_TE | CYGARC_REG_ECMR_RE);
+ put_reg(cpd, _REG_ECMR, reg);
+
+#if 0 //
+ // Try to find out if controller stopped. Supposedly, it should
+ // communicate this by clearing the active signal of the active
+ // RX/TX descriptors.
+
+ // Check RX
+ do {
+ still_active = false;
+ reg = get_reg(cpd, _REG_RDFAR);
+#if 1
+ {
+ int i;
+ cyg_uint8* p;
+ p = cpd->rx_ring;
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ if ((cyg_uint32)p == reg) {
+ if (_SU32(reg, ETHERC_RD_STAT) & ETHERC_RD_STAT_RACT) {
+ still_active = true;
+ break;
+ }
+ }
+ }
+ }
+#else
+ if (_SU32(reg, ETHERC_RD_STAT) & ETHERC_RD_STAT_RACT)
+ still_active = true;
+#endif
+ } while (still_active);
+
+ // Check TX
+ do {
+ still_active = false;
+ reg = get_reg(cpd, _REG_TDFAR);
+#if 1
+ {
+ int i;
+ cyg_uint8* p;
+ p = cpd->tx_ring;
+ for (i = 0; i < cpd->tx_ring_cnt; i++) {
+ if ((cyg_uint32)p == reg) {
+ if (_SU32(reg, ETHERC_TD_STAT) & ETHERC_TD_STAT_TACT) {
+ still_active = true;
+ break;
+ }
+ }
+ }
+ }
+#else
+ if (_SU32(reg, ETHERC_TD_STAT) & ETHERC_TD_STAT_TACT)
+ still_active = true;
+#endif
+ } while (still_active);
+
+ db_printf("all done\n");
+#endif
+ cpd->active = 0;
+}
+
+static void
+etherc_stop(struct eth_drv_sc *sc)
+{
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ etherc_suspend(cpd);
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+etherc_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ cyg_uint32 reg, prm_mode = 0;
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+#ifdef CYGPKG_NET
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+ DEBUG_FUNCTION();
+
+ // If device is already active, suspend it
+ if (cpd->active) {
+ etherc_suspend(cpd);
+ }
+
+#ifdef CYGPKG_NET
+ if (( 0
+#ifdef ETH_DRV_FLAGS_PROMISC_MODE
+ != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
+#endif
+ ) || (ifp->if_flags & IFF_PROMISC)
+ ) {
+ // Then we select promiscuous mode.
+ prm_mode = CYGARC_REG_ECMR_PRM;
+ }
+#endif
+
+ // Unsuspend the device
+ reg = get_reg(cpd, _REG_ECMR);
+ reg |= CYGARC_REG_ECMR_TE | CYGARC_REG_ECMR_RE;
+ reg &= ~CYGARC_REG_ECMR_PRM;
+ reg |= prm_mode;
+ put_reg(cpd, _REG_ECMR, reg);
+
+ put_reg(cpd, _REG_EDRRR, CYGARC_REG_EDRRR_RR);
+
+ cpd->active = 1;
+}
+
+//
+// This routine is called to perform special "control" opertions
+//
+static int
+etherc_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ cyg_uint8 *esa = (cyg_uint8 *)data;
+ int i, res;
+ cyg_uint16 reg;
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+ cyg_bool was_active = cpd->active;
+
+ DEBUG_FUNCTION();
+
+ // If device is already active, suspend it
+ if (cpd->active) {
+ etherc_suspend(cpd);
+ }
+
+ res = 0; // expect success
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+#if 9 & DEBUG
+ db_printf("ETHERC - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ esa[0], esa[1], esa[2], esa[3], esa[4], esa[5] );
+#endif // DEBUG
+
+ for ( i = 0; i < sizeof(cpd->esa); i++ )
+ cpd->esa[i] = esa[i];
+ put_reg(cpd, _REG_MAHR,(cpd->esa[0] << 24) | (cpd->esa[1] << 16) | (cpd->esa[2] << 8) | cpd->esa[3]);
+ put_reg(cpd, _REG_MALR, (cpd->esa[4] << 8) | cpd->esa[5]);
+ break;
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ // Extract the MAC address that is in the chip, and tell the
+ // system about it.
+ cyg_uint32 reg;
+ reg = get_reg(cpd, _REG_MAHR);
+ cpd->esa[0] = (reg >> 24) & 0xff;
+ cpd->esa[1] = (reg >> 16) & 0xff;
+ cpd->esa[2] = (reg >> 08) & 0xff;
+ cpd->esa[3] = (reg >> 00) & 0xff;
+ reg = get_reg(cpd, _REG_MALR);
+ cpd->esa[4] = (reg >> 08) & 0xff;
+ cpd->esa[5] = (reg >> 00) & 0xff;
+ break;
+#endif
+
+#ifdef ETH_DRV_GET_IF_STATS_UD
+ case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+#endif
+ // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+ case ETH_DRV_GET_IF_STATS:
+#endif
+
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+ {
+ struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+ // Chipset entry is no longer supported; RFC1573.
+ for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+ p->snmp_chipset[i] = 0;
+
+ // This perhaps should be a config opt, so you can make up your own
+ // description, or supply it from the instantiation.
+ strcpy( p->description, "SH Etherc" );
+ // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+ if (_MII_LINK_STATE(cpd, 1)) {
+ // Link is up
+ p->operational = 3; // LINK UP
+ if (_MII_DUPLEX_STATE(cpd, 1))
+ p->duplex = 3; // 3 = DUPLEX
+ else
+ p->duplex = 2; // 2 = SIMPLEX
+ if (_MII_SPEED_STATE(cpd, 1))
+ p->speed = 100 * 1000000;
+ else
+ p->speed = 10 * 1000000;
+ } else {
+ // Link is down
+ p->operational = 2; // LINK DOWN
+ p->duplex = 1; // UNKNOWN
+ p->speed = 0;
+ }
+#if FIXME
+#ifdef KEEP_STATISTICS
+ {
+ struct sh_etherc_stats *ps = &(cpd->stats);
+
+ // Admit to it...
+ p->supports_dot3 = true;
+
+ p->tx_good = ps->tx_good ;
+ p->tx_max_collisions = ps->tx_max_collisions ;
+ p->tx_late_collisions = ps->tx_late_collisions ;
+ p->tx_underrun = ps->tx_underrun ;
+ p->tx_carrier_loss = ps->tx_carrier_loss ;
+ p->tx_deferred = ps->tx_deferred ;
+ p->tx_sqetesterrors = ps->tx_sqetesterrors ;
+ p->tx_single_collisions = ps->tx_single_collisions;
+ p->tx_mult_collisions = ps->tx_mult_collisions ;
+ p->tx_total_collisions = ps->tx_total_collisions ;
+ p->rx_good = ps->rx_good ;
+ p->rx_crc_errors = ps->rx_crc_errors ;
+ p->rx_align_errors = ps->rx_align_errors ;
+ p->rx_resource_errors = ps->rx_resource_errors ;
+ p->rx_overrun_errors = ps->rx_overrun_errors ;
+ p->rx_collisions = ps->rx_collisions ;
+ p->rx_short_frames = ps->rx_short_frames ;
+ p->rx_too_long_frames = ps->rx_too_long_frames ;
+ p->rx_symbol_errors = ps->rx_symbol_errors ;
+
+ p->interrupts = ps->interrupts ;
+ p->rx_count = ps->rx_count ;
+ p->rx_deliver = ps->rx_deliver ;
+ p->rx_resource = ps->rx_resource ;
+ p->rx_restart = ps->rx_restart ;
+ p->tx_count = ps->tx_count ;
+ p->tx_complete = ps->tx_complete ;
+ p->tx_dropped = ps->tx_dropped ;
+ }
+#endif // KEEP_STATISTICS
+#endif // FIXME
+
+ p->tx_queue_len = 1;
+ break;
+ }
+#endif
+ default:
+ res = 1;
+ break;
+ }
+
+ // Restore controller state
+ if (was_active) {
+ // Unsuspend the device
+ reg = get_reg(cpd, _REG_ECMR);
+ reg |= CYGARC_REG_ECMR_RE | CYGARC_REG_ECMR_TE;
+ put_reg(cpd, _REG_ECMR, reg);
+ }
+
+ return res;
+}
+
+//
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+//
+static int
+etherc_can_send(struct eth_drv_sc *sc)
+{
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ if (!_MII_LINK_STATE(cpd, 1))
+ return 0; // Link not connected
+
+ return (0 == cpd->txbusy);
+}
+
+//
+// This routine is called to send data to the hardware.
+static void
+etherc_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+ int i, len, plen, ring_entry;
+
+ cyg_uint8* sdata = NULL;
+ cyg_uint8 *d, *buf, *txd;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( tx_count );
+
+ cpd->txbusy = 1;
+ cpd->txkey = key;
+
+ // Find packet length
+ plen = 0;
+ for (i = 0; i < sg_len; i++)
+ plen += sg_list[i].len;
+
+ CYG_ASSERT( plen == total_len, "sg data length mismatch" );
+
+ // Get next TX descriptor
+ ring_entry = cpd->tx_ring_free;
+ do {
+ if (cpd->tx_ring_owned == cpd->tx_ring_cnt) {
+ // Is this a dead end? Probably is.
+#if DEBUG & 1
+ db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
+#endif
+ continue;
+ }
+
+ cpd->tx_ring_free++;
+ cpd->tx_ring_owned++;
+ if (cpd->tx_ring_free == cpd->tx_ring_cnt)
+ cpd->tx_ring_free = 0;
+ } while (0);
+
+ txd = cpd->tx_ring + ring_entry*ETHERC_TD_SIZE;
+ buf = cpd->tx_buffers + ring_entry*_BUF_SIZE;
+ CYG_ASSERT(0 == (_SU32(txd, ETHERC_TD_STAT) & ETHERC_TD_STAT_TACT),
+ "TX descriptor not free");
+
+#if DEBUG & 4
+ db_printf("#####Tx descriptor 0x%08x buffer 0x%08x\n",
+ txd, buf);
+#endif
+
+ // Put data into buffer
+ d = buf;
+ for (i = 0; i < sg_len; i++) {
+ sdata = (cyg_uint8 *)sg_list[i].buf;
+ len = sg_list[i].len;
+
+ CYG_ASSERT( sdata, "No sg data pointer here" );
+ while(len--)
+ *d++ = *sdata++;
+ }
+ CYG_ASSERT( sdata, "No sg data pointer outside" );
+
+ if (plen < IEEE_8023_MIN_FRAME) {
+#if DEBUG & 1
+ db_printf("Packet too short (%d) - padding to %d bytes.\n", plen, IEEE_8023_MIN_FRAME);
+#endif
+ for (i = plen; i < IEEE_8023_MIN_FRAME; i++)
+ *d++ = 0;
+ plen = IEEE_8023_MIN_FRAME;
+ }
+
+ _SU16(txd, ETHERC_TD_TDL) = plen;
+ _SU32(txd, ETHERC_TD_STAT) |= ETHERC_TD_STAT_TACT;
+
+#if DEBUG & 1
+ db_printf("Last TX: LEN %04x STAT %08x PTR %08x\n",
+ _SU16(txd, ETHERC_TD_TDL),
+ _SU32(txd, ETHERC_TD_STAT),
+ _SU32(txd, ETHERC_TD_TBA));
+#endif
+
+ // Set transmit demand
+ put_reg(cpd, _REG_EDTRR, CYGARC_REG_EDTRR_TR);
+
+#if DEBUG & 1
+ {
+ cyg_uint32 reg;
+ reg = get_reg(cpd, _REG_EESR);
+ db_printf("%s:END: EESR at TX: 0x%08x\n", __FUNCTION__, reg);
+ }
+#endif
+}
+
+static void
+etherc_TxEvent(struct eth_drv_sc *sc, int stat)
+{
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+ int success = 1;
+ cyg_uint8 *txd;
+ cyg_uint32 pkt_stat;
+
+ DEBUG_FUNCTION();
+
+ if (0 == cpd->tx_ring_owned) {
+#if DEBUG & 1
+ db_printf("%s: got TX completion when no outstanding packets\n", __FUNCTION__);
+#endif
+ // Ack the TX int
+ put_reg(cpd, _REG_EESR, CYGARC_REG_EESR_TC);
+ return;
+ }
+
+
+ INCR_STAT( tx_complete );
+
+ txd = cpd->tx_ring + cpd->tx_ring_alloc*ETHERC_TD_SIZE;
+ pkt_stat = _SU32(txd, ETHERC_TD_STAT);
+ if (pkt_stat & ETHERC_TD_STAT_TACT) {
+#if DEBUG & 1
+ db_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__);
+#endif
+ // first dirty ring entry not freed - wtf?
+ }
+
+ if (pkt_stat & ETHERC_TD_STAT_TDFE) {
+ // We had an error. Tell the stack.
+ success = 0;
+#if DEBUG & 1
+ db_printf("%s: TX failure, retrying...\n", __FUNCTION__);
+#endif
+ }
+
+ cpd->tx_ring_alloc++;
+ if (cpd->tx_ring_alloc == cpd->tx_ring_cnt)
+ cpd->tx_ring_alloc = 0;
+ cpd->tx_ring_owned--;
+
+#if FIXME
+#ifdef KEEP_STATISTICS
+ {
+ cyg_uint16 reg;
+
+ reg = get_reg( sc, ETHERC_CSR_CSCR );
+
+ // Covering each bit in turn...
+ if ( reg & ETHERC_STATUS_TX_UNRN ) INCR_STAT( tx_underrun );
+ //if ( reg & ETHERC_STATUS_LINK_OK ) INCR_STAT( );
+ //if ( reg & ETHERC_STATUS_CTR_ROL ) INCR_STAT( );
+ //if ( reg & ETHERC_STATUS_EXC_DEF ) INCR_STAT( );
+ if ( reg & ETHERC_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss );
+ if ( reg & ETHERC_STATUS_LATCOL ) INCR_STAT( tx_late_collisions );
+ //if ( reg & ETHERC_STATUS_WAKEUP ) INCR_STAT( );
+ if ( reg & ETHERC_STATUS_TX_DEFR ) INCR_STAT( tx_deferred );
+ //if ( reg & ETHERC_STATUS_LTX_BRD ) INCR_STAT( );
+ if ( reg & ETHERC_STATUS_SQET ) INCR_STAT( tx_sqetesterrors );
+ if ( reg & ETHERC_STATUS_16COL ) INCR_STAT( tx_max_collisions );
+ //if ( reg & ETHERC_STATUS_LTX_MULT) INCR_STAT( );
+ if ( reg & ETHERC_STATUS_MUL_COL ) INCR_STAT( tx_mult_collisions );
+ if ( reg & ETHERC_STATUS_SNGL_COL ) INCR_STAT( tx_single_collisions );
+ if ( reg & ETHERC_STATUS_TX_SUC ) INCR_STAT( tx_good );
+
+ cpd->stats.tx_total_collisions =
+ cpd->stats.tx_late_collisions +
+ cpd->stats.tx_max_collisions +
+ cpd->stats.tx_mult_collisions +
+ cpd->stats.tx_single_collisions;
+
+ // We do not need to look in the Counter Register (ETHERC_COUNTER)
+ // because it just mimics the info we already have above.
+ }
+#endif // KEEP_STATISTICS
+#endif // FIXME
+
+ // Ack the TX int
+ put_reg(cpd, _REG_EESR, CYGARC_REG_EESR_TC);
+
+#if DEBUG & 4
+ db_printf("#####Tx packet freed 0x%08x\n", txd );
+#endif
+
+ if ( cpd->txbusy ) {
+ cpd->txbusy = 0;
+ (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
+ }
+}
+
+
+//
+// This function is called when a packet has been received. Its job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'etherc_recv' will be called to actually fetch it from the hardware.
+//
+static void
+etherc_RxEvent(struct eth_drv_sc *sc)
+{
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+ cyg_uint8 *rxd;
+ cyg_uint32 rstat;
+ cyg_uint32 ints;
+ cyg_uint16 len;
+
+ DEBUG_FUNCTION();
+
+ ints = get_reg(cpd, _REG_EESR);
+#if DEBUG & 1
+ db_printf("RxEvent - ESSR: 0x%08x\n", ints);
+#endif
+
+ while (1) {
+ // Get state of next (supposedly) full ring entry
+ cpd->rxpacket = cpd->rx_ring_next;
+ rxd = cpd->rx_ring + cpd->rxpacket*ETHERC_RD_SIZE;
+ rstat = _SU32(rxd, ETHERC_RD_STAT);
+
+ // Keep going until we hit an entry that is owned by the
+ // controller.
+ if (rstat & ETHERC_RD_STAT_RACT) {
+#if DEBUG & 1
+ int i;
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*ETHERC_RD_SIZE;
+ rstat = _SU32(rxd, ETHERC_RD_STAT);
+
+ if (!(rstat & ETHERC_RD_STAT_RACT)) {
+ int i;
+ cyg_uint32 rstat;
+ cyg_uint16 mlen, blen;
+ cyg_uint8* rxd;
+
+ db_printf("%s: Inconsistent RX state for %d\n", __FUNCTION__, cpd->rxpacket);
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*ETHERC_RD_SIZE;
+
+ rstat = _SU32(rxd, ETHERC_RD_STAT);
+ blen = _SU16(rxd, ETHERC_RD_RBL);
+ mlen = _SU16(rxd, ETHERC_RD_RDL);
+ db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
+ }
+ }
+ }
+#endif
+ break;
+ }
+
+#if DEBUG & 4
+ db_printf("#####Rx packet at index %d\n", cpd->rxpacket);
+#endif
+
+ // Increment counts
+ INCR_STAT( rx_count );
+ cpd->rx_ring_next++;
+ if (cpd->rx_ring_next == cpd->rx_ring_cnt) cpd->rx_ring_next = 0;
+
+ len = _SU16(rxd, ETHERC_RD_RDL);
+
+#ifdef KEEP_STATISTICS
+ //if ( rstat & ETHERC_RD_PTR_FRAM ) INCR_STAT( rx_frame_errors );
+ //if ( rstat & ETHERC_RD_PTR_OFLO ) INCR_STAT( );
+ if ( rstat & ETHERC_RD_STAT_RFOF ) INCR_STAT( rx_crc_errors );
+ //if ( rstat & ETHERC_RD_PTR_BUFF ) INCR_STAT( );
+#endif // KEEP_STATISTICS
+
+ if (0 == (rstat & ETHERC_RD_STAT_RFE)) {
+ // It's OK
+ INCR_STAT( rx_good );
+
+#if DEBUG & 1
+ db_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len);
+#endif
+ // Check for bogusly short packets; can happen in promisc
+ // mode: Asserted against and checked by upper layer
+ // driver.
+#ifdef CYGPKG_NET
+ if ( len > sizeof( struct ether_header ) )
+ // then it is acceptable; offer the data to the network stack
+#endif
+ (sc->funs->eth_drv->recv)(sc, len);
+ } else {
+ // Not OK for one reason or another...
+#if DEBUG & 1
+ db_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n",
+ rstat, len);
+#endif
+ }
+
+ // Free packet (clear all status flags, and set RACT)
+ _SU32(rxd, ETHERC_RD_STAT) &= ETHERC_RD_STAT_CLEAR;
+ _SU32(rxd, ETHERC_RD_STAT) |= ETHERC_RD_STAT_RACT;
+ }
+
+ // Ack RX interrupt set
+ put_reg(cpd, _REG_EESR, CYGARC_REG_EESR_FR);
+ // ensure Receive Request is enabled
+ put_reg(cpd, _REG_EDRRR, CYGARC_REG_EDRRR_RR);
+#if DEBUG & 1
+ ints = get_reg(cpd, _REG_EESR);
+ db_printf("RxEvent exit - ESSR: 0x%08x\n", ints);
+#endif
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// Its job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+etherc_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+ int i, mlen=0, plen;
+ cyg_uint8 *data, *rxd, *buf;
+
+ DEBUG_FUNCTION();
+
+ rxd = cpd->rx_ring + cpd->rxpacket*ETHERC_TD_SIZE;
+ buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
+
+ INCR_STAT( rx_deliver );
+
+ plen = _SU16(rxd, ETHERC_RD_RDL);
+
+ for (i = 0; i < sg_len; i++) {
+ data = (cyg_uint8*)sg_list[i].buf;
+ mlen = sg_list[i].len;
+
+#if DEBUG & 1
+ db_printf("%s : mlen %04x, plen %04x\n", __FUNCTION__, mlen, plen);
+#endif
+ if (data) {
+ while (mlen > 0) {
+ *data++ = *buf++;
+ mlen--;
+ plen--;
+ }
+ }
+ }
+}
+
+static void
+etherc_poll(struct eth_drv_sc *sc)
+{
+ cyg_uint32 event;
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+
+// DEBUG_FUNCTION();
+
+ while (1) {
+ // Get the (unmasked) requests
+ event = get_reg(cpd, _REG_EESR);
+ if (0 == event)
+ break;
+
+ if (event & CYGARC_REG_EESR_FR) {
+ etherc_RxEvent(sc);
+ }
+ else if (event & CYGARC_REG_EESR_TC) {
+ etherc_TxEvent(sc, event);
+ }
+ else if (event & CYGARC_REG_EESR_RDE) {
+#if DEBUG & 1
+ int i;
+ cyg_uint32 rstat;
+ cyg_uint16 mlen, blen;
+ cyg_uint8* rxd;
+ struct etherc_priv_data *cpd =
+ (struct etherc_priv_data *)sc->driver_private;
+
+ db_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event);
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*ETHERC_RD_SIZE;
+
+ rstat = _SU32(rxd, ETHERC_RD_STAT);
+ blen = _SU16(rxd, ETHERC_RD_RBL);
+ mlen = _SU16(rxd, ETHERC_RD_RDL);
+ db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen);
+ }
+#endif
+ // Just clear the flag - RF is handled earlier in the loop
+ // so a new RX block should be ready when this code
+ // executes.
+ put_reg(cpd, _REG_EESR, CYGARC_REG_EESR_RDE);
+ }
+ else {
+#if DEBUG & 1
+ db_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event);
+#endif
+ put_reg(cpd, _REG_EESR, event);
+ }
+ }
+
+ // Make sure RX is enabled
+ if (cpd->active) {
+ cyg_uint32 reg;
+ reg = get_reg(cpd, _REG_ECMR);
+ reg |= CYGARC_REG_ECMR_RE;
+ put_reg(cpd, _REG_ECMR, reg);
+ }
+}
+
+//----------------------------------------------------------------------------
+// MII accessors
+
+#define _MII_WRITE_BIT(_cpd_, _b_) \
+ CYG_MACRO_START \
+ cyg_uint32 _d_ = (_b_) ? CYGARC_REG_PIR_MDO : 0; \
+ HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_WRITE | _d_); \
+ HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_WRITE | _d_ | CYGARC_REG_PIR_MDC); \
+ HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_WRITE | _d_); \
+ CYG_MACRO_END
+
+#define _MII_READ_BIT(_cpd_, _b_) \
+ CYG_MACRO_START \
+ cyg_uint32 _d_; \
+ HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ | CYGARC_REG_PIR_MDC); \
+ HAL_READ_UINT32(_cpd_->base+_REG_PIR, _d_); \
+ HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ); \
+ (_b_) = (_d_ & CYGARC_REG_PIR_MDI) ? 1 : 0; \
+ CYG_MACRO_END
+
+#define _MII_RELEASE(_cpd_) \
+ CYG_MACRO_START \
+ HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ); \
+ HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ | CYGARC_REG_PIR_MDC); \
+ HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ); \
+ CYG_MACRO_END
+
+#define _MII_RELEASE_INDEP(_cpd_) \
+ CYG_MACRO_START \
+ HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ); \
+ CYG_MACRO_END
+
+
+static void
+etherc_write_MII(struct etherc_priv_data *cpd, int id, int reg, cyg_uint16 value)
+{
+ int i;
+
+ // Pre
+ for(i = 0; i < 32; i++)
+ _MII_WRITE_BIT(cpd, 1);
+ // Start of frame
+ _MII_WRITE_BIT(cpd, 0);
+ _MII_WRITE_BIT(cpd, 1);
+ // Operation (write)
+ _MII_WRITE_BIT(cpd, 0);
+ _MII_WRITE_BIT(cpd, 1);
+ // Phy address
+ for (i = 4; i >= 0; i--)
+ _MII_WRITE_BIT(cpd, (id & (1<<i)) ? 1: 0);
+ // Register address
+ for (i = 4; i >= 0; i--)
+ _MII_WRITE_BIT(cpd, (reg & (1<<i)) ? 1: 0);
+ // TA
+ _MII_WRITE_BIT(cpd, 1);
+ _MII_WRITE_BIT(cpd, 0);
+ // Data
+ for (i = 15; i >= 0; i--)
+ _MII_WRITE_BIT(cpd, (value & (1<<i)) ? 1: 0);
+ // Release bus
+ _MII_RELEASE_INDEP(cpd);
+}
+
+static cyg_uint16
+etherc_read_MII(struct etherc_priv_data *cpd, int id, int reg)
+{
+ bool b;
+ int i;
+ cyg_uint16 val = 0;
+
+ // Pre
+ for(i = 0; i < 32; i++)
+ _MII_WRITE_BIT(cpd, 1);
+ // Start of frame
+ _MII_WRITE_BIT(cpd, 0);
+ _MII_WRITE_BIT(cpd, 1);
+ // Operation (read)
+ _MII_WRITE_BIT(cpd, 1);
+ _MII_WRITE_BIT(cpd, 0);
+ // Phy address
+ for (i = 4; i >= 0; i--)
+ _MII_WRITE_BIT(cpd, (id & (1<<i)) ? 1: 0);
+ // Register address
+ for (i = 4; i >= 0; i--)
+ _MII_WRITE_BIT(cpd, (reg & (1<<i)) ? 1: 0);
+ // TA
+ _MII_RELEASE(cpd);
+ // Data
+ for (i = 15; i >= 0; i--) {
+ _MII_READ_BIT(cpd, b);
+ val = val << 1;
+ if (b) val |= 1;
+ }
+
+ return val;
+}
+
+// EOF if_etherc.c
diff --git a/ecos/packages/devs/eth/sh/etherc/current/src/phyter.inl b/ecos/packages/devs/eth/sh/etherc/current/src/phyter.inl
new file mode 100644
index 0000000..f8630b1
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/etherc/current/src/phyter.inl
@@ -0,0 +1,185 @@
+#ifndef CYGONCE_DEVS_ETH_PHYTER_PHYTER_INL
+#define CYGONCE_DEVS_ETH_PHYTER_PHYTER_INL
+//==========================================================================
+//
+// phyther.inl
+//
+// Generic Phyter definitions and helpers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2002-02-19
+// Purpose: phy/MII definitions
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// Caller must define _MII_WRITE and _MII_READ macros
+#ifndef _MII_WRITE
+# error "_MII_WRITE(_priv_, _id_, _reg_, _val_) and _MII_READ(_priv_, _id_, _reg_) must be defined"
+#endif
+
+// Caller can define _MII_HAS_EXTENDED to add support for extended registers
+
+//-----------------------------------------------------------------------------
+// Helpers
+
+// Renegotiate link
+// This function will delay for up to 2 seconds waiting for a renegotiation
+// of the link.
+#define _MII_RENEGOTIATE(_priv_, _id_) \
+ CYG_MACRO_START \
+ _MII_WRITE(_priv_, _id_, CYGARC_REG_MII_BMCR, CYGARC_REG_MII_BMCR_RENEGOTIATE); \
+ _MII_RENEGOTIATION_WAIT(_priv_, _id_); \
+ CYG_MACRO_END
+
+// Wait for renegotiation to complete
+// This function will delay for up to 2 seconds waiting for a renegotiation
+// of the link.
+#define _MII_RENEGOTIATION_WAIT(_priv_, _id_) \
+ CYG_MACRO_START \
+ int _i; \
+ cyg_uint16 _r; \
+ for (_i = 0; _i < 2000; _i++) { \
+ HAL_DELAY_US(1000); \
+ _r = _MII_READ(_priv_, _id_, CYGARC_REG_MII_BMSR); \
+ if (_r & CYGARC_REG_MII_BMSR_AN_COMPLETE) break; \
+ } \
+ CYG_MACRO_END
+
+// Link state query
+#define _MII_LINK_STATE(_priv_, _id_) \
+ ({ int _i; \
+ if (_MII_READ(_priv_, _id_, CYGARC_REG_MII_BMSR) & CYGARC_REG_MII_BMSR_LINK) \
+ (_i) = 1; \
+ else \
+ (_i) = 0; \
+ _i; })
+
+// Clear 100MB capability advertisement bits
+// Caller has to start a new renegoatiation
+#define _MII_SPEED_FORCE_10MB(_priv_, _id_) \
+ CYG_MACRO_START \
+ cyg_uint16 _d; \
+ _d = _MII_READ(_priv_, _id_, CYGARC_REG_MII_ANAR); \
+ _d &= ~(CYGARC_REG_MII_ANAR_T4|CYGARC_REG_MII_ANAR_TX_FD|CYGARC_REG_MII_ANAR_TX); \
+ _MII_WRITE(_priv_, _id_, CYGARC_REG_MII_ANAR, _d); \
+ CYG_MACRO_END
+
+#ifdef _MII_HAS_EXTENDED
+
+// Speed state query
+// 0 = 10Mb, 1 = 100Mb
+#define _MII_SPEED_STATE(_priv_, _id_) \
+ ({ int _i; \
+ if (_MII_READ(_priv_, _id_, CYGARC_REG_MII_PHYSTS) & CYGARC_REG_MII_PHYSTS_SPEED) \
+ (_i) = 0; \
+ else \
+ (_i) = 1; \
+ _i; })
+
+// Duplex state query
+// 0 = simplex, 1 = duplex
+#define _MII_DUPLEX_STATE(_priv_, _id_) \
+ ({ int _i; \
+ if (_MII_READ(_priv_, _id_, CYGARC_REG_MII_PHYSTS) & CYGARC_REG_MII_PHYSTS_DUPLEX) \
+ (_i) = 1; \
+ else \
+ (_i) = 0; \
+ _i; })
+
+#endif // _MII_HAS_EXTENDED
+
+// Dump registers
+// Useful for debugging
+#define _MII_DUMP_REGS(_priv_, _id_) \
+ CYG_MACRO_START \
+ int _i; \
+ diag_printf("PHY registers:\n"); \
+ for(_i = 0; _i <= CYGARC_REG_MII_LAST; _i++) \
+ diag_printf(" %02d %04x\n", _i, _MII_READ(_priv_, _id_, _i)); \
+ CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+// Phyter Registers
+
+// Generic
+#define CYGARC_REG_MII_BMCR 0x00
+#define CYGARC_REG_MII_BMSR 0x01
+#define CYGARC_REG_MII_PHYIDR1 0x02
+#define CYGARC_REG_MII_PHYIDR2 0x03
+#define CYGARC_REG_MII_ANAR 0x04
+#define CYGARC_REG_MII_ANLPAR 0x05
+#define CYGARC_REG_MII_ANER 0x06
+#define CYGARC_REG_MII_ANNPTR 0x07
+
+#define CYGARC_REG_MII_BMCR_RESET 0x8000
+#define CYGARC_REG_MII_BMCR_LOOPBACK 0x4000
+#define CYGARC_REG_MII_BMCR_RENEGOTIATE 0x3300
+
+#define CYGARC_REG_MII_BMSR_AN_COMPLETE 0x0020
+#define CYGARC_REG_MII_BMSR_LINK 0x0004
+
+#define CYGARC_REG_MII_ANAR_T4 0x0200
+#define CYGARC_REG_MII_ANAR_TX_FD 0x0100
+#define CYGARC_REG_MII_ANAR_TX 0x0080
+#define CYGARC_REG_MII_ANAR_10_FD 0x0040
+#define CYGARC_REG_MII_ANAR_10 0x0020
+
+// Extended registers
+#ifndef _MII_HAS_EXTENDED
+# define CYGARC_REG_MII_LAST 0x0f
+#else
+# define CYGARC_REG_MII_PHYSTS 0x10
+# define CYGARC_REG_MII_FCSCR 0x14
+# define CYGARC_REG_MII_RECR 0x15
+# define CYGARC_REG_MII_PCSR 0x16
+# define CYGARC_REG_MII_PHYCTRL 0x19
+# define CYGARC_REG_MII_10BTSCR 0x1a
+# define CYGARC_REG_MII_CDCTRL 0x1b
+# define CYGARC_REG_MII_LAST 0x1f
+
+
+# define CYGARC_REG_MII_PHYSTS_SPEED 0x00000002
+# define CYGARC_REG_MII_PHYSTS_DUPLEX 0x00000004
+
+#endif
+
+#endif // CYGONCE_DEVS_ETH_PHYTER_PHYTER_INL
diff --git a/ecos/packages/devs/eth/sh/etherc/current/src/sh_etherc.h b/ecos/packages/devs/eth/sh/etherc/current/src/sh_etherc.h
new file mode 100644
index 0000000..dba071f
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/etherc/current/src/sh_etherc.h
@@ -0,0 +1,343 @@
+#ifndef CYGONCE_DEVS_ETH_SH_ETHERC_H
+#define CYGONCE_DEVS_ETH_SH_ETHERC_H
+//==========================================================================
+//
+// sh_etherc.h
+//
+// SH EtherC Ethernet CPU module controller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2002-01-30
+// Purpose: Hardware description of SH EtherC controller.
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+
+//------------------------------------------------------------------------
+// Get macros from platform header
+#define __WANT_CONFIG
+#include CYGDAT_DEVS_ETH_SH_ETHERC_INL
+#undef __WANT_CONFIG
+
+//------------------------------------------------------------------------
+// Set to perms of:
+// 0 disables all debug output
+// 1 for process debug output
+// 2 for added data IO output: get_reg, put_reg
+// 4 for packet allocation/free output
+// 8 for only startup status, so we can tell we're installed OK
+#define DEBUG 0x0
+
+#if DEBUG & 1
+#define DEBUG_FUNCTION() do { db_printf("%s\n", __FUNCTION__); } while (0)
+#else
+#define DEBUG_FUNCTION() do {} while(0)
+#endif
+
+// ------------------------------------------------------------------------
+// Debug print function
+#if defined(CYGPKG_REDBOOT) && DEBUG
+
+static void db_printf( char *fmt, ... )
+{
+ extern int start_console(void);
+ extern void end_console(int);
+ va_list a;
+ int old_console;
+ va_start( a, fmt );
+ old_console = start_console();
+ diag_vprintf( fmt, a );
+ end_console(old_console);
+ va_end( a );
+}
+
+#else
+
+#define db_printf diag_printf
+
+#endif
+
+// ------------------------------------------------------------------------
+// Macros for keeping track of statistics
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+# define KEEP_STATISTICS
+#endif
+
+#ifdef KEEP_STATISTICS
+# define INCR_STAT( _x_ ) (cpd->stats. _x_ ++)
+#else
+# define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
+#endif
+
+//------------------------------------------------------------------------
+// Cache translation
+#ifndef CYGARC_UNCACHED_ADDRESS
+# define CYGARC_UNCACHED_ADDRESS(x) (x)
+#endif
+
+// ------------------------------------------------------------------------
+// Macros for accessing structure elements
+
+#define _SU8( _base_, _offset_) \
+ *((cyg_uint8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU16( _base_, _offset_) \
+ *((cyg_uint16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU32( _base_, _offset_) \
+ *((cyg_uint32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+#define _SI8( _base_, _offset_) \
+ *((cyg_int8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI16( _base_, _offset_) \
+ *((cyg_int16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI32( _base_, _offset_) \
+ *((cyg_int32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+// ------------------------------------------------------------------------
+// Controller registers in offset form
+#define _REG_EDMR 0x00
+#define _REG_EDTRR 0x04
+#define _REG_EDRRR 0x08
+#define _REG_TDLAR 0x0c
+#define _REG_RDLAR 0x10
+#define _REG_EESR 0x14
+#define _REG_EESIPR 0x18
+#define _REG_TRSCER 0x1c
+#define _REG_RMFCR 0x20
+#define _REG_TFTR 0x24
+#define _REG_FDR 0x28
+#define _REG_RCR 0x2c
+#define _REG_EDOCR 0x30
+#define _REG_RBWAR 0x40
+#define _REG_RDFAR 0x44
+#define _REG_TBRAR 0x4c
+#define _REG_TDFAR 0x50
+
+#define _REG_ECMR 0x60
+#define _REG_ECSR 0x64
+#define _REG_ECSIPR 0x68
+#define _REG_PIR 0x6c
+#define _REG_MAHR 0x70
+#define _REG_MALR 0x74
+#define _REG_RFLR 0x78
+#define _REG_PSR 0x7c
+#define _REG_TROCR 0x80
+#define _REG_CDCR 0x84
+#define _REG_LCCR 0x88
+#define _REG_CNDCR 0x8c
+#define _REG_IFLCR 0x90
+#define _REG_CECFR 0x94
+#define _REG_FRECR 0x98
+#define _REG_TSFRCR 0x9c
+#define _REG_TLFRCR 0xa0
+#define _REG_RFCR 0xa4
+#define _REG_MAFCR 0xa8
+
+//----------------------------------------------------------------------------
+// Receive buffer Descriptor
+#define ETHERC_RD_STAT 0x00 // 32 bit
+#define ETHERC_RD_RBL 0x04 // 16 bit - receive buffer length
+#define ETHERC_RD_RDL 0x06 // 16 bit - receive data length (-CRC)
+#define ETHERC_RD_RBA 0x08 // 32 bit - receive buffer address
+#define ETHERC_RD_PAD 0x0c // 32 bit
+#define ETHERC_RD_SIZE 0x10
+
+#define ETHERC_RD_STAT_RACT 0x80000000
+#define ETHERC_RD_STAT_RDLE 0x40000000
+#define ETHERC_RD_STAT_RFP_OTO 0x30000000 // one buffer to one frame
+#define ETHERC_RD_STAT_RFE 0x08000000
+#define ETHERC_RD_STAT_RFOF 0x00000200
+#define ETHERC_RD_STAT_RMAF 0x00000080
+#define ETHERC_RD_STAT_RRF 0x00000010
+#define ETHERC_RD_STAT_RTLF 0x00000008
+#define ETHERC_RD_STAT_RTSF 0x00000004
+#define ETHERC_RD_STAT_PRE 0x00000002
+#define ETHERC_RD_STAT_CERF 0x00000001
+
+#define ETHERC_RD_STAT_CLEAR 0x70000000
+
+// Transmit buffer Descriptor
+#define ETHERC_TD_STAT 0x00 // 32 bit
+#define ETHERC_TD_TDL 0x04 // 16 bit - transmit data length
+#define ETHERC_TD_PAD0 0x06 // 16 bit
+#define ETHERC_TD_TBA 0x08 // 32 bit - transmit buffer address
+#define ETHERC_TD_PAD1 0x0c // 32 bit
+#define ETHERC_TD_SIZE 0x10
+
+#define ETHERC_TD_STAT_TACT 0x80000000
+#define ETHERC_TD_STAT_TDLE 0x40000000
+#define ETHERC_TD_STAT_TFP_OTO 0x30000000 // one buffer to one frame
+#define ETHERC_TD_STAT_TDFE 0x08000000
+#define ETHERC_TD_STAT_ITF 0x00000010
+#define ETHERC_TD_STAT_CND 0x00000008
+#define ETHERC_TD_STAT_DLC 0x00000004
+#define ETHERC_TD_STAT_CD 0x00000002
+#define ETHERC_TD_STAT_TRO 0x00000001
+
+
+// Initialization Buffer
+#define ETHERC_IB_MODE 0
+#define ETHERC_IB_PADR0 2
+#define ETHERC_IB_PADR1 4
+#define ETHERC_IB_PADR2 6
+#define ETHERC_IB_LADRF0 8
+#define ETHERC_IB_LADRF1 10
+#define ETHERC_IB_LADRF2 12
+#define ETHERC_IB_LADRF3 14
+#define ETHERC_IB_RDRA 16
+#define ETHERC_IB_TDRA 20
+#define ETHERC_IB_SIZE 24
+
+#define ETHERC_IB_TDRA_CNT_shift 29
+#define ETHERC_IB_TDRA_PTR_mask 0x00ffffff
+#define ETHERC_IB_RDRA_CNT_shift 29
+#define ETHERC_IB_RDRA_PTR_mask 0x00ffffff
+
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+struct sh_etherc_stats {
+ unsigned int tx_good ;
+ unsigned int tx_max_collisions ;
+ unsigned int tx_late_collisions ;
+ unsigned int tx_underrun ;
+ unsigned int tx_carrier_loss ;
+ unsigned int tx_deferred ;
+ unsigned int tx_sqetesterrors ;
+ unsigned int tx_single_collisions;
+ unsigned int tx_mult_collisions ;
+ unsigned int tx_total_collisions ;
+ unsigned int rx_good ;
+ unsigned int rx_crc_errors ;
+ unsigned int rx_align_errors ;
+ unsigned int rx_resource_errors ;
+ unsigned int rx_overrun_errors ;
+ unsigned int rx_collisions ;
+ unsigned int rx_short_frames ;
+ unsigned int rx_too_long_frames ;
+ unsigned int rx_symbol_errors ;
+ unsigned int interrupts ;
+ unsigned int rx_count ;
+ unsigned int rx_deliver ;
+ unsigned int rx_resource ;
+ unsigned int rx_restart ;
+ unsigned int tx_count ;
+ unsigned int tx_complete ;
+ unsigned int tx_dropped ;
+};
+#endif
+
+struct etherc_priv_data;
+typedef cyg_bool (*provide_esa_t)(struct etherc_priv_data* cpd);
+
+typedef struct etherc_priv_data {
+ int index;
+ cyg_uint8 // (split up for atomic byte access)
+ mac_addr_ok:1, // can we bring up?
+ active:1, // has this if been brung up?
+ hardwired_esa:1, // set if ESA is hardwired via CDL
+ txbusy:1, // A packet has been sent
+ spare1:3;
+
+ unsigned long txkey; // Used to ack when packet sent
+ unsigned char* base; // Base address of controller EPROM region
+ int interrupt; // Interrupt vector used by controller
+ unsigned char esa[6]; // Controller ESA
+ // Function to configure the ESA - may fetch ESA from EPROM or
+ // RedBoot config option.
+ void (*config_esa)(struct etherc_priv_data* cpd);
+ void *ndp; // Network Device Pointer
+ provide_esa_t provide_esa;
+
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+ int devid;
+
+ cyg_uint8* rx_buffers; // ptr to base of buffer mem
+ cyg_uint8* rx_ring; // ptr to base of rx ring memory
+ int rx_ring_cnt; // number of entries in ring
+ int rx_ring_next; // index of next full ring entry
+
+ cyg_uint8* tx_buffers;
+ cyg_uint8* tx_ring;
+ int tx_ring_cnt;
+ int tx_ring_free; // index of next free ring entry
+ int tx_ring_alloc; // index of first controller owned ring
+ int tx_ring_owned; // number of controller owned ring entries
+
+ int rxpacket;
+#ifdef KEEP_STATISTICS
+ struct sh_etherc_stats stats;
+#endif
+#if DEBUG & 1
+ cyg_uint32 txd;
+#endif
+} etherc_priv_data;
+
+// ------------------------------------------------------------------------
+
+static __inline__ cyg_uint32
+get_reg(struct etherc_priv_data *cpd, int regno)
+{
+ cyg_int32 val;
+
+ HAL_READ_UINT32(cpd->base+regno, val);
+
+#if DEBUG & 2
+ db_printf("read reg %d val 0x%08x\n", regno, val);
+#endif
+ return val;
+}
+
+static __inline__ void
+put_reg(struct etherc_priv_data *cpd, int regno, cyg_uint32 val)
+{
+ HAL_WRITE_UINT32(cpd->base+regno, val);
+
+#if DEBUG & 2
+ db_printf("write reg %d val 0x%08x\n", regno, val);
+#endif
+}
+
+// ------------------------------------------------------------------------
+#endif // CYGONCE_DEVS_ETH_SH_ETHERC_H
+// EOF sh_etherc.h
diff --git a/ecos/packages/devs/eth/sh/hs7729pci/current/ChangeLog b/ecos/packages/devs/eth/sh/hs7729pci/current/ChangeLog
new file mode 100644
index 0000000..6a765ff
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/hs7729pci/current/ChangeLog
@@ -0,0 +1,47 @@
+2001-06-27 Jesper Skov <jskov@redhat.com>
+
+ * cdl/sh_hs7729pci_eth_drivers.cdl: Implements net drivers.
+
+ * include/devs_eth_sh_hs7729pci.inl: Use uncached addresses for
+ shared mem. Removed fix me.
+
+2001-06-26 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_sh_hs7729pci.inl: Leave PCI definitions to
+ platform HAL.
+
+2001-06-25 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_sh_hs7729pci.inl: Split in config and driver
+ parts, fix some buglets.
+
+2001-05-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/sh_hs7729pci_eth_drivers.cdl: Platform specific
+ information required to use the generic VIA Rhine driver for the
+ HS7729PCI platform.
+ * include/devs_eth_sh_hs7729pci.inl: Same.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/sh/hs7729pci/current/cdl/sh_hs7729pci_eth_drivers.cdl b/ecos/packages/devs/eth/sh/hs7729pci/current/cdl/sh_hs7729pci_eth_drivers.cdl
new file mode 100644
index 0000000..5b5006c
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/hs7729pci/current/cdl/sh_hs7729pci_eth_drivers.cdl
@@ -0,0 +1,129 @@
+# ====================================================================
+#
+# sh_hs7729pci_eth_drivers.cdl
+#
+# Ethernet drivers - support for VIA Rhine ethernet controller
+# on the Hitachi HS7729PCI board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-05-31
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_SH_HS7729PCI {
+ display "SH HS7729PCI board ethernet driver"
+ description "Ethernet driver for SH HS7729PCI board."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_SH_SH7729_HS7729PCI
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the VIA_RHINE package
+ cdl_interface CYGINT_DEVS_ETH_VIA_RHINE_REQUIRED {
+ display "VIA Rhine ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_VIA_RHINE_INL <cyg/io/devs_eth_sh_hs7729pci.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_VIA_RHINE_CFG <pkgconf/devs_eth_sh_hs7729pci.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_SH_HS7729PCI_ETH0 {
+ display "HS7729PCI ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ HS7729PCI port 0."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_VIA_RHINE_REQUIRED
+
+ cdl_option CYGNUM_DEVS_ETH_SH_HS7729PCI_ETH0_RX_RING_SIZE {
+ display "Size of RX ring for ETH0"
+ flavor data
+ default_value 4
+ legal_values { 4 8 16 32 64 128 }
+ description "
+ This option sets the size of the RX ring."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_SH_HS7729PCI_ETH0_TX_RING_SIZE {
+ display "Size of TX ring for ETH0"
+ flavor data
+ default_value 16
+ legal_values { 4 8 16 32 64 128 }
+ description "
+ This option sets the size of the TX ring."
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_SH_HS7729PCI_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ HS7729PCI port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_SH_HS7729PCI_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ calculated 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_SH_HS7729PCI_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/sh/hs7729pci/current/include/devs_eth_sh_hs7729pci.inl b/ecos/packages/devs/eth/sh/hs7729pci/current/include/devs_eth_sh_hs7729pci.inl
new file mode 100644
index 0000000..8e9e3fa
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/hs7729pci/current/include/devs_eth_sh_hs7729pci.inl
@@ -0,0 +1,99 @@
+//==========================================================================
+//
+// devs_eth_sh_hs7729pci.inl
+//
+// HS7729PCI ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-05-31
+// Purpose: HS7729PCI ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#ifdef __WANT_CONFIG
+
+#define CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE (CYGARC_UNCACHED_ADDRESS(&CYGMEM_SECTION_pci_window[0]))
+#define CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE (CYGMEM_SECTION_pci_window_SIZE)
+
+#endif // __WANT_CONFIG
+
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_SH_HS7729PCI_ETH0
+
+static rhine_priv_data via_rhine_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_SH_HS7729PCI_ETH0_SET_ESA
+ enaddr : CYGDAT_DEVS_ETH_SH_HS7729PCI_ETH0_ESA,
+#endif
+ config_esa : NULL, // rely on the hardwired address for now
+ rx_ring : NULL,
+ rx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_SH_HS7729PCI_ETH0_RX_RING_SIZE*/,
+ rx_ring_log_cnt : 2,
+ tx_ring : NULL,
+ tx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_SH_HS7729PCI_ETH0_TX_RING_SIZE*/,
+ tx_ring_log_cnt : 2,
+};
+
+static rhine_priv_data *rhine_priv_array[1] = {&via_rhine_eth0_priv_data};
+
+ETH_DRV_SC(via_rhine_sc,
+ &via_rhine_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_SH_HS7729PCI_ETH0_NAME,
+ rhine_start,
+ rhine_stop,
+ rhine_control,
+ rhine_can_send,
+ rhine_send,
+ rhine_recv,
+ rhine_deliver, // "pseudoDSR" called from fast net thread
+ rhine_poll, // poll function, encapsulates ISR and DSR
+ rhine_int_vector);
+
+NETDEVTAB_ENTRY(rhine_netdev,
+ "rhine_" CYGDAT_DEVS_ETH_SH_HS7729PCI_ETH0_NAME,
+ via_rhine_init,
+ &via_rhine_sc);
+#endif // CYGPKG_DEVS_ETH_SH_HS7729PCI_ETH0
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_sh_hs7729pci.inl
diff --git a/ecos/packages/devs/eth/sh/se7751/current/ChangeLog b/ecos/packages/devs/eth/sh/se7751/current/ChangeLog
new file mode 100644
index 0000000..5cf1281
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/se7751/current/ChangeLog
@@ -0,0 +1,39 @@
+2002-02-18 Jesper Skov <jskov@redhat.com>
+
+ * cdl/sh_se7751_eth_drivers.cdl: Fix typos.
+
+2001-07-12 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_sh_se7751.inl: Driver finds the controller data
+ via PCI library.
+
+2001-07-10 Jesper Skov <jskov@redhat.com>
+
+ * cdl/sh_se7751_eth_drivers.cdl: Platform specific
+ information required to use the generic AMD PCNet driver for the
+ SE7751 platform.
+ * include/devs_eth_sh_se7751.inl: Same.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/sh/se7751/current/cdl/sh_se7751_eth_drivers.cdl b/ecos/packages/devs/eth/sh/se7751/current/cdl/sh_se7751_eth_drivers.cdl
new file mode 100644
index 0000000..c2dbe10
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/se7751/current/cdl/sh_se7751_eth_drivers.cdl
@@ -0,0 +1,129 @@
+# ====================================================================
+#
+# se7751_eth_drivers.cdl
+#
+# Ethernet drivers - support for AMD PCnet ethernet controller
+# on the Hitachi SE7751 board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-04-02
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_SH_SE7751 {
+ display "Hitachi SE7751 board ethernet driver"
+ description "Ethernet driver for Hitachi SE7751 board."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_SH_SH7751_SE7751
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the AMD_PCNET package
+ cdl_interface CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED {
+ display "AMD PCNET ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_PCNET_INL <cyg/io/devs_eth_sh_se7751.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_PCNET_CFG <pkgconf/devs_eth_sh_se7751.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_SH_SE7751_ETH0 {
+ display "SE7751 ethernet port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ SE7751 port 0."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED
+
+ cdl_option CYGNUM_DEVS_ETH_SH_SE7751_ETH0_RX_RING_SIZE {
+ display "Size of RX ring for ETH0"
+ flavor data
+ default_value 4
+ legal_values { 4 8 16 32 64 128 }
+ description "
+ This option sets the size of the RX ring."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_SH_SE7751_ETH0_TX_RING_SIZE {
+ display "Size of TX ring for ETH0"
+ flavor data
+ default_value 16
+ legal_values { 4 8 16 32 64 128 }
+ description "
+ This option sets the size of the TX ring."
+ }
+
+ cdl_option CYGDAT_DEVS_ETH_SH_SE7751_ETH0_NAME {
+ display "Device name for the ETH0 ethernet port 0 driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device for the
+ SE7751 port 0."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_SH_SE7751_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ calculated 1
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_SH_SE7751_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/sh/se7751/current/include/devs_eth_sh_se7751.inl b/ecos/packages/devs/eth/sh/se7751/current/include/devs_eth_sh_se7751.inl
new file mode 100644
index 0000000..728ac3e
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/se7751/current/include/devs_eth_sh_se7751.inl
@@ -0,0 +1,109 @@
+//==========================================================================
+//
+// devs/eth/sh/se7751/include/devs_eth_sh_se7751.inl
+//
+// SE7751 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-07-10
+// Purpose: SE7751 ethernet defintions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+
+#ifdef __WANT_CONFIG
+
+#define CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE (CYGARC_UNCACHED_ADDRESS(&CYGMEM_SECTION_pci_window[0]))
+#define CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE ((cyg_uint32)(CYGMEM_SECTION_pci_window_SIZE))
+
+#endif // __WANT_CONFIG
+
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_SH_SE7751_ETH0
+
+// FIXME: find locations via PCI
+static pcnet_priv_data amd_pcnet_eth0_priv_data = {
+#ifdef CYGSEM_DEVS_ETH_SH_SE7751_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_SH_SE7751_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+ config_esa : NULL, // rely on the hardwired address for now
+ rx_ring : NULL,
+ rx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_RX_RING_SIZE*/,
+ rx_ring_log_cnt : 2,
+ tx_ring : NULL,
+ tx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_TX_RING_SIZE*/,
+ tx_ring_log_cnt : 2,
+};
+
+ETH_DRV_SC(amd_pcnet_sc,
+ &amd_pcnet_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_SH_SE7751_ETH0_NAME,
+ pcnet_start,
+ pcnet_stop,
+ pcnet_control,
+ pcnet_can_send,
+ pcnet_send,
+ pcnet_recv,
+ pcnet_deliver, // "pseudoDSR" called from fast net thread
+ pcnet_poll, // poll function, encapsulates ISR and DSR
+ pcnet_int_vector);
+
+NETDEVTAB_ENTRY(pcnet_netdev,
+ "pcnet_" CYGDAT_DEVS_ETH_SH_SE7751_ETH0_NAME,
+ amd_pcnet_init,
+ &amd_pcnet_sc);
+#endif // CYGPKG_DEVS_ETH_SH_SE7751_ETH0
+
+// These arrays are used for sanity checking of pointers
+struct pcnet_priv_data *
+pcnet_priv_array[CYGNUM_DEVS_ETH_AMD_PCNET_DEV_COUNT] = {
+#ifdef CYGPKG_DEVS_ETH_SH_SE7751_ETH0
+ &amd_pcnet_eth0_priv_data,
+#endif
+};
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_sh_se7751.inl
diff --git a/ecos/packages/devs/eth/sh/se77x9/current/ChangeLog b/ecos/packages/devs/eth/sh/se77x9/current/ChangeLog
new file mode 100644
index 0000000..8f80699
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/se77x9/current/ChangeLog
@@ -0,0 +1,65 @@
+2001-10-16 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_sh_se77x9.inl: Added buffer parameters.
+
+2001-10-10 Gary Thomas <gthomas@redhat.com>
+
+ * include/devs_eth_sh_se77x9.inl (CYGHWR_NS_DP83902A_PLF_RESET):
+ Change in calling convention - now uses soft "reset" address from
+ device specific data.
+
+2001-07-12 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_sh_se77x9.inl: Fix typo.
+
+2001-06-16 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_sh_se77x9.inl: Use proper interrupt vector name.
+
+2001-06-15 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_sh_se77x9.inl: Split in devs/config parts. Use
+ proper delay in reset code.
+ Removed unused delays. Tell driver DMA HW is broken (I suspect the
+ FPGA - and yes, this took a very long time indeed to track down!).
+
+ * cdl/sh_se77x9_eth_drivers.cdl: Removed ring size options. Force
+ use of ESA until I figure out how to read the EPROM.
+
+2001-06-14 Jesper Skov <jskov@redhat.com>
+
+ * cdl/sh_se77x9_eth_drivers.cdl: Made _SET_ESA option configurable.
+
+ * include/devs_eth_sh_se77x9.inl: Added DATA I/O macros since the
+ platform needs to be treated like it was BE when accessing the
+ external devices.
+
+2001-06-13 Jesper Skov <jskov@redhat.com>
+
+ * include/devs_eth_sh_se77x9.inl: Remove debug hack.
+
+ * Created.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/sh/se77x9/current/cdl/sh_se77x9_eth_drivers.cdl b/ecos/packages/devs/eth/sh/se77x9/current/cdl/sh_se77x9_eth_drivers.cdl
new file mode 100644
index 0000000..4cb1c2e
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/se77x9/current/cdl/sh_se77x9_eth_drivers.cdl
@@ -0,0 +1,108 @@
+# ====================================================================
+#
+# sh_se77x9_eth_drivers.cdl
+#
+# Ethernet drivers - support for NS DP83902A ethernet controller
+# on the Hitachi SE77X9 board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-06-13
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_SH_SE77X9 {
+ display "SH SE77X9 board ethernet driver"
+ description "Ethernet driver for SH SE77X9 board."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_SH_SH77X9_SE77X9
+
+ include_dir cyg/io
+
+ # FIXME: This really belongs in the NS DP83902A package
+ cdl_interface CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED {
+ display "NS DP83902A ethernet driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_INL <cyg/io/devs_eth_sh_se77x9.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_CFG <pkgconf/devs_eth_sh_se77x9.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_SH_SE77X9_ETH0 {
+ display "SE77X9 ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ SE77X9 port."
+
+ implements CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_SH_SE77X9_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_SH_SE77X9_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ calculated 1
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_SH_SE77X9_ETH0_ESA {
+ display "The ethernet station address"
+ flavor data
+ default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"}
+ description "The ethernet station address"
+ }
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/sh/se77x9/current/include/devs_eth_sh_se77x9.inl b/ecos/packages/devs/eth/sh/se77x9/current/include/devs_eth_sh_se77x9.inl
new file mode 100644
index 0000000..f3f062c
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/se77x9/current/include/devs_eth_sh_se77x9.inl
@@ -0,0 +1,142 @@
+//==========================================================================
+//
+// devs_eth_sh_se77x9.inl
+//
+// SE77X9 ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-06-13
+// Purpose: SE77X9 ethernet defintions
+//
+// FIXME: M17 contains an EPROM. May contain the ESA, but don't
+// know how to access it.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
+#include <cyg/hal/hal_if.h>
+
+#ifdef __WANT_CONFIG
+
+
+
+#define CYGHWR_NS_DP83902A_PLF_RESET(_dp_) \
+ CYG_MACRO_START \
+ HAL_WRITE_UINT16(_dp_->reset, 0x0000); \
+ CYGACC_CALL_IF_DELAY_US(10); \
+ HAL_WRITE_UINT16(_dp_->reset, 0x0100); \
+ CYG_MACRO_END
+
+#define DP_IN(_b_, _o_, _d_) \
+ CYG_MACRO_START \
+ cyg_uint16 _t; \
+ HAL_READ_UINT16 ((cyg_addrword_t)(_b_)+2*(_o_), _t); \
+ (_d_) = (_t >> 8) & 0xff; \
+ CYG_MACRO_END
+
+#define DP_OUT(_b_, _o_, _d_) \
+ CYG_MACRO_START \
+ HAL_WRITE_UINT16((cyg_addrword_t)(_b_)+2*(_o_), (_d_)<<8); \
+ CYG_MACRO_END
+
+#define DP_IN_DATA(_b_, _d_) \
+ CYG_MACRO_START \
+ cyg_uint16 _t; \
+ HAL_READ_UINT16 ((cyg_addrword_t)(_b_), _t); \
+ (_d_) = ((_t >> 8) & 0xff) | ((_t & 0xff) << 8); \
+ CYG_MACRO_END
+
+#define DP_OUT_DATA(_b_, _d_) \
+ CYG_MACRO_START \
+ cyg_uint16 _t; \
+ _t = (_d_); \
+ (_t) = (((_t) >> 8) & 0xff) | ((_t & 0xff) << 8); \
+ HAL_WRITE_UINT16((cyg_addrword_t)(_b_), _t); \
+ CYG_MACRO_END
+
+#define CYGHWR_NS_DP83902A_PLF_16BIT_DATA
+#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
+
+#endif // __WANT_CONFIG
+
+
+#ifdef __WANT_DEVS
+
+#ifdef CYGPKG_DEVS_ETH_SH_SE77X9_ETH0
+
+static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
+ base : (cyg_uint8*) 0xb0000000,
+ data : (cyg_uint8*) 0xb0040000,
+ reset: (cyg_uint8*) 0xb0080000,
+ interrupt: CYGNUM_HAL_INTERRUPT_LAN,
+ tx_buf1: 0x80,
+ tx_buf2: 0x88,
+ rx_buf_start: 0x90,
+ rx_buf_end: 0xff,
+#ifdef CYGSEM_DEVS_ETH_SH_SE77X9_ETH0_SET_ESA
+ esa : CYGDAT_DEVS_ETH_SH_SE77X9_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+};
+
+ETH_DRV_SC(dp83902a_sc,
+ &dp83902a_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_SH_SE77X9_ETH0_NAME,
+ dp83902a_start,
+ dp83902a_stop,
+ dp83902a_control,
+ dp83902a_can_send,
+ dp83902a_send,
+ dp83902a_recv,
+ dp83902a_deliver, // "pseudoDSR" called from fast net thread
+ dp83902a_poll, // poll function, encapsulates ISR and DSR
+ dp83902a_int_vector);
+
+NETDEVTAB_ENTRY(dp83902a_netdev,
+ "dp83902a_" CYGDAT_DEVS_ETH_SH_SE77X9_ETH0_NAME,
+ dp83902a_init,
+ &dp83902a_sc);
+#endif // CYGPKG_DEVS_ETH_SH_SE77X9_ETH0
+
+#endif // __WANT_DEVS
+
+// EOF devs_eth_sh_se77x9.inl
diff --git a/ecos/packages/devs/eth/sh/sh4_202_md/current/ChangeLog b/ecos/packages/devs/eth/sh/sh4_202_md/current/ChangeLog
new file mode 100644
index 0000000..7051f29
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/sh4_202_md/current/ChangeLog
@@ -0,0 +1,30 @@
+2003-09-05 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/sh4_202_md_eth_drivers.cdl
+ * include/devs_eth_sh4_202_md.inl
+ New package - support for LAN91C111 MAC on SuperH SH4-202 MicroDev
+ board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/sh/sh4_202_md/current/cdl/sh4_202_md_eth_drivers.cdl b/ecos/packages/devs/eth/sh/sh4_202_md/current/cdl/sh4_202_md_eth_drivers.cdl
new file mode 100644
index 0000000..be89cfb
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/sh4_202_md/current/cdl/sh4_202_md_eth_drivers.cdl
@@ -0,0 +1,116 @@
+# ====================================================================
+#
+# sh4_202_md_eth_drivers.cdl
+#
+# Ethernet drivers - support for LAN91C111 ethernet controller
+# on the MicroDev board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): nickg
+# Contributors: nickg
+# Date: 2003-08-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_SH_MICRODEV {
+ display "Microdev SMC91C96 ethernet driver"
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_SH_SH4_202_MD
+
+ include_dir cyg/io
+
+ description "Ethernet driver for Microdev boards."
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+
+ cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
+ display "SMSC LAN91CXX driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL <cyg/io/devs_eth_sh4_202_md.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG <pkgconf/devs_eth_sh_microdev.h>"
+ puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_SH_MICRODEV_ETH0 {
+ display "Microdev ethernet port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the ethernet device driver for the
+ Microdev port."
+
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ implements CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
+
+ cdl_option CYGDAT_DEVS_ETH_SH_MICRODEV_ETH0_NAME {
+ display "Device name for the ETH0 ethernet driver"
+ flavor data
+ default_value {"\"eth0\""}
+ description "
+ This option sets the name of the ethernet device."
+ }
+
+ cdl_component CYGSEM_DEVS_ETH_SH_MICRODEV_ETH0_SET_ESA {
+ display "Set the ethernet station address"
+ flavor bool
+ default_value 0
+ description "Enabling this option will allow the ethernet
+ station address to be forced to the value set by the
+ configuration. This may be required if the hardware does
+ not include a serial EEPROM for the ESA."
+
+ cdl_option CYGDAT_DEVS_ETH_SH_MICRODEV_ETH0_ESA {
+ display "The ethernet station address (MAC)"
+ flavor data
+ default_value {"{0x12, 0x13, 0x14, 0x15, 0x16, 0x17}"}
+ description "A static ethernet station address.
+ Caution: Booting two systems with the same MAC on the same
+ network, will cause severe conflicts."
+ }
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/eth/sh/sh4_202_md/current/include/devs_eth_sh4_202_md.inl b/ecos/packages/devs/eth/sh/sh4_202_md/current/include/devs_eth_sh4_202_md.inl
new file mode 100644
index 0000000..79b20b1
--- /dev/null
+++ b/ecos/packages/devs/eth/sh/sh4_202_md/current/include/devs_eth_sh4_202_md.inl
@@ -0,0 +1,145 @@
+//==========================================================================
+//
+// devs/eth/sh/sh4_202_md/..../include/devs_eth_sh4_202_md.inl
+//
+// Microdev ethernet I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 2003-08-20
+// Purpose: Microdev ethernet definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_sh_microdev.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGPKG_REDBOOT
+# include <pkgconf/redboot.h>
+# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+# include <redboot.h>
+# include <flash_config.h>
+# endif
+#endif
+
+#define LAN91CXX_IS_LAN91C111
+
+#ifdef CYGPKG_DEVS_ETH_SH_MICRODEV_ETH0
+
+#if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
+RedBoot_config_option("Set " CYGDAT_DEVS_ETH_SH_MICRODEV_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa,
+ ALWAYS_ENABLED, true,
+ CONFIG_BOOL, false
+ );
+RedBoot_config_option(CYGDAT_DEVS_ETH_SH_MICRODEV_ETH0_NAME " network hardware address [MAC]",
+ eth0_esa_data,
+ "eth0_esa", true,
+ CONFIG_ESA, 0
+ );
+#endif // CYGPKG_REDBOOT && CYGSEM_REDBOOT_FLASH_CONFIG
+
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+// Note that this section *is* active in an application, outside RedBoot,
+// where the above section is not included.
+
+# include <cyg/hal/hal_if.h>
+
+# ifndef CONFIG_ESA
+# define CONFIG_ESA (6)
+# endif
+# ifndef CONFIG_BOOL
+# define CONFIG_BOOL (1)
+# endif
+
+cyg_bool
+_microdev_provide_eth0_esa(struct lan91cxx_priv_data* cpd)
+{
+ cyg_bool set_esa;
+ int ok;
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa", &set_esa, CONFIG_BOOL);
+ if (ok && set_esa) {
+ ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+ "eth0_esa_data", cpd->enaddr, CONFIG_ESA);
+ }
+ return ok && set_esa;
+}
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
+ base : (unsigned short *) 0xA7500000,
+ interrupt: CYGNUM_HAL_INTERRUPT_LVL3,
+#ifdef CYGSEM_DEVS_ETH_SH_MICRODEV_ETH0_SET_ESA
+ enaddr : CYGDAT_DEVS_ETH_SH_MICRODEV_ETH0_ESA,
+ hardwired_esa : true,
+#else
+ hardwired_esa : false,
+#endif
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ provide_esa : &_microdev_provide_eth0_esa,
+#else
+ provide_esa : NULL,
+#endif
+};
+
+ETH_DRV_SC(lan91cxx_sc,
+ &lan91cxx_eth0_priv_data, // Driver specific data
+ CYGDAT_DEVS_ETH_SH_MICRODEV_ETH0_NAME, // Name for device
+ lan91cxx_start,
+ lan91cxx_stop,
+ lan91cxx_control,
+ lan91cxx_can_send,
+ lan91cxx_send,
+ lan91cxx_recv,
+ lan91cxx_deliver,
+ lan91cxx_poll,
+ lan91cxx_int_vector
+);
+
+NETDEVTAB_ENTRY(lan91cxx_netdev,
+ "lan91cxx_" CYGDAT_DEVS_ETH_SH_MICRODEV_ETH0_NAME,
+ smsc_lan91cxx_init,
+ &lan91cxx_sc);
+
+#endif // CYGPKG_DEVS_ETH_SH_MICRODEV_ETH0
+
+
+
diff --git a/ecos/packages/devs/eth/smsc/lan91cxx/current/ChangeLog b/ecos/packages/devs/eth/smsc/lan91cxx/current/ChangeLog
new file mode 100644
index 0000000..d1f06f0
--- /dev/null
+++ b/ecos/packages/devs/eth/smsc/lan91cxx/current/ChangeLog
@@ -0,0 +1,226 @@
+2005-06-27 Stefan Sommerfeld <sommerfeld@mikrom.com>
+
+ * src/if_lan91cxx.c: Changed some debug messages to output right
+ hex syntax (0x....)
+ * src/if_lan91cxx.c: 32bit mode can now be selected is correctly
+ working. The old implementation truncated some data.
+ * cdl/smsc_lan91cxx_eth_drivers.cdl: Added CDL to control if
+ 16 or 32 bit access is used.
+
+2005-06-12 Yoshinori Sato <ysato@users.sourceforge.jp>
+
+ * src/if_lan91cxx.c: Reset the physical layer before configuring
+ it, otherwise it might not work.
+
+2005-01-24 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/if_lan91cxx.c (lan91cxx_send): Rewrote parts of transmit
+ machinery to deal with odd sized message buffers. The TCP/IP stack
+ generates these in rare circumstances.
+
+2005-01-21 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/smsc_lan91cxx.h:
+ * src/if_lan91cxx.c:
+ Rewrote parts of receive machinery to properly deal with 32 bit
+ wide access to the device. The original code didn't quite work.
+ Switched all calls the HAL_DELAY_US() to CYGACC_CALL_IF_DELAY_US().
+ Various small changes to debugging code.
+
+2004-12-01 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/if_lan91cxx.c (lan91cxx_start): Added option to force speed
+ negotiation to 10MHz. Some embedded boards cannot handle 100MHz.
+ Generally added some small improvements to debugging messages.
+
+2004-05-22 Andrew Dyer <adyer@righthandtech.com>
+
+ * src/if_lan91cxx.c: Fail initialization if no device found.
+
+2004-01-07 Uwe Kindler <ukindler@htwm.de>
+
+ * src/if_lan91cxx.c: Fail initialization if no link found.
+
+2004-01-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/smsc_lan91cxx_eth_drivers.cdl:
+ * src/if_lan91cxx.c (smsc_lan91cxx_init): Allow the interrupt
+ priority to be overrode by the HW specific part of the driver.
+
+2003-12-19 Gary Parnes <garyp@logicpd.com>
+
+ * src/smsc_lan91cxx.h (get_banksel): Allow this function to be
+ overridden.
+
+2003-12-10 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/if_lan91cxx.c: Add some missing endian swapping calls.
+
+2003-12-05 Nick Garnett <nickg@calivar.com>
+
+ * src/if_lan91cxx.c: Added support for revA of the LAN91C111 which
+ has a bug. Fixed up debugging messages so that it uses serial
+ output in RedBoot.
+
+2003-03-03 Patrick Doyle <wpd@delcomsys.com>
+
+ * src/smsc_lan91cxx.h
+ * src/if_lan91cxx.c (smsc_lan91cxx_init): Reworked to support
+ flash, CDL, and eeprom ESA assignment, in that priority.
+
+ * cdl/smsc_lan91cxx_eth_drivers.cdl: Added comment indicating that
+ use of the CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA interface is
+ deprecated.
+
+2003-02-26 Yoshinori Sato <ysato@users.sourceforge.jp>
+
+ * src/smsc_lan91cxx.h: Support big endian arch.
+ * src/if_lan91cxx.c: Support big endian arch.
+
+2002-08-28 Mark Salter <msalter@redhat.com>
+
+ * src/smsc_lan91cxx.h: Support 32-bit data reads.
+ * src/if_lan91cxx.c: Fix standalone (RedBoot) interrupt handling.
+ Support 32-bit data reads.
+
+2002-08-16 Mark Salter <msalter@redhat.com>
+
+ * src/if_lan91cxx.c: Add support for 91C111. Platform-specific
+ include file is now included from within smsc_lan91cxx.h so
+ that register access functions may be overridden if necessary.
+ * src/smsc_lan91cxx.h: Ditto.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_lan91cxx.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2001-12-12 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_lan91cxx.c (lan91cxx_recv): If discarding data due to
+ caller out of buffers, we must read-out and discard the packet to
+ correctly complete the transaction. Bogus assert for buffer
+ pointer removed; other asserts from not discarding data assuaged
+ by first change above.
+
+2001-08-17 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_lan91cxx.c (lan91cxx_poll): The interrupt acknowledge
+ call only occurs in the ISR for this driver because the interrupt
+ via GPIO is edge triggered. We now also acknowledge the interrupt
+ within the poll() routine - otherwise RedBoot net use never acks!
+ Which doesn't matter if the app uses the net, but in a net-free
+ app, it near enough wedges in the resulting interrupt loop.
+
+2001-08-13 Hugo Tyson <hmt@redhat.com>
+
+ * src/smsc_lan91cxx.h (get_att,put_att): Condition out the inline
+ functions if not CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE -
+ because they don't compile. Inlines are not like macros.
+
+2001-07-27 Jordi Colomer <jco@ict.es>
+
+ * cdl/smsc_lan91cxx_eth_drivers.cdl:
+ Add interface for whether the hardware is in PCMCIA mode.
+ * src/if_lan91cxx.c (smsc_lan91cxx_init):
+ Allow for hardware shift addresses
+ Initialize appropriately if PCMCIA mode.
+ * src/smsc_lan91cxx.h:
+ Support address shifts in get_reg,put_Reg, get_data, put_data
+ Add new functions get_banksel , put_att and get_att.
+
+2001-07-11 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_lan91cxx.c (lan91cxx_stop): Clean up any pending tx both
+ to prevent mbuf leak due to noncompletion, and to clear tx_busy so
+ that the newly upbrung device can be used.
+ (lan91cxx_can_send): Similarly detect a stopped tx engine and
+ restart it, and clean up any pending tx, in here. Otherwise the
+ system cannot progress.
+
+2001-03-27 Hugo Tyson <hmt@redhat.com>
+2001-03-27 Robin Farine <acnrf@dial.eunet.ch>
+
+ * src/if_lan91cxx.c (lan91cxx_start): Strip the CRC from
+ incoming frames.
+
+2001-01-26 Hugo Tyson <hmt@redhat.com>
+
+ * src/smsc_lan91cxx.h (smsc_lan91cxx_stats): Add stats structure.
+
+ * src/if_lan91cxx.c (lan91cxx_control): Implement ioctl() call for
+ SNMP statistics gathering. Implement stats counting generally.
+
+2001-01-25 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/smsc_lan91cxx_eth_drivers.cdl
+ (CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM): New option to
+ control whether the IOCTL to set the ESA actually writes the
+ EEPROM. Default disabled for safety.
+ (CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA): New interface controls
+ whether a statically configured ESA is picked up from private data.
+
+ * src/smsc_lan91cxx.h (LAN91CXX_CONFIG): Add this, plus
+ (LAN91CXX_CONTROL_EEPROM_SELECT): et al for EEPROM writing.
+
+ * src/if_lan91cxx.c (lan91cxx_control): Implement updating the
+ EEPROM with the new ESA, if so configured. Otherwise just set the
+ ESA in the device and continue, using the new value.
+ (smsc_lan91cxx_init): Obey the STATIC_ESA interface setting to use the
+ EEPROM or device data for the ESA.
+
+ Removed some never-compiled, never-used stuff for getting an ESA
+ out of RedBoot's flash storage.
+
+2001-01-25 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/smsc_lan91cxx_eth_drivers.cdl: This generic driver does not
+ implement CYGHWR_NET_DRIVER_ETH0 et al; the instantiating package
+ does.
+
+2001-01-24 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_lan91cxx.c (lan91cxx_start): Implement promiscuous mode.
+ This just involves setting a bit in ..._start() if certain
+ interface flags are set. Also import a couple of other details
+ under #ifdef CYGPKG_NET from the i82559 driver for safety.
+
+2001-01-24 Hugo Tyson <hmt@redhat.com>
+
+ * src/if_lan91cxx.c (DEBUG): Refined debug output, for trying it
+ in RedBoot experiments.
+
+2001-01-22 Hugo Tyson <hmt@redhat.com>
+
+ * src/smsc_lan91cxx.h: New file.
+ * src/if_lan91cxx.c: New file.
+ * cdl/smsc_lan91cxx_eth_drivers.cdl: New file.
+ New component. Based on previous work [mis]named, in the same
+ idiom, lan900. Hence this new component with a better name. A
+ major rewrite too, to make the new one work with LAN91C96,
+ specifically.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/smsc/lan91cxx/current/cdl/smsc_lan91cxx_eth_drivers.cdl b/ecos/packages/devs/eth/smsc/lan91cxx/current/cdl/smsc_lan91cxx_eth_drivers.cdl
new file mode 100644
index 0000000..e420007
--- /dev/null
+++ b/ecos/packages/devs/eth/smsc/lan91cxx/current/cdl/smsc_lan91cxx_eth_drivers.cdl
@@ -0,0 +1,127 @@
+# ====================================================================
+#
+# smsc_lan91cxx_eth_drivers.cdl
+#
+# Ethernet drivers - support for LAN91CXX compatible ethernet controllers
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov
+# Date: 2000-11-22
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_SMSC_LAN91CXX {
+ display "SMSC LAN91CXX compatible ethernet driver"
+ description "Ethernet driver for SMSC LAN91CXX compatible controllers."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+
+ active_if CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ compile -library=libextras.a if_lan91cxx.c
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG";
+ }
+
+ cdl_option CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM {
+ display "SIOCSIFHWADDR records ESA (MAC address) in EEPROM"
+ default_value 0
+ description "
+ The ioctl() socket call with operand SIOCSIFHWADDR sets the
+ interface hardware address - the MAC address or Ethernet Station
+ Address (ESA). This option causes the new MAC address to be written
+ into the EEPROM associated with the interface, so that the new
+ MAC address is permanently recorded. Doing this should be a
+ carefully chosen decision, hence this option."
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO {
+ display "Interrupt priority when registering interrupt handler"
+ flavor data
+ default_value 3
+ description "
+ When registering the interrupt handler this specifies the
+ priority of the interrupt. Some hardware platforms require
+ values other than the default given here. Such platforms
+ can then override this value in the hardware specific package. "
+ }
+
+ cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA {
+ display "ESA is statically configured"
+ description "
+ If this is nonzero, then the ESA (MAC address) is statically
+ configured in the platform-specific package which instantiates
+ this driver with all its details.
+
+ Note that use of this option is deprecated in favor of a
+ CYGSEM_DEVS_ETH_..._SET_ESA option in the platform specific
+ driver."
+ }
+
+ cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE {
+ display "Chip is wired in PCMCIA mode"
+ description "
+ If this is nonzero, then the chip is assumed to be hardware
+ configured in PCMCIA mode."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_SMSC_LAN91CXX_OPTIONS {
+ display "LAN91CXX ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_SMSC_LAN91CXX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the LAN91CXX ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c b/ecos/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c
new file mode 100644
index 0000000..5b9fb0c
--- /dev/null
+++ b/ecos/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c
@@ -0,0 +1,1473 @@
+//==========================================================================
+//
+// dev/if_lan91cxx.c
+//
+// Ethernet device driver for SMSC LAN91CXX compatible controllers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt, based on lan900 (for LAN91C110) driver by jskov
+// jskov, based on CS8900 driver by Gary Thomas
+// Contributors: gthomas, jskov, hmt, jco@ict.es, nickg
+// Date: 2001-01-22
+// Purpose:
+// Description: hardware driver for LAN91CXX "LAN9000" ethernet
+// Notes: Pointer register is not saved/restored on receive interrupts.
+// The pointer is shared by both receive/transmit code.
+// But the net stack manages atomicity for you here.
+//
+// The controller has an autorelease mode that allows TX packets
+// to be freed automatically on successful transmission - but
+// that is not used since we're only sending one packet at a
+// time anyway.
+// We may want to pingpong in future for throughput reasons.
+//
+// <jco@ict.es> Added support for PCMCIA mode and shifted
+// address buses.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// Based on LAN91C110 and LAN91C96
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_smsc_lan91cxx.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <cyg/kernel/kapi.h>
+#include <net/if.h> /* Needed for struct ifnet */
+#endif
+
+#ifdef CYGPKG_INFRA_DEBUG
+// Then we log, OOI, the number of times we get a bad packet number
+// from the tx done fifo.
+int lan91cxx_txfifo_good = 0;
+int lan91cxx_txfifo_bad = 0;
+#endif
+
+// Set to perms of:
+// 0 disables all debug output
+// 1 for process debug output
+// 2 for added data IO output: get_reg, put_reg
+// 4 for packet allocation/free output
+// 8 for only startup status, so we can tell we're installed OK
+#define DEBUG 0
+
+
+#if DEBUG
+#if defined(CYGPKG_REDBOOT)
+static void db_printf( char *fmt, ... )
+{
+ extern int start_console(void);
+ extern void end_console(int);
+ va_list a;
+ int old_console;
+ va_start( a, fmt );
+ old_console = start_console();
+ diag_vprintf( fmt, a );
+ end_console(old_console);
+ va_end( a );
+}
+#else
+#if 0
+static void db_printf( char *fmt, ... )
+{
+ va_list a;
+ int old_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+ va_start( a, fmt );
+ CYGACC_CALL_IF_SET_CONSOLE_COMM( 0 );
+ diag_vprintf( fmt, a );
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console);
+ va_end( a );
+}
+#else
+#define db_printf diag_printf
+#endif
+#endif
+#else
+#if 0
+static void db_printf( char *fmt, ... )
+{
+ va_list a;
+ int old_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+ va_start( a, fmt );
+ CYGACC_CALL_IF_SET_CONSOLE_COMM( 0 );
+ diag_vprintf( fmt, a );
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console);
+ va_end( a );
+}
+#else
+#define db_printf( fmt, ... )
+#endif
+#endif
+
+
+#if DEBUG & 1
+#define DEBUG_FUNCTION() do { db_printf("%s\n", __FUNCTION__); } while (0)
+#else
+#define DEBUG_FUNCTION() do {} while(0)
+#endif
+
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+#define KEEP_STATISTICS
+#endif
+
+#ifdef KEEP_STATISTICS
+#define INCR_STAT( _x_ ) (cpd->stats. _x_ ++)
+#else
+#define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
+#endif
+
+#include "smsc_lan91cxx.h"
+
+#ifdef LAN91CXX_IS_LAN91C111
+static void lan91cxx_write_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
+ cyg_uint8 phyreg, cyg_uint16 value);
+static cyg_uint16 lan91cxx_read_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
+ cyg_uint8 phyreg);
+#endif
+
+static void lan91cxx_poll(struct eth_drv_sc *sc);
+
+
+#ifdef LAN91CXX_IS_LAN91C111
+// Revision A of the LAN91C111 has a bug in which it does not set the
+// ODD bit in the status word and control byte of received packets. We
+// work around this by assuming the bit is always set and tacking the
+// extra odd byte onto the packet anyway. Higher protocol levels never
+// believe the packet size reported by the driver and always use the
+// values in the protocol headers. So this workaround is quite safe.
+// In theory nobody should be using the RevA part now, but it appears
+// that some people still have some in their parts bins.
+#define LAN91CXX_RX_STATUS_IS_ODD(__cpd,__stat) \
+ (((__cpd)->c111_reva)?1:((__stat) & LAN91CXX_RX_STATUS_ODDFRM))
+#define LAN91CXX_CONTROLBYTE_IS_ODD(__cpd,__val) \
+ (((__cpd)->c111_reva)?1:((__val) & LAN91CXX_CONTROLBYTE_ODD))
+#else
+#define LAN91CXX_RX_STATUS_IS_ODD(__cpd,__stat) ((__stat) & LAN91CXX_RX_STATUS_ODDFRM)
+#define LAN91CXX_CONTROLBYTE_IS_ODD(__cpd,__val) ((__val) & LAN91CXX_CONTROLBYTE_ODD)
+#endif
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+static cyg_interrupt lan91cxx_interrupt;
+static cyg_handle_t lan91cxx_interrupt_handle;
+
+// This ISR is called when the ethernet interrupt occurs
+static int lan91cxx_isr(cyg_vector_t vector, cyg_addrword_t data)
+ /* , HAL_SavedRegisters *regs */
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+// DEBUG_FUNCTION();
+
+ INCR_STAT( interrupts );
+
+ cyg_drv_interrupt_mask(cpd->interrupt);
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+#endif
+
+// The deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+lan91cxx_deliver(struct eth_drv_sc *sc)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+// DEBUG_FUNCTION();
+
+ // Service the interrupt:
+ lan91cxx_poll(sc);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+}
+
+static int
+lan91cxx_int_vector(struct eth_drv_sc *sc)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+ return (cpd->interrupt);
+}
+
+static bool
+smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+ unsigned short val;
+ int i;
+#if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
+ unsigned char ecor, ecsr;
+#endif
+ cyg_bool esa_configured = false;
+
+ DEBUG_FUNCTION();
+
+ cpd->txbusy = cpd->within_send = 0;
+
+#ifdef CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR
+ cpd->addrsh = CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR;
+#else
+ cpd->addrsh = 0;
+#endif
+
+#if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
+
+ // If the chip is configured in PCMCIA mode, the internal
+ // registers mapped in the attribute memory should be
+ // initialized (i.e. to enable the I/O map)
+
+ ecor = get_att(sc, LAN91CXX_ECOR);
+
+ // pulse SRESET on ECOR
+ ecor |= LAN91CXX_ECOR_RESET;
+ put_att(sc, LAN91CXX_ECOR, ecor);
+
+ CYGACC_CALL_IF_DELAY_US(1);
+
+ ecor &= ~LAN91CXX_ECOR_RESET;
+ put_att(sc, LAN91CXX_ECOR, ecor);
+
+ // then, enable I/O map
+ ecor |= LAN91CXX_ECOR_ENABLE;
+ put_att(sc, LAN91CXX_ECOR, ecor);
+
+ // verify the register contents
+ if (ecor != get_att(sc, LAN91CXX_ECOR))
+ db_printf("LAN91CXX - Cannot access PCMCIA attribute registers\n");
+
+ ecsr = get_att(sc, LAN91CXX_ECSR);
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_8_BIT
+#error "91CXX 8-bit mode not yet supported."
+ ecsr |= LAN91CXX_ECSR_IOIS8;
+#else
+ ecsr &= ~LAN91CXX_ECSR_IOIS8;
+#endif
+ put_att(sc, LAN91CXX_ECSR, ecsr);
+
+#endif
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ // Initialize environment, setup interrupt handler
+ cyg_drv_interrupt_create(cpd->interrupt,
+ CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
+ (cyg_addrword_t)sc, // Data item passed to interrupt handler
+ (cyg_ISR_t *)lan91cxx_isr,
+ (cyg_DSR_t *)eth_drv_dsr, // The logical driver DSR
+ &lan91cxx_interrupt_handle,
+ &lan91cxx_interrupt);
+ cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+
+ // probe chip by reading the signature in BS register
+ val = get_banksel(sc);
+#if DEBUG & 9
+ db_printf("LAN91CXX - supposed BankReg @ %x = %04x\n",
+ cpd->base+LAN91CXX_BS, val );
+#endif
+
+ if ((0xff00 & val) != 0x3300) {
+ CYG_FAIL("No 91Cxx signature" );
+ diag_printf("smsc_lan91cxx_init: No 91Cxx signature found\n");
+ return false;
+ }
+
+ val = get_reg(sc, LAN91CXX_REVISION);
+
+#if DEBUG & 9
+ db_printf("LAN91CXX - type: %01x, rev: %01x\n",
+ (val>>4)&0xf, val & 0xf);
+#endif
+
+#ifdef LAN91CXX_IS_LAN91C111
+ // Set RevA flag for LAN91C111 so we can cope with the odd-bit bug.
+ cpd->c111_reva = (val == 0x3390);
+#endif
+
+ // The controller may provide a function used to set up the ESA
+ if (cpd->config_enaddr)
+ (*cpd->config_enaddr)(cpd);
+
+ // Reset chip
+ put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
+ put_reg(sc, LAN91CXX_RCR, 0);
+
+ val = get_reg(sc, LAN91CXX_EPH_STATUS);
+#ifndef LAN91CXX_IS_LAN91C111
+ // LINK_OK on 91C111 is just a general purpose input and may not
+ // have anything to do with the link.
+ if (!(val & LAN91CXX_STATUS_LINK_OK)) {
+ db_printf("no link\n");
+ return false; // Link not connected
+ }
+#endif
+
+
+#if DEBUG & 9
+ db_printf("LAN91CXX - status: %04x\n", val);
+#endif
+
+#if 0 < CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
+ // Use statically configured ESA from the private data
+#if DEBUG & 9
+ db_printf("LAN91CXX - static ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ cpd->enaddr[0],
+ cpd->enaddr[1],
+ cpd->enaddr[2],
+ cpd->enaddr[3],
+ cpd->enaddr[4],
+ cpd->enaddr[5] );
+#endif // DEBUG
+ // Set up hardware address
+ for (i = 0; i < sizeof(cpd->enaddr); i += 2)
+ put_reg(sc, LAN91CXX_IA01+i/2,
+ cpd->enaddr[i] | (cpd->enaddr[i+1] << 8));
+#else // not CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
+ // Find ESA - check possible sources in sequence and stop when
+ // one provides the ESA:
+ // RedBoot option (via provide_esa)
+ // Compile-time configuration
+ // EEPROM
+
+ if (NULL != cpd->provide_esa) {
+ esa_configured = cpd->provide_esa(cpd);
+# if DEBUG & 8
+ if (esa_configured)
+ db_printf("Got ESA from RedBoot option\n");
+# endif
+ }
+ if (!esa_configured && cpd->hardwired_esa) {
+ // ESA is already set in cpd->esa[]
+ esa_configured = true;
+# if DEBUG & 8
+ db_printf("Got ESA from cpd\n");
+# endif
+ }
+ if (esa_configured) {
+ // Set up hardware address
+ for (i = 0; i < sizeof(cpd->enaddr); i += 2)
+ put_reg(sc, LAN91CXX_IA01+i/2,
+ cpd->enaddr[i] | (cpd->enaddr[i+1] << 8));
+ } else {
+ // Use the address from the serial EEPROM
+ // Read out hardware address
+ for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
+ unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
+ cpd->enaddr[i] = (unsigned char)(0xff & z);
+ cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8));
+ }
+ esa_configured = true;
+# if DEBUG & 8
+ db_printf("Got ESA from eeprom\n");
+# endif
+ }
+#if DEBUG & 9
+ db_printf("LAN91CXX - ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ cpd->enaddr[0],
+ cpd->enaddr[1],
+ cpd->enaddr[2],
+ cpd->enaddr[3],
+ cpd->enaddr[4],
+ cpd->enaddr[5] );
+#endif // DEBUG
+#endif // !CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, cpd->enaddr);
+ return true;
+}
+
+static void
+lan91cxx_stop(struct eth_drv_sc *sc)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+ DEBUG_FUNCTION();
+
+ CYG_ASSERT( cpd->within_send < 10, "stop: Excess send recursions" );
+ cpd->within_send++;
+ // Complete any outstanding activity:
+ if ( cpd->txbusy ) {
+ cpd->txbusy = 0;
+#if DEBUG & 9
+ db_printf("LAN91CXX - Stopping, cleaning up pending TX\n" );
+#endif
+ (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
+ }
+ // Reset chip
+ put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
+ put_reg(sc, LAN91CXX_RCR, 0);
+ cpd->txbusy = cpd->within_send = 0;
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+lan91cxx_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
+{
+ cyg_uint16 intr;
+#ifdef LAN91CXX_IS_LAN91C111
+ int delay;
+#endif
+#ifdef CYGPKG_NET
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+ DEBUG_FUNCTION();
+
+#ifdef LAN91CXX_IS_LAN91C111
+ // 91C111 Errata. Internal PHY comes up disabled. Must enable here.
+ lan91cxx_write_phy(sc, 0, LAN91CXX_PHY_CTRL, LAN91CXX_PHY_CTRL_RST);
+ CYGACC_CALL_IF_DELAY_US(500000);
+ lan91cxx_write_phy(sc, 0, LAN91CXX_PHY_CTRL, LAN91CXX_PHY_CTRL_ANEG_EN |
+ LAN91CXX_PHY_CTRL_SPEED);
+
+#ifdef LAN91CXX_FORCE_10MHZ
+ lan91cxx_write_phy( sc, 0, LAN91CXX_PHY_AUTO_AD, 0x0061);
+#endif
+
+ // Start auto-negotiation
+ put_reg(sc, LAN91CXX_RPCR,
+ LAN91CXX_RPCR_LEDA_RX | LAN91CXX_RPCR_LEDB_LINK | LAN91CXX_RPCR_ANEG);
+
+ // wait for auto-negotiation to finish.
+ // give it ~5 seconds before giving up (no cable?)
+ delay = 50;
+ while (!(lan91cxx_read_phy(sc, 0, LAN91CXX_PHY_STAT) & 0x20)) {
+ if (--delay <= 0)
+ break;
+ CYGACC_CALL_IF_DELAY_US(100000);
+ }
+#if DEBUG & 1
+ if (delay <= 0)
+ diag_printf("auto-negotiation failed.\n");
+#endif
+#endif
+
+ put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_reset_mmu);
+
+ put_reg(sc, LAN91CXX_INTERRUPT, 0); // disable interrupts
+ intr = get_reg(sc, LAN91CXX_INTERRUPT);
+ put_reg(sc, LAN91CXX_INTERRUPT, intr & // ack old interrupts
+ (LAN91CXX_INTERRUPT_TX_INT | LAN91CXX_INTERRUPT_TX_EMPTY_INT |
+ LAN91CXX_INTERRUPT_RX_OVRN_INT | LAN91CXX_INTERRUPT_ERCV_INT));
+ put_reg(sc, LAN91CXX_RCR,
+#ifdef RCR_HAS_ABORT_ENB // 91C96 does not - page 46.
+ LAN91CXX_RCR_ABORT_ENB |
+#endif
+ LAN91CXX_RCR_STRIP_CRC |
+ LAN91CXX_RCR_RXEN | LAN91CXX_RCR_ALMUL);
+ put_reg(sc, LAN91CXX_TCR, LAN91CXX_TCR_TXENA | LAN91CXX_TCR_PAD_EN);
+ put_reg(sc, LAN91CXX_CONTROL, 0);
+ put_reg(sc, LAN91CXX_INTERRUPT, // enable interrupts
+ LAN91CXX_INTERRUPT_RCV_INT_M);
+
+#ifdef CYGPKG_NET
+ if (( 0
+#ifdef ETH_DRV_FLAGS_PROMISC_MODE
+ != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
+#endif
+ ) || (ifp->if_flags & IFF_PROMISC)
+ ) {
+ // Then we select promiscuous mode.
+ unsigned short rcr;
+ rcr = get_reg(sc, LAN91CXX_RCR );
+ rcr |= LAN91CXX_RCR_PRMS;
+ put_reg(sc, LAN91CXX_RCR, rcr );
+ }
+#endif
+}
+
+//
+// This routine is called to perform special "control" opertions
+//
+static int
+lan91cxx_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ unsigned char *esa = (unsigned char *)data;
+ int i;
+ unsigned short reg;
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+#if 9 & DEBUG
+ db_printf("LAN91CXX - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ esa[0],
+ esa[1],
+ esa[2],
+ esa[3],
+ esa[4],
+ esa[5] );
+#ifndef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
+ db_printf("*** PERMANENT EEPROM WRITE NOT ENABLED ***\n");
+#endif
+#endif // DEBUG
+
+#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
+ // Only now can we command the chip to perform EEPROM writes:
+
+ // select arbitrary writing to the EEPROM
+ reg = get_reg(sc, LAN91CXX_CONTROL);
+ reg |= LAN91CXX_CONTROL_EEPROM_SELECT;
+ put_reg(sc, LAN91CXX_CONTROL, reg );
+
+ for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
+ int j;
+ // Set the address register
+ put_reg(sc, LAN91CXX_POINTER, LAN91CXX_ESA_EEPROM_OFFSET + i/2);
+ // Poke the data
+ put_reg(sc, LAN91CXX_GENERAL, esa[i] | (esa[i+1] << 8));
+ // Command the store
+ reg = get_reg(sc, LAN91CXX_CONTROL);
+ reg |= LAN91CXX_CONTROL_STORE;
+ put_reg(sc, LAN91CXX_CONTROL, reg );
+ // and poll for completion
+ for ( j = 1024 * 1024; 0 < j ; j-- ) {
+ reg = get_reg(sc, LAN91CXX_CONTROL);
+ if ( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY) )
+ break;
+ }
+ CYG_ASSERT( 0 < j, "EEPROM write timout!" );
+ }
+
+ reg = get_reg(sc, LAN91CXX_CONTROL);
+ CYG_ASSERT( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY),
+ "EEPROM still busy!" );
+ // Clear the EEPROM selection bit
+ reg &=~LAN91CXX_CONTROL_EEPROM_SELECT;
+ put_reg(sc, LAN91CXX_CONTROL, reg );
+ // and check it "took"
+ reg = get_reg(sc, LAN91CXX_CONTROL);
+ CYG_ASSERT( 0 == (reg & LAN91CXX_CONTROL_EEPROM_SELECT),
+ "EEPROM still selected!" );
+ // and command a complete reload
+ reg |= LAN91CXX_CONTROL_RELOAD;
+ put_reg(sc, LAN91CXX_CONTROL, reg );
+ for ( i = 1024 * 1024; 0 < i ; i-- ) {
+ reg = get_reg(sc, LAN91CXX_CONTROL);
+ if ( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY) )
+ break;
+ }
+ CYG_ASSERT( 0 < i, "EEPROM reload timout!" );
+ // Now extract the MAC address that is in the chip, and tell the
+ // system about it.
+ for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
+ unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
+ cpd->enaddr[i] = (unsigned char)(0xff & z);
+ cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8));
+ }
+#if DEBUG & 9
+ db_printf("LAN91CXX - eeprom new ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ cpd->enaddr[0],
+ cpd->enaddr[1],
+ cpd->enaddr[2],
+ cpd->enaddr[3],
+ cpd->enaddr[4],
+ cpd->enaddr[5] );
+#endif // DEBUG
+ for (i = 0; i < sizeof(cpd->enaddr); i++ ) {
+ CYG_ASSERT( esa[i] == cpd->enaddr[i], "ESA not written correctly" );
+ if ( esa[i] != cpd->enaddr[i] )
+ return 1; // the operation failed.
+ }
+#else // not CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
+ // Whatever, we can write the MAC address into the interface info,
+ // and the chip registers no problem.
+ for ( i = 0; i < sizeof(cpd->enaddr); i++ )
+ cpd->enaddr[i] = esa[i];
+ for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
+ reg = cpd->enaddr[i] | (cpd->enaddr[i+1] << 8);
+ put_reg(sc, LAN91CXX_IA01+i/2, reg );
+ }
+#endif // !CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
+ return 0;
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ // Extract the MAC address that is in the chip, and tell the
+ // system about it.
+ for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
+ unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
+ esa[i] = (unsigned char)(0xff & z);
+ esa[i+1] = (unsigned char)(0xff & (z >> 8));
+ }
+ return 0;
+#endif
+
+#ifdef ETH_DRV_GET_IF_STATS_UD
+ case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+#endif
+ // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+ case ETH_DRV_GET_IF_STATS:
+#endif
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+ {
+ struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+ // Chipset entry is no longer supported; RFC1573.
+ for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+ p->snmp_chipset[i] = 0;
+
+ // This perhaps should be a config opt, so you can make up your own
+ // description, or supply it from the instantiation.
+ strcpy( p->description, "SMSC LAN91Cxx" );
+ // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+ reg = get_reg(sc, LAN91CXX_EPH_STATUS);
+ if ((reg & LAN91CXX_STATUS_LINK_OK) == 0) {
+ p->operational = 2; // LINK DOWN
+ p->duplex = 1; // UNKNOWN
+ p->speed = 0;
+ }
+ else {
+ p->operational = 3; // LINK UP
+ p->duplex = 2; // 2 = SIMPLEX, 3 = DUPLEX
+ p->speed = 10 * 1000000; // it's only a 10Mbit device
+ }
+
+#ifdef KEEP_STATISTICS
+ {
+ struct smsc_lan91cxx_stats *ps = &(cpd->stats);
+
+ // Admit to it...
+ p->supports_dot3 = true;
+
+ p->tx_good = ps->tx_good ;
+ p->tx_max_collisions = ps->tx_max_collisions ;
+ p->tx_late_collisions = ps->tx_late_collisions ;
+ p->tx_underrun = ps->tx_underrun ;
+ p->tx_carrier_loss = ps->tx_carrier_loss ;
+ p->tx_deferred = ps->tx_deferred ;
+ p->tx_sqetesterrors = ps->tx_sqetesterrors ;
+ p->tx_single_collisions = ps->tx_single_collisions;
+ p->tx_mult_collisions = ps->tx_mult_collisions ;
+ p->tx_total_collisions = ps->tx_total_collisions ;
+ p->rx_good = ps->rx_good ;
+ p->rx_crc_errors = ps->rx_crc_errors ;
+ p->rx_align_errors = ps->rx_align_errors ;
+ p->rx_resource_errors = ps->rx_resource_errors ;
+ p->rx_overrun_errors = ps->rx_overrun_errors ;
+ p->rx_collisions = ps->rx_collisions ;
+ p->rx_short_frames = ps->rx_short_frames ;
+ p->rx_too_long_frames = ps->rx_too_long_frames ;
+ p->rx_symbol_errors = ps->rx_symbol_errors ;
+
+ p->interrupts = ps->interrupts ;
+ p->rx_count = ps->rx_count ;
+ p->rx_deliver = ps->rx_deliver ;
+ p->rx_resource = ps->rx_resource ;
+ p->rx_restart = ps->rx_restart ;
+ p->tx_count = ps->tx_count ;
+ p->tx_complete = ps->tx_complete ;
+ p->tx_dropped = ps->tx_dropped ;
+ }
+#endif // KEEP_STATISTICS
+
+ p->tx_queue_len = 1;
+
+ return 0; // OK
+ }
+#endif
+ default:
+ break;
+ }
+ return 1;
+}
+
+//
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+//
+static int
+lan91cxx_can_send(struct eth_drv_sc *sc)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+ int tcr;
+
+// DEBUG_FUNCTION();
+
+#ifndef LAN91CXX_IS_LAN91C111
+ // LINK_OK on 91C111 is just a general purpose input and may not
+ // have anything to do with the link.
+ if ((get_reg(sc, LAN91CXX_EPH_STATUS) & LAN91CXX_STATUS_LINK_OK) == 0) {
+ db_printf("no link\n");
+ return false; // Link not connected
+ }
+#endif
+
+ CYG_ASSERT( cpd->within_send < 10, "can_send: Excess send recursions" );
+ cpd->within_send++;
+
+ tcr = get_reg(sc, LAN91CXX_TCR);
+ if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
+#if DEBUG & 1
+ db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
+#endif
+ // Complete any outstanding activity:
+ if ( cpd->txbusy ) {
+ cpd->txbusy = 0;
+#if DEBUG & 9
+ db_printf("LAN91CXX - can_send, cleaning up pending TX\n" );
+#endif
+ (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
+ }
+ tcr |= LAN91CXX_TCR_TXENA;
+ put_reg(sc, LAN91CXX_TCR, tcr);
+ }
+
+ // This helps unstick deadly embraces.
+ lan91cxx_poll( sc ); // Deal with any outstanding rx state
+ cpd->within_send--;
+
+ return (cpd->txbusy == 0) && (0 == cpd->within_send);
+}
+
+//
+// This routine is called to send data to the hardware.
+static void
+lan91cxx_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+ int i, len, plen, tcr;
+
+ cyg_uint8 *sdata;
+ cyg_uint16 data = 0;
+ int dpos = 0;
+ unsigned short ints, control;
+ cyg_uint16 packet, status;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( tx_count );
+
+#if DEBUG & 1
+ ints = get_reg(sc, LAN91CXX_INTERRUPT);
+ db_printf("%s:START: ints: %04x\n", __FUNCTION__, ints);
+#endif
+
+ // Worry about the TX engine stopping.
+ tcr = get_reg(sc, LAN91CXX_TCR);
+ if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
+#if DEBUG & 1
+ db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
+#endif
+ tcr |= LAN91CXX_TCR_TXENA;
+ put_reg(sc, LAN91CXX_TCR, tcr);
+ }
+
+ // This helps unstick deadly embraces.
+ CYG_ASSERT( cpd->within_send < 10, "send: Excess send recursions" );
+ cpd->within_send++;
+ lan91cxx_poll( sc ); // Deal with any outstanding rx state
+ cpd->within_send--;
+
+ cpd->txbusy = 1;
+ cpd->txkey = key;
+
+ // Find packet length
+ plen = 0;
+ for (i = 0; i < sg_len; i++)
+ plen += sg_list[i].len;
+
+ CYG_ASSERT( plen == total_len, "sg data length mismatch" );
+
+ // Alloc new TX packet
+ do {
+ put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_alloc_for_tx
+#ifndef LAN91CXX_IS_LAN91C111
+ | ((plen >> 8) & 0x07)
+#endif
+ );
+
+ i = 1024 * 1024;
+ do {
+ status = get_reg(sc, LAN91CXX_INTERRUPT);
+ } while (0 == (status & LAN91CXX_INTERRUPT_ALLOC_INT) && (--i > 0) );
+ if ( i )
+ packet = get_reg(sc, LAN91CXX_PNR);
+ else
+ packet = 0xffff;
+#if DEBUG & 1
+ db_printf("%s: allocated packet %04x\n", __FUNCTION__, packet);
+#endif
+ packet = packet >> 8;
+ if (packet & 0x80) {
+ // Hm.. Isn't this a dead end?
+#if DEBUG & 1
+ db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
+#endif
+ // Not if we can make progress with what's filling memory.
+ lan91cxx_poll( sc ); // Deal with any outstanding state
+ continue;
+ }
+ } while (0);
+
+#if DEBUG & 4
+ db_printf("#####Tx packet allocated 0x%04x (previous 0x%04x)\n",
+ packet, cpd->txpacket);
+#endif
+ cpd->txpacket = packet;
+
+ put_reg(sc, LAN91CXX_PNR, packet);
+ // Note: Check FIFO state here before continuing?
+ put_reg(sc, LAN91CXX_POINTER, LAN91CXX_POINTER_AUTO_INCR | 0x0000);
+ // Pointer is now set, and the proper bank is selected for
+ // data writes.
+
+ // Prepare header:
+ put_data(sc, CYG_CPU_TO_LE16(0)); // reserve space for status word
+ // packet length (includes status, byte-count and control shorts)
+ put_data(sc, CYG_CPU_TO_LE16(0x7FE & (plen + 6)) ); // Always even, always < 15xx(dec)
+
+ for (i = 0; i < sg_len; i++) {
+ sdata = (cyg_uint8 *)sg_list[i].buf;
+ len = sg_list[i].len;
+ while( len > 0 )
+ {
+ data |= *sdata<<((dpos&1)*8);
+ dpos++, len--, sdata++;
+ if( (dpos & 1) == 0 )
+ {
+ put_data(sc, CYG_CPU_TO_LE16(data));
+ data = 0;
+ }
+ }
+ }
+
+ // Lay down the control short unconditionally at the end.
+ // (or it might use random memory contents)
+ control = 0;
+ if( 1 & plen ) {
+ // Need to set ODD flag and insert the data
+ control = data;
+ control |= LAN91CXX_CONTROLBYTE_ODD;
+ }
+ control |= LAN91CXX_CONTROLBYTE_CRC; // Just in case...
+ put_data(sc, CYG_CPU_TO_LE16(control));
+
+ // Enqueue the packet
+ put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_enq_packet);
+
+ // Ack TX empty int and unmask it.
+ ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
+ put_reg(sc, LAN91CXX_INTERRUPT, ints | LAN91CXX_INTERRUPT_TX_SET_ACK);
+ put_reg(sc, LAN91CXX_INTERRUPT, ints | LAN91CXX_INTERRUPT_TX_SET_M);
+
+#if DEBUG & 1
+ ints = get_reg(sc, LAN91CXX_INTERRUPT);
+ db_printf("%s:END: ints at TX: %04x\n", __FUNCTION__, ints);
+#endif
+}
+
+static void
+lan91cxx_TxEvent(struct eth_drv_sc *sc, int stat)
+{
+ unsigned short packet, ints, tcr;
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+ int success = 1;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( tx_complete );
+
+ // Ack and mask TX interrupt set
+ ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
+ ints |= LAN91CXX_INTERRUPT_TX_SET_ACK;
+ ints &= ~LAN91CXX_INTERRUPT_TX_SET_M;
+ put_reg(sc, LAN91CXX_INTERRUPT, ints);
+
+ // Get number of completed packet and read the status word
+ packet = get_reg(sc, LAN91CXX_FIFO_PORTS);
+#if DEBUG & 1
+ db_printf("%s:START: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
+#endif
+
+#ifdef KEEP_STATISTICS
+ {
+ unsigned short reg;
+
+ reg = get_reg( sc, LAN91CXX_EPH_STATUS );
+
+ // Covering each bit in turn...
+ if ( reg & LAN91CXX_STATUS_TX_UNRN ) INCR_STAT( tx_underrun );
+ //if ( reg & LAN91CXX_STATUS_LINK_OK ) INCR_STAT( );
+ //if ( reg & LAN91CXX_STATUS_CTR_ROL ) INCR_STAT( );
+ //if ( reg & LAN91CXX_STATUS_EXC_DEF ) INCR_STAT( );
+ if ( reg & LAN91CXX_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss );
+ if ( reg & LAN91CXX_STATUS_LATCOL ) INCR_STAT( tx_late_collisions );
+ //if ( reg & LAN91CXX_STATUS_WAKEUP ) INCR_STAT( );
+ if ( reg & LAN91CXX_STATUS_TX_DEFR ) INCR_STAT( tx_deferred );
+ //if ( reg & LAN91CXX_STATUS_LTX_BRD ) INCR_STAT( );
+ if ( reg & LAN91CXX_STATUS_SQET ) INCR_STAT( tx_sqetesterrors );
+ if ( reg & LAN91CXX_STATUS_16COL ) INCR_STAT( tx_max_collisions );
+ //if ( reg & LAN91CXX_STATUS_LTX_MULT) INCR_STAT( );
+ if ( reg & LAN91CXX_STATUS_MUL_COL ) INCR_STAT( tx_mult_collisions );
+ if ( reg & LAN91CXX_STATUS_SNGL_COL ) INCR_STAT( tx_single_collisions );
+ if ( reg & LAN91CXX_STATUS_TX_SUC ) INCR_STAT( tx_good );
+
+ cpd->stats.tx_total_collisions =
+ cpd->stats.tx_late_collisions +
+ cpd->stats.tx_max_collisions +
+ cpd->stats.tx_mult_collisions +
+ cpd->stats.tx_single_collisions;
+
+ // We do not need to look in the Counter Register (LAN91CXX_COUNTER)
+ // because it just mimics the info we already have above.
+ }
+#endif // KEEP_STATISTICS
+ // We do not really care about Tx failure. Ethernet is not a reliable
+ // medium. But we do care about the TX engine stopping.
+ tcr = get_reg(sc, LAN91CXX_TCR);
+ if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
+#if DEBUG & 1
+ db_printf("%s: ENGINE RESTART: tcr 0x%04x eph 0x%04x ints 0x%04x\n", __FUNCTION__, tcr, get_reg(sc, LAN91CXX_EPH_STATUS), ints);
+#endif
+ tcr |= LAN91CXX_TCR_TXENA;
+ put_reg(sc, LAN91CXX_TCR, tcr);
+ success = 0; // And treat this as an error...
+ }
+
+ packet &= 0xff;
+
+ // It certainly appears that occasionally the tx fifo tells lies; we
+ // get the wrong packet number. Freeing the one we allocated seems to
+ // give correct operation.
+#ifdef CYGPKG_INFRA_DEBUG
+ // Then we log, OOI, the number of times we get a bad packet number
+ // from the tx done fifo.
+ if (cpd->txpacket != packet )
+ lan91cxx_txfifo_bad++;
+ else
+ lan91cxx_txfifo_good++;
+#endif
+#if DEBUG & 4
+ db_printf("#####Tx packet freed 0x%04x (expected 0x%04x)\n", packet, cpd->txpacket );
+#endif
+ // and then free the packet
+ put_reg(sc, LAN91CXX_PNR, cpd->txpacket);
+ put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_rel_packet);
+
+ // Ack the TX int which is supposed to clear the packet from the TX
+ // completion queue.
+ ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
+ ints |= LAN91CXX_INTERRUPT_TX_FIFO_ACK;
+ put_reg(sc, LAN91CXX_INTERRUPT, ints);
+
+#if DEBUG & 1
+ // Hm... The free doesn't seem to have the desired effect?!?
+ ints = get_reg(sc, LAN91CXX_INTERRUPT);
+ packet = get_reg(sc, LAN91CXX_FIFO_PORTS);
+ db_printf("%s:END: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
+#endif
+
+ if ( cpd->txbusy ) {
+ cpd->txbusy = 0;
+ (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
+ }
+}
+
+void get_data_init(struct eth_drv_sc *sc)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+ cpd->data_buf = 0xa5a5a5a5;
+ cpd->data_pos = sizeof(rxd_t);
+}
+
+cyg_uint8 get_data_byte(struct eth_drv_sc *sc)
+{
+ cyg_uint8 c;
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+ if( cpd->data_pos == sizeof(rxd_t) )
+ {
+ cpd->data_buf = get_data(sc);
+ cpd->data_pos = 0;
+ }
+
+ c = (cpd->data_buf>>(cpd->data_pos*8))&0xFF;
+ cpd->data_pos++;
+
+ return c;
+
+}
+
+cyg_uint16 get_data_short(struct eth_drv_sc *sc)
+{
+ cyg_uint16 val;
+
+ val = get_data_byte(sc);
+ val |= get_data_byte(sc)<<8;
+
+ return CYG_LE16_TO_CPU(val);
+}
+
+//
+// This function is called when a packet has been received. Its job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'lan91cxx_recv' will be called to actually fetch it from the hardware.
+//
+static void
+lan91cxx_RxEvent(struct eth_drv_sc *sc)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+ unsigned short stat, len;
+
+ DEBUG_FUNCTION();
+
+ stat = get_reg(sc, LAN91CXX_FIFO_PORTS);
+#if DEBUG & 1
+ db_printf("RxEvent - FIFOs: 0x%04x\n", stat);
+#endif
+ if ( 0x8000 & stat ) {
+ // Then the Rx FIFO is empty
+#if DEBUG & 4
+ db_printf("#####RxEvent with empty fifo\n");
+#endif
+ return;
+ }
+
+ INCR_STAT( rx_count );
+
+#if DEBUG & 4
+ db_printf("#####Rx packet allocated 0x%04x (previous 0x%04x)\n",
+ 0xff & (stat >> 8), cpd->rxpacket );
+#endif
+ // There is an Rx Packet ready
+ cpd->rxpacket = 0xff & (stat >> 8);
+
+ // Read status and (word) length
+ put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
+ LAN91CXX_POINTER_AUTO_INCR | 0x0000));
+ get_data_init(sc);
+
+ stat = get_data_short(sc);
+ len = get_data_short(sc);
+ len = len - 6; // minus header/footer words
+
+#ifdef KEEP_STATISTICS
+ if ( stat & LAN91CXX_RX_STATUS_ALIGNERR ) INCR_STAT( rx_align_errors );
+ //if ( stat & LAN91CXX_RX_STATUS_BCAST ) INCR_STAT( );
+ if ( stat & LAN91CXX_RX_STATUS_BADCRC ) INCR_STAT( rx_crc_errors );
+ if ( stat & LAN91CXX_RX_STATUS_TOOLONG ) INCR_STAT( rx_too_long_frames );
+ if ( stat & LAN91CXX_RX_STATUS_TOOSHORT ) INCR_STAT( rx_short_frames );
+ //if ( stat & LAN91CXX_RX_STATUS_MCAST ) INCR_STAT( );
+#endif // KEEP_STATISTICS
+
+ if ((stat & LAN91CXX_RX_STATUS_BAD) == 0) {
+ INCR_STAT( rx_good );
+ // Then it's OK
+
+ if( LAN91CXX_RX_STATUS_IS_ODD(cpd,stat) )
+ len++;
+
+#if DEBUG & 1
+ db_printf("RxEvent good rx - stat: 0x%04x, len: 0x%04x\n", stat, len);
+#endif
+ // Check for bogusly short packets; can happen in promisc mode:
+ // Asserted against and checked by upper layer driver.
+#ifdef CYGPKG_NET
+ if ( len > sizeof( struct ether_header ) )
+ // then it is acceptable; offer the data to the network stack
+#endif
+ (sc->funs->eth_drv->recv)(sc, len);
+
+ return;
+ }
+
+ // Not OK for one reason or another...
+#if DEBUG & 1
+ db_printf("RxEvent - bad rx: stat: 0x%04x, len: 0x%04x\n", stat, len);
+ db_printf("PHY %2d: %04x\n",0,lan91cxx_read_phy( sc, 0, 0));
+ db_printf("PHY %2d: %04x\n",1,lan91cxx_read_phy( sc, 0, 1));
+ db_printf("PHY %2d: %04x\n",2,lan91cxx_read_phy( sc, 0, 2));
+ db_printf("PHY %2d: %04x\n",3,lan91cxx_read_phy( sc, 0, 3));
+ db_printf("PHY %2d: %04x\n",4,lan91cxx_read_phy( sc, 0, 4));
+ db_printf("PHY %2d: %04x\n",5,lan91cxx_read_phy( sc, 0, 5));
+ db_printf("PHY %2d: %04x\n",16,lan91cxx_read_phy( sc, 0, 16));
+ db_printf("PHY %2d: %04x\n",17,lan91cxx_read_phy( sc, 0, 17));
+ db_printf("PHY %2d: %04x\n",18,lan91cxx_read_phy( sc, 0, 18));
+ db_printf("PHY %2d: %04x\n",19,lan91cxx_read_phy( sc, 0, 19));
+ db_printf("PHY %2d: %04x\n",20,lan91cxx_read_phy( sc, 0, 20));
+#endif
+
+ // Free packet
+ put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
+}
+
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// Its job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+lan91cxx_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+#if (4 & DEBUG) || defined(CYGPKG_INFRA_DEBUG) || \
+ defined(KEEP_STATISTICS) || defined(LAN91CXX_IS_LAN91C111)
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+#endif
+ int i;
+ short mlen=0, plen;
+ cyg_uint8 *data=NULL;
+ short val;
+ unsigned char *cp, cval;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( rx_deliver );
+
+ put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
+ LAN91CXX_POINTER_AUTO_INCR));
+ get_data_init(sc);
+
+ val = get_data_short(sc);
+ plen = get_data_short(sc);
+ plen = plen - 6;
+
+ for (i = 0; i < sg_len; i++) {
+ int clen;
+ data = (cyg_uint8 *)sg_list[i].buf;
+ mlen = sg_list[i].len;
+
+ clen = mlen;
+ if( clen > plen )
+ clen = plen;
+
+#if DEBUG & 1
+ db_printf("%s : mlen 0x%04x plen 0x%04x clen 0x%04x\n", __FUNCTION__, mlen, plen, clen);
+#endif
+ mlen -= clen;
+ plen -= clen;
+
+ if (data) {
+ while( clen > 0 ) {
+ *data++ = get_data_byte(sc);
+ clen--;
+ }
+ }
+ else { // must actively discard ie. read it from the chip anyway.
+#if DEBUG & 1
+ db_printf("lan91cxx_recv: No data!!!!!\n");
+#endif
+ while( clen > 0 ) {
+ (void)get_data_byte(sc);
+ clen--;
+ }
+ }
+#if DEBUG & 1
+ diag_dump_buf( sg_list[i].buf, sg_list[i].len > 64 ? 64 : sg_list[i].len );
+#endif
+ }
+ val = get_data_short(sc); // Read control word (and potential data) unconditionally
+
+ cp = (unsigned char *)data;
+
+ CYG_ASSERT(val & LAN91CXX_CONTROLBYTE_RX,
+ "Controlbyte is not for Rx");
+ CYG_ASSERT( (1 == mlen) == (0 != LAN91CXX_CONTROLBYTE_IS_ODD(cpd,val)),
+ "Controlbyte does not match");
+ if (data && (1 == mlen) && LAN91CXX_CONTROLBYTE_IS_ODD(cpd,val) ) {
+ cval = val & 0x00ff; // last byte contains data
+ *cp = cval;
+ }
+
+ val = get_reg(sc, LAN91CXX_FIFO_PORTS);
+#if DEBUG & 4
+ if ( 0x8000 & val ) // Then the Rx FIFO is empty
+ db_printf("#####Rx packet NOT freed, stat is 0x%04x (expected 0x%04x)\n",
+ val, cpd->rxpacket);
+ else
+ db_printf("#####Rx packet freed 0x%04x (expected 0x%04x)\n",
+ 0xff & (val >> 8), cpd->rxpacket );
+#endif
+ CYG_ASSERT( (0xff & (val >> 8)) == cpd->rxpacket, "Unexpected rx packet" );
+
+ // Free packet
+ put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
+}
+
+
+static void
+lan91cxx_poll(struct eth_drv_sc *sc)
+{
+ unsigned short event;
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+// DEBUG_FUNCTION();
+ while (1) {
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ // Get the (unmasked) requests
+ event = get_reg(sc, LAN91CXX_INTERRUPT);
+ event = event & (event >> 8) & 0xff;
+
+ if (0 == event)
+ break;
+#if 0
+ if (event & LAN91CXX_INTERRUPT_ERCV_INT) {
+ // Early receive interrupt
+ db_printf("Early receive interrupt\n");
+ }
+ else if (event & LAN91CXX_INTERRUPT_EPH_INT) {
+ // ethernet protocol handler failures
+ db_printf("Ethernet protocol handler failures\n");
+ }
+ else if (event & LAN91CXX_INTERRUPT_RX_OVRN_INT) {
+ // receive overrun
+ db_printf("Receive overrun\n");
+ }
+ else if (event & LAN91CXX_INTERRUPT_ALLOC_INT) {
+ // allocation interrupt
+ db_printf("Allocation interrupt\n");
+ }
+ else
+#endif
+ if (event & LAN91CXX_INTERRUPT_TX_SET) {
+ lan91cxx_TxEvent(sc, event);
+ }
+ if (event & LAN91CXX_INTERRUPT_RCV_INT) {
+ lan91cxx_RxEvent(sc);
+ }
+ if (event & ~(LAN91CXX_INTERRUPT_TX_SET | LAN91CXX_INTERRUPT_RCV_INT))
+ db_printf("%s: Unknown interrupt: 0x%04x\n",
+ __FUNCTION__, event);
+ }
+}
+
+#ifdef LAN91CXX_IS_LAN91C111
+
+static cyg_uint16
+lan91cxx_read_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr, cyg_uint8 phyreg)
+{
+ int i, mask, input_idx, clk_idx = 0;
+ cyg_uint16 mii_reg, value;
+ cyg_uint8 bits[64];
+
+ // 32 consecutive ones on MDO to establish sync
+ for (i = 0; i < 32; ++i)
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+
+ // Start code <01>
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+
+ // Read command <10>
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
+
+ // Output the PHY address, msb first
+ for (mask = 0x10; mask; mask >>= 1) {
+ if (phyaddr & mask)
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+ else
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
+ }
+
+ // Output the phy register number, msb first
+ for (mask = 0x10; mask; mask >>= 1) {
+ if (phyreg & mask)
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+ else
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
+ }
+
+ // Tristate and turnaround (1 bit times)
+ bits[clk_idx++] = 0;
+
+ // Input starts at this bit time
+ input_idx = clk_idx;
+
+ // Will input 16 bits
+ for (i = 0; i < 16; ++i)
+ bits[clk_idx++] = 0;
+
+ // Final clock bit
+ bits[clk_idx++] = 0;
+
+ // Get the current MII register value
+ mii_reg = get_reg(sc, LAN91CXX_MGMT);
+
+ // Turn off all MII Interface bits
+ mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK |
+ LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
+
+ // Clock all 64 cycles
+ for (i = 0; i < sizeof(bits); ++i) {
+ // Clock Low - output data
+ put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i]);
+ CYGACC_CALL_IF_DELAY_US(50);
+
+ // Clock Hi - input data
+ put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i] | LAN91CXX_MGMT_MCLK);
+ CYGACC_CALL_IF_DELAY_US(50);
+
+ bits[i] |= get_reg(sc, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
+ }
+
+ // Return to idle state
+ put_reg(sc, LAN91CXX_MGMT, mii_reg);
+ CYGACC_CALL_IF_DELAY_US(50);
+
+ // Recover input data
+ for (value = 0, i = 0; i < 16; ++i) {
+ value <<= 1;
+ if (bits[input_idx++] & LAN91CXX_MGMT_MDI)
+ value |= 1;
+ }
+ return value;
+}
+
+static void
+lan91cxx_write_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
+ cyg_uint8 phyreg, cyg_uint16 value)
+{
+ int i, mask, clk_idx = 0;
+ cyg_uint16 mii_reg;
+ cyg_uint8 bits[65];
+
+ // 32 consecutive ones on MDO to establish sync
+ for (i = 0; i < 32; ++i)
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+
+ // Start code <01>
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+
+ // Write command <01>
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+
+ // Output the PHY address, msb first
+ for (mask = 0x10; mask; mask >>= 1) {
+ if (phyaddr & mask)
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+ else
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
+ }
+
+ // Output the phy register number, msb first
+ for (mask = 0x10; mask; mask >>= 1) {
+ if (phyreg & mask)
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+ else
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
+ }
+
+ // Tristate and turnaround (2 bit times)
+ bits[clk_idx++] = 0;
+ bits[clk_idx++] = 0;
+
+ // Write out 16 bits of data, msb first
+ for (mask = 0x8000; mask; mask >>= 1) {
+ if (value & mask)
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
+ else
+ bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
+ }
+
+ // Final clock bit (tristate)
+ bits[clk_idx++] = 0;
+
+ // Get the current MII register value
+ mii_reg = get_reg(sc, LAN91CXX_MGMT);
+
+ // Turn off all MII Interface bits
+ mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK |
+ LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
+
+ // Clock all cycles
+ for (i = 0; i < sizeof(bits); ++i) {
+ // Clock Low - output data
+ put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i]);
+ CYGACC_CALL_IF_DELAY_US(50);
+
+ // Clock Hi - input data
+ put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i] | LAN91CXX_MGMT_MCLK);
+ CYGACC_CALL_IF_DELAY_US(50);
+
+// bits[i] |= get_reg(sc, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
+ }
+
+ // Return to idle state
+ put_reg(sc, LAN91CXX_MGMT, mii_reg);
+ CYGACC_CALL_IF_DELAY_US(50);
+}
+#endif // LAN91CXX_IS_LAN91C111
+
+// EOF if_lan91cxx.c
diff --git a/ecos/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h b/ecos/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h
new file mode 100644
index 0000000..0bd4a23
--- /dev/null
+++ b/ecos/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h
@@ -0,0 +1,467 @@
+#ifndef CYGONCE_DEVS_ETH_SMSC_LAN91CXX_LAN91CXX_H
+#define CYGONCE_DEVS_ETH_SMSC_LAN91CXX_LAN91CXX_H
+//==========================================================================
+//
+// lan91cxx.h
+//
+// SMCS LAN91C110 (LAN91CXX compatible) Ethernet chip
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov, hmt, jco, nickg
+// Date: 2001-01-22
+// Purpose: Hardware description of LAN9000 series, LAN91C96/110.
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_endian.h>
+
+#define LAN91CXX_TCR 0x00
+#define LAN91CXX_EPH_STATUS 0x01
+#define LAN91CXX_RCR 0x02
+#define LAN91CXX_COUNTER 0x03
+#define LAN91CXX_MIR 0x04
+#define LAN91CXX_MCR 0x05 // Other than 91C111
+#define LAN91CXX_RPCR 0x05 // 91C111 only
+#define LAN91CXX_RESERVED_0 0x06
+#define LAN91CXX_BS 0x07
+#define LAN91CXX_CONFIG 0x08
+#define LAN91CXX_BASE_REG 0x09
+#define LAN91CXX_IA01 0x0a
+#define LAN91CXX_IA23 0x0b
+#define LAN91CXX_IA45 0x0c
+#define LAN91CXX_GENERAL 0x0d // 91C96 - was "RESERVED_1" for others
+#define LAN91CXX_CONTROL 0x0e
+#define LAN91CXX_BS2 0x0f
+#define LAN91CXX_MMU_COMMAND 0x10
+#define LAN91CXX_PNR 0x11
+#define LAN91CXX_FIFO_PORTS 0x12
+#define LAN91CXX_POINTER 0x13
+#define LAN91CXX_DATA_HIGH 0x14
+#define LAN91CXX_DATA 0x15
+#define LAN91CXX_INTERRUPT 0x16
+#define LAN91CXX_BS3 0x17
+#define LAN91CXX_MT01 0x18
+#define LAN91CXX_MT23 0x19
+#define LAN91CXX_MT45 0x1a
+#define LAN91CXX_MT67 0x1b
+#define LAN91CXX_MGMT 0x1c
+#define LAN91CXX_REVISION 0x1d
+#define LAN91CXX_ERCV 0x1e
+#define LAN91CXX_BS4 0x1f
+
+#define LAN91CXX_RCR_SOFT_RST 0x8000 // soft reset
+#define LAN91CXX_RCR_FILT_CAR 0x4000 // filter carrier
+#define LAN91CXX_RCR_ABORT_ENB 0x2000 // abort on collision
+#define LAN91CXX_RCR_STRIP_CRC 0x0200 // strip CRC
+#define LAN91CXX_RCR_RXEN 0x0100 // enable RX
+#define LAN91CXX_RCR_ALMUL 0x0004 // receive all muticasts
+#define LAN91CXX_RCR_PRMS 0x0002 // promiscuous
+#define LAN91CXX_RCR_RX_ABORT 0x0001 // set when abort due to long frame
+
+#define LAN91CXX_TCR_SWFDUP 0x8000 // Switched Full Duplex mode
+#define LAN91CXX_TCR_ETEN_TYPE 0x4000 // ETEN type (91C96) 0 <=> like a 91C94
+#define LAN91CXX_TCR_EPH_LOOP 0x2000 // loopback mode
+#define LAN91CXX_TCR_STP_SQET 0x1000 // Stop transmission on SQET error
+#define LAN91CXX_TCR_FDUPLX 0x0800 // full duplex
+#define LAN91CXX_TCR_MON_CSN 0x0400 // monitor carrier during tx (91C96)
+#define LAN91CXX_TCR_NOCRC 0x0100 // does not append CRC to frames
+#define LAN91CXX_TCR_PAD_EN 0x0080 // pads frames with 00 to min length
+#define LAN91CXX_TCR_FORCOL 0x0004 // force collision
+#define LAN91CXX_TCR_LLOOP 0x0002 // local loopback (91C96)
+#define LAN91CXX_TCR_TXENA 0x0001 // enable
+
+#define LAN91CXX_POINTER_RCV 0x8000
+#define LAN91CXX_POINTER_AUTO_INCR 0x4000
+#define LAN91CXX_POINTER_READ 0x2000
+#define LAN91CXX_POINTER_ETEN 0x1000
+#define LAN91CXX_POINTER_NOT_EMPTY 0x0800
+
+
+#define LAN91CXX_INTERRUPT_TX_IDLE_M 0x8000 // (91C96)
+#define LAN91CXX_INTERRUPT_ERCV_INT_M 0x4000
+#define LAN91CXX_INTERRUPT_EPH_INT_M 0x2000
+#define LAN91CXX_INTERRUPT_RX_OVRN_INT_M 0x1000
+#define LAN91CXX_INTERRUPT_ALLOC_INT_M 0x0800
+#define LAN91CXX_INTERRUPT_TX_EMPTY_INT_M 0x0400
+#define LAN91CXX_INTERRUPT_TX_INT_M 0x0200
+#define LAN91CXX_INTERRUPT_RCV_INT_M 0x0100
+#define LAN91CXX_INTERRUPT_TX_IDLE 0x0080 // (91C96)
+#define LAN91CXX_INTERRUPT_ERCV_INT 0x0040 // also ack
+#define LAN91CXX_INTERRUPT_EPH_INT 0x0020
+#define LAN91CXX_INTERRUPT_RX_OVRN_INT 0x0010 // also ack
+#define LAN91CXX_INTERRUPT_ALLOC_INT 0x0008
+#define LAN91CXX_INTERRUPT_TX_EMPTY_INT 0x0004 // also ack
+#define LAN91CXX_INTERRUPT_TX_INT 0x0002 // also ack
+#define LAN91CXX_INTERRUPT_RCV_INT 0x0001
+
+#if 1 // Whichever we choose, the behaviour is the same.
+#define LAN91CXX_INTERRUPT_TX_SET 0x0002 // TX
+#define LAN91CXX_INTERRUPT_TX_SET_ACK 0x0000 // -none-
+#define LAN91CXX_INTERRUPT_TX_FIFO_ACK 0x0002 // TX alone
+#define LAN91CXX_INTERRUPT_TX_SET_M 0x0200 // TX alone
+#else
+#define LAN91CXX_INTERRUPT_TX_SET 0x0006 // TX_EMPTY + TX
+#define LAN91CXX_INTERRUPT_TX_SET_ACK 0x0004 // TX_EMPTY and not plain TX
+#define LAN91CXX_INTERRUPT_TX_FIFO_ACK 0x0002 // TX alone
+#define LAN91CXX_INTERRUPT_TX_SET_M 0x0600 // TX_EMPTY + TX
+#endif
+
+#define LAN91CXX_CONTROL_RCV_BAD 0x4000
+#define LAN91CXX_CONTROL_AUTO_RELEASE 0x0800
+#define LAN91CXX_CONTROL_LE_ENABLE 0x0080
+#define LAN91CXX_CONTROL_CR_ENABLE 0x0040
+#define LAN91CXX_CONTROL_TE_ENABLE 0x0020
+
+// These are for setting the MAC address in the 91C96 serial EEPROM
+#define LAN91CXX_CONTROL_EEPROM_SELECT 0x0004
+#define LAN91CXX_CONTROL_RELOAD 0x0002
+#define LAN91CXX_CONTROL_STORE 0x0001
+#define LAN91CXX_CONTROL_EEPROM_BUSY 0x0003
+#define LAN91CXX_ESA_EEPROM_OFFSET 0x0020
+
+#define LAN91CXX_STATUS_TX_UNRN 0x8000
+#define LAN91CXX_STATUS_LINK_OK 0x4000
+#define LAN91CXX_STATUS_CTR_ROL 0x1000
+#define LAN91CXX_STATUS_EXC_DEF 0x0800
+#define LAN91CXX_STATUS_LOST_CARR 0x0400
+#define LAN91CXX_STATUS_LATCOL 0x0200
+#define LAN91CXX_STATUS_WAKEUP 0x0100
+#define LAN91CXX_STATUS_TX_DEFR 0x0080
+#define LAN91CXX_STATUS_LTX_BRD 0x0040
+#define LAN91CXX_STATUS_SQET 0x0020
+#define LAN91CXX_STATUS_16COL 0x0010
+#define LAN91CXX_STATUS_LTX_MULT 0x0008
+#define LAN91CXX_STATUS_MUL_COL 0x0004
+#define LAN91CXX_STATUS_SNGL_COL 0x0002
+#define LAN91CXX_STATUS_TX_SUC 0x0001
+
+#define LAN91CXX_MMU_noop 0x0000
+#define LAN91CXX_MMU_alloc_for_tx 0x0020
+#define LAN91CXX_MMU_reset_mmu 0x0040
+#define LAN91CXX_MMU_rem_rx_frame 0x0060
+#define LAN91CXX_MMU_rem_tx_frame 0x0070 // (91C96) only when TX stopped
+#define LAN91CXX_MMU_remrel_rx_frame 0x0080
+#define LAN91CXX_MMU_rel_packet 0x00a0
+#define LAN91CXX_MMU_enq_packet 0x00c0
+#define LAN91CXX_MMU_reset_tx_fifo 0x00e0
+
+#define LAN91CXX_CONTROLBYTE_CRC 0x1000
+#define LAN91CXX_CONTROLBYTE_ODD 0x2000
+#define LAN91CXX_CONTROLBYTE_RX 0x4000
+
+#define LAN91CXX_RX_STATUS_ALIGNERR 0x8000
+#define LAN91CXX_RX_STATUS_BCAST 0x4000
+#define LAN91CXX_RX_STATUS_BADCRC 0x2000
+#define LAN91CXX_RX_STATUS_ODDFRM 0x1000
+#define LAN91CXX_RX_STATUS_TOOLONG 0x0800
+#define LAN91CXX_RX_STATUS_TOOSHORT 0x0400
+#define LAN91CXX_RX_STATUS_HASHVALMASK 0x007e // MASK
+#define LAN91CXX_RX_STATUS_MCAST 0x0001
+#define LAN91CXX_RX_STATUS_BAD \
+ (LAN91CXX_RX_STATUS_ALIGNERR | \
+ LAN91CXX_RX_STATUS_BADCRC | \
+ LAN91CXX_RX_STATUS_TOOLONG | \
+ LAN91CXX_RX_STATUS_TOOSHORT)
+
+// Attribute memory registers in PCMCIA mode
+#define LAN91CXX_ECOR 0x8000
+#define LAN91CXX_ECOR_RESET (1<<7)
+#define LAN91CXX_ECOR_LEVIRQ (1<<6)
+#define LAN91CXX_ECOR_ATTWR (1<<2)
+#define LAN91CXX_ECOR_ENABLE (1<<0)
+
+#define LAN91CXX_ECSR 0x8002
+#define LAN91CXX_ECSR_IOIS8 (1<<5)
+#define LAN91CXX_ECSR_PWRDWN (1<<2)
+#define LAN91CXX_ECSR_INTR (1<<1)
+
+// These are for manipulating the MII interface
+#define LAN91CXX_MGMT_MDO 0x0001
+#define LAN91CXX_MGMT_MDI 0x0002
+#define LAN91CXX_MGMT_MCLK 0x0004
+#define LAN91CXX_MGMT_MDOE 0x0008
+
+// Internal PHY registers (91c111)
+#define LAN91CXX_PHY_CTRL 0
+#define LAN91CXX_PHY_STAT 1
+#define LAN91CXX_PHY_ID1 2
+#define LAN91CXX_PHY_ID2 3
+#define LAN91CXX_PHY_AUTO_AD 4
+#define LAN91CXX_PHY_AUTO_CAP 5
+#define LAN91CXX_PHY_CONFIG1 16
+#define LAN91CXX_PHY_CONFIG2 17
+#define LAN91CXX_PHY_STATUS_OUT 18
+#define LAN91CXX_PHY_MASK 19
+
+// PHY control bits
+#define LAN91CXX_PHY_CTRL_COLTST (1 << 7)
+#define LAN91CXX_PHY_CTRL_DPLX (1 << 8)
+#define LAN91CXX_PHY_CTRL_ANEG_RST (1 << 9)
+#define LAN91CXX_PHY_CTRL_MII_DIS (1 << 10)
+#define LAN91CXX_PHY_CTRL_PDN (1 << 11)
+#define LAN91CXX_PHY_CTRL_ANEG_EN (1 << 12)
+#define LAN91CXX_PHY_CTRL_SPEED (1 << 13)
+#define LAN91CXX_PHY_CTRL_LPBK (1 << 14)
+#define LAN91CXX_PHY_CTRL_RST (1 << 15)
+
+#define LAN91CXX_RPCR_LEDA_LINK (0 << 2)
+#define LAN91CXX_RPCR_LEDA_TXRX (4 << 2)
+#define LAN91CXX_RPCR_LEDA_RX (6 << 2)
+#define LAN91CXX_RPCR_LEDA_TX (7 << 2)
+#define LAN91CXX_RPCR_LEDB_LINK (0 << 5)
+#define LAN91CXX_RPCR_LEDB_TXRX (4 << 5)
+#define LAN91CXX_RPCR_LEDB_RX (6 << 5)
+#define LAN91CXX_RPCR_LEDB_TX (7 << 5)
+#define LAN91CXX_RPCR_ANEG (1 << 11)
+#define LAN91CXX_RPCR_DPLX (1 << 12)
+#define LAN91CXX_RPCR_SPEED (1 << 13)
+
+
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+struct smsc_lan91cxx_stats {
+ unsigned int tx_good ;
+ unsigned int tx_max_collisions ;
+ unsigned int tx_late_collisions ;
+ unsigned int tx_underrun ;
+ unsigned int tx_carrier_loss ;
+ unsigned int tx_deferred ;
+ unsigned int tx_sqetesterrors ;
+ unsigned int tx_single_collisions;
+ unsigned int tx_mult_collisions ;
+ unsigned int tx_total_collisions ;
+ unsigned int rx_good ;
+ unsigned int rx_crc_errors ;
+ unsigned int rx_align_errors ;
+ unsigned int rx_resource_errors ;
+ unsigned int rx_overrun_errors ;
+ unsigned int rx_collisions ;
+ unsigned int rx_short_frames ;
+ unsigned int rx_too_long_frames ;
+ unsigned int rx_symbol_errors ;
+ unsigned int interrupts ;
+ unsigned int rx_count ;
+ unsigned int rx_deliver ;
+ unsigned int rx_resource ;
+ unsigned int rx_restart ;
+ unsigned int tx_count ;
+ unsigned int tx_complete ;
+ unsigned int tx_dropped ;
+};
+#endif
+
+struct lan91cxx_priv_data;
+typedef cyg_bool (*provide_esa_t)(struct lan91cxx_priv_data* cpd);
+
+typedef struct lan91cxx_priv_data {
+ int txbusy; // A packet has been sent
+ unsigned long txkey; // Used to ack when packet sent
+ unsigned short* base; // Base I/O address of controller
+ // (as it comes out of reset)
+#if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
+ unsigned char* attbase; // Base attribute address of controller
+ // only used in PCMCIA mode
+#endif
+ int interrupt; // Interrupt vector used by controller
+ unsigned char enaddr[6]; // Controller ESA
+ // Function to configure the ESA - may fetch ESA from EPROM or
+ // RedBoot config option. Use of the 'config_enaddr()' function
+ // is depreciated in favor of the 'provide_esa()' function and
+ // 'hardwired_esa' boolean
+ void (*config_enaddr)(struct lan91cxx_priv_data* cpd);
+ // New function to fetch the ESA from flash via RedBoot
+ // (see devs_eth_innovator.inl)
+ provide_esa_t provide_esa;
+ bool hardwired_esa;
+ int txpacket;
+ int rxpacket;
+ int within_send;
+ int addrsh; // Address bits to shift
+ int c111_reva; // true if this is a revA LAN91C111
+ cyg_uint32 data_buf;
+ int data_pos;
+#ifdef KEEP_STATISTICS
+ struct smsc_lan91cxx_stats stats;
+#endif
+} lan91cxx_priv_data;
+
+// ------------------------------------------------------------------------
+
+#include CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL
+
+#ifdef LAN91CXX_32BIT_RX
+typedef cyg_uint32 rxd_t;
+#else
+typedef cyg_uint16 rxd_t;
+#endif
+
+#ifndef SMSC_PLATFORM_DEFINED_GET_REG
+static __inline__ unsigned short
+get_reg(struct eth_drv_sc *sc, int regno)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+ unsigned short val;
+
+ HAL_WRITE_UINT16(cpd->base+(LAN91CXX_BS << cpd->addrsh), CYG_CPU_TO_LE16(regno>>3));
+ HAL_READ_UINT16(cpd->base+((regno&0x7) << cpd->addrsh), val);
+ val = CYG_LE16_TO_CPU(val);
+
+#if DEBUG & 2
+ diag_printf("read reg %d val 0x%04x\n", regno, val);
+#endif
+ return val;
+}
+#endif // SMSC_PLATFORM_DEFINED_GET_REG
+
+#ifndef SMSC_PLATFORM_DEFINED_PUT_REG
+static __inline__ void
+put_reg(struct eth_drv_sc *sc, int regno, unsigned short val)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+ HAL_WRITE_UINT16(cpd->base+(LAN91CXX_BS << cpd->addrsh), CYG_CPU_TO_LE16(regno>>3));
+ HAL_WRITE_UINT16(cpd->base+((regno&0x7) << cpd->addrsh), CYG_CPU_TO_LE16(val));
+
+#if DEBUG & 2
+ diag_printf("write reg %d val 0x%04x\n", regno, val);
+#endif
+}
+#endif // SMSC_PLATFORM_DEFINED_PUT_REG
+
+#ifndef SMSC_PLATFORM_DEFINED_PUT_DATA
+// ------------------------------------------------------------------------
+// Assumes bank2 has been selected
+static __inline__ void
+put_data(struct eth_drv_sc *sc, unsigned short val)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+ HAL_WRITE_UINT16(cpd->base+((LAN91CXX_DATA & 0x7) << cpd->addrsh), val);
+
+#if DEBUG & 2
+ diag_printf("write data 0x%04x\n", val);
+#endif
+}
+#endif // SMSC_PLATFORM_DEFINED_PUT_DATA
+
+#ifndef SMSC_PLATFORM_DEFINED_GET_DATA
+// Assumes bank2 has been selected
+static __inline__ rxd_t
+get_data(struct eth_drv_sc *sc)
+{
+ rxd_t val;
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+#ifdef LAN91CXX_32BIT_RX
+ HAL_READ_UINT32(cpd->base+((LAN91CXX_DATA_HIGH & 0x7) << cpd->addrsh), val);
+#else
+ HAL_READ_UINT16(cpd->base+((LAN91CXX_DATA & 0x7) << cpd->addrsh), val);
+#endif
+
+#if DEBUG & 2
+ diag_printf("read data 0x%x\n", val);
+#endif
+ return val;
+}
+#endif // SMSC_PLATFORM_DEFINED_GET_DATA
+
+// ------------------------------------------------------------------------
+// Read the bank register (this one is bank-independent)
+#ifndef SMSC_PLATFORM_DEFINED_GET_BANKSEL
+static __inline__ unsigned short
+get_banksel(struct eth_drv_sc *sc)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+ unsigned short val;
+
+ HAL_READ_UINT16(cpd->base+(LAN91CXX_BS << cpd->addrsh), val);
+ val = CYG_LE16_TO_CPU(val);
+#if DEBUG & 2
+ diag_printf("read bank val 0x%04x\n", val);
+#endif
+ return val;
+}
+#endif
+
+
+// ------------------------------------------------------------------------
+// Write on PCMCIA attribute memory
+#if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
+static __inline__ void
+put_att(struct eth_drv_sc *sc, int offs, unsigned char val)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+
+ HAL_WRITE_UINT8(cpd->attbase + (offs << cpd->addrsh), CYG_CPU_TO_LE16(val));
+
+#if DEBUG & 2
+ diag_printf("write attr %d val 0x%02x\n", offs, val);
+#endif
+}
+
+// Read from PCMCIA attribute memory
+static __inline__ unsigned char
+get_att(struct eth_drv_sc *sc, int offs)
+{
+ struct lan91cxx_priv_data *cpd =
+ (struct lan91cxx_priv_data *)sc->driver_private;
+ unsigned char val;
+
+ HAL_READ_UINT8(cpd->attbase + (offs << cpd->addrsh), val);
+ val = CYG_LE16_TO_CPU(val);
+#if DEBUG & 2
+ diag_printf("read attr %d val 0x%02x\n", offs, val);
+#endif
+ return val;
+}
+#endif // #if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
+
+// ------------------------------------------------------------------------
+#endif // CYGONCE_DEVS_ETH_SMSC_LAN91CXX_LAN91CXX_H
+// EOF smsc_lan91cxx.h
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/ChangeLog b/ecos/packages/devs/eth/synth/ecosynth/current/ChangeLog
new file mode 100644
index 0000000..9672883
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/ChangeLog
@@ -0,0 +1,128 @@
+2009-07-14 Bart Veer <bartv@ecoscentric.com>
+
+ * host/configure.in: allow builds on x86_64 machines.
+
+ * host/configure, host/Makefile.in, host/aclocal.m4: regenerate
+
+2008-08-18 Bart Veer <bartv@ecoscentric.com>
+
+ * host/Makefile.am, host/configure.in: update host-configury.
+ * host/Makefile.in, host/configure, host/aclocal.m4: regenerate
+
+2008-08-13 Bart Veer <bartv@ecoscentric.com>
+
+ * host/rawether.c: eliminate compiler warning.
+ * src/syntheth.c (synth_eth_start): ignore the enaddr argument.
+
+2005-07-22 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/syntheth.c (synth_eth_init): Cast to keep the compiler
+ happy.
+
+2003-07-16 Gary Thomas <gary@mlbassoc.com>
+
+ * host/rawether.c: Change error reporting to use standard 'strerror()'
+ function since the use of sys_errlist[] is depricated.
+
+2003-07-09 Bart Veer <bartv@ecoscentric.com>
+
+ * host/Makefile.am: add a dummy install-data-hook if not
+ supported.
+
+ * host/Makefile.in, host/aclocal.m4, host/configure: regenerate
+
+2003-05-06 Bart Veer <bartv@ecoscentric.com>
+
+ * host/ethernet.tcl (filters_initialize):
+ Fix typo reported by Scott Wilkinson
+
+2003-02-25 Iztok Zupet <iz@vsr.si>
+
+ * doc/syntheth.sgml: Replaced .gif with .png to get PDF
+ output.
+ * doc/overview.gif: delete.
+ * doc/overview.png: add.
+
+2003-04-08 Andrew Lunn <lunn@londo>
+
+ * host/rawether.c (tap_init): Set the persistent flag on the tap
+ device if requested by the user. This allows dhcpd and radvd to
+ keep running on the tap device between invocations of the synth
+ target.
+ * doc/syntheth.sgml: Documentation for the persistent option.
+
+2003-04-01 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/syntheth.c (synth_eth_init): Set the flag IFF_ALLMULTI when
+ the underlying device supports multicast so eth_drv correctly sets
+ mutlicast filtering.
+ * cdl/syntheth.cdl: This driver implements multicast.
+
+2003-02-25 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * doc/syntheth.sgml: Declare as <part> not <reference> to get
+ correct TOC numbering.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/syntheth.cdl: Add doc link.
+
+ * doc/syntheth.sgml: Comment out DOCTYPE for now to allow building
+ with standard doc build.
+ Add an enclosing <reference> so it's structured better with standard
+ doc build.
+
+2003-02-13 Bart Veer <bartv@ecoscentric.com>
+
+ * src/syntheth.c, cdl/syntheth.cdl: add dependency on errno.h for
+ error codes, and avoid memset() warning
+
+2003-02-12 Bart Veer <bartv@ecoscentric.com>
+
+ * host/Makefile.in, host/configure:
+ Regenerate after toplevel acinclude.m4 update
+
+2003-02-12 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/syntheth.cdl (CYGPKG_DEVS_ETH_ECOSYNTH_CFLAGS_ADD):
+ Define -D_KERNEL -D__ECOS in line with other drivers. Fixes build
+ issue with freeBSD stack.
+
+2002-09-25 Bart Veer <bartv@ecoscentric.com>
+
+ * host/configure.in, host/rawether.c, doc/syntheth.sgml:
+ Only support the tap device if running a recent Linux kernel
+
+2002-09-22 Bart Veer <bartv@ecoscentric.com>
+
+ * host/configure.in:
+ Remove Tcl-related checks, the ethernet package only requires
+ the functionality of the architectural HAL support
+
+2002-08-07 Bart Veer <bartv@ecoscentric.com>
+
+ * synthetic target ethernet driver package created
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/cdl/syntheth.cdl b/ecos/packages/devs/eth/synth/ecosynth/current/cdl/syntheth.cdl
new file mode 100644
index 0000000..fd7b981
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/cdl/syntheth.cdl
@@ -0,0 +1,146 @@
+# ====================================================================
+#
+# syntheth.cdl
+#
+# Synthetic target ethernet package.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Original data: bartv
+# Contributors:
+# Date: 2002-08-07
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ECOSYNTH {
+ display "Synthetic target ethernet driver"
+ description "
+ The ethernet driver for the eCos synthetic target allows applications
+ and other packages such as a TCP/IP stack to perform ethernet I/O.
+ This can involve either an unused ethernet device, or an emulated
+ ethernet device as provided by the Linux kernel's tunnel/tap
+ support. The eCos code interacts with a suitable Linux application
+ through the I/O auxiliary. Up to four ethernet devices are
+ supported, and the host-side target definition file controls how
+ each device will perform its I/O."
+ doc ref/devs-eth-synth-ecosynth.html
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_HAL_SYNTH
+ implements CYGINT_IO_ETH_MULTICAST
+
+ cdl_option CYGVAR_DEVS_ETH_ECOSYNTH_ETH0 {
+ display "Provide eth0 device"
+ description "
+ The synthetic target can provide up to four ethernet devices,
+ eth0 to eth3. By default eth0 is enabled when a TCP/IP stack
+ is part of the configuration, disabled otherwise."
+ default_value CYGPKG_NET_STACK
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH0
+ }
+
+ cdl_option CYGVAR_DEVS_ETH_ECOSYNTH_ETH1 {
+ display "Provide eth1 device"
+ description "
+ The synthetic target can provide up to four ethernet devices,
+ eth0 to eth3. By default eth1 is always disabled, but can
+ be enabled if the eCos application needs more than one ethernet
+ device."
+ default_value 0
+ implements CYGHWR_NET_DRIVERS
+ implements CYGHWR_NET_DRIVER_ETH1
+ }
+
+ cdl_option CYGVAR_DEVS_ETH_ECOSYNTH_ETH2 {
+ display "Provide eth2 device"
+ description "
+ The synthetic target can provide up to four ethernet devices,
+ eth0 to eth3. By default eth2 is always disabled, but can
+ be enabled if the eCos application needs more than two ethernet
+ devices."
+ default_value 0
+ implements CYGHWR_NET_DRIVERS
+ }
+
+ cdl_option CYGVAR_DEVS_ETH_ECOSYNTH_ETH3 {
+ display "Provide eth3 device"
+ description "
+ The synthetic target can provide up to four ethernet devices,
+ eth0 to eth3. By default eth3 is always disabled, but can
+ be enabled if the eCos application needs more than three ethernet
+ devices."
+ default_value 0
+ implements CYGHWR_NET_DRIVERS
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_ECOSYNTH_OPTIONS {
+ display "Build options"
+ active_if { CYGVAR_DEVS_ETH_ECOSYNTH_ETH0 || CYGVAR_DEVS_ETH_ECOSYNTH_ETH1 || CYGVAR_DEVS_ETH_ECOSYNTH_ETH2 || CYGVAR_DEVS_ETH_ECOSYNTH_ETH3 }
+ flavor none
+ compile -library=libextras.a syntheth.c
+ requires CYGINT_ISO_ERRNO_CODES CYGINT_ISO_STRING_MEMFUNCS
+ description "
+ Package-specific build options including control over compiler
+ flags used only in building this package."
+
+ cdl_option CYGPKG_DEVS_ETH_ECOSYNTH_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building this package. These flags are used in addition
+ to the set of global flags."
+ }
+ cdl_option CYGPKG_DEVS_ETH_ECOSYNTH_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building this package. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF syntheth.cdl
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/doc/devs-eth-synth-ecosynth.html b/ecos/packages/devs/eth/synth/ecosynth/current/doc/devs-eth-synth-ecosynth.html
new file mode 100644
index 0000000..1a93f47
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/doc/devs-eth-synth-ecosynth.html
@@ -0,0 +1,928 @@
+<!-- Copyright (C) 2002 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/). -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission is obtained from the copyright holder. -->
+<HTML
+><HEAD
+><TITLE
+>Synthetic Target Ethernet Driver</TITLE
+><meta name="MSSmartTagsPreventParsing" content="TRUE">
+<META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="DEVS-ETH-SYNTH-ECOSYNTH">Synthetic Target Ethernet Driver</H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN4"
+></A
+><H2
+>Name</H2
+>Synthetic Target Ethernet Support&nbsp;--&nbsp;Allow synthetic target applications to perform ethernet I/O</DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN7"
+></A
+><H2
+>Overview</H2
+><P
+>The synthetic target ethernet package can provide up to four network
+devices, <TT
+CLASS="VARNAME"
+>eth0</TT
+> to <TT
+CLASS="VARNAME"
+>eth3</TT
+>. These can
+be used directly by the eCos application or, more commonly, by a
+TCP/IP stack that is linked with the eCos application. Each eCos
+device can be mapped on to a real Linux network device. For example,
+if the Linux PC has two ethernet cards and <TT
+CLASS="VARNAME"
+>eth1</TT
+> is
+not currently being used by Linux itself, then one of the eCos devices
+can be mapped on to this Linux device. Alternatively, it is possible
+to map some or all of the eCos devices on to the ethertap support
+provided by the Linux kernel.
+ </P
+><P
+>The ethernet package depends on the I/O auxiliary provided by the
+synthetic target architectural HAL package. During initialization the
+eCos application will attempt to instantiate the desired devices, by
+sending a request to the auxiliary. This will load a Tcl script
+<TT
+CLASS="FILENAME"
+>ethernet.tcl</TT
+> that is responsible for handling the
+instantiation request and subsequent I/O operations, for example
+transmitting an ethernet packet. However, some of the low-level I/O
+operations cannot conveniently be done by a Tcl script so
+<TT
+CLASS="FILENAME"
+>ethernet.tcl</TT
+> will actually run a separate program
+<B
+CLASS="COMMAND"
+>rawether</B
+> to interact with the Linux network device.
+ </P
+><DIV
+CLASS="INFORMALFIGURE"
+><A
+NAME="AEN17"><P
+></P
+><DIV
+CLASS="MEDIAOBJECT"
+><P
+><IMG
+SRC="overview.gif"
+ALIGN="CENTER"></P
+></DIV
+><P
+></P
+></DIV
+><P
+>On the target-side there are configuration options to control which
+network devices should be present. For many applications a single
+device will be sufficient, but if the final eCos application is
+something like a network bridge then the package can support multiple
+devices. On the host-side each eCos network device needs to be mapped
+on to a Linux one, either a real ethernet device or an ethertap
+device. This is handled by an entry in the target definition file:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device ethernet {
+ eth0 real eth1
+ eth1 ethertap tap3 00:01:02:03:FE:05
+ &#8230;
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>The ethernet package also comes with support for packet logging,
+and provides various facilities for use by user Tcl scripts.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-ETH-ECOSYNTH-INSTALL"
+></A
+><H2
+>Installation</H2
+><P
+>Before a synthetic target eCos application can access ethernet devices
+it is necessary to build and install host-side support. The relevant
+code resides in the <TT
+CLASS="FILENAME"
+>host</TT
+>
+subdirectory of the synthetic target ethernet package, and building it
+involves the standard <B
+CLASS="COMMAND"
+>configure</B
+>,
+<B
+CLASS="COMMAND"
+>make</B
+> and <B
+CLASS="COMMAND"
+>make install</B
+> steps.
+The build involves a new executable <B
+CLASS="COMMAND"
+>rawether</B
+> which
+must be able to access a raw Linux network device. This is achieved by
+installing it suid root, so the <B
+CLASS="COMMAND"
+>make install</B
+> step
+has to be run with superuser privileges.
+ </P
+><DIV
+CLASS="CAUTION"
+><P
+></P
+><TABLE
+CLASS="CAUTION"
+BORDER="1"
+WIDTH="100%"
+><TR
+><TD
+ALIGN="CENTER"
+><B
+>Caution</B
+></TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+><P
+>Installing <B
+CLASS="COMMAND"
+>rawether</B
+> suid root introduces a
+potential security problem. Although normally
+<B
+CLASS="COMMAND"
+>rawether</B
+> is executed only by the I/O auxiliary,
+theoretically it can be run by any program. Effectively it gives any
+user the ability to monitor all ethernet traffic and to inject
+arbitrary packets into the network. Also, as with any suid root
+programs there may be as yet undiscovered exploits. Users and system
+administrators should consider the risks before running <B
+CLASS="COMMAND"
+>make
+install</B
+>.
+ </P
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>There are two main ways of building the host-side software. It is
+possible to build both the generic host-side software and all
+package-specific host-side software, including the ethernet support,
+in a single build tree. This involves using the
+<B
+CLASS="COMMAND"
+>configure</B
+> script at the toplevel of the eCos
+repository. For more information on this, see the
+<TT
+CLASS="FILENAME"
+>README.host</TT
+> file at the top of the repository.
+Note that if you have an existing build tree which does not include
+the synthetic target ethernet support then it will be necessary to
+rerun the toplevel configure script: the search for appropriate
+packages happens at configure time.
+ </P
+><P
+>The alternative is to build just the host-side for this package.
+This requires a separate build directory, building directly in the
+source tree is disallowed. The <B
+CLASS="COMMAND"
+>configure</B
+> options
+are much the same as for a build from the toplevel, and the
+<TT
+CLASS="FILENAME"
+>README.host</TT
+> file can be consulted for more
+details. It is essential that the ethernet support be configured with
+the same <TT
+CLASS="OPTION"
+>--prefix</TT
+> option as other eCos host-side
+software, especially the I/O auxiliary provided by the architectural
+synthetic target HAL package, otherwise the I/O auxiliary will be
+unable to locate the ethernet support.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-ETH-ECOSYNTH-OPTIONS"
+></A
+><H2
+>Target-side Configuration Options</H2
+><P
+>The target-side code can be configured to support up to four ethernet
+devices, <TT
+CLASS="VARNAME"
+>eth0</TT
+> to <TT
+CLASS="VARNAME"
+>eth3</TT
+>. By
+default <TT
+CLASS="VARNAME"
+>eth0</TT
+> is enabled if the configuration
+includes a TCP/IP stack, otherwise it is disabled. The other three
+devices are always disabled by default. If any of the devices are
+enabled then there will also be the usual configuration options
+related to building this package. Other options related to network
+devices, for example whether or not to use DHCP, are provided by
+the generic network device package.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-ETH-ECOSYNTH-REAL"
+></A
+><H2
+>Real Ethernet</H2
+><P
+>One obvious way of providing a synthetic target eCos application with
+ethernet I/O is to use a real ethernet device in the PC: transmitted
+packets go out on a real network, and packets on the network addressed
+to the right MAC address are passed on to eCos. This way synthetic
+target networking behaves just like networking on a real target with
+ethernet hardware. For example, if there is a DHCP server anywhere on
+the network then eCos will be able to contact it during networking
+startup and get hold of IP address information.
+ </P
+><P
+>Configuring the ethernet support to use a real ethernet device
+requires a simple entry in the target definition file:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device ethernet {
+ &lt;eCos device&gt; real &lt;linux device&gt;
+ &#8230;
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>For example, to map the eCos network device <TT
+CLASS="VARNAME"
+>eth0</TT
+> to
+the Linux device <TT
+CLASS="VARNAME"
+>eth1</TT
+>:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device ethernet {
+ eth0 real eth1
+ &#8230;
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>It is not possible for an ethernet device to be shared by both the
+eCos TCP/IP stack and the Linux one: there would be no simple way to
+work out which stack incoming packets are intended for. In theory
+it might be possible to do some demultiplexing using distinct IP
+addresses, but it would be impossible to support some functionality
+such as DHCP. Therefore the <B
+CLASS="COMMAND"
+>rawether</B
+> program will
+refuse to access any ethernet device already in use. On a typical
+Linux system <TT
+CLASS="VARNAME"
+>eth0</TT
+> will be used for Linux
+networking, and the PC will have to be equipped with additional
+ethernet devices for use by eCos.
+ </P
+><P
+>The <B
+CLASS="COMMAND"
+>rawether</B
+> program will access the hardware via
+the appropriate Linux device driver, so it is important that the
+system is set up such that the relevant module will be automatically
+loaded or is already loaded. The details of this will depend on the
+installed distribution and version, but typically it will involve an
+entry in <TT
+CLASS="FILENAME"
+>/etc/modules.conf</TT
+>.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-ETH-ECOSYNTH-ETHERTAP"
+></A
+><H2
+>Ethertap</H2
+><P
+>The Linux kernel's ethertap facility provides a virtual network
+interface. A Linux application, for example the
+<B
+CLASS="COMMAND"
+>rawether</B
+> program, can open a special character
+device <TT
+CLASS="FILENAME"
+>/dev/net/tun</TT
+>, perform various
+<TT
+CLASS="FUNCTION"
+>ioctl</TT
+> calls, and then <TT
+CLASS="FILENAME"
+>write</TT
+>
+and <TT
+CLASS="FILENAME"
+>read</TT
+> ethernet packets. When the device is
+opened the Linux kernel automatically creates a new network interface,
+for example <TT
+CLASS="VARNAME"
+>tap0</TT
+>. The Linux TCP/IP stack can be
+made to use this network interface like any other interface, receiving
+and transmitting ethernet packets. The net effect is a virtual network
+connecting just the Linux and eCos TCP/IP stacks, with no other nodes
+attached. By default all traffic remains inside this virtual network
+and is never forwarded to a real network.
+ </P
+><P
+>Support for the ethertap facility may or may not be provided
+automatically, depending on your Linux distribution and version. If
+your system does not have a device <TT
+CLASS="FILENAME"
+>/dev/net/tun</TT
+>
+or a module <TT
+CLASS="FILENAME"
+>tun.o</TT
+> then the appropriate kernel
+documentation should be consulted, for example
+<TT
+CLASS="FILENAME"
+>/usr/src/linux-2.4/Documentation/networking/tuntap.txt</TT
+>.
+If you are using an old Linux kernel then the ethertap functionality
+may be missing completely. When the <B
+CLASS="COMMAND"
+>rawether</B
+>
+program is configured and built, the <B
+CLASS="COMMAND"
+>configure</B
+>
+script will check for a file <TT
+CLASS="FILENAME"
+>/usr/include/linux/if_tun.h</TT
+>. If that
+file is missing then <B
+CLASS="COMMAND"
+>rawether</B
+> will be built without
+ethertap functionality, and only real ethernet interfaces will be
+supported.
+ </P
+><P
+>The target definition file is used to map eCos network devices on to
+ethertap devices. The simplest usage is:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device ethernet {
+ eth0 ethertap
+ &#8230;
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>The Linux kernel will automatically allocate the next available tap
+network interface. Usually this will be <TT
+CLASS="VARNAME"
+>tap0</TT
+> but if
+other software is using the ethertap facility, for example to
+implement a VPN, then a different number may be allocated. Usually it
+will be better to specify the particular tap device that should be
+used for each eCos device, for example:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device ethernet {
+ eth0 ethertap tap3
+ eth1 ethertap tap4
+ &#8230;
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>The user now knows exactly which eCos device is mapped onto which
+Linux device, avoiding much potential confusion. Because the virtual
+devices are emulated ethernet devices, they require MAC addresses.
+There is no physical hardware to provide these addresses, so normally
+MAC addresses will be invented. That means that each time the eCos
+application is run it will have different MAC addresses, which makes
+it more difficult to compare the results of different runs. To get
+more deterministic behaviour it is possible to specify the MAC
+addresses in the target definition file:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device ethernet {
+ eth0 ethertap tap3 00:01:02:03:FE:05
+ eth1 ethertap tap4 00:01:02:03:FE:06
+ &#8230;
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>During the initialization phase the eCos application will instantiate
+the various network devices. This will cause the I/O auxiliary to load
+the <TT
+CLASS="FILENAME"
+>ethernet.tcl</TT
+> script and spawn
+<B
+CLASS="COMMAND"
+>rawether</B
+> processes, which in turn will
+<TT
+CLASS="FUNCTION"
+>open</TT
+> <TT
+CLASS="FILENAME"
+>/dev/net/tun</TT
+> and
+perform the appropriate <TT
+CLASS="FILENAME"
+>ioctl</TT
+> calls. On the Linux
+side there will now be new network interfaces such as
+<TT
+CLASS="VARNAME"
+>tap3</TT
+>, and these can be configured like any other
+network interface using commands such as <B
+CLASS="COMMAND"
+>ifconfig</B
+>.
+In addition, if the Linux system is set up with hotplug support then
+it may be possible to arrange for the network interface to become
+active automatically. On a Red Hat Linux system this would require
+files such as
+<TT
+CLASS="FILENAME"
+>/etc/sysconfig/network-scripts/ifcfg-tap3</TT
+>,
+containing data like:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>DEVICE="tap3"
+BOOTPROTO="none"
+BROADCAST=10.2.2.255
+IPADDR="10.2.2.1"
+NETMASK="255.255.255.0"
+NETWORK=10.2.2.0
+ONBOOT="no"</PRE
+></TD
+></TR
+></TABLE
+><P
+>This gives the Linux interface the address <TT
+CLASS="LITERAL"
+>10.2.2.1</TT
+>
+on the network <TT
+CLASS="LITERAL"
+>10.2.2.0</TT
+>. The eCos network device
+should be configured with a compatible address. One way of doing this
+would be to enable <TT
+CLASS="VARNAME"
+>CYGHWR_NET_DRIVER_ETH0_ADDRS</TT
+>,
+set <TT
+CLASS="VARNAME"
+>CYGHWR_NET_DRIVER_ETH0_ADDRS_IP</TT
+> to
+<TT
+CLASS="LITERAL"
+>10.2.2.2</TT
+>, and similarly update the
+<TT
+CLASS="VARNAME"
+>NETMASK</TT
+>, <TT
+CLASS="VARNAME"
+>BROADCAST</TT
+>,
+<TT
+CLASS="VARNAME"
+>GATEWAY</TT
+> and <TT
+CLASS="VARNAME"
+>SERVER</TT
+> configuration
+options.
+ </P
+><P
+>It should be noted that the ethertap facility provides a virtual
+network, and any packets transmitted by the eCos application will
+not appear on a real network. Therefore usually there will no
+accessible DHCP server, and eCos cannot use DHCP or BOOTP to obtain IP
+address information. Instead the eCos configuration should use manual
+or static addresses.
+ </P
+><P
+>An alternative approach would be to set up the Linux box as a network
+bridge, using commands like <B
+CLASS="COMMAND"
+>brctl</B
+> to connect the
+virtual network interface <TT
+CLASS="VARNAME"
+>tap3</TT
+> to a physical
+network interface such as <TT
+CLASS="VARNAME"
+>eth0</TT
+>. Any packets sent by
+the eCos application will get forwarded automatically to the real
+network, and some packets on the real network will get forwarded over
+the virtual network to the eCos application. Note that the eCos
+application might also get some packets that were not intended for it,
+but usually those will just be discarded by the eCos TCP/IP stack. The
+exact details of setting up a network bridge are left as an exercise
+to the reader.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-ETH-ECOSYNTH-LOGGING"
+></A
+><H2
+>Packet Logging</H2
+><P
+>The ethernet support comes with support for logging the various
+packets that are transferred, including a simple protocol analyser.
+This generates simple text output using the filter mechanisms provided
+by the I/O auxiliary, so it is possible to control the appearance and
+visibility of different types of output. For example the user might
+want to see IPv4 headers and all ICMPv4 and ARP operations, but not
+TCP headers or any of the packet data.
+ </P
+><P
+>The protocol analyser is not intended to be a fully functional
+analyser with knowledge of many different TCP/IP protocols, advanced
+search facilities, graphical traffic displays, and so on.
+Functionality like that is already provided by other tools such as
+<SPAN
+CLASS="APPLICATION"
+>ethereal</SPAN
+> and
+<SPAN
+CLASS="APPLICATION"
+>tcpdump</SPAN
+>. Achieving similar levels of
+functionality would require a lot of work, for very little gain. It is
+still useful to have some protocol analysis functionality available
+because the output will be interleaved with other output, for example
+<TT
+CLASS="FILENAME"
+>printf</TT
+> calls from the application. That may make
+it easier to understand the sequence of events.
+ </P
+><P
+>One problem with logging ethernet traffic is that it can involve very
+large amounts of data. If the application is expected to run for a
+long time or is very I/O intensive then it is easy to end up with many
+megabytes. When running in graphical mode all the logging data will be
+held in memory, even data that is not currently visible. At some point
+the system will begin to run low on memory and performance will
+suffer. To avoid problems, the ethernet script maintains a flag that
+controls whether or not packet logging is active. The default is to
+run with logging disabled, but this can be changed in the target
+definition file:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device ethernet {
+ &#8230;
+ logging 1
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>The ethernet script will add a toolbar button that allows this flag to
+be changed at run-time, allowing the user to capture traffic for
+certain periods of time while the application continues running.
+ </P
+><P
+>The target definition file can contain the following entries for the
+various packet logging filters:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device ethernet {
+ &#8230;
+ filter ether -hide 0 -background LightBlue -foreground "#000080"
+ filter arp -hide 0 -background LightBlue -foreground "#000050"
+ filter ipv4 -hide 0 -background LightBlue -foreground "#000040"
+ filter ipv6 -hide 1 -background LightBlue -foreground "#000040"
+ filter icmpv4 -hide 0 -background LightBlue -foreground "#000070"
+ filter icmpv6 -hide 1 -background LightBlue -foreground "#000070"
+ filter udp -hide 0 -background LightBlue -foreground "#000030"
+ filter tcp -hide 0 -background LightBlue -foreground "#000020"
+ filter hexdata -hide 1 -background LightBlue -foreground "#000080"
+ filter asciidata -hide 1 -background LightBlue -foreground "#000080"
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>All output will show the eCos network device, for example
+<TT
+CLASS="LITERAL"
+>eth0</TT
+>, and the direction relative to the eCos
+application. Some of the filters will show packet headers, for example
+<TT
+CLASS="LITERAL"
+>ether</TT
+> gives details of the ethernet packet header
+and <TT
+CLASS="LITERAL"
+>tcp</TT
+> gives information about TCP headers such as
+whether or not the SYN flag is set. The TCP and UDP filters will also
+show source and destination addresses, using numerical addresses and
+if possible host names. However, host names will only be shown if the
+host appears in <TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+>: doing full DNS
+lookups while the data is being captured would add significantly to
+complexity and overhead. The <TT
+CLASS="LITERAL"
+>hexdata</TT
+> and
+<TT
+CLASS="LITERAL"
+>asciidata</TT
+> filters show the remainder of the packets
+after the ethernet, IP and TCP or UDP headers have been stripped.
+ </P
+><P
+>Some of the filters will provide raw dumps of some of the packet data.
+Showing up to 1500 bytes of data for each packet would be expensive,
+and often the most interesting information is near the start of the
+packet. Therefore it is possible to set a limit on the number of bytes
+that will be shown using the target definition file. The default limit
+is 64 bytes.
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device ethernet {
+ &#8230;
+ max_show 128
+}</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-ETH-ECOSYNTH-GUI"
+></A
+><H2
+>User Interface Additions</H2
+><P
+>When running in graphical mode the ethernet script extends the user
+interface in two ways: a button is added to the toolbar so that users
+can enable or disable packet logging; and an entry is added to the
+<SPAN
+CLASS="GUIMENU"
+>Help</SPAN
+> menu for the ethernet-specific documentation.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-ETH-ECOSYNTH-ARGS"
+></A
+><H2
+>Command Line Arguments</H2
+><P
+>The synthetic target ethernet support does not use any command line
+arguments. All configuration is handled through the target definition
+file.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-ETH-ECOSYNTH-HOOKS"
+></A
+><H2
+>Hooks</H2
+><P
+>The ethernet support defines two hooks that can be used by other
+scripts, especially user scripts: <TT
+CLASS="LITERAL"
+>ethernet_tx</TT
+> and
+<TT
+CLASS="LITERAL"
+>ethernet_rx</TT
+>. The tx hook is called whenever eCos
+tries to transmit a packet. The rx hook is called whenever an incoming
+packet is passed to the eCos application. Note that this may be a
+little bit after the packet was actually received by the I/O auxiliary
+since it can buffer some packets. Both hooks are called with two
+arguments, the name of the network device and the packet being
+transferred. Typical usage might look like:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+> proc my_tx_hook { arg_list } {
+ set dev [lindex $arg_list 0]
+ incr ::my_ethernet_tx_packets($dev)
+ incr ::my_ethernet_tx_bytes($dev) [string length [lindex $arg_list 1]]
+ }
+ proc my_rx_hook { arg_list } {
+ set dev [lindex $arg_list 0]
+ incr ::my_ethernet_rx_packets($dev)
+ incr ::my_ethernet_rx_bytes($dev) [string length [lindex $arg_list 1]]
+ }
+ synth::hook_add "ethernet_tx" my_tx_hook
+ synth::hook_add "ethernet_rx" my_rx_hook</PRE
+></TD
+></TR
+></TABLE
+><P
+>The global arrays <TT
+CLASS="VARNAME"
+>my_ethernet_tx_packets</TT
+> etc. will
+now be updated whenever there is ethernet traffic. Other code,
+probably running at regular intervals by use of the Tcl
+<B
+CLASS="COMMAND"
+>after</B
+> procedure, can then use this information to
+update a graphical monitor of some sort.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-ETH-ECOSYNTH-TCL"
+></A
+><H2
+>Additional Tcl Procedures</H2
+><P
+>The ethernet support provides one additional Tcl procedure that can be
+used by other scripts;
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>ethernet::devices_get_list </PRE
+></TD
+></TR
+></TABLE
+><P
+>This procedure returns a list of the ethernet devices that have been
+instantiated, for example <TT
+CLASS="LITERAL"
+>{eth0 eth1}</TT
+>.
+ </P
+></DIV
+></BODY
+></HTML
+>
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/doc/makefile b/ecos/packages/devs/eth/synth/ecosynth/current/doc/makefile
new file mode 100644
index 0000000..8345281
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/doc/makefile
@@ -0,0 +1,54 @@
+#=============================================================================
+#
+# makefile
+#
+# For building the synthetic target ethernet package documentation
+#
+#=============================================================================
+# ####ECOSGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2002 Free Software Foundation, Inc.
+#
+# eCos is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 or (at your option) any later
+# version.
+#
+# eCos is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with eCos; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered by
+# the GNU General Public License. However the source code for this file
+# must still be made available in accordance with section (3) of the GNU
+# General Public License v2.
+#
+# This exception does not invalidate any other reasons why a work based
+# on this file might be covered by the GNU General Public License.
+# -------------------------------------------
+# ####ECOSGPLCOPYRIGHTEND####
+#=============================================================================
+#####DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Date: 2002-08-20
+#####DESCRIPTIONEND####
+#=============================================================================
+
+TOPLEVEL := ../../../../../..
+MAIN_SGML := syntheth.sgml
+MAIN_HTML := devs-eth-synth.html
+MAIN_PDF := devs-eth-synth.pdf
+OTHER_SGML :=
+PICTURES :=
+
+include $(TOPLEVEL)/pkgconf/rules.doc
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/doc/overview.fig b/ecos/packages/devs/eth/synth/ecosynth/current/doc/overview.fig
new file mode 100644
index 0000000..3753ea0
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/doc/overview.fig
@@ -0,0 +1,54 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 1500 300 1500 1500
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 2400 300 2400 1500
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 300 300 3000 300 3000 1500 300 1500 300 300
+2 2 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5
+ 3600 300 6000 300 6000 1500 3600 1500 3600 300
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 4800 300 4800 1500
+2 1 0 1 0 7 50 0 -1 4.000 0 0 7 1 1 2
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+ 3000 900 3600 900
+2 1 0 1 0 7 50 0 -1 4.000 0 0 7 1 1 2
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+ 6000 1050 6600 1050
+2 1 0 1 0 7 50 0 -1 4.000 0 0 7 1 1 2
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+ 7500 450 8100 450
+2 1 0 1 0 7 50 0 -1 4.000 0 0 7 1 1 2
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+ 7500 1050 8100 1050
+2 2 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5
+ 6600 900 7500 900 7500 1200 6600 1200 6600 900
+2 2 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5
+ 6600 300 7500 300 7500 600 6600 600 6600 300
+2 1 0 1 0 7 50 0 -1 4.000 0 0 7 1 1 2
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+ 6000 450 6600 450
+4 0 0 50 0 0 12 0.0000 4 180 825 375 1200 application\001
+4 0 0 50 0 0 12 0.0000 4 135 390 600 900 eCos\001
+4 0 0 50 0 0 12 0.0000 4 135 540 1650 900 TCP/IP\001
+4 0 0 50 0 0 12 0.0000 4 135 330 2550 675 eth0\001
+4 0 0 50 0 0 12 0.0000 4 135 330 2550 1200 eth1\001
+4 0 0 50 0 0 12 0.0000 4 180 975 3675 900 I/O Auxiliary\001
+4 0 0 50 0 0 12 0.0000 4 135 870 4950 900 ethernet.tcl\001
+4 0 0 50 0 0 12 0.0000 4 135 330 8175 525 eth1\001
+4 0 0 50 0 0 12 0.0000 4 180 330 8175 1125 tap3\001
+4 0 0 50 0 0 12 0.0000 4 135 675 6675 1125 rawether\001
+4 0 0 50 0 0 12 0.0000 4 135 675 6675 525 rawether\001
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/doc/overview.png b/ecos/packages/devs/eth/synth/ecosynth/current/doc/overview.png
new file mode 100644
index 0000000..00f5c4e
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/doc/overview.png
Binary files differ
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/doc/syntheth.sgml b/ecos/packages/devs/eth/synth/ecosynth/current/doc/syntheth.sgml
new file mode 100644
index 0000000..398cdba
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/doc/syntheth.sgml
@@ -0,0 +1,554 @@
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- syntheth.sgml -->
+<!-- -->
+<!-- Synthetic target ethernet support package. -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2002 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2002/08/20 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-eth-synth-ecosynth-ref">
+<!-- reference id="devs-eth-synth-ecosynth-ref" -->
+ <title>Synthetic Target Ethernet Driver</title>
+
+<refentry id="devs-eth-synth-ecosynth">
+ <refmeta>
+ <refentrytitle>Synthetic Target Ethernet Driver</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Synthetic Target Ethernet Support</refname>
+ <refpurpose>Allow synthetic target applications to perform ethernet I/O</refpurpose>
+ </refnamediv>
+
+ <refsect1><title>Overview</title>
+ <para>
+The synthetic target ethernet package can provide up to four network
+devices, <varname>eth0</varname> to <varname>eth3</varname>. These can
+be used directly by the eCos application or, more commonly, by a
+TCP/IP stack that is linked with the eCos application. Each eCos
+device can be mapped on to a real Linux network device. For example,
+if the Linux PC has two ethernet cards and <varname>eth1</varname> is
+not currently being used by Linux itself, then one of the eCos devices
+can be mapped on to this Linux device. Alternatively, it is possible
+to map some or all of the eCos devices on to the ethertap support
+provided by the Linux kernel.
+ </para>
+ <para>
+The ethernet package depends on the I/O auxiliary provided by the
+synthetic target architectural HAL package. During initialization the
+eCos application will attempt to instantiate the desired devices, by
+sending a request to the auxiliary. This will load a Tcl script
+<filename>ethernet.tcl</filename> that is responsible for handling the
+instantiation request and subsequent I/O operations, for example
+transmitting an ethernet packet. However, some of the low-level I/O
+operations cannot conveniently be done by a Tcl script so
+<filename>ethernet.tcl</filename> will actually run a separate program
+<command>rawether</command> to interact with the Linux network device.
+ </para>
+ <informalfigure PgWide=1>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="overview.png" Scalefit=1 Align="Center">
+ </imageobject>
+ </mediaobject>
+ </informalfigure>
+ <para>
+On the target-side there are configuration options to control which
+network devices should be present. For many applications a single
+device will be sufficient, but if the final eCos application is
+something like a network bridge then the package can support multiple
+devices. On the host-side each eCos network device needs to be mapped
+on to a Linux one, either a real ethernet device or an ethertap
+device. This is handled by an entry in the target definition file:
+ </para>
+ <programlisting>
+synth_device ethernet {
+ eth0 real eth1
+ eth1 ethertap tap3 00:01:02:03:FE:05
+ &hellip;
+}
+</programlisting>
+ <para>
+The ethernet package also comes with support for packet logging,
+and provides various facilities for use by user Tcl scripts.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-ecosynth-install"><title>Installation</title>
+ <para>
+Before a synthetic target eCos application can access ethernet devices
+it is necessary to build and install host-side support. The relevant
+code resides in the <filename class="directory">host</filename>
+subdirectory of the synthetic target ethernet package, and building it
+involves the standard <command>configure</command>,
+<command>make</command> and <command>make install</command> steps.
+The build involves a new executable <command>rawether</command> which
+must be able to access a raw Linux network device. This is achieved by
+installing it suid root, so the <command>make install</command> step
+has to be run with superuser privileges.
+ </para>
+ <caution><para>
+Installing <command>rawether</command> suid root introduces a
+potential security problem. Although normally
+<command>rawether</command> is executed only by the I/O auxiliary,
+theoretically it can be run by any program. Effectively it gives any
+user the ability to monitor all ethernet traffic and to inject
+arbitrary packets into the network. Also, as with any suid root
+programs there may be as yet undiscovered exploits. Users and system
+administrators should consider the risks before running <command>make
+install</command>.
+ </para></caution>
+ <para>
+There are two main ways of building the host-side software. It is
+possible to build both the generic host-side software and all
+package-specific host-side software, including the ethernet support,
+in a single build tree. This involves using the
+<command>configure</command> script at the toplevel of the eCos
+repository. For more information on this, see the
+<filename>README.host</filename> file at the top of the repository.
+Note that if you have an existing build tree which does not include
+the synthetic target ethernet support then it will be necessary to
+rerun the toplevel configure script: the search for appropriate
+packages happens at configure time.
+ </para>
+ <para>
+The alternative is to build just the host-side for this package.
+This requires a separate build directory, building directly in the
+source tree is disallowed. The <command>configure</command> options
+are much the same as for a build from the toplevel, and the
+<filename>README.host</filename> file can be consulted for more
+details. It is essential that the ethernet support be configured with
+the same <option>--prefix</option> option as other eCos host-side
+software, especially the I/O auxiliary provided by the architectural
+synthetic target HAL package, otherwise the I/O auxiliary will be
+unable to locate the ethernet support.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-ecosynth-options"><title>Target-side Configuration Options</title>
+ <para>
+The target-side code can be configured to support up to four ethernet
+devices, <varname>eth0</varname> to <varname>eth3</varname>. By
+default <varname>eth0</varname> is enabled if the configuration
+includes a TCP/IP stack, otherwise it is disabled. The other three
+devices are always disabled by default. If any of the devices are
+enabled then there will also be the usual configuration options
+related to building this package. Other options related to network
+devices, for example whether or not to use DHCP, are provided by
+the generic network device package.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-ecosynth-real"><title>Real Ethernet</title>
+ <para>
+One obvious way of providing a synthetic target eCos application with
+ethernet I/O is to use a real ethernet device in the PC: transmitted
+packets go out on a real network, and packets on the network addressed
+to the right MAC address are passed on to eCos. This way synthetic
+target networking behaves just like networking on a real target with
+ethernet hardware. For example, if there is a DHCP server anywhere on
+the network then eCos will be able to contact it during networking
+startup and get hold of IP address information.
+ </para>
+ <para>
+Configuring the ethernet support to use a real ethernet device
+requires a simple entry in the target definition file:
+ </para>
+ <programlisting>
+synth_device ethernet {
+ &lt;eCos device&gt; real &lt;linux device&gt;
+ &hellip;
+}
+</programlisting>
+ <para>
+For example, to map the eCos network device <varname>eth0</varname> to
+the Linux device <varname>eth1</varname>:
+ </para>
+ <programlisting>
+synth_device ethernet {
+ eth0 real eth1
+ &hellip;
+}
+</programlisting>
+ <para>
+It is not possible for an ethernet device to be shared by both the
+eCos TCP/IP stack and the Linux one: there would be no simple way to
+work out which stack incoming packets are intended for. In theory
+it might be possible to do some demultiplexing using distinct IP
+addresses, but it would be impossible to support some functionality
+such as DHCP. Therefore the <command>rawether</command> program will
+refuse to access any ethernet device already in use. On a typical
+Linux system <varname>eth0</varname> will be used for Linux
+networking, and the PC will have to be equipped with additional
+ethernet devices for use by eCos.
+ </para>
+ <para>
+The <command>rawether</command> program will access the hardware via
+the appropriate Linux device driver, so it is important that the
+system is set up such that the relevant module will be automatically
+loaded or is already loaded. The details of this will depend on the
+installed distribution and version, but typically it will involve an
+entry in <filename>/etc/modules.conf</filename>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-ecosynth-ethertap"><title>Ethertap</title>
+ <para>
+The Linux kernel's ethertap facility provides a virtual network
+interface. A Linux application, for example the
+<command>rawether</command> program, can open a special character
+device <filename>/dev/net/tun</filename>, perform various
+<function>ioctl</function> calls, and then <filename>write</filename>
+and <filename>read</filename> ethernet packets. When the device is
+opened the Linux kernel automatically creates a new network interface,
+for example <varname>tap0</varname>. The Linux TCP/IP stack can be
+made to use this network interface like any other interface, receiving
+and transmitting ethernet packets. The net effect is a virtual network
+connecting just the Linux and eCos TCP/IP stacks, with no other nodes
+attached. By default all traffic remains inside this virtual network
+and is never forwarded to a real network.
+ </para>
+ <para>
+Support for the ethertap facility may or may not be provided
+automatically, depending on your Linux distribution and version. If
+your system does not have a device <filename>/dev/net/tun</filename>
+or a module <filename>tun.o</filename> then the appropriate kernel
+documentation should be consulted, for example
+<filename>/usr/src/linux-2.4/Documentation/networking/tuntap.txt</filename>.
+If you are using an old Linux kernel then the ethertap functionality
+may be missing completely. When the <command>rawether</command>
+program is configured and built, the <command>configure</command>
+script will check for a file <filename
+class="headerfile">/usr/include/linux/if_tun.h</filename>. If that
+file is missing then <command>rawether</command> will be built without
+ethertap functionality, and only real ethernet interfaces will be
+supported.
+ </para>
+ <para>
+The target definition file is used to map eCos network devices on to
+ethertap devices. The simplest usage is:
+ </para>
+ <programlisting>
+synth_device ethernet {
+ eth0 ethertap
+ &hellip;
+}
+</programlisting>
+ <para>
+The Linux kernel will automatically allocate the next available tap
+network interface. Usually this will be <varname>tap0</varname> but if
+other software is using the ethertap facility, for example to
+implement a VPN, then a different number may be allocated. Usually it
+will be better to specify the particular tap device that should be
+used for each eCos device, for example:
+ </para>
+ <programlisting>
+synth_device ethernet {
+ eth0 ethertap tap3
+ eth1 ethertap tap4
+ &hellip;
+}
+</programlisting>
+ <para>
+The user now knows exactly which eCos device is mapped onto which
+Linux device, avoiding much potential confusion. Because the virtual
+devices are emulated ethernet devices, they require MAC addresses.
+There is no physical hardware to provide these addresses, so normally
+MAC addresses will be invented. That means that each time the eCos
+application is run it will have different MAC addresses, which makes
+it more difficult to compare the results of different runs. To get
+more deterministic behaviour it is possible to specify the MAC
+addresses in the target definition file:
+ </para>
+ <programlisting>
+synth_device ethernet {
+ eth0 ethertap tap3 00:01:02:03:FE:05
+ eth1 ethertap tap4 00:01:02:03:FE:06
+ &hellip;
+}
+</programlisting>
+ <para>
+During the initialization phase the eCos application will instantiate
+the various network devices. This will cause the I/O auxiliary to load
+the <filename>ethernet.tcl</filename> script and spawn
+<command>rawether</command> processes, which in turn will
+<function>open</function> <filename>/dev/net/tun</filename> and
+perform the appropriate <filename>ioctl</filename> calls. On the Linux
+side there will now be new network interfaces such as
+<varname>tap3</varname>, and these can be configured like any other
+network interface using commands such as <command>ifconfig</command>.
+In addition, if the Linux system is set up with hotplug support then
+it may be possible to arrange for the network interface to become
+active automatically. On a Red Hat Linux system this would require
+files such as
+<filename>/etc/sysconfig/network-scripts/ifcfg-tap3</filename>,
+containing data like:
+ </para>
+ <programlisting>
+DEVICE="tap3"
+BOOTPROTO="none"
+BROADCAST=10.2.2.255
+IPADDR="10.2.2.1"
+NETMASK="255.255.255.0"
+NETWORK=10.2.2.0
+ONBOOT="no"
+</programlisting>
+ <para>
+This gives the Linux interface the address <literal>10.2.2.1</literal>
+on the network <literal>10.2.2.0</literal>. The eCos network device
+should be configured with a compatible address. One way of doing this
+would be to enable <varname>CYGHWR_NET_DRIVER_ETH0_ADDRS</varname>,
+set <varname>CYGHWR_NET_DRIVER_ETH0_ADDRS_IP</varname> to
+<literal>10.2.2.2</literal>, and similarly update the
+<varname>NETMASK</varname>, <varname>BROADCAST</varname>,
+<varname>GATEWAY</varname> and <varname>SERVER</varname> configuration
+options.
+ </para>
+ <para>
+It should be noted that the ethertap facility provides a virtual
+network, and any packets transmitted by the eCos application will
+not appear on a real network. Therefore usually there will no
+accessible DHCP server, and eCos cannot use DHCP or BOOTP to obtain IP
+address information. Instead the eCos configuration should use manual
+or static addresses.
+ </para>
+ <para>
+When <command>rawether</command> exits, the tap interface is removed
+by the kernel. By adding the parameter persistent
+<command>rawether</command> will set the persistent flag on the tap
+device.
+ </para>
+ <programlisting>
+synth_device ethernet {
+ eth0 ethertap tap3 00:01:02:03:FE:05
+ eth1 ethertap tap4 00:01:02:03:FE:06 persistent
+ &hellip;
+}
+</programlisting>
+ <para>
+With this flag set the kernel will not remove the interface when
+<command>rawether</command> exits. This means applications such as
+<command>dhcpd</command>, <command>radvd</command>, and
+<command>tcpdump</command> will continue to run on the interface
+between invocations of synthetic targets. As a result the target can
+dynamically obtain its IP addresses from these daemons. Note it is a
+good idea to specify a MAC address otherwise a different random MAC
+address will be used each time and the dhcpd daemon will not be able
+to reissue the same IP address.
+ </para>
+ <para>
+Host daemons like dhcpd, ntpd, radvd etc are started at boot
+time. Since the tap device does not exists at this point in time it is
+not possible for these daemons to bind to the tap device. A simple
+solution is to use the program
+<command>install/bin/mktap</command>. This takes one parameter, the
+name of the tap device it should create. eg,
+<literal>tap3</literal>.
+ </para>
+ <para>
+An alternative approach would be to set up the Linux box as a network
+bridge, using commands like <command>brctl</command> to connect the
+virtual network interface <varname>tap3</varname> to a physical
+network interface such as <varname>eth0</varname>. Any packets sent by
+the eCos application will get forwarded automatically to the real
+network, and some packets on the real network will get forwarded over
+the virtual network to the eCos application. Note that the eCos
+application might also get some packets that were not intended for it,
+but usually those will just be discarded by the eCos TCP/IP stack. The
+exact details of setting up a network bridge are left as an exercise
+to the reader.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-ecosynth-logging"><title>Packet Logging</title>
+ <para>
+The ethernet support comes with support for logging the various
+packets that are transferred, including a simple protocol analyser.
+This generates simple text output using the filter mechanisms provided
+by the I/O auxiliary, so it is possible to control the appearance and
+visibility of different types of output. For example the user might
+want to see IPv4 headers and all ICMPv4 and ARP operations, but not
+TCP headers or any of the packet data.
+ </para>
+ <para>
+The protocol analyser is not intended to be a fully functional
+analyser with knowledge of many different TCP/IP protocols, advanced
+search facilities, graphical traffic displays, and so on.
+Functionality like that is already provided by other tools such as
+<application>ethereal</application> and
+<application>tcpdump</application>. Achieving similar levels of
+functionality would require a lot of work, for very little gain. It is
+still useful to have some protocol analysis functionality available
+because the output will be interleaved with other output, for example
+<filename>printf</filename> calls from the application. That may make
+it easier to understand the sequence of events.
+ </para>
+ <para>
+One problem with logging ethernet traffic is that it can involve very
+large amounts of data. If the application is expected to run for a
+long time or is very I/O intensive then it is easy to end up with many
+megabytes. When running in graphical mode all the logging data will be
+held in memory, even data that is not currently visible. At some point
+the system will begin to run low on memory and performance will
+suffer. To avoid problems, the ethernet script maintains a flag that
+controls whether or not packet logging is active. The default is to
+run with logging disabled, but this can be changed in the target
+definition file:
+ </para>
+ <programlisting>
+synth_device ethernet {
+ &hellip;
+ logging 1
+}
+</programlisting>
+ <para>
+The ethernet script will add a toolbar button that allows this flag to
+be changed at run-time, allowing the user to capture traffic for
+certain periods of time while the application continues running.
+ </para>
+ <para>
+The target definition file can contain the following entries for the
+various packet logging filters:
+ </para>
+ <programlisting width=72>
+synth_device ethernet {
+ &hellip;
+ filter ether -hide 0 -background LightBlue -foreground "#000080"
+ filter arp -hide 0 -background LightBlue -foreground "#000050"
+ filter ipv4 -hide 0 -background LightBlue -foreground "#000040"
+ filter ipv6 -hide 1 -background LightBlue -foreground "#000040"
+ filter icmpv4 -hide 0 -background LightBlue -foreground "#000070"
+ filter icmpv6 -hide 1 -background LightBlue -foreground "#000070"
+ filter udp -hide 0 -background LightBlue -foreground "#000030"
+ filter tcp -hide 0 -background LightBlue -foreground "#000020"
+ filter hexdata -hide 1 -background LightBlue -foreground "#000080"
+ filter asciidata -hide 1 -background LightBlue -foreground "#000080"
+}
+</programlisting>
+ <para>
+All output will show the eCos network device, for example
+<literal>eth0</literal>, and the direction relative to the eCos
+application. Some of the filters will show packet headers, for example
+<literal>ether</literal> gives details of the ethernet packet header
+and <literal>tcp</literal> gives information about TCP headers such as
+whether or not the SYN flag is set. The TCP and UDP filters will also
+show source and destination addresses, using numerical addresses and
+if possible host names. However, host names will only be shown if the
+host appears in <filename>/etc/hosts</filename>: doing full DNS
+lookups while the data is being captured would add significantly to
+complexity and overhead. The <literal>hexdata</literal> and
+<literal>asciidata</literal> filters show the remainder of the packets
+after the ethernet, IP and TCP or UDP headers have been stripped.
+ </para>
+ <para>
+Some of the filters will provide raw dumps of some of the packet data.
+Showing up to 1500 bytes of data for each packet would be expensive,
+and often the most interesting information is near the start of the
+packet. Therefore it is possible to set a limit on the number of bytes
+that will be shown using the target definition file. The default limit
+is 64 bytes.
+ </para>
+ <programlisting width=72>
+synth_device ethernet {
+ &hellip;
+ max_show 128
+}
+</programlisting>
+ </refsect1>
+
+ <refsect1 id="devs-eth-ecosynth-gui"><title>User Interface Additions</title>
+ <para>
+When running in graphical mode the ethernet script extends the user
+interface in two ways: a button is added to the toolbar so that users
+can enable or disable packet logging; and an entry is added to the
+<guimenu>Help</guimenu> menu for the ethernet-specific documentation.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-ecosynth-args"><title>Command Line Arguments</title>
+ <para>
+The synthetic target ethernet support does not use any command line
+arguments. All configuration is handled through the target definition
+file.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-ecosynth-hooks"><title>Hooks</title>
+ <para>
+The ethernet support defines two hooks that can be used by other
+scripts, especially user scripts: <literal>ethernet_tx</literal> and
+<literal>ethernet_rx</literal>. The tx hook is called whenever eCos
+tries to transmit a packet. The rx hook is called whenever an incoming
+packet is passed to the eCos application. Note that this may be a
+little bit after the packet was actually received by the I/O auxiliary
+since it can buffer some packets. Both hooks are called with two
+arguments, the name of the network device and the packet being
+transferred. Typical usage might look like:
+ </para>
+ <programlisting>
+ proc my_tx_hook { arg_list } {
+ set dev [lindex $arg_list 0]
+ incr ::my_ethernet_tx_packets($dev)
+ incr ::my_ethernet_tx_bytes($dev) [string length [lindex $arg_list 1]]
+ }
+ proc my_rx_hook { arg_list } {
+ set dev [lindex $arg_list 0]
+ incr ::my_ethernet_rx_packets($dev)
+ incr ::my_ethernet_rx_bytes($dev) [string length [lindex $arg_list 1]]
+ }
+ synth::hook_add "ethernet_tx" my_tx_hook
+ synth::hook_add "ethernet_rx" my_rx_hook
+</programlisting>
+ <para>
+The global arrays <varname>my_ethernet_tx_packets</varname> etc. will
+now be updated whenever there is ethernet traffic. Other code,
+probably running at regular intervals by use of the Tcl
+<command>after</command> procedure, can then use this information to
+update a graphical monitor of some sort.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-eth-ecosynth-tcl"><title>Additional Tcl Procedures</title>
+ <para>
+The ethernet support provides one additional Tcl procedure that can be
+used by other scripts;
+ </para>
+ <programlisting>
+ethernet::devices_get_list
+</programlisting>
+ <para>
+This procedure returns a list of the ethernet devices that have been
+instantiated, for example <literal>{eth0 eth1}</literal>.
+ </para>
+ </refsect1>
+
+</refentry>
+</part>
+<!-- /reference -->
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/Makefile.am b/ecos/packages/devs/eth/synth/ecosynth/current/host/Makefile.am
new file mode 100644
index 0000000..a0583fe
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/Makefile.am
@@ -0,0 +1,94 @@
+## Process this file with automake to produce Makefile.in
+## =====================================================================
+##
+## Makefile.am
+##
+## Build support for the host-side synthetic target support,
+## the ethernetpackage.
+##
+## =====================================================================
+# ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of the eCos host tools.
+# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street,
+# Fifth Floor, Boston, MA 02110-1301, USA.
+# -------------------------------------------
+# ####ECOSHOSTGPLCOPYRIGHTEND####
+## =====================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): bartv
+## Contact(s): bartv
+## Date: 2002/08/07
+## Version: 0.01
+##
+######DESCRIPTIONEND####
+## =====================================================================
+
+AUTOMAKE_OPTIONS = 1.10 foreign
+
+## Only some platforms are supported. Having the configure script throw
+## an error when attempting to configure on an unsupported platform
+## would be a mistake, since that would prevent any configury from
+## the toplevel on unsupported platforms. Instead an automake conditional
+## is used, leading to null makefiles on unsupported platforms.
+
+AM_CFLAGS = @ecos_CFLAGS@ -DECOSYNTH_VERSION=\"@VERSION@\" \
+ -DECOS_REPOSITORY=\"@ECOS_REPOSITORY@\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DPKG_DIR=\"@PACKAGE_DIR@\" \
+ -DPKG_VERSION=\"@PACKAGE_VERSION@\" \
+ -DPKG_INSTALL=\"@PACKAGE_INSTALL@\"
+AM_CXXFLAGS = @ecos_CXXFLAGS@
+INCLUDES = @ecos_INCLUDES@
+LIBS = @ecos_LIBS@ @ecos_LDADD@
+
+if SUPPORTED
+## The synthetic target support consists of a single program rawether,
+## a number of Tcl scripts, and some additional data files. These are
+## all installed in a single directory $(libexec)/ecos/<package>_<version>/
+## Neither the rawether executable nor any of the scripts are directly
+## executable, instead rawether gets fork()'d/execve()'d by the Tcl
+## script so $(libexec) is appropriate. Strictly speaking the
+## Tcl scripts and data files are architecture-independent so should
+## probably be installed in an analogous directory below $(datadir),
+## but that would add more directories for little real gain. The scripts
+## are treated as data files since they should not be executed directly,
+## i.e. they should not be installed with the execute bit set.
+
+etherdir = $(libexecdir)/ecos/@PACKAGE_INSTALL@
+ether_PROGRAMS = rawether
+ether_DATA = ethernet.tcl ethernet.tdf netrecord.xbm
+
+rawether_SOURCES = rawether.c
+
+## Manual dependencies
+rawether.$(OBJEXT) : Makefile ../src/protocol.h
+
+## The rawether program needs to run with root privileges, or it will
+## be unable to access the ethernet hardware.
+install-data-hook:
+ chown root $(etherdir)/rawether
+ chmod u+s $(etherdir)/rawether
+
+else
+## When automake scans for hooks it does not take conditionals fully
+## into account. If the conditional is not satisfied the generated
+## makefile will still try to invoke the hook, so dummy hooks are needed.
+install-data-hook:
+ echo Nothing to be done for this platform
+endif
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/Makefile.in b/ecos/packages/devs/eth/synth/ecosynth/current/host/Makefile.in
new file mode 100644
index 0000000..2b2109f
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/Makefile.in
@@ -0,0 +1,721 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of the eCos host tools.
+# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street,
+# Fifth Floor, Boston, MA 02110-1301, USA.
+# -------------------------------------------
+# ####ECOSHOSTGPLCOPYRIGHTEND####
+#######DESCRIPTIONBEGIN####
+######DESCRIPTIONEND####
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@SUPPORTED_TRUE@ether_PROGRAMS = rawether$(EXEEXT)
+subdir = .
+DIST_COMMON = $(am__configure_deps) \
+ $(srcdir)/../../../../../../../acsupport/config.guess \
+ $(srcdir)/../../../../../../../acsupport/config.sub \
+ $(srcdir)/../../../../../../../acsupport/depcomp \
+ $(srcdir)/../../../../../../../acsupport/install-sh \
+ $(srcdir)/../../../../../../../acsupport/missing \
+ $(srcdir)/../../../../../../../acsupport/mkinstalldirs \
+ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/configure \
+ ../../../../../../../acsupport/ChangeLog \
+ ../../../../../../../acsupport/config.guess \
+ ../../../../../../../acsupport/config.sub \
+ ../../../../../../../acsupport/depcomp \
+ ../../../../../../../acsupport/install-sh \
+ ../../../../../../../acsupport/ltconfig \
+ ../../../../../../../acsupport/ltmain.sh \
+ ../../../../../../../acsupport/missing \
+ ../../../../../../../acsupport/mkinstalldirs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/../../../../../../../acsupport/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(SHELL) \
+ $(top_srcdir)/../../../../../../../acsupport/mkinstalldirs
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(etherdir)" "$(DESTDIR)$(etherdir)"
+PROGRAMS = $(ether_PROGRAMS)
+am__rawether_SOURCES_DIST = rawether.c
+@SUPPORTED_TRUE@am_rawether_OBJECTS = rawether.$(OBJEXT)
+rawether_OBJECTS = $(am_rawether_OBJECTS)
+rawether_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) \
+ $(top_srcdir)/../../../../../../../acsupport/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(rawether_SOURCES)
+DIST_SOURCES = $(am__rawether_SOURCES_DIST)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+DATA = $(ether_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d "$(distdir)" \
+ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr "$(distdir)"; }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECOS_REPOSITORY = @ECOS_REPOSITORY@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @ecos_LIBS@ @ecos_LDADD@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSVC_SRCDIR = @MSVC_SRCDIR@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_DIR = @PACKAGE_DIR@
+PACKAGE_INSTALL = @PACKAGE_INSTALL@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+ecos_CFLAGS = @ecos_CFLAGS@
+ecos_CXXFLAGS = @ecos_CXXFLAGS@
+ecos_INCLUDES = @ecos_INCLUDES@
+ecos_LDADD = @ecos_LDADD@
+ecos_LIBS = @ecos_LIBS@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = 1.10 foreign
+AM_CFLAGS = @ecos_CFLAGS@ -DECOSYNTH_VERSION=\"@VERSION@\" \
+ -DECOS_REPOSITORY=\"@ECOS_REPOSITORY@\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DPKG_DIR=\"@PACKAGE_DIR@\" \
+ -DPKG_VERSION=\"@PACKAGE_VERSION@\" \
+ -DPKG_INSTALL=\"@PACKAGE_INSTALL@\"
+
+AM_CXXFLAGS = @ecos_CXXFLAGS@
+INCLUDES = @ecos_INCLUDES@
+@SUPPORTED_TRUE@etherdir = $(libexecdir)/ecos/@PACKAGE_INSTALL@
+@SUPPORTED_TRUE@ether_DATA = ethernet.tcl ethernet.tdf netrecord.xbm
+@SUPPORTED_TRUE@rawether_SOURCES = rawether.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+install-etherPROGRAMS: $(ether_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(etherdir)" || $(MKDIR_P) "$(DESTDIR)$(etherdir)"
+ @list='$(ether_PROGRAMS)'; test -n "$(etherdir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(etherdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(etherdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-etherPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ether_PROGRAMS)'; test -n "$(etherdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(etherdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(etherdir)" && rm -f $$files
+
+clean-etherPROGRAMS:
+ -test -z "$(ether_PROGRAMS)" || rm -f $(ether_PROGRAMS)
+rawether$(EXEEXT): $(rawether_OBJECTS) $(rawether_DEPENDENCIES)
+ @rm -f rawether$(EXEEXT)
+ $(LINK) $(rawether_OBJECTS) $(rawether_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rawether.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+install-etherDATA: $(ether_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(etherdir)" || $(MKDIR_P) "$(DESTDIR)$(etherdir)"
+ @list='$(ether_DATA)'; test -n "$(etherdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(etherdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(etherdir)" || exit $$?; \
+ done
+
+uninstall-etherDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ether_DATA)'; test -n "$(etherdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(etherdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(etherdir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @$(am__cd) '$(distuninstallcheck_dir)' \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(etherdir)" "$(DESTDIR)$(etherdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-etherPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-etherDATA install-etherPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-etherDATA uninstall-etherPROGRAMS
+
+.MAKE: install-am install-data-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
+ clean-etherPROGRAMS clean-generic ctags dist dist-all \
+ dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ dist-xz \
+ dist-zip distcheck distclean distclean-compile \
+ distclean-generic distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am \
+ install-data-hook install-dvi install-dvi-am install-etherDATA \
+ install-etherPROGRAMS install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
+ ps ps-am tags uninstall uninstall-am uninstall-etherDATA \
+ uninstall-etherPROGRAMS
+
+
+@SUPPORTED_TRUE@rawether.$(OBJEXT) : Makefile ../src/protocol.h
+
+@SUPPORTED_TRUE@install-data-hook:
+@SUPPORTED_TRUE@ chown root $(etherdir)/rawether
+@SUPPORTED_TRUE@ chmod u+s $(etherdir)/rawether
+
+@SUPPORTED_FALSE@install-data-hook:
+@SUPPORTED_FALSE@ echo Nothing to be done for this platform
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/acinclude.m4 b/ecos/packages/devs/eth/synth/ecosynth/current/host/acinclude.m4
new file mode 100644
index 0000000..de916cd
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/acinclude.m4
@@ -0,0 +1,43 @@
+dnl Process this file with aclocal to get an aclocal.m4 file. Then
+dnl process that with autoconf.
+dnl ====================================================================
+dnl
+dnl acinclude.m4
+dnl
+dnl ====================================================================
+dnl ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+dnl -------------------------------------------
+dnl This file is part of the eCos host tools.
+dnl Copyright (C) 2002 Free Software Foundation, Inc.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 or (at your option) any
+dnl later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the
+dnl Free Software Foundation, Inc., 51 Franklin Street,
+dnl Fifth Floor, Boston, MA 02110-1301, USA.
+dnl -------------------------------------------
+dnl ####ECOSHOSTGPLCOPYRIGHTEND####
+dnl ====================================================================
+dnl#####DESCRIPTIONBEGIN####
+dnl
+dnl Author(s): bartv
+dnl Contact(s): bartv
+dnl Date: 2002/08/07
+dnl Version: 0.01
+dnl
+dnl####DESCRIPTIONEND####
+dnl ====================================================================
+
+dnl Access shared macros.
+dnl AM_CONDITIONAL needs to be mentioned here or else aclocal does not
+dnl incorporate the macro into aclocal.m4
+sinclude(../../../../../../../acsupport/acinclude.m4)
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/aclocal.m4 b/ecos/packages/devs/eth/synth/ecosynth/current/host/aclocal.m4
new file mode 100644
index 0000000..4cbba05
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/aclocal.m4
@@ -0,0 +1,992 @@
+# generated automatically by aclocal 1.11 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.63],,
+[m4_warning([this file was generated for autoconf 2.63.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/configure b/ecos/packages/devs/eth/synth/ecosynth/current/host/configure
new file mode 100755
index 0000000..dc5c874
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/configure
@@ -0,0 +1,6403 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.63.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+ if (eval ":") 2>/dev/null; then
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+
+ if test $as_have_required = yes && (eval ":
+(as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=\$LINENO
+ as_lineno_2=\$LINENO
+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+ :
+else
+ as_candidate_shells=
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ case $as_dir in
+ /*)
+ for as_base in sh bash ksh sh5; do
+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+ done;;
+ esac
+done
+IFS=$as_save_IFS
+
+
+ for as_shell in $as_candidate_shells $SHELL; do
+ # Try only shells that exist, to save several forks.
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+ CONFIG_SHELL=$as_shell
+ as_have_required=yes
+ if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+ (exit $1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+ break
+fi
+
+fi
+
+ done
+
+ if test "x$CONFIG_SHELL" != x; then
+ for as_var in BASH_ENV ENV
+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ done
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+ if test $as_have_required = no; then
+ echo This script requires a shell more modern than all the
+ echo shells that I found on your system. Please install a
+ echo modern shell, or manually run the script under such a
+ echo shell if you do have one.
+ { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+ echo No shell found that supports shell functions.
+ echo Please tell bug-autoconf@gnu.org about your system,
+ echo including any error possibly output before this message.
+ echo This can help us improve future autoconf versions.
+ echo Configuration will now proceed without shell functions.
+}
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="rawether.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+SUPPORTED_FALSE
+SUPPORTED_TRUE
+EGREP
+GREP
+CPP
+PACKAGE_INSTALL
+PACKAGE_DIR
+ECOS_REPOSITORY
+MSVC_FALSE
+MSVC_TRUE
+MSVC_SRCDIR
+ecos_LIBS
+ecos_INCLUDES
+ecos_LDADD
+ecos_CXXFLAGS
+ecos_CFLAGS
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+enable_dependency_tracking
+enable_debug
+enable_ansi
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { $as_echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { $as_echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2
+ { (exit 1); exit 1; }; } ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ { $as_echo "$as_me: error: working directory cannot be determined" >&2
+ { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ { $as_echo "$as_me: error: pwd does not report name of working directory" >&2
+ { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2
+ { (exit 1); exit 1; }; }
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-debug do a debug rather than a release build
+ --enable-ansi do an ANSI rather than a unicode build
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.63
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.63. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args '$ac_arg'"
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_aux_dir=
+for ac_dir in ../../../../../../../acsupport "$srcdir"/../../../../../../../acsupport; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in ../../../../../../../acsupport \"$srcdir\"/../../../../../../../acsupport" >&5
+$as_echo "$as_me: error: cannot find install-sh or install.sh in ../../../../../../../acsupport \"$srcdir\"/../../../../../../../acsupport" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking that a separate build tree is being used" >&5
+$as_echo_n "checking that a separate build tree is being used... " >&6; }
+ ecos_cwd=`/bin/pwd`
+ if test "${srcdir}" = "." ; then
+ srcdir=${ecos_cwd}
+ fi
+ if test "${ecos_cwd}" = "${srcdir}" ; then
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:$LINENO: error: This configure script should not be run inside the source tree. Instead please use a separate build tree" >&5
+$as_echo "$as_me: error: This configure script should not be run inside the source tree. Instead please use a separate build tree" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ { { $as_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
+$as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
+ { (exit 1); exit 1; }; }
+
+{ $as_echo "$as_me:$LINENO: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ { { $as_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+$as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+ { (exit 1); exit 1; }; }
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
+$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
+$as_echo "$as_me: error: invalid value of canonical build" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:$LINENO: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+$as_echo "$as_me: error: invalid value of canonical host" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+am__api_version='1.11'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ { { $as_echo "$as_me:$LINENO: error: unsafe absolute working directory name" >&5
+$as_echo "$as_me: error: unsafe absolute working directory name" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ { { $as_echo "$as_me:$LINENO: error: unsafe srcdir value: \`$srcdir'" >&5
+$as_echo "$as_me: error: unsafe srcdir value: \`$srcdir'" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&5
+$as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+$as_echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+{ $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:$LINENO: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+done
+IFS=$as_save_IFS
+
+fi
+
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ test -d ./--version && rmdir ./--version
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:$LINENO: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+$as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=eCos_synthetic_target_ethernet
+ VERSION=0.1
+
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+{ $as_echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+
+{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_c89=$ac_arg
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:$LINENO: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:$LINENO: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:$LINENO: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CXXFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CXX" am_compiler_list=
+
+{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CXX_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+ am__fastdepCXX_TRUE=
+ am__fastdepCXX_FALSE='#'
+else
+ am__fastdepCXX_TRUE='#'
+ am__fastdepCXX_FALSE=
+fi
+
+
+
+
+
+ ecos_CFLAGS=""
+ ecos_CXXFLAGS=""
+ ecos_LDADD=""
+ ecos_INCLUDES=""
+ ecos_LIBS=""
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking \"for Visual C++\"" >&5
+$as_echo_n "checking \"for Visual C++\"... " >&6; }
+ MSVC="no";
+ if test "${CC}" = "cl" ; then
+ MSVC="yes"
+ CXX="cl"
+ MSVC_SRCDIR=${srcdir}
+
+
+ if test "${MSVC}" = "yes" ; then
+ MSVC_SRCDIR=`cygpath -w ${MSVC_SRCDIR} | tr \\\\\\\\ /`
+ fi
+
+
+ ecos_INCLUDES="${ecos_INCLUDES} \"-I${MSVC_SRCDIR}\""
+ ecos_LDADD="-link"
+ ecos_LIBS="advapi32.lib"
+ fi
+ if test "${MSVC}" = "yes"; then
+ MSVC_TRUE=
+ MSVC_FALSE='#'
+else
+ MSVC_TRUE='#'
+ MSVC_FALSE=
+fi
+
+ if test "${MSVC}" = "yes" ; then
+ { $as_echo "$as_me:$LINENO: result: unfortunately yes" >&5
+$as_echo "unfortunately yes" >&6; }
+ else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking \"the default compiler flags\"" >&5
+$as_echo_n "checking \"the default compiler flags\"... " >&6; }
+
+ ecosflags_enable_debug="no"
+ # Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then
+ enableval=$enable_debug; case "${enableval}" in
+ yes) ecosflags_enable_debug="yes" ;;
+ *) ecosflags_enable_debug="no" ;;
+ esac
+fi
+
+
+ ecosflags_enable_ansi="no"
+ if test "${MSVC}" = "yes" ; then
+ # Check whether --enable-ansi was given.
+if test "${enable_ansi+set}" = set; then
+ enableval=$enable_ansi; case "${enableval}" in
+ yes) ecosflags_enable_ansi="yes" ;;
+ *) ecosflags_enable_ansi="no" ;;
+ esac
+fi
+
+ fi
+
+ if test "${GCC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -pipe -Wall -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -pipe -Wall -Wpointer-arith -Wcast-qual -Woverloaded-virtual"
+ elif test "${MSVC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -nologo -W3"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -nologo -W3 -GR -GX"
+ else
+ { { $as_echo "$as_me:$LINENO: error: \"default flags for ${CC} are not known\"" >&5
+$as_echo "$as_me: error: \"default flags for ${CC} are not known\"" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ if test "${ecosflags_enable_debug}" = "yes" ; then
+ if test "${GCC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -g -O0"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -g -O0"
+ elif test "${MSVC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -MDd -Zi"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -MDd -Zi"
+ fi
+ else
+ if test "${GCC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -O2"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -O2"
+ elif test "${MSVC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -MD -O2"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -MD -O2"
+ fi
+ fi
+
+ CFLAGS="${ac_save_CFLAGS}"
+ CXXFLAGS="${ac_save_CXXFLAGS}"
+
+ { $as_echo "$as_me:$LINENO: result: done" >&5
+$as_echo "done" >&6; }
+
+
+
+ package_dir=`cd ${srcdir} && /bin/pwd`
+ PACKAGE_VERSION=`dirname ${package_dir}`
+ PACKAGE_VERSION=`basename ${PACKAGE_VERSION}`
+
+ package_dir=`dirname ${package_dir}`
+ package_dir=`dirname ${package_dir}`
+
+ possibles="${package_dir}/.. ${package_dir}/../.. ${package_dir}/../../.. ${package_dir}/../../../.."
+ possibles="${possibles} ${package_dir}/../../../../.. ${package_dir}/../../../../../.."
+
+ repository_root=""
+ for i in ${possibles}; do
+ if test -d "$i/"acsupport""; then
+ repository_root=$i
+ break
+ fi
+ done
+
+ if test "${repository_root}" = "" ; then
+ { { $as_echo "$as_me:$LINENO: error: Failed to identify this package's position within the eCos repository" >&5
+$as_echo "$as_me: error: Failed to identify this package's position within the eCos repository" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ ECOS_REPOSITORY=`cd "${repository_root}/packages/pkgconf/.." && /bin/pwd`
+
+ PACKAGE_DIR=`echo ${package_dir} | sed -e "s:${ECOS_REPOSITORY}/::"`
+
+ PACKAGE_INSTALL="${PACKAGE_DIR}/${PACKAGE_VERSION}"
+
+
+
+
+
+
+
+case "${host}" in
+ i[34567]86-*-linux-gnu* ) SUPPORTED="yes";;
+ x86_64-*-linux-gnu* ) SUPPORTED="yes";;
+ * ) SUPPORTED="no"
+esac
+if test "${SUPPORTED}" = "no" ; then
+ { $as_echo "$as_me:$LINENO: WARNING: Synthetic target ethernet support is only available on x86 Linux hosts" >&5
+$as_echo "$as_me: WARNING: Synthetic target ethernet support is only available on x86 Linux hosts" >&2;}
+fi
+
+if test "${SUPPORTED}" = "yes" ; then
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:$LINENO: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:$LINENO: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_header_stdc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ eval "$as_ac_Header=yes"
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in "linux/if_tun.h"
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+as_val=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ TAP_SUPPORTED="yes"
+else
+ TAP_SUPPORTED="no"
+fi
+
+done
+
+ if test "${TAP_SUPPORTED}" = "no" ; then
+ { $as_echo "$as_me:$LINENO: WARNING: No <linux/if_tun.h> header, ethertap support disabled." >&5
+$as_echo "$as_me: WARNING: No <linux/if_tun.h> header, ethertap support disabled." >&2;}
+ fi
+fi
+
+if test "${SUPPORTED}" = "no" ; then
+ { $as_echo "$as_me:$LINENO: WARNING: The synthetic ethernet support cannot be built on this platform." >&5
+$as_echo "$as_me: WARNING: The synthetic ethernet support cannot be built on this platform." >&2;}
+fi
+
+ if test "${SUPPORTED}" = "yes"; then
+ SUPPORTED_TRUE=
+ SUPPORTED_FALSE='#'
+else
+ SUPPORTED_TRUE='#'
+ SUPPORTED_FALSE=
+fi
+
+
+
+ac_config_files="$ac_config_files Makefile:Makefile.in"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${MSVC_TRUE}" && test -z "${MSVC_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"MSVC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"MSVC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${SUPPORTED_TRUE}" && test -z "${SUPPORTED_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"SUPPORTED\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"SUPPORTED\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.63. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTION]... [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.63,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_FILES="$CONFIG_FILES '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { $as_echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile:Makefile.in" ;;
+
+ *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ $as_echo "$as_me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=' '
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5
+$as_echo "$as_me: error: could not setup config files machinery" >&2;}
+ { (exit 1); exit 1; }; }
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5
+$as_echo "$as_me: error: invalid tag $ac_tag" >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ ac_file_inputs="$ac_file_inputs '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:$LINENO: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+
+
+ :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir=$dirpart/$fdir
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+
+ esac
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/configure.in b/ecos/packages/devs/eth/synth/ecosynth/current/host/configure.in
new file mode 100644
index 0000000..5ff7a99
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/configure.in
@@ -0,0 +1,94 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl ====================================================================
+dnl
+dnl configure.in
+dnl
+dnl configure script for eCos synthetic target ethernet
+dnl host-side support
+dnl
+dnl ====================================================================
+dnl ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+dnl -------------------------------------------
+dnl This file is part of the eCos host tools.
+dnl Copyright (C) 2002 Free Software Foundation, Inc.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 or (at your option) any
+dnl later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the
+dnl Free Software Foundation, Inc., 51 Franklin Street,
+dnl Fifth Floor, Boston, MA 02110-1301, USA.
+dnl -------------------------------------------
+dnl ####ECOSHOSTGPLCOPYRIGHTEND####
+dnl ====================================================================
+dnl#####DESCRIPTIONBEGIN####
+dnl
+dnl Author(s): bartv
+dnl Contact(s): bartv
+dnl Date: 2002/08/07
+dnl Version: 0.01
+dnl
+dnl####DESCRIPTIONEND####
+dnl ====================================================================
+
+
+AC_INIT(rawether.c)
+
+dnl Pick up the support files from the top-level acsupport directory.
+AC_CONFIG_AUX_DIR(../../../../../../../acsupport)
+
+ECOS_CHECK_BUILD_ne_SRC
+AC_CANONICAL_HOST
+AM_INIT_AUTOMAKE(eCos_synthetic_target_ethernet,0.1,0)
+AM_MAINTAINER_MODE
+AC_PROG_CC
+AC_PROG_CXX
+AC_OBJEXT
+AC_EXEEXT
+ECOS_PROG_MSVC
+ECOS_PROG_STANDARD_COMPILER_FLAGS
+ECOS_PACKAGE_DIRS
+
+dnl The current version of the synthetic target is implemented only for
+dnl x86 Linux platforms, so a test is appropriate here. However
+dnl it is not a good idea for the configure script to report an error:
+dnl that would prevent any top-level configury working for other
+dnl platforms. Instead an automake conditional is used to suppress adding
+dnl targets to the build.
+case "${host}" in
+ i[[34567]]86-*-linux-gnu* ) SUPPORTED="yes";;
+ x86_64-*-linux-gnu* ) SUPPORTED="yes";;
+ * ) SUPPORTED="no"
+esac
+if test "${SUPPORTED}" = "no" ; then
+ AC_MSG_WARN([Synthetic target ethernet support is only available on x86 Linux hosts])
+fi
+
+if test "${SUPPORTED}" = "yes" ; then
+ dnl Old kernels may not have tun/tap support. rawether can
+ dnl still operate via a spare ethernet interface.
+ AC_CHECK_HEADERS("linux/if_tun.h",TAP_SUPPORTED="yes",TAP_SUPPORTED="no")
+ if test "${TAP_SUPPORTED}" = "no" ; then
+ AC_MSG_WARN([No <linux/if_tun.h> header, ethertap support disabled.])
+ fi
+fi
+
+if test "${SUPPORTED}" = "no" ; then
+ AC_MSG_WARN([The synthetic ethernet support cannot be built on this platform.])
+fi
+
+AM_CONDITIONAL(SUPPORTED, test "${SUPPORTED}" = "yes")
+
+dnl There is no real need for a config.h file at this time, since the code
+dnl is specific to x86 Linux. This may change in future.
+dnl AM_CONFIG_HEADER(config.h:config.h.in)
+
+AC_OUTPUT(Makefile:Makefile.in)
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/ethernet.tcl b/ecos/packages/devs/eth/synth/ecosynth/current/host/ethernet.tcl
new file mode 100644
index 0000000..eec60f1
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/ethernet.tcl
@@ -0,0 +1,1224 @@
+# {{{ Banner
+
+# ============================================================================
+#
+# ethernet.tcl
+#
+# Ethernet support for the eCos synthetic target I/O auxiliary
+#
+# ============================================================================
+# ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of the eCos host tools.
+# Copyright (C) 2002 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street,
+# Fifth Floor, Boston, MA 02110-1301, USA.
+# -------------------------------------------
+# ####ECOSHOSTGPLCOPYRIGHTEND####
+# ============================================================================
+# #####DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Contact(s): bartv
+# Date: 2002/08/07
+# Version: 0.01
+# Description:
+# Implementation of the ethernet device. This script should only ever
+# be run from inside the ecosynth auxiliary.
+#
+# ####DESCRIPTIONEND####
+# ============================================================================
+
+# }}}
+
+# Overview.
+#
+# Linux provides a number of different ways of performing low-level
+# ethernet I/O from user space, including accessing an otherwise
+# unused ethernet card via a PF_PACKET socket, and the tap facility.
+# The necessary functionality is not readily accessible from Tcl,
+# and performing this low-level I/O generally requires special
+# privileges. Therefore the actual I/O happens in a C program
+# rawether, installed suid root,
+#
+# The synthetic ethernet package supports up to four ethernet devices,
+# eth0 to eth3. The target definition file maps these onto the
+# underlying I/O facility. Instantiation requires spawning a rawether
+# process with appropriate arguments, and then waiting for a message
+# from that process indicating whether or not the instantiation
+# succeeded. That message includes the MAC address. A file event
+# handler is installed to handle data detected by raw ether.
+#
+# eCos can send a number of requests: transmit a packet, start the
+# interface (possibly in promiscuous mode), stop the interface,
+# or get the various parameters such as the MAC address. All those
+# requests can just be passed on to the rawether process. Incoming
+# ethernet packets are slightly more complicated: rawether will
+# immediately pass these up to this Tcl script, which will buffer
+# the packets until they are requested by eCos; in addition an
+# interrupt will be raised.
+
+namespace eval ethernet {
+ # The protocol between eCos and this script.
+ variable SYNTH_ETH_TX 0x01
+ variable SYNTH_ETH_RX 0x02
+ variable SYNTH_ETH_START 0x03
+ variable SYNTH_ETH_STOP 0x04
+ variable SYNTH_ETH_GETPARAMS 0x05
+ variable SYNTH_ETH_MULTIALL 0x06
+
+ # This array holds all the interesting data for all the
+ # interfaces, indexed by the instance id. It is also useful
+ # to keep track of the instance id's associated with ethernet
+ # devices.
+ array set data [list]
+ set ids [list]
+
+ # One-off initialization, for example loading images. If this fails
+ # then all attempts at instantiation will fail as well.
+ variable init_ok 1
+ variable install_dir $synth::device_install_dir
+ variable rawether_executable [file join $ethernet::install_dir "rawether"]
+
+ if { ![file exists $rawether_executable] } {
+ synth::report_error "Ethernet device, rawether executable has not been installed in $ethernet::install_dir.\n"
+ set init_ok 0
+ } elseif { ![file executable $rawether_executable] } {
+ synth::report_error "Ethernet device, installed program $rawether_executable is not executable.\n"
+ set init_ok 0
+ }
+
+ if { $synth::flag_gui } {
+ foreach _image [list "netrecord.xbm"] {
+ variable image_[file rootname $_image]
+ if { ! [synth::load_image "ethernet::image_[file rootname $_image]" [file join $ethernet::install_dir $_image]] } {
+ set init_ok 0
+ }
+ }
+ unset _image
+ }
+
+ # Maximum number of packets that should be buffered per interface.
+ # This can be changed in the target definition
+ variable max_buffered_packets 16
+
+ if { [synth::tdf_has_option "ethernet" "max_buffer"] } {
+ set ethernet::max_buffered_packets [synth::tdf_get_option "ethernet" "max_buffer"]
+ if { ![string is integer -strict $ethernet::max_buffered_packets] } {
+ synth::report_error "Ethernet device, invalid value in target definition file $synth::target_definition\n \
+ Entry max_buffer should be a simple integer, not $ethernet::max_buffered_packets\n"
+ set init_ok 0
+ }
+ }
+
+ # Define hooks for tx and rx packets
+ synth::hook_define "ethernet_tx"
+ synth::hook_define "ethernet_rx"
+
+ # Get a list of known ethernet devices
+ proc devices_get_list { } {
+ set result [list]
+ foreach id $ids {
+ lappend result $::ethernet::data($id,name)
+ }
+ return $result
+ }
+
+ # ----------------------------------------------------------------------------
+ proc instantiate { id name data } {
+ if { ! $ethernet::init_ok } {
+ synth::report_warning "Cannot instantiate ethernet device $name, initialization failed.\n"
+ return ""
+ }
+
+ # id is a small number that uniquely identifies this device. It will
+ # be used as an array index.
+ # name is something like eth0 or eth1
+ # There should be no device-specific data
+
+ # The hard work is done by an auxiliary process which needs to be
+ # spawned off. It requires some additional information to map the
+ # eCos device name on to a suitable Linux network device such
+ # as tap0. That information has to come from the config file.
+ if { ![synth::tdf_has_option "ethernet" $name] } {
+ synth::report_error "Cannot instantiate ethernet device $name\n \
+ No entry in target definition file $synth::target_definition\n"
+ return ""
+ }
+ set use [synth::tdf_get_option "ethernet" $name]
+
+ # Do some validation here, before the rawether process is started.
+ # Typical entries would look like
+ # eth0 real eth1
+ # eth1 ethertap [[tap-device] [MAC] [persistent]]
+ set junk ""
+ set optional ""
+ set mac ""
+ if { [regexp -- {^\s*real\s*[a-zA-z0-9_]+$} $use] } {
+ # Real ethernet.
+ } elseif { [regexp -- {^\s*ethertap\s*(.*)$} $use junk optional ] } {
+ if { "" != $optional } {
+ if { ! [regexp -- {^tap[0-9]+\s*(.*)$} $optional junk mac ] } {
+ synth::report_error "Cannot instantiate ethernet device $name\n \
+ Invalid entry \"$use\" in target definition file $synth::target_definition\n \
+ Should be \"ethertap \[<tap-device> \[<MAC address>\]\] [persistent]\"\n"
+ return ""
+ }
+ if { "" != $mac } {
+ if { ! [regexp -- {^\s*([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}\s*} $mac ] } {
+ synth::report_error "Cannot instantiate ethernet device $name\n \
+ Invalid entry \"$use\" in target definition file $synth::target_definition\n \
+ MAC address should be of the form xx:xx:xx:xx:xx:xx, all hexadecimal digits.\n"
+ return ""
+ }
+ }
+ }
+ } else {
+ synth::report_error "Cannot instantiate ethernet device $name\n \
+ Invalid entry \"$use\" in target definition file $synth::target_definition\n \
+ Should be \"real <Linux ethernet device>\" or \"ethertap \[<tap-device> \[<MAC address>\]\]\"\n"
+ return ""
+ }
+
+ # Now spawn the rawether process. Its stdin and stdout are
+ # pipes connected to ecosynth. Its stderr is redirected to
+ # the current tty to avoid confusion between incoming ethernet
+ # packets and diagnostics.
+ if { [catch { set rawether [open "|$ethernet::rawether_executable $use 2>/dev/tty" w+] } message ] } {
+ synth::report_error "Failed to spawn rawether process for device $name\n $message"
+ return ""
+ }
+
+ # No translation on this pipe please.
+ fconfigure $rawether -translation binary -encoding binary -buffering none
+
+ # Now wait for the rawether device to initialize. It should send back a single
+ # byte, '0' for failure or '1' for success. Failure is followed by a text
+ # message which should be reported. Success is followed by a six-byte MAC
+ # address.
+ set reply [read $rawether 1]
+ if { "" == $reply } {
+ synth::report_error "rawether process for device $name exited unexpectedly.\n"
+ catch { close $rawether }
+ return ""
+ }
+
+ if { "1" != $reply } {
+ set message [read $rawether 1024]
+ synth::report_error "rawether process was unable to initialize eCos device $name ($use)\n $message"
+ catch { close $rawether }
+ return ""
+ }
+
+ set reply [read $rawether 7]
+ if { [string length $reply] != 7 } {
+ synth::report_error "rawether process for eCos device $name ($use) failed to provide the initialization response.\n"
+ catch { close $rawether }
+ return ""
+ }
+ set mac [string range $reply 0 5]
+ set multi [string index $reply 6]
+
+ # Finally allocate an interrupt vector
+ set vector [synth::interrupt_allocate $name]
+ if { -1 == $vector } {
+ # No more interrupts left. An error will have been reported already.
+ catch { close $rawether }
+ return ""
+ }
+
+ # The device is up and running. Fill in the array entries
+ lappend ethernet::ids $id
+ set ethernet::data($id,alive) 1
+ set ethernet::data($id,name) $name
+ set ethernet::data($id,rawether) $rawether
+ set ethernet::data($id,packets) [list]
+ set ethernet::data($id,packet_count) 0
+ set ethernet::data($id,up) 0
+ set ethernet::data($id,interrupt_vector) $vector
+ set ethernet::data($id,MAC) $mac
+ set ethernet::data($id,multi) $multi
+
+ # Set up the event handler to handle incoming packets. There should
+ # not be any until the interface is brought up
+ fileevent $rawether readable [list ethernet::handle_packet $name $id $rawether]
+
+ # Finally return the request handler. The eCos device driver will
+ # automatically get back an ack.
+ return ethernet::handle_request
+ }
+
+ # ----------------------------------------------------------------------------
+ # eCos has sent a request to a device instance. Most of these requests should
+ # just be forwarded to rawether. Some care has to be taken to preserve
+ # packet boundaries and avoid confusion. It is also necessary to worry
+ # about the rawether process exiting unexpectedly, which may cause
+ # puts operations to raise an error (subject to buffering).
+ #
+ # Note: it might actually be more efficient to always send a header plus
+ # 1514 bytes of data, reducing the number of system calls at the cost of
+ # some extra data copying, but with at least two process switches per
+ # ethernet transfer efficiency is not going to be particularly good
+ # anyway.
+
+ proc send_rawether { id packet } {
+ if { $ethernet::data($id,alive) } {
+ set chan $ethernet::data($id,rawether)
+ if { [catch { puts -nonewline $chan $packet } ] } {
+ set ethernet::data($id,alive) 0
+ # No further action is needed here, instead the read handler
+ # will detect EOF and report abnormal termination.
+ }
+ }
+ }
+
+ proc handle_request { id reqcode arg1 arg2 reqdata reqlen reply_len } {
+
+ if { $reqcode == $ethernet::SYNTH_ETH_TX } {
+ # Transmit a single packet. To preserve packet boundaries
+ # this involves a four-byte header containing opcode and
+ # size, followed by the data itself.
+ set header [binary format "ccs" $reqcode 0 [string length $reqdata]]
+ ethernet::send_rawether $id $header
+ ethernet::send_rawether $id $reqdata
+ if { $ethernet::logging_enabled } {
+ ethernet::log_packet $ethernet::data($id,name) "tx" $reqdata
+ }
+ synth::hook_call "ethernet_tx" $ethernet::data($id,name) $reqdata
+
+ } elseif { $reqcode == $ethernet::SYNTH_ETH_RX } {
+ # Return a single packet to eCos, plus a count of the number
+ # of remaining packets. All packets are buffered here, not
+ # in rawether.
+ if { $ethernet::data($id,packet_count) == 0 } {
+ synth::send_reply 0 0 ""
+ } else {
+ incr ethernet::data($id,packet_count) -1
+ set packet [lindex $ethernet::data($id,packets) 0]
+ set ethernet::data($id,packets) [lrange $ethernet::data($id,packets) 1 end]
+ synth::send_reply $ethernet::data($id,packet_count) [string length $packet] $packet
+ if { $ethernet::logging_enabled } {
+ ethernet::log_packet $ethernet::data($id,name) "rx" $packet
+ }
+ synth::hook_call "ethernet_rx" $ethernet::data($id,name) $packet
+ }
+ } elseif { $reqcode == $ethernet::SYNTH_ETH_START } {
+ # Start the interface in either normal or promiscuous
+ # mode, depending on arg1. No reply is expected. Also
+ # mark the interface as up so that any packets transmitted
+ # by rawether will not be discarded
+ set ethernet::data($id,up) 1
+ set header [binary format "ccs" $reqcode $arg1 0]
+ ethernet::send_rawether $id $header
+ } elseif { $reqcode == $ethernet::SYNTH_ETH_STOP } {
+ # Stop the interface. All pending packets should be
+ # discarded and no new packets should be accepted.
+ # No reply is expected so just pass this on to rawether
+ set ethernet::data($id,up) 0
+ set ethernet::data($id,packets) [list]
+ set ethernet::data($id,packet_count) 0
+ set header [binary format "ccs" $reqcode 0 0]
+ ethernet::send_rawether $id $header
+ } elseif { $reqcode == $ethernet::SYNTH_ETH_GETPARAMS } {
+ # Retrieve the interrupt number, the MAC address,
+ # and the multicast flag for this interface. eCos should be
+ # expecting back 6 bytes of data for the MAC, plus an
+ # extra byte for the multi flag, and the interrupt
+ # number as the return code. This is all known locally.
+ set reply "$ethernet::data($id,MAC)$ethernet::data($id,multi)"
+ synth::send_reply $ethernet::data($id,interrupt_vector) 7 $reply
+ } elseif { $reqcode == $ethernet::SYNTH_ETH_MULTIALL } {
+ set header [binary format "ccs" $reqcode $arg1 0]
+ ethernet::send_rawether $id $header
+ } else {
+ synth::report_error "Received unexpected request $reqcode for ethernet device"
+ }
+ }
+
+ # ----------------------------------------------------------------------------
+ # Incoming data.
+ #
+ # The rawether process continually reads packets from the low-level device
+ # and tries to forward them on to this script, where they will be received
+ # by an event handler. The packet consists of a four-byte header containing
+ # the size, followed by the ethernet data itself. This ensures that
+ # packet boundaries are preserved. Incoming packets are buffered inside
+ # the auxiliary until eCos sends an RX request, and an interrupt is
+ # generated.
+ #
+ # If eCos stops accepting data or if it cannot process the ethernet packets
+ # quickly enough then the auxiliary could end up buffering an unbounded
+ # amount of data. That is a bad idea, so there is an upper bound on the
+ # number of buffered packets. Any excess packets get dropped.
+ #
+ # Error conditions or EOF indicate that rawether has terminated. This
+ # should not happen during normal operation. rawether should only exit
+ # because of an ecos_exit hook when the channel gets closed, and the
+ # event handler gets removed first.
+ #
+ # Incoming packets are logged when they are received by eCos, not when
+ # they are received from the rawether device. That gives a somewhat more
+ # accurate view of what is happening inside eCos - a packet stuck in
+ # a fifo has little impact.
+ proc _handle_packet_error { msg id } {
+ append msg " No further I/O will happen on this interface.\n"
+ synth::report_warning $msg
+ set ethernet::data($id,alive) 0
+ fileevent $ethernet::data($id,rawether) readable ""
+ catch { close $ethernet::data($id,rawether) }
+ }
+
+ proc handle_packet { name id chan } {
+ set header [read $chan 4]
+ if { 4 != [string length $header] } {
+ ethernet::_handle_packet_error "rawether process for $name has terminated unexpectedly.\n" $id
+ return
+ }
+
+ binary scan $header "ccs" code arg1 len
+ if { $ethernet::SYNTH_ETH_RX != $code } {
+ set msg "protocol mismatch from rawether process for $name\n"
+ append msg " Function code $code not recognised.\n"
+ ethernet::_handle_packet_error $msg $id
+ return
+ }
+ if { ($len < 14) || ($len > 1514) } {
+ set msg "protocol mismatch from rawether process for $name\n"
+ append msg " Invalid transfer length $len\n"
+ ethernet::_handle_packet_error $msg $id
+ return
+ }
+
+ set data [read $chan $len]
+ if { $len != [string length $data] } {
+ set msg "protocol mismatch from rawether process for $name\n"
+ append msg " Expected $len byte ethernet packet, received [string length $data] bytes\n"
+ ethernet::_handle_packet_error $msg $id
+ return
+ }
+
+ # The data has been received correctly. Should it be buffered?
+ if { !$ethernet::data($id,up) } {
+ return
+ }
+ if { $ethernet::data($id,packet_count) >= $ethernet::max_buffered_packets } {
+ return
+ }
+
+ # Store the packet, and inform eCos there is work to be done
+ lappend ethernet::data($id,packets) $data
+ incr ethernet::data($id,packet_count)
+ synth::interrupt_raise $ethernet::data($id,interrupt_vector)
+
+ }
+
+ # ----------------------------------------------------------------------------
+ # When eCos has exited, the rawether processes can and should be
+ # shut down immediately.
+ proc ecos_exited { arg_list } {
+ foreach id $ethernet::ids {
+ if { $ethernet::data($id,alive) } {
+ set ethernet::data($id,alive) 0
+ fileevent $ethernet::data($id,rawether) readable ""
+ catch { close $ethernet::data($id,rawether) }
+ }
+ }
+ }
+ synth::hook_add "ecos_exit" ethernet::ecos_exited
+
+ # ----------------------------------------------------------------------------
+ # Read in various data files for use by the filters
+ #
+ # Other possible sources of information include arp, ypcat, and
+ # dns. Those are avoided for now because they involve running
+ # additional processes that might hang for a while. Also arp
+ # would only give useful information for very recently accessed
+ # machines, NIS might not be running, and dns could involve an
+ # expensive lookup while the system is running .
+
+ array set services [list]
+ array set hosts [list]
+ array set protocols [list]
+
+ proc read_services { } {
+ catch {
+ set fd [open "/etc/services" "r"]
+ while { -1 != [gets $fd line] } {
+ set junk ""
+ set name ""
+ set number ""
+ set protocol ""
+ if { [regexp -- {^([-a-zA-Z0-9_]+)\s*([0-9]+)/((?:tcp)|(?:udp)).*$} $line junk name number protocol] } {
+ set ethernet::services($number,$protocol) $name
+ }
+ }
+ close $fd
+ }
+ }
+
+ proc read_protocols { } {
+ catch {
+ set fd [open "/etc/protocols" "r"]
+ while { -1 != [gets $fd line] } {
+ set junk ""
+ set name ""
+ set number ""
+ if { [regexp -- {^([-a-zA-Z0-9_]+)\s*([0-9]+)\s.*} $line junk name number] } {
+ set ethernet::protocols($number) $name
+ }
+ }
+ close $fd
+ }
+ }
+
+ proc read_hosts { } {
+ catch {
+ set fd [open "/etc/hosts" "r"]
+ while { -1 != [gets $fd line] } {
+ set junk ""
+ set name ""
+ set number ""
+
+ # Deliberately ignore parts of the name after the first .
+ if { [regexp -- {^([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})\s*([a-zA-Z0-9]+)(\.|\s|$)} $line junk number name] } {
+ # The number should be naturalized if it is going to match reliably
+ scan $line "%d.%d.%d.%d" a b c d
+ set index [expr (($a & 0x0FF) << 24) | (($b & 0x0FF) << 16) | (($c & 0x0FF) << 8) | ($d & 0x0FF)]
+ set ethernet::hosts($index) $name
+ }
+ }
+ close $fd
+ }
+ }
+
+ # ----------------------------------------------------------------------------
+ # Filtering support. This is only really used when running in GUI mode.
+ # However all the relevant options are still extracted and validated,
+ # to avoid warnings about unrecognised options.
+
+ variable logging_enabled 0
+ variable max_show 64
+
+ # Construct a string for the data, either all of it or up to max_show bytes.
+ # This is just hex in chunks of four bytes.
+ proc format_hex_data { data } {
+ set result ""
+
+ set len [string length $data]
+ if { $len > $ethernet::max_show } {
+ set len $ethernet::max_show
+ }
+ binary scan $data "H[expr 2 * $len]" hex
+ for { set i 0 } { $i < $len } { incr i 4 } {
+ append result "[string range $hex [expr $i * 2] [expr ($i * 2) + 7]] "
+ }
+ set result [string trimright $result]
+ return $result
+ }
+
+ # Given an IPv4 network address, turn it into a.b.c.d and the
+ # host name as well (if known). The argument should be a 32-bit
+ # integer.
+ proc inet_ipv4_ntoa { number } {
+ set result [format "%d.%d.%d.%d" [expr ($number >> 24) & 0x0FF] [expr ($number >> 16) & 0x0FF] \
+ [expr ($number >> 8) & 0x0FF] [expr $number & 0x0FF]]
+ if { [info exists ethernet::hosts($number) ] } {
+ append result "($ethernet::hosts($number))"
+ }
+ return $result
+ }
+
+ # Given an ipv4 address encapsulated in an IPv6 address, do the necessary
+ # conversion. We have something like 123:4567, we want a.b.c.d plus
+ # a host address.
+ proc inet_ipv4_in_ipv6_ntoa { top bottom } {
+ if { "" == $top } {
+ set top 0
+ }
+ if { "" == $bottom } {
+ set bottom 0
+ }
+ set top "0x$top"
+ set bottom "0x$bottom"
+
+ set ipv4 [expr ($top << 16) | $bottom]
+ return inet_ipv4_ntoa $ipv4
+ }
+
+ # Ditto for IPv6. The argument should be a 32-digit hexadecimal string.
+ # For now there is no simple way of mapping these onto host names,
+ # unless the address is an IPv4-mapped or compatible one, or one of
+ # special cases such as loopback.
+ proc inet_ipv6_ntoa { number } {
+ # We have something like 12345678abcdef. Start by inserting the appropriate
+ # colons.
+ set result [format "%s:%s:%s:%s:%s:%s:%s:%s" [string range $number 0 3] [string range $number 4 7] \
+ [string range $number 8 11] [string range $number 12 15] [string range $number 16 19] \
+ [string range $number 20 23] [string range $number 24 27] [string range $number 28 31]]
+ # Now eliminate unwanted 0's at the start of each range.
+ regsub {^0+} $result {} result
+ regsub -all {:0+} $result {:} result
+
+ # If we have ended up with sequences of colons, abbreviate
+ # them into pairs.
+ regsub -all {::+} $result {::} result
+
+ # There are a couple of special addresses
+ if { "::1" == $result } {
+ return "::1(loopback)"
+ } elseif { "::" == $result } {
+ return "::(IN6ADDR_ANY)"
+ }
+
+ # Look for IPv4-mapped addresses.
+ set junk ""
+ set ipv4_1 ""
+ set ipv4_2 ""
+ if { [regexp -nocase -- {::ffff:([0-9a-f]{0,3}):([0-9a-f]{0,3})$} $result junk ipv4_1 ipv4_2] } {
+ set result [inet_ipv4_in_ipv6_nto $ipv4_1 $ipv4_2]
+ return "::FFFF:$result"
+ } elseif { [regexp -nocase -- {::([0-9a-f]{0,3}):([0-9a-f]{0,3})$} $result junk ipv4_1 ipv4_2] } {
+ set result [inet_ipv4_in_ipv6_nto $ipv4_1 $ipv4_2]
+ return "::$result"
+ } else {
+ # Could still be aggregatable global unicast, link-local, site-local or multicast.
+ # But not decoded further for now.
+ return $result
+ }
+ }
+
+ proc log_packet { device direction packet } {
+ if { [string length $packet] < 14 } {
+ return
+ }
+ binary scan $packet {H2H2H2H2H2H2 H2H2H2H2H2H2 S} dest5 dest4 dest3 dest2 dest1 dest0 src5 src4 src3 src2 src1 src0 eth_protocol
+ set packet [string range $packet 14 end]
+
+ set ether_msg "$device $direction: [string length $packet] bytes, "
+ append ether_msg [format ">%s:%s:%s:%s:%s:%s <%s:%s:%s:%s:%s:%s" $dest5 $dest4 $dest3 $dest2 $dest1 $dest0 $src5 $src4 $src3 $src2 $src1 $src0]
+ set eth_protocol [expr $eth_protocol & 0x0FFFF]
+ if { $eth_protocol <= 1536 } {
+ append ether_msg " 802.3 "
+ if { [string length $packet] < 8 } {
+ return
+ }
+ binary scan $packet {a6 S} junk eth_protocol
+ set packet [string range $packet 8 end]
+ }
+ append ether_msg [format " %04x" $eth_protocol]
+ if { $eth_protocol == 0x0800 } {
+ append ether_msg "(ip)"
+ } elseif { $eth_protocol == 0x00806 } {
+ append ether_msg "(arp)"
+ } elseif { $eth_protocol == 0x08035 } {
+ append ether_msg "(rarp)"
+ }
+ append ether_msg " [ethernet::format_hex_data $packet]\n"
+ synth::output $ether_msg "eth_ether"
+
+ if { 0x0806 == $eth_protocol } {
+ # An ARP request. This should always be 28 bytes.
+ if { [string length $packet] < 28 } {
+ return
+ }
+ binary scan $packet {SSccS H2H2H2H2H2H2 I H2H2H2H2H2H2 I} hard_type prot_type hard_size prot_size op \
+ sender5 sender4 sender3 sender2 sender1 sender0 sender_ip \
+ target5 target4 target3 target2 target1 target0 target_ip
+ set hard_type [expr $hard_type & 0x0FFFF]
+ set prot_type [expr $prot_type & 0x0FFFF]
+ set hard_size [expr $hard_size & 0x0FF]
+ set prot_size [expr $prot_size & 0x0FF]
+ set op [expr $op & 0x0FFFF]
+ set sender_ip [expr $sender_ip & 0x0FFFFFFFF]
+ set target_ip [expr $target_ip & 0x0FFFFFFFF]
+
+ set arp_msg "$device $direction: ARP "
+ if { $op == 1 } {
+ append arp_msg "request "
+ } elseif { $op == 2 } {
+ append arp_msg "reply "
+ } else {
+ append_arp_msg "<unknown opcode> "
+ }
+ if { $hard_type != 1 } {
+ append arp_msg "(unexpected hard_type field $hard_type, should be 1) "
+ }
+ if { $prot_type != 0x0800 } {
+ append arp_msg "(unexpected prot_type field $prot_type, should be 0x0800) "
+ }
+ if { $hard_size != 6 } {
+ append arp_msg "(unexpected hard_size field $hard_size, should be 6) "
+ }
+ if { $prot_size != 4 } {
+ append arp_msg "(unexpected prot_size field $prot_size, should be 4) "
+ }
+ append arp_msg [format ", sender %s:%s:%s:%s:%s:%s " $sender5 $sender4 $sender3 $sender2 $sender1 $sender0]
+ append arp_msg [ethernet::inet_ipv4_ntoa $sender_ip]
+ append arp_msg [format ", target %s:%s:%s:%s:%s:%s " $target5 $target4 $target3 $target2 $target1 $target0]
+ append arp_msg [ethernet::inet_ipv4_ntoa $target_ip]
+ append arp_msg "\n"
+
+ synth::output $arp_msg "eth_arp"
+ return
+ }
+
+ if { 0x0800 != $eth_protocol } {
+ return
+ }
+
+ # We have an IP packet. Is this IPv4 or IPv6? The first byte contains
+ # the version and the overall length of the IP header in 32-bit words
+ if { [string length $packet] < 20 } {
+ return
+ }
+ binary scan $packet {c} tmp
+ set ip_version [expr ($tmp >> 4) & 0x0F]
+ set ip_hdrsize [expr $tmp & 0x0F]
+ if { 4 == $ip_version } {
+ binary scan $packet {ccSSSccSII} tmp tos len id frag ttl ip_protocol checksum source_ip dest_ip
+ set ipv4_msg "$device $direction: IPv4"
+ if { 0 != $tos } {
+ append ipv4_msg [format " tos %02x," [expr $tos & 0x0FF]]
+ }
+ append ipv4_msg [format " len %d, id %d," [expr $len & 0x0FFFF] [expr $id & 0x0FFFF]]
+ if { 0 != $frag } {
+ append ipv4_msg [format " frag %u" [expr 8 * ($frag & 0x01FFF)]]
+ if { 0 != ($frag & 0x04000) } {
+ append ipv4_msg " DF"
+ }
+ if { 0 != ($frag & 0x02000) } {
+ append ipv4_msg " MF"
+ }
+ append ipv4_msg ","
+ }
+ append ipv4_msg [format " ttl %d," $ttl]
+ set ip_protocol [expr $ip_protocol & 0x0FF]
+ if { [info exists ethernet::protocols($ip_protocol)] } {
+ append ipv4_msg " $ethernet::protocols($ip_protocol),"
+ } else {
+ append ipv4_msg [format " protocol %d" $ip_protocol]
+ }
+
+ set source_name [ethernet::inet_ipv4_ntoa $source_ip]
+ set dest_name [ethernet::inet_ipv4_ntoa $dest_ip]
+ append ipv4_msg " >${dest_name}, <${source_name}\n"
+
+ synth::output $ipv4_msg "eth_ipv4"
+
+ # If this packet is a fragment other than the first, do not try to decode
+ # subsequent packets. The header information will not be present.
+ if { 0 != ($frag & 0x01FFF)} {
+ return
+ }
+ set packet [string range $packet [expr 4 * $ip_hdrsize] end]
+
+ } elseif { 6 == $ip_version } {
+ if { [string length $packet] < 40 } {
+ return
+ }
+ binary scan $packet {ISccH16H16} flow payload_length next_header hop_limit source_ip dest_ip
+ set ipv6_msg "$device $direction: IPv6"
+ set prio [expr ($flow & 0x0F000000) >> 24]
+ set flow [expr $flow & 0x00FFFFFF]
+ if { 0 != $flow } {
+ append ipv6_msg [format " flow %04x prio %x," $flow $prio]
+ }
+ append ipv6_msg " payload [expr $payload bytes & 0x0FFFF],"
+ append ipv6_msg " hop limit [expr $hop_limit & 0x0FF],"
+ set next_header [expr $next_header & 0x0FF]
+ if { [info exists ethernet::protocols($next_header)] } {
+ append ipv6_msg " $ethernet::protocols($next_header),"
+ } else {
+ append ipv6_msg [format " protocol %d," $next_header]
+ }
+
+ set source_name [ethernet::inet_ipv6_ntoa $source_ip]
+ set dest_name [ethernet::inet_ipv6_ntoa $dest_ip]
+ append ipv6_msg " >${dest_name}, <${source_name}\n"
+
+ synth::output $ipv6_msg "eth_ipv6"
+
+ set packet [string range $packet 40 end]
+
+ } else {
+ synth::output "$device $direction: unknown IP version $ip_version\n" "eth_ipv4"
+ return
+ }
+
+
+ # Now for some known protocols, icmp, tcp, udp and icmpv6
+ # Possible ipv6-frag should be handled here as well. The
+ # fragment header should be followed by another header such
+ # as tcp or udp.
+ if { 1 == $ip_protocol } {
+ # ipv4 ICMP
+ if { [string length $packet] < 4 } {
+ return
+ }
+ binary scan $packet {ccS} code type checksum
+
+ set icmpv4_msg "$device $direction: ICMPv4 "
+ set error 0
+ set data 0
+ switch -- $code {
+ 0 {
+ append icmpv4_msg "ping reply"
+ if { [string length $packet] >= 8 } {
+ # The id and seq are in the sender's format, not network format.
+ # We have to assume either little or bigendian, so go for the former
+ binary scan $packet {iss} junk id seq
+ append icmpv4_msg [format " id %u, seq %u" [expr $id & 0x0FFFF] [expr $seq & 0x0FFFF]]
+ set data 1
+ set packet [string range $packet 8 end]
+ }
+ }
+ 3 {
+ append icmpv4_msg "unreachable/"
+ switch -- $type {
+ 0 { append icmpv4_msg "network" }
+ 1 { append icmpv4_msg "host" }
+ 2 { append icmpv4_msg "protocol" }
+ 3 { append icmpv4_msg "port" }
+ 4 { append icmpv4_msg "frag needed but don't frag set" }
+ 5 { append icmpv4_msg "source route failed" }
+ 6 { append icmpv4_msg "destination network unknown" }
+ 7 { append icmpv4_msg "destination host unknown" }
+ 8 { append icmpv4_msg "source host isolated" }
+ 9 { append icmpv4_msg "destination network prohibited" }
+ 10 { append icmpv4_msg "destination host prohibited" }
+ 11 { append icmpv4_msg "network for TOS" }
+ 12 { append icmpv4_msg "host for TOS" }
+ 13 { append icmpv4_msg "communication prohibited" }
+ 14 { append icmpv4_msg "host precedence violation" }
+ 15 { append icmpv4_msg "precedence cutoff" }
+ default { append icmpv4_msg "unknown" }
+ }
+ set error 1
+ }
+ 4 {
+ append icmpv4_msg "source quench"
+ set error 1
+ }
+ 5 {
+ append icmpv4_msg "redirect/"
+ switch -- $type {
+ 0 { append icmpv4_msg "network" }
+ 1 { append icmpv4_msg "host" }
+ 2 { append icmpv4_msg "tos & network" }
+ 3 { append icmpv4_msg "tos & host" }
+ default { append icmpv4_msg "unknown" }
+ }
+ set error 1
+ }
+ 8 {
+ append icmpv4_msg "ping request"
+ if { [string length $packet] >= 8 } {
+ binary scan $packet {iss} junk id seq
+ append icmpv4_msg [format " id %u, seq %u" [expr $id & 0x0FFFF] [expr $seq & 0x0FFFF]]
+ set data 1
+ set packet [string range $packet 8 end]
+ }
+ }
+ 9 {
+ append icmpv4_msg "router advertisement"
+ }
+ 10 {
+ append icmpv4_msg "router solicitation"
+ }
+ 11 {
+ append icmpv4_msg "time exceeded/"
+ switch -- $type {
+ 0 { append icmpv4_msg "transit" }
+ 1 { append icmpv4_msg "reassembly" }
+ default { append icmpv4_msg "unknown" }
+ }
+ set error 1
+ }
+ 12 {
+ append icmpv4_msg "parameter problem/"
+ switch -- $type {
+ 0 { append icmpv4_msg "IP header bad" }
+ 1 { append icmpv4_msg "required option missing" }
+ default { append icmpv4_msg "unknown" }
+ }
+ set error 1
+ }
+ 13 {
+ append icmpv4_msg "timestamp request"
+ }
+ 14 {
+ append icmpv4_msg "timestamp reply"
+ }
+ 15 {
+ append icmpv4_msg "information request"
+ }
+ 16 {
+ append icmpv4_msg "information reply"
+ }
+ 17 {
+ append icmpv4_msg "address mask request"
+ }
+ 18 {
+ append icmpv4_msg "address mask reply"
+ }
+ default {
+ append icmpv4_msg "unknown"
+ }
+ }
+ if { $error && ([string length $packet] >= 36) } {
+ # The ICMP message contains an IP header and hopefully the TCP or UDP ports as well
+ # Only deal with the simple cases.
+ binary scan $packet {iiccSiccSIISS} icmp_junk1 icmp_junk2 ip_lenver ip_junk1 ip_junk2 ip_junk3 ip_junk4 ip_protocol ip_junk5 \
+ ip_source ip_dest ip_source_port ip_dest_port
+ if { (5 == ($ip_lenver & 0x0F)) && ((6 == $ip_protocol) || (17 == $ip_protocol)) } {
+ if { 6 == $ip_protocol } {
+ append icmpv4_msg ", tcp"
+ } else {
+ append icmpv4_msg ", udp"
+ }
+ append icmpv4_msg " >[ethernet::inet_ipv4_ntoa $ip_dest]:$ip_dest_port <[ethernet::inet_ipv4_ntoa $ip_source]:$ip_source_port"
+ }
+ }
+
+ append icmpv4_msg "\n"
+ synth::output $icmpv4_msg "eth_icmpv4"
+
+ # Only some of the requests contain additional data that should be displayed
+ if { !$data } {
+ return
+ }
+
+ } elseif { 58 == $ip_protocol } {
+ # ipv6 ICMP
+ if { [string length $packet] < 4 } {
+ return
+ }
+ binary scan $packet {ccS} code type checksum
+
+ set icmpv6_msg "$device $direction: ICMPv6 "
+ set error 0
+ set data 0
+ switch -- $code {
+ 1 {
+ append icmpv6_msg "unreachable/"
+ switch -- $type {
+ 0 { append icmpv6_msg "no route" }
+ 1 { append icmpv6_msg "prohibited" }
+ 2 { append icmpv6_msg "not a neighbour" }
+ 3 { append icmpv6_msg "any other reason" }
+ 4 { append icmpv6_msg "UDP port unreachable" }
+ default { append icmpv6_msg "unknown" }
+ }
+ set error 1
+ }
+ 2 {
+ append icmpv6_msg "packet too big"
+ set error 1
+ }
+ 3 {
+ append icmpv6_msg "time exceeded/"
+ switch -- $type {
+ 0 { append icmpv6_msg "hop limit" }
+ 1 { append icmpv6_msg "fragment reassembly" }
+ default { append icmpv6_msg "unknown" }
+ }
+ set error 1
+ }
+ 4 {
+ append icmpv6_msg "parameter problem"
+ switch -- $type {
+ 0 { append icmpv6_msg "erroneous header" }
+ 1 { append icmpv6_msg "unrecognized next header" }
+ 2 { append icmpv6_msg "unrecognized option" }
+ default { append icmpv6_msg "unknown" }
+ }
+ set error 1
+ }
+ 128 {
+ append icmpv6_msg "ping request"
+ # FIXME: is this the same format as for icmpv4?
+ }
+ 129 {
+ append icmpv6_msg "ping reply"
+ # FIXME: is this the same format as for icmpv4?
+ }
+ 130 {
+ append icmpv6_msg "group membership query"
+ }
+ 131 {
+ append icmpv6_msg "group membership report"
+ }
+ 132 {
+ append icmpv6_msg "group membership reduction"
+ }
+ 133 {
+ append icmpv6_msg "router solicitation"
+ }
+ 134 {
+ append icmpv6_msg "router advertisement"
+ }
+ 135 {
+ append icmpv6_msg "neighbour solicitation"
+ }
+ 136 {
+ append icmpv6_msg "neighbour advertisement"
+ }
+ 137 {
+ append icmpv6_msg "redirect"
+ }
+ }
+
+ if { $error && ([string length $packet] >= 44) } {
+ # The ICMP message contains an IPv6 header and hopefully the TCP or UDP ports as well
+ binary scan $packet {isccH16H16SS} icmp_junk1 icmp_junk2 ip_protocol icmp_junk3 ip_source ip_dest ip_source_port ip_dest_port
+ if { 6 == $ip_protocol } {
+ append icmpv6_msg ", tcp"
+ } elseif { 17 == $ip_protocol } {
+ append icmpv6_msg ", udp"
+ }
+ append icmpv6_msg " >[ethernet::inet_ipv4_ntoa $ip_dest]:$ip_dest_port <[ethernet::inet_ipv6_ntoa $ip_source]:$ip_source_port"
+ }
+ append icmpv6_msg "\n"
+ synth::output $icmpv6_msg "eth_icmpv6"
+
+ if { !$data } {
+ return
+ }
+
+ } elseif { 6 == $ip_protocol } {
+ # TCP
+ if { [string length $packet] < 20 } {
+ return
+ }
+ binary scan $packet {SSIIccSSS} source_port dest_port seq ack hdrsize flags winsize checksum urg
+ set source_port [expr $source_port & 0x0FFFF]
+ set dest_port [expr $dest_port & 0x0FFFF]
+ set hdrsize [expr ($hdrsize >> 4) & 0x0F]
+ set winsize [expr $winsize & 0x0FFFF]
+ set urg [expr $urg & 0x0FFFF]
+
+ set tcp_msg "$device $direction tcp: "
+ append tcp_msg " >${dest_name}:${dest_port}"
+ if { [info exists ethernet::services($dest_port,udp)] } {
+ append tcp_msg "($ethernet::services($dest_port,udp))"
+ }
+ append tcp_msg "<${source_name}:$source_port"
+ if { [info exists ethernet::services($source_port,udp)] } {
+ append tcp_msg "($ethernet::services($source_port,udp))"
+ }
+
+ append tcp_msg ", "
+ if { $flags & 0x08 } {
+ append tcp_msg "PSH "
+ }
+ if { $flags & 0x04 } {
+ append tcp_msg "RST "
+ }
+ if { $flags & 0x02 } {
+ append tcp_msg "SYN "
+ }
+ if { $flags & 0x01 } {
+ append tcp_msg "FIN "
+ }
+ append tcp_msg [format "seq %u" $seq]
+
+ if { 0 != ($flags & 0x010) } {
+ append tcp_msg [format ", ACK %u" $ack]
+ }
+ append tcp_msg ", win $winsize"
+ if { 0 != ($flags & 0x020) } {
+ append tcp_msg ", URG $urg"
+ }
+ append tcp_msg "\n"
+ synth::output $tcp_msg "eth_tcp"
+
+ set packet [string range $packet [expr 4 * $hdrsize] end]
+ } elseif { 17 == $ip_protocol } {
+ # UDP
+ if { [string length $packet] < 8 } {
+ return
+ }
+ set udp_msg "$device $direction: udp "
+ binary scan $packet {SSSS} source_port dest_port len checksum
+ set source_port [expr $source_port & 0x0FFFF]
+ set dest_port [expr $dest_port & 0x0FFFF]
+ append udp_msg [format "%d bytes, " [expr $len & 0x0FFFF]]
+ append udp_msg " >${dest_name}:$dest_port"
+ if { [info exists ethernet::services($dest_port,udp)] } {
+ append udp_msg "($ethernet::services($dest_port,udp))"
+ }
+ append udp_msg "<${source_name}:$source_port"
+ if { [info exists ethernet::services($source_port,udp)] } {
+ append udp_msg "($ethernet::services($source_port,udp))"
+ }
+ append udp_msg "\n"
+ synth::output $udp_msg "eth_udp"
+ set packet [string range $packet 8 end]
+ } else {
+ # Unknown protocol, so no way of knowing where the data starts.
+ return
+ }
+
+ # At this point we may have a payload. This should be
+ # dumped in both hex and ascii. The code tries to preserve
+ # alignment.
+ if { [string length $packet] == 0 } {
+ return
+ }
+ set hexdata_msg "$device $direction: data [format_hex_data $packet]\n"
+ set asciidata_msg "$device $direction: data "
+ set len [string length $packet]
+ if { $len > $ethernet::max_show } {
+ set len $ethernet::max_show
+ }
+ for { set i 0 } { $i < $len } { incr i } {
+ set char [string index $packet $i]
+ if { "\r" == $char } {
+ append asciidata_msg "\\r"
+ } elseif { "\n" == $char } {
+ append asciidata_msg "\\n"
+ } elseif { "\t" == $char } {
+ append asciidata_msg "\\t"
+ } elseif { [string is print -strict $char] } {
+ append asciidata_msg " $char"
+ } else {
+ append asciidata_msg "??"
+ }
+ if { 3 == ($i % 4) } {
+ append asciidata_msg " "
+ }
+ }
+ append asciidata_msg "\n"
+ synth::output $hexdata_msg "eth_hexdata"
+ synth::output $asciidata_msg "eth_asciidata"
+
+ return
+ }
+
+ # A utility for handling the ethernet record button on the toolbar
+ proc logging_button_toggle { } {
+ if { $ethernet::logging_enabled } {
+ set ethernet::logging_enabled 0
+ .toolbar.ethernet_logging configure -relief flat
+ } else {
+ set ethernet::logging_enabled 1
+ .toolbar.ethernet_logging configure -relief sunken
+ }
+ }
+
+ # A dummy procedure for initialization. All of this could execute at
+ # the toplevel, but there are lots of locals.
+ proc filters_initialize { } {
+ ethernet::read_services
+ ethernet::read_protocols
+ ethernet::read_hosts
+
+ # Add a button on the toolbar for enabling/disabling logging.
+ # Also add an entry to the help menu
+ if { $synth::flag_gui } {
+ button .toolbar.ethernet_logging -image $ethernet::image_netrecord -borderwidth 2 -relief flat -command ethernet::logging_button_toggle
+ pack .toolbar.ethernet_logging -side left -padx 2
+ synth::register_balloon_help .toolbar.ethernet_logging "Record ethernet traffic"
+
+ if { [synth::tdf_has_option "ethernet" "logging"] } {
+ set ethernet::logging_enabled [synth::tdf_get_option "ethernet" "logging"]
+ } else {
+ # Default to logging ethernet traffic. This may not be the right thing to do
+ # because users may see too much output by default, but it is easy enough
+ # to disable.
+ set ethernet::logging_enabled 1
+ }
+ if { $ethernet::logging_enabled } {
+ .toolbar.ethernet_logging configure -relief sunken
+ }
+
+ set ethernet_help [file join $synth::device_src_dir "doc" "devs-eth-synth-ecosynth.html"]
+ if { ![file readable $ethernet_help] } {
+ synth::report_warning "Failed to locate synthetic ethernet documentation $ethernet_help\n \
+ Help->Ethernet target menu option disabled.\n"
+ set ethernet_help ""
+ }
+ if { "" == $ethernet_help } {
+ .menubar.help add command -label "Ethernet" -state disabled
+ } else {
+ .menubar.help add command -label "Ethernet" -command [list synth::handle_help "file://$ethernet_help"]
+ }
+ }
+
+ if { [synth::tdf_has_option "ethernet" "max_show"] } {
+ set ethernet::max_show [synth::tdf_get_option "ethernet" "max_show"]
+ if { ! [string is integer -strict $ethernet::max_show] } {
+ synth::report_error "Ethernet device, invalid value in target definition file $synth::target_definition\n \
+ Entry max_show should be a simple integer, not $ethernet::max_show\n"
+ set ethernet::init_ok 0
+ }
+ }
+
+ # Filters. First, perform some validation.
+ set known_filters [list "ether" "arp" "ipv4" "ipv6" "icmpv4" "icmpv6" "udp" "tcp" "hexdata" "asciidata"]
+ set tdf_filters [synth::tdf_get_options "ethernet" "filter"]
+ array set filter_options [list]
+
+ foreach filter $tdf_filters {
+ if { 0 == [llength $filter] } {
+ synth::report_error "Ethernet device, invalid value in target definition file $synth::target_definition\n \
+ Option \"filter\" requires the name of a known filters.\n"
+ set ethernet::init_ok 0
+ continue
+ }
+ set name [lindex $filter 0]
+ if { [info exists filter_options($name)] } {
+ synth::report_error "Ethernet device, invalid value in target definition file $synth::target_definition\n \
+ \"filter $name\" should be defined only once.\n"
+ set ethernet::init_ok 0
+ continue
+ }
+ if { -1 == [lsearch -exact $known_filters $name] } {
+ synth::report_error "Ethernet device, invalid value in target definition file $synth::target_definition\n \
+ Unknown filter \"$name\".\n \
+ Known filters are $known_filters\n"
+ set ethernet::init_ok 0
+ continue
+ }
+ set filter_options($name) [lrange $filter 1 end]
+ }
+
+ # We now know about all the filter entries in the target definition file.
+ # Time to create the filters themselves, provided we are running in GUI mode.
+ if { $synth::flag_gui } {
+ foreach filter $known_filters {
+ if { ! [info exists filter_options($filter)] } {
+ synth::filter_add "eth_$filter" -text "ethernet $filter"
+ } else {
+ array set parsed_options [list]
+ set message ""
+ if { ![synth::filter_parse_options $filter_options($filter) parsed_options message] } {
+ synth::report_error \
+ "Invalid entry in target definition file $synth::target_definition\n \
+ Ethernet filter $filter\n $message"
+ set ethernet::init_ok 0
+ } else {
+ set parsed_options("-text") "ethernet $filter"
+ synth::filter_add_parsed "eth_$filter" parsed_options
+ }
+ }
+ }
+ }
+ }
+ ethernet::filters_initialize
+}
+
+return ethernet::instantiate
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/ethernet.tdf b/ecos/packages/devs/eth/synth/ecosynth/current/host/ethernet.tdf
new file mode 100644
index 0000000..46efa69
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/ethernet.tdf
@@ -0,0 +1,117 @@
+# Target definition file fragment for ethernet devices.
+#
+# The target-side can instantiate up to four ethernet devices,
+# eth0 to eth3. Each instance requires an entry in the
+# target definition file specifying what underlying Linux
+# kernel facility should be used to implement the I/O. This
+# can take the following forms:
+#
+# 1) an existing ethernet device, e.g.
+# eth0 real eth1
+# thus mapping the eCos device eth0 on to the Linux device eth1.
+# The latter network interface must not currently be in use
+# by Linux. Traffic will flow to and from the real ethernet, and
+# communication is possible with any machine on the LAN.
+#
+# 2) the Linux kernel's tap facility.
+# eth0 ethertap
+# This will result in a Linux ethernet interface such as
+# tap3 appearing. The interface can be configured like any
+# other network device, for example by using the ifconfig
+# command or by creating a configuration file
+# /etc/sysconfig/network-scripts/ifcfg-tap3
+# The result is a virtual ethernet segment visible only
+# to the Linux host and eCos. Bridge software inside the
+# Linux host can be used to connect eCos to a larger network.
+#
+# Optionally a specific tap device can be configured,
+# eth0 ethertap tap3
+# By default the code will pick up the next free tap device,
+# usually tap0. If the Linux interface should come up automatically
+# then this can be achieved with an ifcfg-tap?? configuration
+# file. Explicitly specifying the tap device can avoid some
+# confusion.
+#
+# Both the eCos and the Linux network interface need a unique
+# MAC address. There is no real ethernet hardware involved to
+# supply these addresses, so they have to be invented. The
+# Linux kernel will automatically invent one for its interface.
+# By default a random MAC address will also be generated for
+# the eCos interface, but to make the system more deterministic
+# it is possible to specify the MAC address to be used. This
+# facility is only available in conjunction with an explicit
+# tap device, e.g.:
+# eth0 ethertap tap3 00:01:02:03:04:05
+# The MAC address should be in the usual format: six 2-digit
+# hexadecimal numbers separated by colons. It is the user's
+# responsibility to make sure that the address specified
+# does not match any other real or invented address visible
+# on the local network.
+#
+# It is possible that bursts of ethernet traffic occur, causing
+# packets to arrive faster than they can be forwarded to and
+# processed by eCos. It is desirable that some number of packets
+# be buffered, matching the behaviour of many ethernet devices
+# with built-in fifos. However the number of these packets should
+# be restricted: if eCos stops accepting ethernet packets or
+# cannot handle the data quickly enough, then it is possible that
+# an unlimited number of packets could accumulate in the I/O
+# auxiliary until all available memory and swap space is exhausted.
+# By default up to 16 packets will be buffered per device, but
+# this can be changes with the max_buffer option.
+#
+# The ethernet emulation code can perform logging and limited
+# analysis of each ethernet packet. For example if a particular
+# packet is an IPv4 ICMP request then details of the request
+# will be logged to the main text window. The appearance of the
+# various filters can be controlled here, using the usual
+# options such as -foreground, -background, and -hide.
+#
+# This logging of each ethernet frame can be somewhat time-consuming
+# and, for a long run, require a lot of memory. Logging can be
+# disabled by default if desired, and a button on the toolbar allows
+# this setting to be toggled.
+#
+# Ethernet packets can be up to 1514 bytes, so showing entire packets
+# on a single line can mean very wide lines. In practice the interesting
+# data is usually at the start, so the output can be truncated to a
+# maximum number of bytes. The data is displayed in hex so each byte
+# requires two columns, and some spacing will be added as well to
+# improve legibility.
+
+synth_device ethernet {
+ ## Map eCos devices on to Linux ones.
+
+ # eth0 real eth1
+ # eth0 ethertap
+ # eth0 ethertap tap3
+ eth0 ethertap tap3 00:FE:42:63:84:A5
+
+ # eth1 ethertap tap4 00:FE:12:34:56:78
+ # eth2 ethertap tap5 00:FE:9A:BC:DE:F0
+ # eth3 real eth2
+
+ ## Maximum number of packets that should be buffered per interface.
+ ## Default 16
+ max_buffer 32
+
+ ## Should packets be logged? The default is yes.
+ # logging 0
+
+ ## Maximum number of data bytes to be shown.
+ ## Default 64
+ # max_show 128
+
+ ## Filters for the various recognised protocols.
+ ## By default all filters are visible and use standard colours.
+ # filter ether -hide 0
+ # filter arp -hide 1
+ # filter ipv4 -hide 1
+ # filter ipv6 -hide 1
+ # filter icmpv4 -hide 1
+ # filter icmpv6 -hide 1
+ # filter udp -hide 1
+ # filter tcp -hide 1
+ # filter hexdata -hide 0
+ # filter asciidata -hide 0
+}
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/fromnet.xbm b/ecos/packages/devs/eth/synth/ecosynth/current/host/fromnet.xbm
new file mode 100644
index 0000000..74c0cd0
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/fromnet.xbm
@@ -0,0 +1,4 @@
+#define fromnet_width 8
+#define fromnet_height 8
+static unsigned char fromnet_bits[] = {
+ 0x00, 0x87, 0xa5, 0x95, 0xfd, 0x95, 0xa5, 0x87};
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/netrecord.xbm b/ecos/packages/devs/eth/synth/ecosynth/current/host/netrecord.xbm
new file mode 100644
index 0000000..706c05a
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/netrecord.xbm
@@ -0,0 +1,6 @@
+#define netrecord_width 16
+#define netrecord_height 15
+static unsigned char netrecord_bits[] = {
+ 0x00, 0x00, 0xce, 0x39, 0x4a, 0x08, 0xce, 0x09, 0x46, 0x08, 0xca, 0x39,
+ 0x00, 0x00, 0x0e, 0x20, 0x4a, 0x24, 0x2a, 0x28, 0xfa, 0x3f, 0x2a, 0x28,
+ 0x4a, 0x24, 0x0e, 0x20, 0x00, 0x00};
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/rawether.c b/ecos/packages/devs/eth/synth/ecosynth/current/host/rawether.c
new file mode 100644
index 0000000..cbab0f2
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/rawether.c
@@ -0,0 +1,793 @@
+//============================================================================
+//
+// rawether.c
+//
+// A utility program to perform low-level ethernet operations
+//
+//============================================================================
+// ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of the eCos host tools.
+// Copyright (C) 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####ECOSHOSTGPLCOPYRIGHTEND####
+//============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contact(s): bartv, andrew.lunn@ascom.ch
+// Date: 2002/08/07
+// Version: 0.01
+// Description:
+//
+// This program is fork'ed by the ethernet.tcl script running inside
+// the synthetic target auxiliary. It is responsible for performing
+// low-level ethernet I/O.
+//
+//####DESCRIPTIONEND####
+//============================================================================
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <signal.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <linux/if_packet.h>
+#include <linux/if_ether.h>
+#ifdef HAVE_LINUX_IF_TUN_H
+# include <linux/if_tun.h>
+#endif
+
+// The protocol between host and target is defined by a private
+// target-side header.
+#include "../src/protocol.h"
+
+// Allow debug builds. Set this flag to 0, 1 or 2
+#define DEBUG 0
+
+// ----------------------------------------------------------------------------
+// Statics.
+
+// Are we using a real ethernet device or ethertap?
+static int real_ether = 0;
+static int ethertap = 0;
+
+// The six-byte MAC address, which must be returned to eCos
+static unsigned char MAC[6];
+
+// Does the driver support multicasting?
+static int multicast_supported = 0;
+
+// The file descriptor for incoming data ethernet packets.
+// Used for select() together with fd 0 corresponding to ecosynth
+static int ether_fd = -1;
+
+// Is the interface up?
+static int up = 0;
+
+// Space for incoming and outgoing packets. In the case of rx_buffer
+// there are an extra four bytes at the front for the protocol header.
+#define MTU 1514
+static unsigned char tx_buffer[MTU];
+static unsigned char rx_buffer[MTU+4];
+
+// Indirect to get to the actual implementation functions.
+static void (*tx_fn)(unsigned char*, int);
+static void (*rx_fn)(void);
+static void (*start_fn)(int);
+static void (*stop_fn)(void);
+static void (*multicast_fn)(int);
+
+
+// ----------------------------------------------------------------------------
+// A utility buffer for messages.
+#define MSG_SIZE 256
+static char msg[MSG_SIZE];
+
+// Report an error to ecosynth during initialization. This means a
+// single byte 0, followed by a string.
+static void
+report_error(char* msg)
+{
+ write(1, "0", 1);
+ write(1, msg, strlen(msg));
+ close(1);
+ exit(0);
+}
+
+// Report success to ecosynth. This means a byte 1 followed by
+// the MAC address.
+static void
+report_success(void)
+{
+ write(1, "1", 1);
+ memcpy(msg, MAC, 6);
+ msg[6] = multicast_supported;
+ write(1, msg, 7);
+}
+
+
+// ----------------------------------------------------------------------------
+// Real ethernet. This involves creating a SOCK_RAW socket and binding it
+// to the appropriate interface. Relevant documentation can be found in
+// the man pages (packet(7) and netdevice(7)).
+
+// The device name. Needed for various ioctl()'s.
+static char real_devname[IFNAMSIZ];
+
+// The interface index.
+static int real_ifindex = -1;
+
+// Transmit a single ethernet frame. The socket should be set up so a
+// simple send() operation should do the trick. Errors such as EAGAIN,
+// indicating that the network device is still busy, are ignored.
+// Ethernet is not a reliable communication medium.
+static void
+real_handle_tx(unsigned char* buffer, int size)
+{
+ int result;
+
+ result = send(ether_fd, buffer, size, MSG_DONTWAIT);
+ if (result < 0) {
+ // It appears that one retry is worthwhile, to clear pending
+ // errors or something.
+ result = send(ether_fd, buffer, size, MSG_DONTWAIT);
+ }
+#if (DEBUG > 0)
+ fprintf(stderr, "rawether dbg: tx %d bytes -> %d\n", size, result);
+#endif
+#if (DEBUG > 1)
+ fprintf(stderr, " %x:%x:%x:%x:%x:%x %x:%x:%x:%x:%x:%x %x:%x\n",
+ buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5],
+ buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11],
+ buffer[12], buffer[13]);
+#endif
+}
+
+// Receive a single ethernet frame, using the static rxbuffer. If the
+// interface is not currently up discard it. Otherwise forward it on
+// to ecosynth.
+
+static void
+real_handle_rx(void)
+{
+ int size;
+ int result;
+
+ size = recv(ether_fd, rx_buffer + 4, MTU, MSG_TRUNC);
+
+#if (DEBUG > 0)
+ fprintf(stderr, "rawether dbg: rx returned %d, errno %s (%d)\n", size, strerror(errno), errno);
+#endif
+
+ if (size < 0) {
+ return; // Ignore errors, just go around the main loop again.
+ }
+ if ((size < 14) || (size > MTU)) {
+ return; // Invalid packet size. Discard the packet.
+ }
+
+#if (DEBUG > 1)
+ fprintf(stderr, " %x:%x:%x:%x:%x:%x %x:%x:%x:%x:%x:%x %x:%x\n",
+ rx_buffer[4], rx_buffer[5], rx_buffer[6], rx_buffer[7], rx_buffer[8], rx_buffer[9],
+ rx_buffer[10], rx_buffer[11], rx_buffer[12], rx_buffer[13], rx_buffer[14], rx_buffer[15],
+ rx_buffer[16], rx_buffer[17]);
+#endif
+
+ if (!up) {
+ // eCos is not currently expecting packets, so discard them.
+ // This may not actually be necessary because the interface
+ // is only up when eCos wants it to be up.
+ return;
+ }
+
+ // It looks this packet should get forwarded to eCos.
+ rx_buffer[0] = SYNTH_ETH_RX;
+ rx_buffer[1] = 0;
+ rx_buffer[2] = size & 0x00FF;
+ rx_buffer[3] = (size >> 8) & 0x00FF;
+ do {
+ result = write(1, rx_buffer, 4 + size);
+ } while ((-1 == result) && (EINTR == errno));
+
+ if (result != (size + 4)) {
+ fprintf(stderr, "rawether(%s): failed to send ethernet packet to I/O auxiliary, exiting.\n", real_devname);
+ exit(1);
+ }
+}
+
+// Utility to manipulate interface flags. This involves retrieving the
+// current flags, or'ing in some bits, and'ing out others, and updating.
+static void
+real_update_ifflags(int set_bits, int clear_bits)
+{
+ struct ifreq request;
+ int flags;
+
+ strncpy(request.ifr_name, real_devname, IFNAMSIZ);
+ if (ioctl(ether_fd, SIOCGIFFLAGS, &request) < 0) {
+ fprintf(stderr, "rawether (%s): failed to get interface flags, exiting\n", real_devname);
+ exit(1);
+ }
+
+ flags = request.ifr_flags;
+
+ flags |= set_bits;
+ flags &= ~clear_bits;
+
+ if (flags == request.ifr_flags) {
+ // Nothing is changing.
+ return;
+ }
+
+ strncpy(request.ifr_name, real_devname, IFNAMSIZ);
+ request.ifr_flags = flags;
+ if (ioctl(ether_fd, SIOCSIFFLAGS, &request) < 0) {
+ fprintf(stderr, "rawether (%s): failed to update interface flags, exiting\n", real_devname);
+ exit(1);
+ }
+}
+
+
+// Starting an interface. This involves bringing the interface up,
+// and optionally setting promiscuous mode.
+// NOTE: is UP really the right thing here? There is no IP address
+// for this interface. In theory this should not matter because
+// we have a bound socket which should receive all packets for
+// this interface.
+
+static void
+real_handle_start(int promiscuous)
+{
+ if (promiscuous) {
+ real_update_ifflags(IFF_UP | IFF_PROMISC, 0);
+ } else {
+ real_update_ifflags(IFF_UP, IFF_PROMISC);
+ }
+ up = 1;
+}
+
+// Stopping an interface means clearing the UP flag
+static void
+real_handle_stop(void)
+{
+ up = 0;
+ real_update_ifflags(0, IFF_UP | IFF_PROMISC);
+}
+
+// Enabling/disabling multicast support.
+static void
+real_handle_multiall(int on)
+{
+ struct packet_mreq req;
+
+ req.mr_ifindex = real_ifindex;
+ req.mr_type = PACKET_MR_ALLMULTI;
+ req.mr_alen = 0;
+ if (setsockopt(ether_fd, SOL_PACKET, on ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP, (void*)&req, sizeof(req)) < 0) {
+ fprintf(stderr, "rawether (%s): failed to manipulate multicast-all flag, exiting\n", real_devname);
+ exit(1);
+ }
+}
+
+// When the application exists make sure that the interface goes down again.
+
+static void
+real_atexit(void)
+{
+ if (up) {
+ real_update_ifflags(0, IFF_UP | IFF_PROMISC);
+ }
+}
+
+static void
+real_init(char* devname)
+{
+ struct sockaddr_ll addr;
+ struct ifreq request;
+
+ tx_fn = &real_handle_tx;
+ rx_fn = &real_handle_rx;
+ start_fn = &real_handle_start;
+ stop_fn = &real_handle_stop;
+ multicast_fn = &real_handle_multiall;
+
+ if (strlen(devname) >= IFNAMSIZ) {
+ snprintf(msg, MSG_SIZE, "Invalid real network device name \"%s\", too long.\n", devname);
+ report_error(msg);
+ }
+ strcpy(real_devname, devname);
+
+ // All ioctl() operations need a socket. We might as well create the
+ // raw socket immediately and use that.
+ ether_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if (ether_fd < 0) {
+ snprintf(msg, MSG_SIZE, "Unable to create a raw socket for accessing network device\n"
+ " Error %s (errno %d)\n", strerror(errno), errno);
+ report_error(msg);
+ }
+
+ strncpy(request.ifr_name, real_devname, IFNAMSIZ);
+ if (ioctl(ether_fd, SIOCGIFINDEX, &request) < 0) {
+ snprintf(msg, MSG_SIZE, "Device %s does not correspond to a valid interface.\n"
+ " Error %s (errno %d)\n", real_devname, strerror(errno), errno);
+ report_error(msg);
+ }
+ real_ifindex = request.ifr_ifindex;
+
+ // The interface exists. Now check that it is usable.
+ strncpy(request.ifr_name, real_devname, IFNAMSIZ);
+ if (ioctl(ether_fd, SIOCGIFFLAGS, &request) < 0) {
+ snprintf(msg, MSG_SIZE, "Failed to get current interface flags for %s\n"
+ " Error %s (errno %d)\n", real_devname, strerror(errno), errno);
+ report_error(msg);
+ }
+
+ if (request.ifr_flags & (IFF_UP | IFF_RUNNING)) {
+ snprintf(msg, MSG_SIZE, "Network device %s is already up and running.\n"
+ " Exclusive access is required\n", real_devname);
+ report_error(msg);
+ }
+ if (request.ifr_flags & IFF_LOOPBACK) {
+ report_error("Loopback devices cannot be used for synthetic target ethernet emulation.\n");
+ }
+ if (request.ifr_flags & IFF_POINTOPOINT) {
+ report_error("Point-to-point devices cannot be used for synthetic target ethernet emulation.\n");
+ }
+ if (request.ifr_flags & IFF_MULTICAST) {
+ multicast_supported = 1;
+ }
+
+ // Make sure the interface is down. There is no point in receiving packets just yet.
+ real_update_ifflags(0, IFF_UP | IFF_PROMISC);
+
+ // The flags look ok. Now get hold of the hardware address.
+ strncpy(request.ifr_name, real_devname, IFNAMSIZ);
+ if (ioctl(ether_fd, SIOCGIFHWADDR, &request) < 0) {
+ snprintf(msg, MSG_SIZE, "Failed to get hardware address for %s\n"
+ " Error %s (errno %d)\n", real_devname, strerror(errno), errno);
+ report_error(msg);
+ }
+ if (ARPHRD_ETHER != request.ifr_hwaddr.sa_family) {
+ snprintf(msg, MSG_SIZE, "Device %s is not an ethernet device.\n", real_devname);
+ report_error(msg);
+ }
+ memcpy(MAC, request.ifr_hwaddr.sa_data, 6);
+
+ // The device is useable. Now just bind the socket to the appropriate address.
+ addr.sll_family = AF_PACKET;
+ addr.sll_protocol = htons(ETH_P_ALL);
+ addr.sll_ifindex = real_ifindex;
+ if (bind(ether_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
+ snprintf(msg, MSG_SIZE, "Failed to bind socket for direct hardware address to %s\n"
+ " Error %s (errno %d)\n", real_devname, strerror(errno), errno);
+ report_error(msg);
+ }
+
+ // Make sure the interface gets shut down when rawether exits.
+ atexit(real_atexit);
+
+ // And that should be it.
+}
+
+// ----------------------------------------------------------------------------
+// Ethertap device.
+//
+// See /usr/src/linux-2.x.y/Documentation/networking/tuntap.txt for more
+// information on the tun/tap driver.
+//
+// Basically during initialization this code opens /dev/net/tun, then
+// performs a TUNSETIFF ioctl() to initialize it. This causes a
+// new network device tap?? to appear. Any ethernet frames written
+// by the Linux kernel to this device can be read from the
+// dev/net/tun file descriptor, and ethernet frames can be written to
+// the same descriptor. The net effect is a virtual ethernet segment
+// with one interface managed by the Linux kernel and another
+// interface (or, theoretically, several) accessible via the file
+// descriptor.
+//
+// The Linux kernel will invent a MAC address for its interface. An
+// additional one is needed for eCos. This is either invented or
+// specified in the target definition file.
+//
+// Old Linux kernels may not have the required support. This is detected
+// by an autoconf test for <linux/if_tun.h>
+#ifdef HAVE_LINUX_IF_TUN_H
+
+static void
+tap_handle_tx(unsigned char* buffer, int size)
+{
+ int result;
+
+ result = write(ether_fd, buffer, size);
+#if (DEBUG > 0)
+ fprintf(stderr, "rawether dbg: tx %d bytes -> %d\n", size, result);
+#endif
+#if (DEBUG > 1)
+ fprintf(stderr, " %x:%x:%x:%x:%x:%x %x:%x:%x:%x:%x:%x %x:%x\n",
+ buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5],
+ buffer[6], buffer[7], buffer[8], buffer[9], buffer[10], buffer[11],
+ buffer[12], buffer[13]);
+#endif
+}
+
+// Receive a single packet from the socket. It is assumed that the
+// tuntap code inside the kernel will preserve packet boundaries.
+//
+// For now it is assumed that all incoming packets are intended for
+// eCos. That may not be accurate, and additional filtering in
+// software might be appropriate. In promiscuous mode all packets
+// should be accepted, obviously. Otherwise all broadcasts should
+// be accepted, as should all messages intended for this specific
+// interface's MAC address. Multicasts should be accepted only if
+// enabled.
+static void
+tap_handle_rx(void)
+{
+ int size;
+ int result;
+
+ // select() has succeeded so this read() should never block.
+ size = read(ether_fd, rx_buffer + 4, MTU);
+#if (DEBUG > 0)
+ fprintf(stderr, "rawether dbg: rx returned %d, errno %s (%d)\n", size, strerror(errno), errno);
+#endif
+
+ if (size < 0) {
+ return; // Ignore errors, just go around the main loop again.
+ }
+ if ((size < 14) || (size > MTU)) {
+ return; // Invalid packet size. Discard the packet.
+ }
+
+#if (DEBUG > 1)
+ fprintf(stderr, " %x:%x:%x:%x:%x:%x %x:%x:%x:%x:%x:%x %x:%x\n",
+ rx_buffer[4], rx_buffer[5], rx_buffer[6], rx_buffer[7], rx_buffer[8], rx_buffer[9],
+ rx_buffer[10], rx_buffer[11], rx_buffer[12], rx_buffer[13], rx_buffer[14], rx_buffer[15],
+ rx_buffer[16], rx_buffer[17]);
+#endif
+
+ if (!up) {
+ // eCos is not currently expecting packets, so discard them.
+ return;
+ }
+
+ // It looks this packet should get forwarded to eCos.
+ rx_buffer[0] = SYNTH_ETH_RX;
+ rx_buffer[1] = 0;
+ rx_buffer[2] = size & 0x00FF;
+ rx_buffer[3] = (size >> 8) & 0x00FF;
+ do {
+ result = write(1, rx_buffer, 4 + size);
+ } while ((-1 == result) && (EINTR == errno));
+
+ if (result != (size + 4)) {
+ fprintf(stderr, "rawether(%s): failed to send ethernet packet to I/O auxiliary, exiting.\n", real_devname);
+ exit(1);
+ }
+}
+
+// Nothing much can be done for start or stop. Just set the flag and
+// let the rx and tx code discard packets when appropriate.
+//
+// For now the device is implicitly promiscuous and accepts all
+// multicasts. Given the nature of a tap device it is unlikely that
+// any packets will arrive which are not destined here.
+// FIXME: this may have to change if bridging is enabled.
+static void
+tap_handle_start(int promiscuous)
+{
+ up = 1;
+}
+
+static void
+tap_handle_stop(void)
+{
+ up = 0;
+}
+
+static void
+tap_handle_multiall(int on)
+{
+}
+
+static void
+tap_init(int argc, char** argv)
+{
+ char* devname = NULL;
+ struct ifreq ifr;
+ int persistent = 0;
+ int have_mac = 0;
+
+ tx_fn = &tap_handle_tx;
+ rx_fn = &tap_handle_rx;
+ start_fn = &tap_handle_start;
+ stop_fn = &tap_handle_stop;
+ multicast_fn = &tap_handle_multiall;
+
+ // Which device? By default let the system pick one, but the user
+ // can override this.
+ if (0 != argc) {
+ devname = argv[0];
+ }
+
+ // Work out the MAC address. By default a random one is generated,
+ // but the user can specify one to avoid a source of randomness.
+ // This MAC address is not actually needed by any of the code here,
+ // but should be returned to eCos.
+ if (2 <= argc) {
+ unsigned int mac_data[6]; // sscanf() needs unsigned ints
+ int result = sscanf(argv[1], "%x:%x:%x:%x:%x:%x",
+ &(mac_data[0]), &(mac_data[1]), &(mac_data[2]),
+ &(mac_data[3]), &(mac_data[4]), &(mac_data[5]));
+ if (6 != result) {
+ if (strncmp(argv[1], "persistent", 10)) {
+ snprintf(msg, MSG_SIZE, "Invalid MAC address %s\n", argv[1]);
+ report_error(msg);
+ }
+ } else {
+ MAC[0] = mac_data[0];
+ MAC[1] = mac_data[1];
+ MAC[2] = mac_data[2];
+ MAC[3] = mac_data[3];
+ MAC[4] = mac_data[4];
+ MAC[5] = mac_data[5];
+ argv += 1;
+ argc -= 1;
+ have_mac = 1;
+ }
+ }
+ if ( 1 != have_mac) {
+ srand(time(NULL));
+ MAC[0] = 0;
+ MAC[1] = 0x0FF;
+ MAC[2] = rand() & 0x0FF;
+ MAC[3] = rand() & 0x0FF;
+ MAC[4] = rand() & 0x0FF;
+ MAC[5] = rand() & 0x0FF;
+ }
+
+ // Should we make the TAP device persistent. When persistence is
+ // enabled, the tap device is not removed when rawether
+ // exits. This makes daemons happier. They can keep running
+ // between invocations of rawether.
+ if (2 <= argc ) {
+ persistent = !strncmp(argv[1], "persistent", 10);
+ }
+
+ ether_fd = open("/dev/net/tun", O_RDWR);
+ if (ether_fd < 0) {
+ snprintf(msg, MSG_SIZE, "Failed to open /dev/net/tun, errno %s (%d)\n", strerror(errno), errno);
+ report_error(msg);
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ if (NULL != devname) {
+ strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1);
+ }
+ if (ioctl(ether_fd, TUNSETIFF, (void*)&ifr) < 0) {
+ snprintf(msg, MSG_SIZE, "Failed to initialize /dev/net/tun, errno %s (%d)\n", strerror(errno), errno);
+ report_error(msg);
+ }
+
+ // Supporting multicasts is a no-op
+ multicast_supported = 1;
+
+ if (persistent) {
+ if (ioctl(ether_fd, TUNSETPERSIST, 1) < 0) {
+ snprintf(msg, MSG_SIZE, "Failed to set persistent flag, errno %s (%d)\n",
+ strerror(errno), errno);
+ report_error(msg);
+ }
+ }
+ // All done.
+}
+#else
+static void
+tap_init(int argc, char** argv)
+{
+ snprintf(msg, MSG_SIZE, "Ethertap support was not available when the host-side support was built\n");
+ report_error(msg);
+}
+#endif // HAVE_LINUX_IF_TUN_H
+
+// ----------------------------------------------------------------------------
+// Receive a single request from ecosynth. This consists of a four-byte
+// header, optionally followed by a tx packet. EOF indicates that
+// ecosynth has exited, so this process should just exit immediately
+// as well. Any problems should be reported to stderr, followed by
+// termination.
+//
+// Currently rawether is single-threaded. Theoretically this could
+// cause a deadlock situation where the I/O auxiliary is trying to send
+// rawether a request and is blocked on the write, while rawether is trying
+// to send data to the I/O auxiliary. In practice the pipes should do
+// enough buffering to avoid complications, especially since rawether
+// gives priority to requests from the auxiliary.
+
+static void
+handle_ecosynth_request(void)
+{
+ unsigned char req[4];
+ int result;
+ int code, arg, size;
+
+ result = read(0, req, 4);
+ if (result == 0) {
+ // select() succeeded but no data. EOF. So exit
+ exit(0);
+ }
+ if (result < 0) {
+ // EINTR? EAGAIN? The latter should not happen since the pipe
+ // has not been put into non-blocking mode.
+ if ((EINTR == errno) || (EAGAIN == errno)) {
+ return;
+ } else {
+ fprintf(stderr, "rawether: unexpected error reading request from ecosynth\n");
+ fprintf(stderr, " %s\n", strerror(errno));
+ exit(1);
+ }
+ }
+ if (result < 4) {
+ fprintf(stderr, "rawether: unexpected error reading request from ecosynth\n Expected 4 bytes, only received %d\n", result);
+ exit(1);
+ }
+
+ code = req[0];
+ arg = req[1];
+ size = req[2] + (req[3] << 8);
+
+#if (DEBUG > 1)
+ fprintf(stderr, "rawether dbg: request %x from auxiliary\n", code);
+#endif
+
+ switch(code) {
+ case SYNTH_ETH_TX:
+ {
+ if (size < 14) {
+ fprintf(stderr, "rawether: attempt to send invalid ethernet packet of only %d bytes\n"
+ "Ethernet packets should be at least 14 bytes.\n", size);
+ exit(1);
+ }
+ if (size > MTU) {
+ fprintf(stderr, "rawether: attempt to send invalid ethernet packet of %d bytes\n"
+ "Only packets of up to %d bytes are supported.\n", size, MTU);
+ exit(1);
+ }
+ do {
+ result = read(0, tx_buffer, size);
+ } while ((-1 == result) && (EINTR == errno));
+ if (0 == result) {
+ // EOF, at an inopportune moment
+ exit(0);
+ }
+ if (result < size) {
+ fprintf(stderr, "rawether: error reading ethernet packet from I/O auxiliary\n"
+ "Expected %d bytes but only read %d\n", size, result);
+ exit(1);
+ }
+
+ (*tx_fn)(tx_buffer, size);
+ break;
+ }
+ case SYNTH_ETH_START:
+ {
+ (*start_fn)(arg);
+ break;
+ }
+
+ case SYNTH_ETH_STOP:
+ {
+ (*stop_fn)();
+ break;
+ }
+
+ case SYNTH_ETH_MULTIALL:
+ {
+ (*multicast_fn)(arg);
+ break;
+ }
+
+ // SYNTH_ETH_RX and SYNTH_ETH_GETPARAMS are handled inside ethernet.tcl
+
+ default:
+ fprintf(stderr, "rawether: protocol violation, received unknown request %d\n", code);
+ exit(1);
+ }
+}
+
+// The main loop. This waits for an event either from ecosynth or from
+// the underlying ethernet device, using select. Requests from
+// ecosynth are handled, and take priority to prevent the connecting
+// pipe from filling up and ecosynth blocking. Incoming ethernet
+// frames are forwarded to ecosynth.
+
+static void
+mainloop(void)
+{
+ fd_set read_set;
+ struct timeval timeout;
+ int result;
+
+ for ( ; ; ) {
+ FD_ZERO(&read_set);
+ FD_SET(0, &read_set);
+ FD_SET(ether_fd, &read_set);
+ timeout.tv_sec = 24 * 60 * 60;
+ timeout.tv_usec = 0;
+
+ result = select(ether_fd + 1, &read_set, NULL, NULL, &timeout);
+ if (result <= 0) {
+ continue;
+ }
+
+ if (FD_ISSET(0, &read_set)) {
+ handle_ecosynth_request();
+ } else if (FD_ISSET(ether_fd, &read_set)) {
+ (*rx_fn)();
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+int
+main(int argc, char**argv)
+{
+ // Ignore incoming ctrl-C's. We are in the same process group as the
+ // eCos application which may sensibly be ctrl-C'd, but that should
+ // result in the auxiliary detecting EOF and closing the pipe to
+ // this process, which in turn causes this process to exit completely.
+ signal(SIGINT, SIG_IGN);
+
+ if (2 > argc ) {
+ report_error("Expected at least one argument, \"real\" or \"ethertap\"\n");
+ }
+ if (0 == strcmp("real", argv[1])) {
+ real_ether = 1;
+ real_init(argv[2]);
+ } else if (0 == strcmp("ethertap", argv[1])) {
+ ethertap = 1;
+ tap_init(argc - 2, argv + 2);
+ } else {
+ snprintf(msg, MSG_SIZE, "Invalid argument %s, expected \"real\" or \"ethertap\"\n", argv[1]);
+ report_error(msg);
+ }
+
+ // If the device-specific initialization succeeded we must be set.
+ report_success();
+
+ mainloop();
+
+ return 0;
+}
+
+
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/host/tonet.xbm b/ecos/packages/devs/eth/synth/ecosynth/current/host/tonet.xbm
new file mode 100644
index 0000000..e7f1f8b
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/host/tonet.xbm
@@ -0,0 +1,4 @@
+#define tonet_width 8
+#define tonet_height 8
+static unsigned char tonet_bits[] = {
+ 0x00, 0x87, 0x95, 0xa5, 0xfd, 0xa5, 0x95, 0x87};
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/src/protocol.h b/ecos/packages/devs/eth/synth/ecosynth/current/src/protocol.h
new file mode 100644
index 0000000..2282d9a
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/src/protocol.h
@@ -0,0 +1,71 @@
+#ifndef CYGONCE_DEVS_ETH_ECOSYNTH_PROTOCOL_H
+#define CYGONCE_DEVS_ETH_ECOSYNTH_PROTOCOL_H
+
+//=============================================================================
+//
+// protocol.h
+//
+// Protocol between target-side and host-side ethernet support.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors:bartv
+// Date: 2002-08-08
+// Purpose: Protocol definitions.
+// Usage: #include "protocol.h"
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// Transmit: no arguments, up to 1514 bytes of outgoing data, no reply expected.
+#define SYNTH_ETH_TX 0x01
+// Receive: no arguments or data, the return code indicates whether or not
+// there are more packets to follow, and the return data is up to 1514 bytes.
+#define SYNTH_ETH_RX 0x02
+// Start: one argument, non-zero -> promiscuous mode. No reply.
+#define SYNTH_ETH_START 0x03
+// Stop: no arguments or reply.
+#define SYNTH_ETH_STOP 0x04
+// Settings: no arguments or data. The return code holds the interrupt vector.
+// The return data is six bytes of MAC address, plus a single byte indicating
+// whether or not multicasting is supported.
+#define SYNTH_ETH_GETPARAMS 0x05
+// Enable/disable multicasting. One argument, enable/disable.
+#define SYNTH_ETH_MULTIALL 0x06
+
+#endif // CYGONCE_DEVS_ETH_ECOSYNTH_PROTOCOL.H
diff --git a/ecos/packages/devs/eth/synth/ecosynth/current/src/syntheth.c b/ecos/packages/devs/eth/synth/ecosynth/current/src/syntheth.c
new file mode 100644
index 0000000..0272d43
--- /dev/null
+++ b/ecos/packages/devs/eth/synth/ecosynth/current/src/syntheth.c
@@ -0,0 +1,457 @@
+//==========================================================================
+//
+// syntheth.c
+//
+// Network device driver for the synthetic target
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors: bartv
+// Date: 2002-08-07
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/devs_eth_ecosynth.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <errno.h>
+#include <string.h>
+
+#define __ECOS 1
+#include <sys/types.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#include <cyg/io/eth/eth_drv_stats.h>
+
+#ifdef CYGPKG_NET
+# include <net/if.h>
+#else
+# define IFF_PROMISC 0
+#endif
+
+#include <cyg/hal/hal_io.h>
+#include "protocol.h"
+
+// ----------------------------------------------------------------------------
+// Device instances. The synthetic target ethernet package can support
+// up to four ethernet devices, eth0 to eth3. A synth_eth structure
+// holds the data that is specific to a given device. Each device
+// needs an instance of this structure, followed by ETH_DRV_SC and
+// NETDEVTAB_ENTRY macros. Another macro SYNTH_ETH_INSTANCE takes
+// care of all that, to avoid unnecessary duplication of code here.
+//
+// NOTE: unfortunately this involves duplicating the eth_hwr_funs
+// structure. This could be eliminated but it would require bypassing
+// the ETH_DRV_SC macro.
+
+#define ETHERNET_MINTU 14
+#define ETHERNET_MAXTU 1514
+
+
+typedef struct synth_eth {
+ int synth_id; // Device id within the auxiliary
+ int up; // Has there been a call to start()?
+ int in_send; // Detect recursive calls
+ int tx_done;
+ unsigned long tx_key; // Allow mbuf's to be freed
+ volatile int rx_pending; // There is pending data.
+ int rx_len; // Length of buffered data.
+ unsigned char MAC[6]; // Obtained from the underlying ethernet device
+ cyg_vector_t interrupt; // Interrupt number allocated by the auxiliary
+ int multi_supported; // Does the driver support multicasting?
+ cyg_handle_t interrupt_handle; // Allow the ISR and DSR to be installed.
+ cyg_interrupt interrupt_data;
+ unsigned char tx_data[ETHERNET_MAXTU];
+ unsigned char rx_data[ETHERNET_MAXTU];
+} synth_eth;
+
+#define SYNTH_ETH_INSTANCE( _number_) \
+static synth_eth synth_eth##_number_ = { \
+ synth_id: -1, \
+ up: 1, \
+ in_send: 0, \
+ tx_done: 0, \
+ tx_key: 0L, \
+ rx_pending: 0, \
+ rx_len: 0, \
+ MAC: { 0, 0, 0, 0, 0, 0 }, \
+ interrupt: 0, \
+ interrupt_handle: 0 \
+}; \
+ETH_DRV_SC(synth_eth_sc##_number_, \
+ (void*) &synth_eth##_number_, \
+ "eth" #_number_, \
+ synth_eth_start, \
+ synth_eth_stop, \
+ synth_eth_ioctl, \
+ synth_eth_can_send, \
+ synth_eth_send, \
+ synth_eth_recv, \
+ synth_eth_deliver, \
+ synth_eth_poll, \
+ synth_eth_intvector); \
+NETDEVTAB_ENTRY(synth_eth_netdev##_number_, \
+ "synth_eth" #_number_, \
+ synth_eth_init, \
+ &synth_eth_sc##_number_);
+
+#ifdef CYGVAR_DEVS_ETH_ECOSYNTH_ETH0
+SYNTH_ETH_INSTANCE(0);
+#endif
+#ifdef CYGVAR_DEVS_ETH_ECOSYNTH_ETH1
+SYNTH_ETH_INSTANCE(1);
+#endif
+#ifdef CYGVAR_DEVS_ETH_ECOSYNTH_ETH2
+SYNTH_ETH_INSTANCE(2);
+#endif
+#ifdef CYGVAR_DEVS_ETH_ECOSYNTH_ETH3
+SYNTH_ETH_INSTANCE(3);
+#endif
+
+// ----------------------------------------------------------------------------
+// Data transmits.
+//
+// The eCos application will just send the data to the auxiliary,
+// which will in turn pass it on to the rawether utility. There is no
+// need for any response. Flow control is implicit: if the eCos
+// application tries to send ethernet packets too quickly then those
+// get passed on to the auxiliary, which in turn will pass them on to
+// the rawether process. If rawether is still busy with the previous
+// packet then the auxiliary will block on a pipe write, and in turn
+// the eCos application will block. As long as rawether manages to
+// complete its operations reasonably quickly these blocks should not
+// be noticeable to the user.
+//
+// So can_send() should always return true for an interface that is up
+// and running. The send operation needs to take the sg list, turn it
+// into a single buffer, and transmit it to the auxiliary. At that
+// point the transmission is already complete so eth_drv_dsr() should
+// be called to call deliver() and release the buffer.
+//
+// However there are some complications. The first is polled operation,
+// where eth_drv_dsr() is a no-op and should not really be called at
+// all because there are no interrupts going off. The second is that
+// calling eth_drv_dsr() directly will cause recursive operation:
+// send() -> dsr -> can_send()/send() -> ...
+// This is a bad idea, so can_send() has to check that we are not
+// already inside a send(). Data transmission will proceed merrily
+// once the send has returned.
+
+static int
+synth_eth_can_send(struct eth_drv_sc* sc)
+{
+ synth_eth* eth = (synth_eth*)(sc->driver_private);
+ return synth_auxiliary_running && eth->up && !eth->in_send && !eth->tx_done;
+}
+
+static void
+synth_eth_send(struct eth_drv_sc* sc,
+ struct eth_drv_sg* sg_list, int sg_len, int total_len,
+ unsigned long key)
+{
+ synth_eth* eth = (synth_eth*)(sc->driver_private);
+
+ CYG_PRECONDITION((total_len >= ETHERNET_MINTU) && (total_len <= ETHERNET_MAXTU), "Only normal-sized ethernet packets are supported");
+ CYG_PRECONDITION(!eth->in_send && !eth->tx_done, "Ethernet device must not still be in use for transmits");
+
+ eth->in_send = 1;
+ eth->tx_key = key;
+ if (synth_auxiliary_running && eth->up) {
+ int i;
+ unsigned char* buf = eth->tx_data;
+ for (i = 0; i < sg_len; i++) {
+ memcpy(buf, (void*) sg_list[i].buf, sg_list[i].len);
+ buf += sg_list[i].len;
+ CYG_LOOP_INVARIANT(buf <= &(eth->tx_data[ETHERNET_MAXTU]), "sg list must not exceed ethernet MTU");
+ }
+ CYG_POSTCONDITION(buf == &(eth->tx_data[total_len]), "sg list lengths should match total_len");
+
+ synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_TX, 0, 0, eth->tx_data, total_len,
+ (void*) 0, (unsigned char*)0, (int*)0, 0);
+ }
+
+ // The transfer has now completed, one way or another, so inform
+ // the higher-level code immediately.
+ eth->tx_done = 1;
+ eth_drv_dsr(eth->interrupt, 0, (cyg_addrword_t) sc);
+ eth->in_send = 0;
+}
+
+// ----------------------------------------------------------------------------
+// Receives.
+//
+// These are rather more complicated because there are real interrupts
+// involved, and polling needs to be supported as well. The actual
+// transfer of data from auxiliary to eCos happens inside deliver(),
+// and the data is buffered up in the synth_eth structure. All that
+// needs to be done here is scatter the existing data into the
+// sg_list. If higher-level code has run out of space then the
+// sg_list may contain null pointers.
+
+static void
+synth_eth_recv(struct eth_drv_sc* sc, struct eth_drv_sg* sg_list, int sg_len)
+{
+ synth_eth* eth = (synth_eth*)(sc->driver_private);
+ unsigned char* buf = eth->rx_data;
+ int len = eth->rx_len;
+ int i;
+
+ for (i = 0; i < sg_len; i++) {
+ if (0 == sg_list[i].buf) {
+ break;
+ } else if (len <= sg_list[i].len) {
+ memcpy((void*)sg_list[i].buf, buf, len);
+ break;
+ } else {
+ memcpy((void*)sg_list[i].buf, buf, sg_list[i].len);
+ buf += sg_list[i].len;
+ len -= sg_list[i].len;
+ }
+ }
+}
+
+// The ISR does not have to do anything, the DSR does the real work.
+static cyg_uint32
+synth_eth_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_drv_interrupt_acknowledge(vector);
+ return CYG_ISR_CALL_DSR;
+}
+
+// The DSR also does not have to do very much. The data argument is
+// actually the eth_drv_sc structure, which must match the vector.
+// Interrupts only go off when there are pending receives, so set the
+// rx_pending flag and call the generic DSR to do the real work.
+static void
+synth_eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct eth_drv_sc* sc = (struct eth_drv_sc*) data;
+ synth_eth* eth = (synth_eth*)(sc->driver_private);
+ CYG_ASSERT(eth->interrupt == vector, "Interrupt vectors cannot change during a run");
+
+ eth->rx_pending = 1;
+ eth_drv_dsr(vector, count, data);
+}
+
+// ----------------------------------------------------------------------------
+// Delivery. This is invoked by a thread inside the TCP/IP stack, or by
+// the poll function.
+static void
+synth_eth_deliver(struct eth_drv_sc* sc)
+{
+ synth_eth* eth = (synth_eth*)(sc->driver_private);
+
+ if (eth->tx_done) {
+ eth->tx_done = 0;
+ (*sc->funs->eth_drv->tx_done)(sc, eth->tx_key, 1);
+ }
+ while (eth->rx_pending) {
+ int more = 1;
+ eth->rx_pending = 0;
+
+ while (more && eth->up && synth_auxiliary_running) {
+ synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_RX, 0, 0, (void*) 0, 0,
+ &more, eth->rx_data, &(eth->rx_len), ETHERNET_MAXTU);
+ CYG_LOOP_INVARIANT(!more || (0 != eth->rx_len), "Auxiliary must send at least one packet if several are available");
+ if (eth->rx_len > 0) {
+ CYG_ASSERT((eth->rx_len >= ETHERNET_MINTU) && (eth->rx_len <= ETHERNET_MAXTU), "Only normal-sized ethernet packets are supported");
+ // Inform higher-level code that data is available.
+ // This should result in a call to recv() with a
+ // suitable sg_list. If out of memory, recv()
+ // will see a null pointer.
+ (*sc->funs->eth_drv->recv)(sc, eth->rx_len);
+ }
+ };
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// Polling support. Transmits are relatively straightforward because
+// all the hard work is handled by send(). Receives are rather more
+// complicated because interrupts are disabled so we never know when
+// there is really pending data. However deliver() will do the right
+// thing even if there is no data, so simply faking up an interrupt
+// is enough. This does mean extra traffic between application and
+// auxiliary, but polling does rather imply that.
+static void
+synth_eth_poll(struct eth_drv_sc* sc)
+{
+ synth_eth* eth = (synth_eth*)(sc->driver_private);
+ if (synth_auxiliary_running && eth->up) {
+ eth->rx_pending = 1;
+ }
+ synth_eth_deliver(sc);
+}
+
+static int
+synth_eth_intvector(struct eth_drv_sc* sc)
+{
+ synth_eth* eth = (synth_eth*)(sc->driver_private);
+ return eth->interrupt;
+}
+
+// ----------------------------------------------------------------------------
+// ioctl()'s.
+//
+// SET_MAC_ADDRESS is not currently implemented, and probably should
+// not be implemented because the underlying ethernet device may not
+// support it.
+//
+// SET_MC_ALL is supported if the underlying hardware does. This is
+// needed for IPV6 support. More selective multicasting via
+// SET_MC_LIST is not supported, because it imposes too heavy a
+// requirement on the underlying Linux device. SET_MC_LIST can be
+// used to disable multicast support.
+//
+// GET_IF_STATS_UD and GET_IF_STATS are not currently implemented
+static int
+synth_eth_ioctl(struct eth_drv_sc* sc, unsigned long key, void* data, int data_length)
+{
+ synth_eth* eth = (synth_eth*)(sc->driver_private);
+ int result = EINVAL;
+
+ switch(key) {
+ case ETH_DRV_SET_MC_ALL:
+ {
+ if (eth->multi_supported) {
+ synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_MULTIALL, 1, 0, (unsigned char*) 0, 0,
+ (void*)0, (unsigned char*)0, (int*)0, 0);
+ result = 0;
+ }
+ break;
+ }
+ case ETH_DRV_SET_MC_LIST:
+ {
+ struct eth_drv_mc_list* mcl = (struct eth_drv_mc_list*) data;
+ if (eth->multi_supported && (0 == mcl->len)) {
+ synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_MULTIALL, 0, 0, (unsigned char*) 0, 0,
+ (void*)0, (unsigned char*)0, (int*)0, 0);
+ result = 0;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// Starting and stopping an interface. This includes restarting in
+// promiscuous mode.
+static void
+synth_eth_start(struct eth_drv_sc* sc, unsigned char* enaddr, int flags)
+{
+ synth_eth* eth = (synth_eth*)(sc->driver_private);
+
+ eth->up = 0;
+ eth->rx_pending = 0;
+
+ if ((-1 != eth->synth_id) && synth_auxiliary_running) {
+ synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_START, flags & IFF_PROMISC, 0, (void*) 0, 0,
+ (int*)0, (void*) 0, (int*) 0, 0);
+ }
+ eth->up = 1;
+}
+
+static void
+synth_eth_stop(struct eth_drv_sc* sc)
+{
+ synth_eth* eth = (synth_eth*)(sc->driver_private);
+
+ eth->up = 0;
+ if ((-1 != eth->synth_id) && synth_auxiliary_running) {
+ synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_STOP, 0, 0, (void*) 0, 0,
+ (int*) 0, (void*) 0, (int*) 0, 0);
+ }
+ eth->rx_pending = 0;
+}
+
+
+// ----------------------------------------------------------------------------
+// Initialization.
+//
+// This requires instantiating a device of class ethernet with a specific
+// device name held in the eth_drv_sc structure. No additional device data
+// is needed. If a device can be instantiated then the interrupt vector
+// and the MAC address can be obtained, and an interrupt handler can be
+// installed.
+static bool
+synth_eth_init(struct cyg_netdevtab_entry* ndp)
+{
+ bool result = false;
+ struct eth_drv_sc* sc = (struct eth_drv_sc*)(ndp->device_instance);
+ struct synth_eth* eth = (struct synth_eth*)(sc->driver_private);
+
+ if (synth_auxiliary_running) {
+ eth->synth_id = synth_auxiliary_instantiate("devs/eth/synth/ecosynth", SYNTH_MAKESTRING(CYGPKG_DEVS_ETH_ECOSYNTH), "ethernet",
+ sc->dev_name, (const char*) 0);
+
+ if (-1 != eth->synth_id) {
+ unsigned char data[7];
+ result = true;
+ synth_auxiliary_xchgmsg(eth->synth_id, SYNTH_ETH_GETPARAMS, 0, 0, (const unsigned char*) 0, 0,
+ (int *)&(eth->interrupt), data, 0, 7);
+ memcpy(eth->MAC, data, 6);
+ eth->multi_supported = data[6];
+ cyg_drv_interrupt_create(eth->interrupt,
+ 0,
+ (CYG_ADDRWORD) sc,
+ &synth_eth_isr,
+ &synth_eth_dsr,
+ &(eth->interrupt_handle),
+ &(eth->interrupt_data));
+ cyg_drv_interrupt_attach(eth->interrupt_handle);
+ cyg_drv_interrupt_unmask(eth->interrupt);
+ }
+ }
+ (*sc->funs->eth_drv->init)(sc, eth->MAC);
+
+#ifdef CYGPKG_NET
+ if (eth->multi_supported) {
+ sc->sc_arpcom.ac_if.if_flags |= IFF_ALLMULTI;
+ }
+#endif
+ return result;
+}
diff --git a/ecos/packages/devs/eth/via/rhine/current/ChangeLog b/ecos/packages/devs/eth/via/rhine/current/ChangeLog
new file mode 100644
index 0000000..95b9e68
--- /dev/null
+++ b/ecos/packages/devs/eth/via/rhine/current/ChangeLog
@@ -0,0 +1,168 @@
+2011-08-28 Stephen Polkowski <stephen@centtech.com>
+ Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * src/via_rhine.h: Fix some compiler warning.
+ * src/if_rhine.c (via_rhine_init): Manage ESA with HAL_PCI_IO* macros.
+ [ Bugzilla 1001269 ]
+
+2004-08-12 Jani Monoses <jani@iv.ro>
+
+ * src/if_rhine.c: Fix builing with lwip.
+
+2002-06-14 Gary Thomas <gary@chez-thomas.org>
+
+ * src/if_rhine.c:
+ Need to include <pkgconf/io_eth_drivers.h> for proper configuration
+ of stand-alone (polled) vs. system (interrupt driven) mode.
+
+2001-08-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/via_rhine.h:
+ * src/if_rhine.c:
+ printf() is no longer a part of RedBoot. Thus all programs
+ must use diag_printf() and related functions instead.
+
+2001-07-05 Jesper Skov <jskov@redhat.com>
+
+ * src/via_rhine.h: Define IMR init value.
+ * src/if_rhine.c: And use it.
+
+ * src/if_rhine.c: Remove unused code.
+ * src/via_rhine.h: Remove unused variable.
+
+ * src/if_rhine.c (find_rhine_match_func): Added debug output. Fix
+ some warnings and an error.
+
+2001-07-04 Jesper Skov <jskov@redhat.com>
+
+ * src/if_rhine.c: Added D-Link pre-reset magic. Disabled driver
+ polls (leave it to interrupt handler).
+
+ * src/via_rhine.h: Added more definitions.
+
+ * src/if_rhine.c (rhine_can_send): Force MII status update by
+ reading from PHY controller.
+
+2001-07-02 Jesper Skov <jskov@redhat.com>
+
+ * src/via_rhine.h: Fail to build if CPU to PCI address translation
+ macros are not provided.
+
+2001-06-29 Jesper Skov <jskov@redhat.com>
+
+ * src/via_rhine.h: Fix macro typos.
+
+ * src/if_rhine.c (rhine_poll): Put a mutex on this function.
+
+2001-06-28 Jesper Skov <jskov@redhat.com>
+
+ * src/if_rhine.c: Comment out unused function to silence warning.
+ Removed unused mem_base. Set interrupt priority to non-zero.
+
+ * src/via_rhine.h (INCR_STAT): Fix typo.
+
+2001-06-27 Jesper Skov <jskov@redhat.com>
+
+ * src/if_rhine.c (rhine_can_send): Read MII status which appears
+ to make link magic work. Not at all clear why this is so, but it
+ works.
+
+ * src/via_rhine.h: Disable debug output.
+
+ * src/if_rhine.c (rhine_start): Name magic registers.
+ (rhine_start): Remove some verbose output.
+
+ * src/via_rhine.h: Added register definitions. Removed unused key
+ IDs.
+
+2001-06-26 Jesper Skov <jskov@redhat.com>
+
+ * src/if_rhine.c: Rename PCI IO macros.
+ * src/via_rhine.h: Same. And include PCI header.
+
+ * cdl/via_rhine_eth_drivers.cdl: Require PCI package.
+
+2001-06-25 Jesper Skov <jskov@redhat.com>
+
+ * src/if_rhine.c: Some cleanups, more debug code added, use macros
+ for accessing PCI IO space which platform can override. Some of
+ these changes from David Woodhouse.
+ * src/via_rhine.h: All macros moved to this file.
+
+2001-06-07 Jesper Skov <jskov@redhat.com>
+
+ * src/via_rhine.h: Rename MII definitions.
+ * src/if_rhine.c: Don't reset the controller when stopping. This
+ fixes the problem with the link state being weird. Clean up the
+ renegotiate code a bit.
+
+ * src/if_rhine.c: Added code to gather statistics.
+ Some output cleanup, sanity checking of RX queue only when
+ assertions enabled.
+
+2001-06-06 Jesper Skov <jskov@redhat.com>
+
+ * src/via_rhine.h: MII definitions.
+ * src/if_rhine.c: Added MII accessor functions to allow a forced
+ renegotiate of the connection on a link fail.
+
+ * src/if_rhine.c: Use PCI information to configure devices. Mask
+ interrupts in handlers.
+ (rhine_dsr): Oops, skipped driver synchronization.
+
+ * src/via_rhine.h: Added more private data.
+
+ * cdl/via_rhine_eth_drivers.cdl: Removed static ESA config option
+ - it belongs in the platform configury. Added device count for PCI
+ configury.
+ * src/if_rhine.c: Fix static ESA configury.
+ * src/via_rhine.h: Changed private data accordingly.
+
+ * src/if_rhine.c: Fix buglet in handling of small packets, small
+ hacks to interrupt handling.
+
+2001-06-01 Jesper Skov <jskov@redhat.com>
+
+ * src/if_rhine.c: Tell stack the ESA. Pad short packets.
+
+ * src/via_rhine.h: Added defs.
+
+ * src/if_rhine.c: Mask off PCI addresses - need proper macros for
+ this, or rather, use PCI API to get correct addresses. Close RX/TX
+ descriptor loops. Load RX/TX base pointers into NIC. Enable TX.
+
+2001-05-31 Jesper Skov <jskov@redhat.com>
+
+ * src/via_rhine.h: Make TX/RX descriptor entries 32 bit only to
+ avoid endian issues with offsets.
+
+ * src/if_rhine.c: Hacking code to (more or less) comply to
+ Rhine. Needs debugging though - manual is really thin!
+
+2001-05-30 Jesper Skov <jskov@redhat.com>
+
+ * Cloned from AMD PCNet driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/eth/via/rhine/current/cdl/via_rhine_eth_drivers.cdl b/ecos/packages/devs/eth/via/rhine/current/cdl/via_rhine_eth_drivers.cdl
new file mode 100644
index 0000000..a6588d4
--- /dev/null
+++ b/ecos/packages/devs/eth/via/rhine/current/cdl/via_rhine_eth_drivers.cdl
@@ -0,0 +1,95 @@
+# ====================================================================
+#
+# via_rhine_eth_drivers.cdl
+#
+# Ethernet drivers - support for VIA RHINE ethernet controllers
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov
+# Date: 2001-05-30
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_VIA_RHINE {
+ display "VIA RHINE compatible ethernet driver"
+ description "Ethernet driver for VIA RHINE compatible controllers."
+
+ parent CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_ETH_DRIVERS
+ active_if CYGPKG_IO_PCI
+
+ active_if CYGINT_DEVS_ETH_VIA_RHINE_REQUIRED
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ compile -library=libextras.a if_rhine.c
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_DEVS_ETH_VIA_RHINE_CFG";
+ }
+
+ cdl_option CYGNUM_DEVS_ETH_VIA_RHINE_DEV_COUNT {
+ display "Number of supported interfaces."
+ calculated { CYGINT_DEVS_ETH_VIA_RHINE_REQUIRED }
+ flavor data
+ description "
+ This option selects the number of PCI ethernet interfaces to
+ be supported by the driver."
+ }
+
+ cdl_component CYGPKG_DEVS_ETH_VIA_RHINE_OPTIONS {
+ display "RHINE ethernet driver build options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_ETH_VIA_RHINE_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "-D_KERNEL -D__ECOS" }
+ description "
+ This option modifies the set of compiler flags for
+ building the RHINE ethernet driver package.
+ These flags are used in addition
+ to the set of global flags."
+ }
+ }
+}
diff --git a/ecos/packages/devs/eth/via/rhine/current/src/if_rhine.c b/ecos/packages/devs/eth/via/rhine/current/src/if_rhine.c
new file mode 100644
index 0000000..6eb93ce
--- /dev/null
+++ b/ecos/packages/devs/eth/via/rhine/current/src/if_rhine.c
@@ -0,0 +1,1306 @@
+//==========================================================================
+//
+// dev/if_rhine.c
+//
+// Ethernet device driver for VIA RHINE compatible controllers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, based on pcnet driver
+// Contributors: gthomas, jskov, hmt
+// Date: 2001-05-30
+// Purpose:
+// Description: hardware driver for VIA Rhine ethernet
+//
+// FIXME: Make endian safe
+// Make use of virtual addressing for memory shared over PCI
+// (see _ADDR_MASK).
+// Link failure not detected for some reason.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_eth_via_rhine.h>
+#include <pkgconf/io_eth_drivers.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+#ifdef CYGPKG_NET
+#include <pkgconf/net.h>
+#include <cyg/kernel/kapi.h>
+#include <net/if.h> /* Needed for struct ifnet */
+#include <pkgconf/io_eth_drivers.h>
+#endif
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#ifdef CYGPKG_IO_PCI
+#include <cyg/io/pci.h>
+#else
+#error "Need PCI package here"
+#endif
+
+#define _BUF_SIZE 1544
+
+#ifdef CYGPKG_INFRA_DEBUG
+// Then we log, OOI, the number of times we get a bad packet number
+// from the tx done fifo.
+int rhine_txfifo_good = 0;
+int rhine_txfifo_bad = 0;
+#endif
+
+#include "via_rhine.h"
+
+#define __WANT_DEVS
+#include CYGDAT_DEVS_ETH_VIA_RHINE_INL
+#undef __WANT_DEVS
+
+static void rhine_poll(struct eth_drv_sc *sc);
+
+// This ISR is called when the ethernet interrupt occurs
+static cyg_uint32
+rhine_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct rhine_priv_data *cpd = (struct rhine_priv_data *)data;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( interrupts );
+
+ cyg_drv_interrupt_mask(cpd->interrupt);
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+static void
+rhine_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ // This conditioning out is necessary because of explicit calls to this
+ // DSR - which would not ever be called in the case of a polled mode
+ // usage ie. in RedBoot.
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ struct rhine_priv_data* cpd = (struct rhine_priv_data *)data;
+ struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->ndp);
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+
+ // but here, it must be a *sc:
+ eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
+#else
+# ifndef CYGPKG_REDBOOT
+# error Empty Rhine ethernet DSR is compiled. Is this what you want?
+# endif
+#endif
+}
+
+// The deliver function (ex-DSR) handles the ethernet [logical] processing
+static void
+rhine_deliver(struct eth_drv_sc *sc)
+{
+ struct rhine_priv_data *cpd = (struct rhine_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ // Service the interrupt:
+ rhine_poll(sc);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+}
+
+static int
+rhine_int_vector(struct eth_drv_sc *sc)
+{
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+
+ return (cpd->interrupt);
+}
+
+// ------------------------------------------------------------------------
+// Physical interface
+#if 0 // fix warning since this isn't actually used
+static void
+rhine_write_MII(struct rhine_priv_data *cpd, int id, int reg, cyg_uint16 value)
+{
+ cyg_uint8 stat;
+ int i = 1000;
+
+ // Wait for a previous access to complete (within reason)
+ do {
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIICR, stat);
+ } while ((stat & (RHINE_MIICR_RCMD | RHINE_MIICR_WCMD)) && i-- > 0);
+
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, 0);
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PHYADR, id);
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIIAD, reg);
+ HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_MIIDATA, value);
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, RHINE_MIICR_WCMD);
+}
+#endif
+
+static int
+rhine_read_MII(struct rhine_priv_data *cpd, int id, int reg)
+{
+ int i = 1000;
+ cyg_uint8 stat;
+ cyg_uint16 val;
+
+ // Wait for a previous access to complete (within reason)
+ do {
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIICR, stat);
+ } while ((stat & (RHINE_MIICR_RCMD | RHINE_MIICR_WCMD)) && i-- > 0);
+
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, 0);
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PHYADR, id);
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIIAD, reg);
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, RHINE_MIICR_RCMD);
+
+ i = 1000;
+ do {
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIICR, stat);
+ } while ((stat & RHINE_MIICR_RCMD) && i-- > 0);
+
+ HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_MIIDATA, val);
+ return val;
+}
+
+// ------------------------------------------------------------------------
+// Memory management
+//
+// Simply carve off from the front of the PCI mapped window into real memory
+static cyg_uint32 rhine_heap_size;
+static cyg_uint8 *rhine_heap_base;
+static cyg_uint8 *rhine_heap_free;
+
+static void*
+pciwindow_mem_alloc(int size)
+{
+ void *p_memory;
+ int _size = size;
+
+ CYG_ASSERT(
+ (CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE <= (int)rhine_heap_free)
+ &&
+ ((CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE +
+ CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE) > (int)rhine_heap_free)
+ &&
+ (0 < rhine_heap_size)
+ &&
+ (CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE >= rhine_heap_size)
+ &&
+ (CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE == (int)rhine_heap_base),
+ "Heap variables corrupted" );
+
+ p_memory = (void *)0;
+ size = (size + 3) & ~3;
+ if ( (rhine_heap_free+size) < (rhine_heap_base+rhine_heap_size) ) {
+ cyg_uint32 *p;
+ p_memory = (void *)rhine_heap_free;
+ rhine_heap_free += size;
+ for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 )
+ *p++ = 0;
+ }
+
+#if DEBUG & 9
+ diag_printf("Allocated %d bytes at %08x\n", size, p_memory);
+#endif
+
+ return p_memory;
+}
+
+static cyg_pci_match_func find_rhine_match_func;
+
+static cyg_bool
+find_rhine_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
+{
+#if DEBUG & 9
+ diag_printf("PCI match vendor %04x device %04x\n", v, d);
+#endif
+ return
+ (0x1106 == v) && // vendor: VIA
+ ((0x3065 == d) || // device: DL10030A
+ (0x3043 == d)); // device: VT86C100A
+}
+
+static int
+pci_init_find_rhines( void )
+{
+ cyg_pci_device_id devid;
+ cyg_pci_device dev_info;
+ cyg_uint16 cmd;
+ int device_index;
+ int found_devices = 0;
+
+ DEBUG_FUNCTION();
+
+#ifdef CYGARC_UNCACHED_ADDRESS
+ CYG_ASSERT( CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) ==
+ CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE,
+ "PCI window configured does not match PCI memory section base" );
+#else
+ CYG_ASSERT( (CYG_ADDRWORD)CYGMEM_SECTION_pci_window ==
+ CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE,
+ "PCI window configured does not match PCI memory section base" );
+#endif
+ CYG_ASSERT( CYGMEM_SECTION_pci_window_SIZE ==
+ CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE,
+ "PCI window configured does not match PCI memory section size" );
+
+ if (
+#ifdef CYGARC_UNCACHED_ADDRESS
+ CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) !=
+#else
+ (CYG_ADDRWORD)CYGMEM_SECTION_pci_window !=
+#endif
+ CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE
+ ||
+ CYGMEM_SECTION_pci_window_SIZE !=
+ CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE ) {
+#if DEBUG & 8
+ diag_printf("pci_init_find_rhines(): PCI window misconfigured\n");
+#endif
+ return 0;
+ }
+
+ // First initialize the heap in PCI window'd memory
+ rhine_heap_size = CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE;
+ rhine_heap_base = (cyg_uint8 *)CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE;
+ rhine_heap_free = rhine_heap_base;
+
+ cyg_pci_init();
+#if DEBUG & 8
+ diag_printf("Finished cyg_pci_init();\n");
+#endif
+
+ devid = CYG_PCI_NULL_DEVID;
+
+ for (device_index = 0;
+ device_index < CYGNUM_DEVS_ETH_VIA_RHINE_DEV_COUNT;
+ device_index++) {
+ struct rhine_priv_data* cpd = rhine_priv_array[device_index];
+
+ cpd->index = device_index;
+
+ // See above for find_rhine_match_func - it selects any of several
+ // variants. This is necessary in case we have multiple mixed-type
+ // devices on one board in arbitrary orders.
+ if (cyg_pci_find_matching( &find_rhine_match_func, NULL, &devid )) {
+#if DEBUG & 8
+ diag_printf("eth%d = rhine\n", device_index);
+#endif
+ cyg_pci_get_device_info(devid, &dev_info);
+
+ cpd->interrupt_handle = 0; // Flag not attached.
+ if (cyg_pci_translate_interrupt(&dev_info, &cpd->interrupt)) {
+#if DEBUG & 8
+ diag_printf(" Wired to HAL vector %d\n", cpd->interrupt);
+#endif
+ cyg_drv_interrupt_create(
+ cpd->interrupt,
+ 1, // Priority - unused
+ (cyg_addrword_t)cpd,// Data item passed to ISR & DSR
+ rhine_isr, // ISR
+ rhine_dsr, // DSR
+ &cpd->interrupt_handle, // handle to intr obj
+ &cpd->interrupt_object ); // space for int obj
+
+ cyg_drv_interrupt_attach(cpd->interrupt_handle);
+
+ // Don't unmask the interrupt yet, that could get us into a
+ // race.
+ }
+ else {
+ cpd->interrupt = 0;
+#if DEBUG & 8
+ diag_printf(" Does not generate interrupts.\n");
+#endif
+ }
+
+ if (cyg_pci_configure_device(&dev_info)) {
+#if DEBUG & 8
+ int i;
+ diag_printf("Found device on bus %d, devfn 0x%02x:\n",
+ CYG_PCI_DEV_GET_BUS(devid),
+ CYG_PCI_DEV_GET_DEVFN(devid));
+
+ if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
+ diag_printf(" Note that board is active. Probed"
+ " sizes and CPU addresses invalid!\n");
+ }
+ diag_printf(" Vendor 0x%04x", dev_info.vendor);
+ diag_printf("\n Device 0x%04x", dev_info.device);
+ diag_printf("\n Command 0x%04x, Status 0x%04x\n",
+ dev_info.command, dev_info.status);
+
+ diag_printf(" Class/Rev 0x%08x", dev_info.class_rev);
+ diag_printf("\n Header 0x%02x\n", dev_info.header_type);
+
+ diag_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
+ dev_info.header.normal.sub_vendor,
+ dev_info.header.normal.sub_id);
+
+ for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
+ diag_printf(" BAR[%d] 0x%08x /", i, dev_info.base_address[i]);
+ diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
+ dev_info.base_size[i], dev_info.base_map[i]);
+ }
+ diag_printf(" eth%d configured\n", device_index);
+#endif
+ found_devices++;
+ cpd->found = 1;
+ cpd->active = 0;
+ cpd->devid = devid;
+ cpd->base = (unsigned char*) dev_info.base_map[0];
+#if DEBUG & 8
+ diag_printf(" I/O address = 0x%08x\n", cpd->base);
+#endif
+
+ // Don't use cyg_pci_set_device_info since it clears
+ // some of the fields we want to print out below.
+ cyg_pci_read_config_uint16(dev_info.devid,
+ CYG_PCI_CFG_COMMAND, &cmd);
+ cmd |= (CYG_PCI_CFG_COMMAND_IO // enable I/O space
+ | CYG_PCI_CFG_COMMAND_MEMORY // enable memory space
+ | CYG_PCI_CFG_COMMAND_MASTER); // enable bus master
+ cyg_pci_write_config_uint16(dev_info.devid,
+ CYG_PCI_CFG_COMMAND, cmd);
+
+ // Extra init code needed for D-Link controller. This
+ // is snuffed from the Linux driver and was provided
+ // by D-Link. I've been unable to find documentation
+ // for the part.
+ if (0x3065 == dev_info.device) {
+ cyg_uint8 tmp;
+
+#if DEBUG & 8
+ diag_printf("Pre-reset init code for D-Link.\n");
+#endif
+ HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_STICKYHW, tmp);
+ tmp &= 0xfc;
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_STICKYHW, tmp);
+
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_WOL_CG_CLR, 0x80);
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_WOL_CR_CLR, 0xff);
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_PWR_CSR_CLR, 0xff);
+ }
+
+ // Now the PCI part of the device is configured, reset
+ // it. This should make it safe to enable the
+ // interrupt
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_CR1, RHINE_CR1_SRST);
+
+ // Reload ESA from EEPROM
+ {
+ cyg_uint8 tmp;
+ int i;
+
+#if DEBUG & 8
+ diag_printf("Reload ESA from EEPROM...");
+#endif
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_EECSR, 0x20);
+ for (i = 0; i < 150; i++) {
+ HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_EECSR, tmp);
+ if (!(tmp & 0x20)) {
+ break;
+ }
+ }
+#if DEBUG & 8
+ if (tmp & 0x20)
+ diag_printf("Timed out\n");
+ else
+ diag_printf("Done\n");
+#endif
+ }
+
+ // This is the indicator for "uses an interrupt"
+ if (cpd->interrupt_handle != 0) {
+ cyg_drv_interrupt_acknowledge(cpd->interrupt);
+ cyg_drv_interrupt_unmask(cpd->interrupt);
+#if DEBUG & 8
+ diag_printf(" Enabled interrupt %d\n", cpd->interrupt);
+#endif
+ }
+#if DEBUG & 8
+ diag_printf(" **** Device enabled for I/O and Memory "
+ "and Bus Master\n");
+#endif
+ }
+ else {
+ cpd->found = 0;
+ cpd->active = 0;
+#if DEBUG & 8
+ diag_printf("Failed to configure device %d\n", device_index);
+#endif
+ }
+ }
+ else {
+ cpd->found = 0;
+ cpd->active = 0;
+#if DEBUG & 8
+ diag_printf("eth%d not found\n", device_index);
+#endif
+ }
+ }
+
+ if (0 == found_devices)
+ return 0;
+
+ return 1;
+}
+
+static bool
+via_rhine_init(struct cyg_netdevtab_entry *tab)
+{
+ static int initialized = 0; // only probe PCI et al *once*
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+ cyg_uint8 *d, *p, *p_next;
+ int i;
+ cyg_addrword_t ba;
+
+ DEBUG_FUNCTION();
+
+ if ( 0 == initialized++ ) {
+ // then this is the first time ever:
+ if ( ! pci_init_find_rhines() ) {
+#if DEBUG & 8
+ diag_printf( "pci_init_find_rhines failed" );
+#endif
+ return false;
+ }
+ }
+
+ // If this device is not present, exit
+ if (0 == cpd->found)
+ return 0;
+
+#if DEBUG & 8
+ diag_printf( "Rhine device SC %08x CPD %08x\n", sc, cpd);
+#endif
+
+ // Look for physical MII device
+ for (i = 0; i < 32; i++) {
+ cyg_uint16 mii_status = rhine_read_MII(cpd, i, MII_BMSR);
+ if (mii_status != 0x0000 && mii_status != 0xffff) {
+ cpd->phys_id = i;
+#if DEBUG & 8
+ diag_printf("Found MII interface at id %d, status %04x, adv 0x%04x, link 0x%04x\n",
+ cpd->phys_id, mii_status, rhine_read_MII(cpd,i,4), rhine_read_MII(cpd,i,5));
+#endif
+ break;
+ }
+ }
+#if DEBUG & 8
+ if (i == 32)
+ diag_printf("No MII interface found!");
+#endif
+
+ // Prepare ESA
+ if (cpd->hardwired_esa) {
+ // Force the NIC to use the specified ESA
+ for (i = 0; i < 6; i++)
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PAR0 + i, cpd->esa[i]);
+ } else {
+ // Use the address from the serial EEPROM
+ for (i = 0; i < 6; i++)
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_PAR0 + i, cpd->esa[i]);
+ }
+#if DEBUG & 8
+ diag_printf("RHINE - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ (cpd->hardwired_esa) ? "static" : "eeprom",
+ cpd->esa[0],
+ cpd->esa[1],
+ cpd->esa[2],
+ cpd->esa[3],
+ cpd->esa[4],
+ cpd->esa[5] );
+#endif
+
+ // Prepare RX and TX rings
+ p = cpd->rx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc((1<<cpd->rx_ring_log_cnt)*RHINE_RD_SIZE));
+ d = cpd->rx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc(_BUF_SIZE*cpd->rx_ring_cnt));
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ p_next = p + RHINE_RD_SIZE;
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)d, ba);
+ _SU32(p, RHINE_RDES2) = ba;
+ _SU32(p, RHINE_RDES1) = _BUF_SIZE;
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)p_next, ba);
+ _SU32(p, RHINE_RDES3) = ba;
+ _SU32(p, RHINE_RDES0) = RHINE_RDES0_OWN;
+#if DEBUG & 8
+ diag_printf("Set RDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ (unsigned long)p,
+ _SU32(p, RHINE_RDES0), _SU32(p, RHINE_RDES1),
+ _SU32(p, RHINE_RDES2), _SU32(p, RHINE_RDES3));
+#endif
+ p = p_next;
+ d += _BUF_SIZE;
+ }
+ // last entry wraps to the first
+ p -= RHINE_RD_SIZE;
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->rx_ring, ba);
+ _SU32(p, RHINE_RDES3) = ba;
+#if DEBUG & 8
+ diag_printf("Set RDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ (unsigned long)p,
+ _SU32(p, RHINE_RDES0), _SU32(p, RHINE_RDES1),
+ _SU32(p, RHINE_RDES2), _SU32(p, RHINE_RDES3));
+#endif
+ cpd->rx_ring_next = 0;
+ // CPU to PCI space translation
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->rx_ring, ba);
+ HAL_PCI_IO_WRITE_UINT32(cpd->base + RHINE_CUR_RX, ba);
+
+ p = cpd->tx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc((1<<cpd->tx_ring_log_cnt)*RHINE_TD_SIZE));
+ d = cpd->tx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc(_BUF_SIZE*cpd->tx_ring_cnt));
+ for (i = 0; i < cpd->tx_ring_cnt; i++) {
+
+ _SU32(p, RHINE_TDES0) = 0;
+ _SU32(p, RHINE_TDES1) = (RHINE_TDES1_IC|RHINE_TDES1_EDP|RHINE_TDES1_STP|RHINE_TDES1_C);
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)d, ba);
+ _SU32(p, RHINE_TDES2) = ba;
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)(p + RHINE_TD_SIZE), ba);
+ _SU32(p, RHINE_TDES3) = ba;
+#if DEBUG & 8
+ diag_printf("Set TDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ (unsigned long)p,
+ _SU32(p, RHINE_TDES0), _SU32(p, RHINE_TDES1),
+ _SU32(p, RHINE_TDES2), _SU32(p, RHINE_TDES3));
+#endif
+ p += RHINE_TD_SIZE;
+ d += _BUF_SIZE;
+ }
+
+ // last entry wraps to the first
+ p -= RHINE_TD_SIZE;
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->tx_ring, ba);
+ _SU32(p, RHINE_TDES3) = ba;
+#if DEBUG & 8
+ diag_printf("Set TDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ (unsigned long)p,
+ _SU32(p, RHINE_TDES0), _SU32(p, RHINE_TDES1),
+ _SU32(p, RHINE_TDES2), _SU32(p, RHINE_TDES3));
+#endif
+ cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;
+ HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->tx_ring, ba);
+ HAL_PCI_IO_WRITE_UINT32(cpd->base + RHINE_CUR_TX, ba);
+
+ cpd->txbusy = 0;
+
+#if DEBUG & 9
+ {
+ cyg_uint8 tmp1, tmp2;
+ HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_CR0, tmp1);
+ HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_CR1, tmp2);
+ diag_printf("CR0: %02x CR1: %02x\n", tmp1, tmp2);
+ }
+#endif
+
+ // and record the net dev pointer
+ cpd->ndp = (void *)tab;
+
+ // Initialize upper level driver
+ (sc->funs->eth_drv->init)(sc, cpd->esa);
+
+#if DEBUG & 9
+ diag_printf("Done\n");
+#endif
+ return true;
+}
+
+static void
+rhine_stop(struct eth_drv_sc *sc)
+{
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ // Stop chip
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_CR0, RHINE_CR0_STOP);
+}
+
+//
+// This function is called to "start up" the interface. It may be called
+// multiple times, even when the hardware is already running. It will be
+// called whenever something "hardware oriented" changes and should leave
+// the hardware ready to send/receive packets.
+//
+static void
+rhine_start(struct eth_drv_sc *sc, unsigned char *esa, int flags)
+{
+#ifdef CYGPKG_NET
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+ // Disable device
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, RHINE_CR0_STOP);
+ // Ack old interrupts
+ HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, 0xffff);
+ // Enable interrupts
+ HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_IMR, RHINE_IMR_INIT);
+ // Enable duplex
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_CR1, RHINE_CR1_DPOLL /* | RHINE_CR1_FDX*/);
+ // Accept broadcast, multicast and small packets
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_RCR, RHINE_RCR_AB | RHINE_RCR_AM | RHINE_RCR_AR);
+ // Tweak some magic (undocumented) parameters
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_BCR0, RHINE_BCR0_MAGIC_INIT);
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_BCR1, RHINE_BCR1_MAGIC_INIT);
+
+#if 1 // FIXME
+ HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_TCR, 0x20);
+#endif
+
+#ifdef CYGPKG_NET
+ if (( 0
+#ifdef ETH_DRV_FLAGS_PROMISC_MODE
+ != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
+#endif
+ ) || (ifp->if_flags & IFF_PROMISC)
+ ) {
+ // Then we select promiscuous mode.
+ cyg_uint8 rcr;
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_RCR, rcr);
+ rcr |= RHINE_RCR_PRO;
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_RCR, rcr);
+ }
+#endif
+ // Enable device
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, RHINE_CR0_STRT | RHINE_CR0_RXON | RHINE_CR0_TXON);
+}
+
+//
+// This routine is called to perform special "control" opertions
+//
+static int
+rhine_control(struct eth_drv_sc *sc, unsigned long key,
+ void *data, int data_length)
+{
+ cyg_uint8 *esa = (cyg_uint8 *)data;
+ int i, res;
+ cyg_uint8 reg, old_stat;
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ // Stop the controller while accessing (possibly altering) registers
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, old_stat);
+ reg = old_stat;
+ reg |= RHINE_CR0_STOP;
+ reg &= ~RHINE_CR0_STRT;
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, reg);
+
+ res = 0; // expect success
+ switch (key) {
+ case ETH_DRV_SET_MAC_ADDRESS:
+#if DEBUG & 9
+ diag_printf("RHINE - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ esa[0],
+ esa[1],
+ esa[2],
+ esa[3],
+ esa[4],
+ esa[5] );
+#endif // DEBUG
+
+ for ( i = 0; i < sizeof(cpd->esa); i++ ) {
+ cpd->esa[i] = esa[i];
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PAR0 + i, esa[i]);
+ }
+ break;
+
+#ifdef ETH_DRV_GET_MAC_ADDRESS
+ case ETH_DRV_GET_MAC_ADDRESS:
+ // Extract the MAC address that is in the chip, and tell the
+ // system about it.
+ for (i = 0; i < sizeof(cpd->esa); i++) {
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_PAR0 + i, esa[i]);
+ }
+ break;
+#endif
+
+#ifdef ETH_DRV_GET_IF_STATS_UD
+ case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
+#endif
+ // drop through
+#ifdef ETH_DRV_GET_IF_STATS
+ case ETH_DRV_GET_IF_STATS:
+#endif
+
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+ {
+ cyg_uint8 reg;
+ struct ether_drv_stats *p = (struct ether_drv_stats *)data;
+ // Chipset entry is no longer supported; RFC1573.
+ for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
+ p->snmp_chipset[i] = 0;
+
+ // This perhaps should be a config opt, so you can make up your own
+ // description, or supply it from the instantiation.
+ strcpy( p->description, "VIA Rhine" );
+ // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
+
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIISR, reg);
+ if (reg & RHINE_MIISR_LNKFL) {
+ p->operational = 2; // LINK DOWN
+ p->duplex = 1; // UNKNOWN
+ p->speed = 0;
+ }
+ else {
+ p->operational = 3; // LINK UP
+ p->speed = (reg & RHINE_MIISR_SPEED) ? 10 * 1000000 : 100 * 1000000;
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR1, reg);
+ if (reg & RHINE_CR1_FDX)
+ p->duplex = 3; // 3 = DUPLEX
+ else
+ p->duplex = 2; // 2 = SIMPLEX
+ }
+
+#ifdef KEEP_STATISTICS
+ {
+ struct via_rhine_stats *ps = &(cpd->stats);
+
+ // Admit to it...
+ p->supports_dot3 = true;
+
+ p->tx_good = ps->tx_good ;
+ p->tx_max_collisions = ps->tx_max_collisions ;
+ p->tx_late_collisions = ps->tx_late_collisions ;
+ p->tx_underrun = ps->tx_underrun ;
+ p->tx_carrier_loss = ps->tx_carrier_loss ;
+ p->tx_deferred = ps->tx_deferred ;
+ p->tx_sqetesterrors = ps->tx_sqetesterrors ;
+ p->tx_single_collisions = ps->tx_single_collisions;
+ p->tx_mult_collisions = ps->tx_mult_collisions ;
+ p->tx_total_collisions = ps->tx_total_collisions ;
+ p->rx_good = ps->rx_good ;
+ p->rx_crc_errors = ps->rx_crc_errors ;
+ p->rx_align_errors = ps->rx_align_errors ;
+ p->rx_resource_errors = ps->rx_resource_errors ;
+ p->rx_overrun_errors = ps->rx_overrun_errors ;
+ p->rx_collisions = ps->rx_collisions ;
+ p->rx_short_frames = ps->rx_short_frames ;
+ p->rx_too_long_frames = ps->rx_too_long_frames ;
+ p->rx_symbol_errors = ps->rx_symbol_errors ;
+
+ p->interrupts = ps->interrupts ;
+ p->rx_count = ps->rx_count ;
+ p->rx_deliver = ps->rx_deliver ;
+ p->rx_resource = ps->rx_resource ;
+ p->rx_restart = ps->rx_restart ;
+ p->tx_count = ps->tx_count ;
+ p->tx_complete = ps->tx_complete ;
+ p->tx_dropped = ps->tx_dropped ;
+ }
+#endif // KEEP_STATISTICS
+
+ p->tx_queue_len = 1;
+ break;
+ }
+#endif
+ default:
+ res = 1;
+ break;
+ }
+
+ // Restore controller state
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, old_stat);
+
+ return res;
+}
+
+//
+// This routine is called to see if it is possible to send another packet.
+// It will return non-zero if a transmit is possible, zero otherwise.
+//
+static int
+rhine_can_send(struct eth_drv_sc *sc)
+{
+ cyg_uint8 stat;
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+
+ DEBUG_FUNCTION();
+
+ // This MII read forces the MIISR to get updated
+ (void) rhine_read_MII(cpd, cpd->phys_id, MII_BMSR);
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIISR, stat);
+ if (stat & RHINE_MIISR_LNKFL) {
+#if DEBUG & 1
+ diag_printf("*** Link failure\n");
+#endif
+ return false; // Link not connected
+ }
+
+ return (cpd->txbusy == 0);
+}
+
+//
+// This routine is called to send data to the hardware.
+static void
+rhine_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
+ int total_len, unsigned long key)
+{
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+ int i, len, plen, ring_entry;
+
+ cyg_uint8* sdata = NULL;
+ cyg_uint8 *d, *buf, *txd;
+ cyg_uint16 status;
+ cyg_uint8 cr0;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( tx_count );
+
+ // Worry about the engine stopping.
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, status);
+ if ( 0 == (RHINE_CR0_STRT & status) ) {
+#if DEBUG & 1
+ diag_printf("%s: ENGINE RESTART: status %04x\n", __FUNCTION__, status);
+#endif
+ status &= ~RHINE_CR0_STOP;
+ status |= RHINE_CR0_STRT;
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, status);
+ }
+
+ cpd->txbusy = 1;
+ cpd->txkey = key;
+
+ // Find packet length
+ plen = 0;
+ for (i = 0; i < sg_len; i++)
+ plen += sg_list[i].len;
+
+ CYG_ASSERT( plen == total_len, "sg data length mismatch" );
+
+ // Get next TX descriptor
+ ring_entry = cpd->tx_ring_free;
+ do {
+ if (cpd->tx_ring_owned == cpd->tx_ring_cnt) {
+ // Is this a dead end? Probably is.
+#if DEBUG & 1
+ diag_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
+#endif
+ continue;
+ }
+
+ cpd->tx_ring_free++;
+ cpd->tx_ring_owned++;
+ if (cpd->tx_ring_free == cpd->tx_ring_cnt)
+ cpd->tx_ring_free = 0;
+ } while (0);
+
+ txd = cpd->tx_ring + ring_entry*RHINE_TD_SIZE;
+ buf = cpd->tx_buffers + ring_entry*_BUF_SIZE;
+ CYG_ASSERT(0 == (_SU32(txd, RHINE_TDES0) & RHINE_TDES0_OWN),
+ "TX descriptor not free");
+
+#if DEBUG & 4
+ diag_printf("##Tx descriptor index %d TDES %08x buffer %08x\n",
+ ring_entry, txd, buf);
+#endif
+
+ // Put data into buffer
+ d = buf;
+ for (i = 0; i < sg_len; i++) {
+ sdata = (cyg_uint8 *)sg_list[i].buf;
+ len = sg_list[i].len;
+
+ CYG_ASSERT( sdata, "No sg data pointer here" );
+ while(len--)
+ *d++ = *sdata++;
+ }
+ CYG_ASSERT( sdata, "No sg data pointer outside" );
+
+ // Annoyingly the chip doesn't pad to minimal packet size, so do
+ // that by steam
+ if (plen < 60) {
+ plen = 60;
+#if DEBUG & 4
+ diag_printf("Padded %d bytes packet to 60 bytes\n", plen);
+#endif
+ }
+
+ CYG_ASSERT( (plen & RHINE_TDES1_TLNG_mask) == plen, "packet too long");
+ CYG_ASSERT( (plen & RHINE_TDES1_TLNG_mask) >= 60, "packet too short");
+ _SU32(txd, RHINE_TDES1) &= ~RHINE_TDES1_TLNG_mask;
+ _SU32(txd, RHINE_TDES1) |= plen;
+ _SU32(txd, RHINE_TDES0) = RHINE_TDES0_OWN;
+
+#if DEBUG & 1 // FIXME
+ diag_printf("Before TX: Desc (@0x%08lx) %08x %08x %08x %08x\n Next (@0x%08lx) %08x %08x %08x %08x\n",
+ (unsigned long) txd,
+ _SU32(txd, RHINE_TDES0), _SU32(txd, RHINE_TDES1),
+ _SU32(txd, RHINE_TDES2), _SU32(txd, RHINE_TDES3),
+ ( (unsigned long)txd)+0x10,
+ _SU32(txd, (0x10+RHINE_TDES0)), _SU32(txd, (0x10+RHINE_TDES1)),
+ _SU32(txd,(0x10+ RHINE_TDES2)), _SU32(txd,(0x10+ RHINE_TDES3)));
+#endif
+
+ // Ack TX empty int
+ HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_PTX);
+ // Set transmit demand
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, cr0);
+ cr0 |= RHINE_CR0_TDMD;
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, cr0);
+
+#if DEBUG & 1
+ HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_ISR, status);
+ diag_printf("%s:END: ints at TX: %04x\n", __FUNCTION__, status);
+#endif
+
+}
+
+static void
+rhine_TxEvent(struct eth_drv_sc *sc, int stat)
+{
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+ int success = 1;
+ cyg_uint8 *txd;
+ cyg_uint8 status;
+
+ DEBUG_FUNCTION();
+
+ INCR_STAT( tx_complete );
+
+ txd = cpd->tx_ring + cpd->tx_ring_alloc*RHINE_TD_SIZE;
+#if DEBUG & 4
+ diag_printf("##Tx packet %d freed %08x %08x!\n", cpd->tx_ring_alloc, txd, _SU32(txd, RHINE_TDES0) );
+#endif
+ if ((_SU32(txd, RHINE_TDES0) & RHINE_TDES0_OWN)) {
+#if DEBUG & 1
+ diag_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__);
+#endif
+ // first dirty ring entry not freed - wtf?
+ }
+ cpd->tx_ring_alloc++;
+ if (cpd->tx_ring_alloc == cpd->tx_ring_cnt)
+ cpd->tx_ring_alloc = 0;
+ cpd->tx_ring_owned--;
+
+#ifdef KEEP_STATISTICS
+ {
+ cyg_uint32 reg = _SU32(txd, RHINE_TDES0);
+ int collisions;
+
+ // Covering each bit in turn...
+ if ( reg & RHINE_TDES0_TXOK ) INCR_STAT( tx_good );
+ if ( reg & RHINE_TDES0_CRS ) INCR_STAT( tx_carrier_loss );
+ if ( reg & RHINE_TDES0_OWC ) INCR_STAT( tx_late_collisions );
+ if ( reg & RHINE_TDES0_ABT ) INCR_STAT( tx_max_collisions );
+
+ if ( reg & RHINE_TDES0_DFR ) INCR_STAT( tx_deferred );
+
+ collisions = ((reg & RHINE_TDES0_NCR_mask) >> RHINE_TDES0_NCR_shift);
+ if (1 == collisions)
+ INCR_STAT( tx_single_collisions );
+ else if (1 < collisions)
+ INCR_STAT( tx_mult_collisions );
+
+ cpd->stats.tx_total_collisions =
+ cpd->stats.tx_late_collisions +
+ cpd->stats.tx_max_collisions +
+ cpd->stats.tx_mult_collisions +
+ cpd->stats.tx_single_collisions;
+ }
+#endif // KEEP_STATISTICS
+
+ // We do not really care about Tx failure. Ethernet is not a reliable
+ // medium. But we do care about the TX engine stopping.
+ HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, status);
+ if ( 0 == (RHINE_CR0_STRT & status) ) {
+#if DEBUG & 1
+ diag_printf("%s: ENGINE RESTART: status %04x\n", __FUNCTION__, status);
+#endif
+ status &= ~RHINE_CR0_STOP;
+ status |= RHINE_CR0_STRT;
+ HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, status);
+ success = 0; // And treat this as an error...
+ }
+
+ if ( cpd->txbusy ) {
+ cpd->txbusy = 0;
+ (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
+ }
+
+ // Ack TX interrupt set
+ HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_PTX);
+}
+
+//
+// This function is called when a packet has been received. Its job is
+// to prepare to unload the packet from the hardware. Once the length of
+// the packet is known, the upper layer of the driver can be told. When
+// the upper layer is ready to unload the packet, the internal function
+// 'rhine_recv' will be called to actually fetch it from the hardware.
+//
+static void
+rhine_RxEvent(struct eth_drv_sc *sc)
+{
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+ cyg_uint8 *rxd;
+ cyg_uint32 rstat;
+ cyg_uint16 ints, len, mask;
+
+ DEBUG_FUNCTION();
+
+ HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_ISR, ints);
+#if DEBUG & 1
+ diag_printf("RxEvent - CSR: 0x%04x\n", ints);
+#endif
+ if ( 0 == (RHINE_ISR_PRX & ints) )
+ // Then there's no RX event pending
+ return;
+
+ // Mask interrupt
+ HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_IMR, mask);
+ mask &= ~RHINE_IMR_PRX;
+ HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_IMR, mask);
+
+ while (1) {
+ // Get state of next (supposedly) full ring entry
+ cpd->rxpacket = cpd->rx_ring_next;
+ rxd = cpd->rx_ring + cpd->rxpacket*RHINE_RD_SIZE;
+ rstat = _SU32(rxd, RHINE_RDES0);
+
+ // Keep going until we hit an entry that is owned by the
+ // controller.
+ if (rstat & RHINE_RDES0_OWN) {
+#ifdef CYGDBG_USE_ASSERTS
+ // Sanity check of queue
+ int i;
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*RHINE_RD_SIZE;
+ rstat = _SU32(rxd, RHINE_RDES0);
+
+ if (!(rstat & RHINE_RDES0_OWN)) {
+ int i;
+ cyg_uint32 rstat;
+ cyg_uint8* rxd;
+
+ diag_printf("####Rx %s Inconsistent RX state - next was %d\n",
+ __FUNCTION__, cpd->rx_ring_next);
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*RHINE_RD_SIZE;
+ rstat = _SU32(rxd, RHINE_RDES0);
+ diag_printf("#### %02d: 0x%08x\n", i, rstat);
+ }
+ }
+ break;
+ }
+#endif
+ break;
+ }
+
+#if DEBUG & 4
+ diag_printf("##Rx packet %d RDES %08x stat %08x\n",
+ cpd->rxpacket, rxd, rstat);
+#endif
+
+ // Increment counts
+ INCR_STAT( rx_count );
+ cpd->rx_ring_next++;
+ if (cpd->rx_ring_next == cpd->rx_ring_cnt) cpd->rx_ring_next = 0;
+
+ len = (rstat & RHINE_RDES0_FLNG_mask) >> RHINE_RDES0_FLNG_shift;
+
+#ifdef KEEP_STATISTICS
+ if ( rstat & RHINE_RDES0_CRC ) INCR_STAT( rx_crc_errors );
+ if ( rstat & RHINE_RDES0_FAE ) INCR_STAT( rx_align_errors );
+ if ( rstat & RHINE_RDES0_LONG ) INCR_STAT( rx_too_long_frames );
+#endif // KEEP_STATISTICS
+
+ if (RHINE_RDES0_RXOK & rstat) {
+ // It's OK
+ INCR_STAT( rx_good );
+
+#if DEBUG & 1
+ diag_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len);
+ {
+ unsigned char *buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
+
+ int i;
+ diag_printf("RDES: %08x %08x %08x %08x\n",
+ _SU32(rxd, RHINE_RDES0), _SU32(rxd, RHINE_RDES1),
+ _SU32(rxd, RHINE_RDES2), _SU32(rxd, RHINE_RDES3));
+
+ diag_printf("Packet data at %p\n", buf);
+ for (i=0;i<len;i++) diag_printf("%02x ", buf[i]);
+ diag_printf("\n");
+ }
+#endif
+ // Check for bogusly short packets; can happen in promisc
+ // mode: Asserted against and checked by upper layer
+ // driver.
+#ifdef CYGPKG_NET
+ if ( len > sizeof( struct ether_header ) )
+ // then it is acceptable; offer the data to the network stack
+#endif
+ (sc->funs->eth_drv->recv)(sc, len);
+ } else {
+ // Not OK for one reason or another...
+#if DEBUG & 1
+ diag_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n",
+ rstat, len);
+#endif
+ }
+
+ // Free packet (clear all status flags, and set OWN)
+ _SU32(rxd, RHINE_RDES0) = RHINE_RDES0_OWN;
+ }
+
+ // Ack RX int
+ HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_PRX);
+ // And reenable the interrupt
+ HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_IMR, mask);
+ mask |= RHINE_IMR_PRX;
+ HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_IMR, mask);
+}
+
+//
+// This function is called as a result of the "eth_drv_recv()" call above.
+// Its job is to actually fetch data for a packet from the hardware once
+// memory buffers have been allocated for the packet. Note that the buffers
+// may come in pieces, using a scatter-gather list. This allows for more
+// efficient processing in the upper layers of the stack.
+//
+static void
+rhine_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
+{
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+ int i, mlen=0, plen;
+ cyg_uint8 *data, *rxd, *buf;
+
+ DEBUG_FUNCTION();
+
+ rxd = cpd->rx_ring + cpd->rxpacket*RHINE_RD_SIZE;
+ buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
+
+ INCR_STAT( rx_deliver );
+
+ plen = (_SU32(rxd, RHINE_RDES0) & RHINE_RDES0_FLNG_mask) >> RHINE_RDES0_FLNG_shift;
+
+ for (i = 0; i < sg_len; i++) {
+ data = (cyg_uint8*)sg_list[i].buf;
+ mlen = sg_list[i].len;
+
+#if DEBUG & 1
+ diag_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
+#endif
+ if (data) {
+ while (mlen > 0) {
+ *data++ = *buf++;
+ mlen--;
+ plen--;
+ }
+ }
+ }
+}
+
+static void
+rhine_poll(struct eth_drv_sc *sc)
+{
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+ cyg_uint16 event, mask;
+ static volatile bool locked = false;
+
+// DEBUG_FUNCTION();
+
+ while (1) {
+ // Get the (unmasked) requests
+ HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_ISR, event);
+ HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_IMR, mask);
+
+ event &= mask;
+
+ if (0 == event)
+ break;
+
+ if (event & RHINE_ISR_PRX) {
+ rhine_RxEvent(sc);
+ }
+ else if (event & RHINE_ISR_PTX) {
+ rhine_TxEvent(sc, event);
+ }
+ else if (event & RHINE_ISR_RU) {
+#if DEBUG & 1
+ int i;
+ cyg_uint32 rstat;
+ cyg_uint8* rxd;
+ struct rhine_priv_data *cpd =
+ (struct rhine_priv_data *)sc->driver_private;
+
+ diag_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event);
+ for (i = 0; i < cpd->rx_ring_cnt; i++) {
+ rxd = cpd->rx_ring + i*RHINE_RD_SIZE;
+
+ rstat = _SU32(rxd, RHINE_RDES0);
+ diag_printf(" %02d: 0x%08x\n", i, rstat);
+ }
+#endif
+ HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_RU);
+ }
+ else {
+#if DEBUG & 1
+ diag_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event);
+#endif
+ // Clear unhandled interrupts and hope for the best
+ // This should never happen though, since we only enable
+ // the sources we handle.
+ HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, event);
+ }
+ }
+
+ locked = false;
+}
+// EOF if_rhine.c
diff --git a/ecos/packages/devs/eth/via/rhine/current/src/via_rhine.h b/ecos/packages/devs/eth/via/rhine/current/src/via_rhine.h
new file mode 100644
index 0000000..3e91c99
--- /dev/null
+++ b/ecos/packages/devs/eth/via/rhine/current/src/via_rhine.h
@@ -0,0 +1,468 @@
+#ifndef CYGONCE_DEVS_ETH_VIA_RHINE_H
+#define CYGONCE_DEVS_ETH_VIA_RHINE_H
+//==========================================================================
+//
+// via_rhine.h
+//
+// VIA Rhine Ethernet chip
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-05-30
+// Purpose: Hardware description of VIA Rhine series.
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/io/pci_hw.h> // HAL_PCI_ macros
+
+//------------------------------------------------------------------------
+// Get macros from platform header
+#define __WANT_CONFIG
+#include CYGDAT_DEVS_ETH_VIA_RHINE_INL
+#undef __WANT_CONFIG
+
+//------------------------------------------------------------------------
+// Set to perms of:
+// 0 disables all debug output
+// 1 for process debug output
+// 2 for added data IO output: get_reg, put_reg
+// 4 for packet allocation/free output
+// 8 for only startup status, so we can tell we're installed OK
+#define DEBUG 0x00
+
+#if DEBUG & 1
+# define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0)
+#else
+# define DEBUG_FUNCTION() do {} while(0)
+#endif
+
+// ------------------------------------------------------------------------
+// Macros for keeping track of statistics
+#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
+#define KEEP_STATISTICS
+#endif
+
+#ifdef KEEP_STATISTICS
+#define INCR_STAT( _x_ ) (cpd->stats. _x_ ++)
+#else
+#define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
+#endif
+
+//------------------------------------------------------------------------
+// Cache translation
+#ifndef CYGARC_UNCACHED_ADDRESS
+# define CYGARC_UNCACHED_ADDRESS(x) (x)
+#endif
+
+//------------------------------------------------------------------------
+// Address translation
+#ifndef HAL_PCI_CPU_TO_BUS
+# error "HAL PCI support must define translation macros"
+#endif
+
+//------------------------------------------------------------------------
+// Macros for accessing structure elements
+
+#define _SU8( _base_, _offset_) \
+ *((volatile cyg_uint8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU16( _base_, _offset_) \
+ *((volatile cyg_uint16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SU32( _base_, _offset_) \
+ *((volatile cyg_uint32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+#define _SI8( _base_, _offset_) \
+ *((volatile cyg_int8 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI16( _base_, _offset_) \
+ *((volatile cyg_int16 *)((CYG_ADDRWORD)_base_+(_offset_)))
+#define _SI32( _base_, _offset_) \
+ *((volatile cyg_int32 *)((CYG_ADDRWORD)_base_+(_offset_)))
+
+// ------------------------------------------------------------------------
+// Macros for accessing controller registers
+#ifndef HAL_PCI_IO_READ_UINT8
+# define HAL_PCI_IO_READ_UINT8(addr, datum) HAL_READ_UINT8(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT8(addr, datum) HAL_WRITE_UINT8(addr, datum)
+# define HAL_PCI_IO_READ_UINT16(addr, datum) HAL_READ_UINT16(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT16(addr, datum) HAL_WRITE_UINT16(addr, datum)
+# define HAL_PCI_IO_READ_UINT32(addr, datum) HAL_READ_UINT32(addr, datum)
+# define HAL_PCI_IO_WRITE_UINT32(addr, datum) HAL_WRITE_UINT32(addr, datum)
+#endif
+
+// ------------------------------------------------------------------------
+// Control registers
+#define RHINE_PAR0 0x00
+#define RHINE_PAR1 0x01
+#define RHINE_PAR2 0x02
+#define RHINE_PAR3 0x03
+#define RHINE_PAR4 0x04
+#define RHINE_PAR5 0x05
+
+#define RHINE_RCR 0x06
+#define RHINE_TCR 0x07
+#define RHINE_CR0 0x08
+#define RHINE_CR1 0x09
+
+#define RHINE_ISR 0x0c // 16 bit
+#define RHINE_IMR 0x0e // 16 bit
+
+#define RHINE_CUR_RX 0x18
+#define RHINE_CUR_TX 0x1c
+
+
+#define RHINE_PHYADR 0x6c
+#define RHINE_MIISR 0x6d
+#define RHINE_BCR0 0x6e
+#define RHINE_BCR1 0x6f
+#define RHINE_MIICR 0x70
+#define RHINE_MIIAD 0x71
+#define RHINE_MIIDATA 0x72 // 16 bit
+
+
+#define RHINE_EECSR 0x74
+
+#define RHINE_CFGA 0x78
+#define RHINE_CFGB 0x79
+#define RHINE_CFGC 0x7a
+#define RHINE_CFGD 0x7b
+
+#define RHINE_STICKYHW 0x83
+#define RHINE_WOL_CR_CLR 0xa4
+#define RHINE_WOL_CG_CLR 0xa7
+#define RHINE_PWR_CSR_CLR 0xac
+
+#define RHINE_RCR_RRSF 0x80
+#define RHINE_RCR_RFT_64 0x00
+#define RHINE_RCR_RFT_SF 0x60
+#define RHINE_RCR_PRO 0x10
+#define RHINE_RCR_AB 0x08
+#define RHINE_RCR_AM 0x04
+#define RHINE_RCR_AR 0x02
+#define RHINE_RCR_SEP 0x01
+
+#define RHINE_TCR_RTSF 0x80
+#define RHINE_TCR_TFT_64 0x00
+#define RHINE_TCR_TFT_SF 0x60
+#define RHINE_TCR_OFFSET 0x08
+#define RHINE_TCR_LB1 0x04
+#define RHINE_TCR_LB0 0x02
+
+#define RHINE_CR0_RDMD 0x40
+#define RHINE_CR0_TDMD 0x20
+#define RHINE_CR0_TXON 0x10
+#define RHINE_CR0_RXON 0x08
+#define RHINE_CR0_STOP 0x04
+#define RHINE_CR0_STRT 0x02
+#define RHINE_CR0_INIT 0x01
+
+#define RHINE_CR1_SRST 0x80
+#define RHINE_CR1_DPOLL 0x08
+#define RHINE_CR1_FDX 0x04
+#define RHINE_CR1_ETEN 0x02
+#define RHINE_CR1_EREN 0x01
+
+#define RHINE_ISR_KEYI 0x8000
+#define RHINE_ISR_SRCI 0x4000
+#define RHINE_ISR_ABTI 0x2000
+#define RHINE_ISR_NORBF 0x1000
+#define RHINE_ISR_PKRACE 0x0800
+#define RHINE_ISR_OVFI 0x0400
+#define RHINE_ISR_ETI 0x0200
+#define RHINE_ISR_ERI 0x0100
+#define RHINE_ISR_CNT 0x0080
+#define RHINE_ISR_BE 0x0040
+#define RHINE_ISR_RU 0x0020
+#define RHINE_ISR_TU 0x0010
+#define RHINE_ISR_TXE 0x0008
+#define RHINE_ISR_RXE 0x0004
+#define RHINE_ISR_PTX 0x0002
+#define RHINE_ISR_PRX 0x0001
+
+#define RHINE_IMR_KEYI 0x8000
+#define RHINE_IMR_SRCI 0x4000
+#define RHINE_IMR_ABTI 0x2000
+#define RHINE_IMR_NORBF 0x1000
+#define RHINE_IMR_PKRACE 0x0800
+#define RHINE_IMR_OVFI 0x0400
+#define RHINE_IMR_ETI 0x0200
+#define RHINE_IMR_ERI 0x0100
+#define RHINE_IMR_CNT 0x0080
+#define RHINE_IMR_BE 0x0040
+#define RHINE_IMR_RU 0x0020
+#define RHINE_IMR_TU 0x0010
+#define RHINE_IMR_TXE 0x0008
+#define RHINE_IMR_RXE 0x0004
+#define RHINE_IMR_PTX 0x0002
+#define RHINE_IMR_PRX 0x0001
+
+#define RHINE_IMR_INIT (RHINE_IMR_PTX | RHINE_IMR_PRX | RHINE_IMR_RU)
+
+#define RHINE_BCR0_MAGIC_INIT 0x00
+
+#define RHINE_BCR1_POT2 0x04
+#define RHINE_BCR1_POT1 0x02
+#define RHINE_BCR1_MAGIC_INIT (RHINE_BCR1_POT1|RHINE_BCR1_POT2)
+
+
+#define RHINE_MIICR_MAUTO 0x80
+#define RHINE_MIICR_RCMD 0x40
+#define RHINE_MIICR_WCMD 0x20
+#define RHINE_MIICR_MDPM 0x10
+#define RHINE_MIICR_MOUT 0x08
+#define RHINE_MIICR_MDO 0x04
+#define RHINE_MIICR_MDI 0x02
+#define RHINE_MIICR_MDC 0x01
+
+#define RHINE_MIISR_GPIO1POL 0x80
+#define RHINE_MIISR_MFDC 0x20
+#define RHINE_MIISR_PHYOPT 0x10
+#define RHINE_MIISR_MIIERR 0x08
+#define RHINE_MIISR_MRERR 0x04
+#define RHINE_MIISR_LNKFL 0x02
+#define RHINE_MIISR_SPEED 0x01
+
+#define RHINE_EECSR_EEPR 0x80
+#define RHINE_EECSR_EMBP 0x40
+#define RHINE_EECSR_LOAD 0x20
+#define RHINE_EECSR_DPM 0x10
+#define RHINE_EECSR_ECS 0x08
+#define RHINE_EECSR_ECK 0x04
+#define RHINE_EECSR_EDI 0x02
+#define RHINE_EECSR_EDO 0x01
+
+
+
+#define RHINE_CFGA_EELOAD 0x80
+#define RHINE_CFGA_JUMPER 0x40
+#define RHINE_CFGA_MMIEN 0x20
+#define RHINE_CFGA_MIIOPT 0x10
+#define RHINE_CFGA_AUTOOPT 0x08
+#define RHINE_CFGA_GPIO2I 0x04
+#define RHINE_CFGA_GPIO2O 0x02
+#define RHINE_CFGA_GPIO2OE 0x01
+
+#define RHINE_CFGB_QPKTDIS 0x80
+#define RHINE_CFGB_TRACEN 0x40
+#define RHINE_CFGB_MRDM 0x20
+#define RHINE_CFGB_TXARBIT 0x10
+#define RHINE_CFGB_RXARBIT 0x08
+#define RHINE_CFGB_MWWAIT 0x04
+#define RHINE_CFGB_MRWAIT 0x02
+#define RHINE_CFGB_LATMEN 0x01
+
+#define RHINE_CFGC_BROPT 0x40
+#define RHINE_CFGC_DLYEN 0x20
+#define RHINE_CFGC_BTSEL 0x08
+#define RHINE_CFGC_BPS2 0x04
+#define RHINE_CFGC_BPS1 0x02
+#define RHINE_CFGC_BPS0 0x01
+
+#define RHINE_CFGD_GPIOEN 0x80
+#define RHINE_CFGD_DIAG 0x40
+#define RHINE_CFGD_MRDLEN 0x20
+#define RHINE_CFGD_MAGIC 0x10
+#define RHINE_CFGD_CRANDOM 0x08
+#define RHINE_CFGD_CAP 0x04
+#define RHINE_CFGD_MBA 0x02
+#define RHINE_CFGD_BAKOPT 0x01
+
+
+
+
+//----------------------------------------------------------------------------
+// Receive buffer Descriptor
+#define RHINE_RDES0 0x00 // frame length, status registers
+#define RHINE_RDES1 0x04 // receive length
+#define RHINE_RDES2 0x08 // rx data buffer
+#define RHINE_RDES3 0x0c // next
+#define RHINE_RD_SIZE 0x10
+
+#define RHINE_RDES0_OWN 0x80000000
+#define RHINE_RDES0_FLNG_mask 0x07ff0000
+#define RHINE_RDES0_FLNG_shift 16
+#define RHINE_RDES0_RXOK 0x00008000
+#define RHINE_RDES0_RES1 0x00004000
+#define RHINE_RDES0_MAR 0x00002000
+#define RHINE_RDES0_BAR 0x00001000
+#define RHINE_RDES0_PHY 0x00000800
+#define RHINE_RDES0_CHN 0x00000400
+#define RHINE_RDES0_STP 0x00000200
+#define RHINE_RDES0_EDP 0x00000100
+#define RHINE_RDES0_BUFF 0x00000080
+#define RHINE_RDES0_SERR 0x00000040
+#define RHINE_RDES0_RUNT 0x00000020
+#define RHINE_RDES0_LONG 0x00000010
+#define RHINE_RDES0_FOV 0x00000008
+#define RHINE_RDES0_FAE 0x00000004
+#define RHINE_RDES0_CRC 0x00000002
+#define RHINE_RDES0_RERR 0x00000001
+
+#define RHINE_RD_RLEN_IC 0x00800000
+#define RHINE_RD_RLEN_C 0x00008000
+#define RHINE_RD_RLEN_RLEN_mask 0x000007ff
+
+
+//----------------------------------------------------------------------------
+// Transmit buffer Descriptor
+#define RHINE_TDES0 0x00 // status & own
+#define RHINE_TDES1 0x04 // tx config & length
+#define RHINE_TDES2 0x08 // tx data buffer
+#define RHINE_TDES3 0x0c // next
+#define RHINE_TD_SIZE 0x10
+
+#define RHINE_TDES0_OWN 0x80000000
+#define RHINE_TDES0_TXOK 0x00008000
+#define RHINE_TDES0_JAB 0x00004000
+#define RHINE_TDES0_SERR 0x00002000
+#define RHINE_TDES0_RES1 0x00001000
+#define RHINE_TDES0_RES2 0x00000800
+#define RHINE_TDES0_CRS 0x00000400
+#define RHINE_TDES0_OWC 0x00000200
+#define RHINE_TDES0_ABT 0x00000100
+#define RHINE_TDES0_CDH 0x00000080
+#define RHINE_TDES0_NCR_mask 0x00000038
+#define RHINE_TDES0_NCR_shift 3
+#define RHINE_TDES0_RES3 0x00000004
+#define RHINE_TDES0_UDF 0x00000002
+#define RHINE_TDES0_DFR 0x00000001
+
+#define RHINE_TDES1_TCR_mask 0x00ff0000
+#define RHINE_TDES1_TCR_shift 16
+#define RHINE_TDES1_IC 0x00800000
+#define RHINE_TDES1_EDP 0x00400000
+#define RHINE_TDES1_STP 0x00200000
+#define RHINE_TDES1_CRC 0x00010000
+#define RHINE_TDES1_C 0x00008000
+#define RHINE_TDES1_TLNG_mask 0x000007ff
+
+// ------------------------------------------------------------------------
+
+#define MII_BMCR 0
+#define MII_BMSR 1
+
+#define MII_BMCR_RENEGOTIATE 0x3300
+
+#define MII_BMSR_AN_COMPLETE 0x0020
+#define MII_BMSR_LINK 0x0004
+
+// ------------------------------------------------------------------------
+
+#ifdef KEEP_STATISTICS
+struct via_rhine_stats {
+ unsigned int tx_good ;
+ unsigned int tx_max_collisions ;
+ unsigned int tx_late_collisions ;
+ unsigned int tx_underrun ;
+ unsigned int tx_carrier_loss ;
+ unsigned int tx_deferred ;
+ unsigned int tx_sqetesterrors ;
+ unsigned int tx_single_collisions;
+ unsigned int tx_mult_collisions ;
+ unsigned int tx_total_collisions ;
+ unsigned int rx_good ;
+ unsigned int rx_crc_errors ;
+ unsigned int rx_align_errors ;
+ unsigned int rx_resource_errors ;
+ unsigned int rx_overrun_errors ;
+ unsigned int rx_collisions ;
+ unsigned int rx_short_frames ;
+ unsigned int rx_too_long_frames ;
+ unsigned int rx_symbol_errors ;
+ unsigned int interrupts ;
+ unsigned int rx_count ;
+ unsigned int rx_deliver ;
+ unsigned int rx_resource ;
+ unsigned int rx_restart ;
+ unsigned int tx_count ;
+ unsigned int tx_complete ;
+ unsigned int tx_dropped ;
+};
+#endif
+
+typedef struct rhine_priv_data {
+ int index;
+ cyg_uint8 // (split up for atomic byte access)
+ found:1, // was hardware discovered?
+ mac_addr_ok:1, // can we bring up?
+ active:1, // has this if been brung up?
+ hardwired_esa:1, // set if ESA is hardwired via CDL
+ spare1:4;
+
+ int txbusy; // A packet has been sent
+ unsigned long txkey; // Used to ack when packet sent
+ unsigned char* base; // Base address of controller IO region
+ cyg_vector_t interrupt; // Interrupt vector used by controller
+ unsigned char esa[6]; // Controller ESA
+ // Function to configure the ESA - may fetch ESA from EPROM or
+ // RedBoot config option.
+ void (*config_esa)(struct rhine_priv_data* cpd);
+ void *ndp; // Network Device Pointer
+
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+
+ int devid;
+
+ int phys_id; // ID of physical MII controller
+
+ cyg_uint8* rx_buffers; // ptr to base of buffer mem
+ cyg_uint8* rx_ring; // ptr to base of rx ring memory
+ int rx_ring_cnt; // number of entries in ring
+ int rx_ring_log_cnt; // log of above
+ int rx_ring_next; // index of next full ring entry
+
+ cyg_uint8* tx_buffers;
+ cyg_uint8* tx_ring;
+ int tx_ring_cnt;
+ int tx_ring_log_cnt;
+ int tx_ring_free; // index of next free ring entry
+ int tx_ring_alloc; // index of first controller owned ring
+ int tx_ring_owned; // number of controller owned ring entries
+
+ int rxpacket;
+#ifdef KEEP_STATISTICS
+ struct via_rhine_stats stats;
+#endif
+} rhine_priv_data;
+
+// ------------------------------------------------------------------------
+#endif // CYGONCE_DEVS_ETH_VIA_RHINE_H
+// EOF via_rhine.h
diff --git a/ecos/packages/devs/flash/amd/am29xxxxx/current/ChangeLog b/ecos/packages/devs/flash/amd/am29xxxxx/current/ChangeLog
new file mode 100644
index 0000000..c2e2130
--- /dev/null
+++ b/ecos/packages/devs/flash/amd/am29xxxxx/current/ChangeLog
@@ -0,0 +1,384 @@
+2010-07-14 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_AM29LV640M]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add AM29LV640M part
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_S29GL512P]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add Spansion S29GL512P part
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_S29GL01GP]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add Spansion S29GL01GP part
+
+2009-02-17 Lars Povlsen <lpovlsen@vitesse.com>
+
+ * include/flash_am29xxxxx_parts.inl:
+ Added Macronix MX29LV128M B part (8- and 16-bit)
+ Added Macronix MX29LV128M T part (8-bit)
+ Added Spansion S29GL128N part (8-bit)
+
+2009-02-16 René Schipp von Branitz Nielsen <rbn@vitesse.com>
+
+ * include/flash_am29xxxxx.inl: Silence warning with use of
+ CYGHWR_DEVS_FLASH_ST_M29W320D.
+
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_amd_am29xxxxx.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2006-11-28 Oyvind Harboe <oyvind.harboe@zylin.com>
+
+ * Fixed boot sectors for ST M29W320D
+
+2006-08-29 Yoshinori Sato <ysato@users.sourceforge.jp>
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_S29GL128M]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add AMD/SPANSION S29GL128M part
+
+2005-08-11 Oyvind Harboe <oyvind.harboe@zylin.com>
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_ST_M29W320D]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add ST M29W320D part.
+
+2006-04-03 Lars Povlsen <lpovlsen@vitesse.com>
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_MX29LV128]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add MXIC MX29LV128 part.
+
+ * include/flash_am29xxxxx.inl: (find_sector) Fixed dealing with
+ bootblocks. Was returning device block size even for boot blocks.
+
+2006-02-15 Stephane Deltour <stephane.deltour@barco.com>
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_S29GL128N]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add AMD/SPANSION S29GL128N part.
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_S29GL256N]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add AMD/SPANSION S29GL256N part.
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_S29GL512N]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add AMD/SPANSION S29GL512N part.
+
+2005-09-08 Peter Korsgaard <jacmet@sunsite.dk>
+
+ * include/flash_am29xxxxx.inl (flash_program_buf): Handle writes
+ with length not a multiple of flash word size.
+
+2005-04-17 David Vrabel <dvrabel@arcom.com>
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_AM29F002T]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add AMD AM29F002T part.
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_AM29LV256]:
+ * cdl/flash_amd_am29xxxxx.cdl: Add AMD AM29LV256 part.
+
+ * include/flash_am29xxxxx_parts.inl [CYGHWR_DEVS_FLASH_AMD_AM29LV128]:
+ Use long device id for AM29LV128 part.
+
+2005-03-18 Peter Korsgaard <jacmet@sunsite.dk>
+
+ * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_S29PL032J,
+ CYGHWR_DEVS_FLASH_AMD_S29PL064J, CYGHWR_DEVS_FLASH_AMD_S29PL127J):
+ * cdl/flash_amd_am29xxxxx.cdl: Add support for Spansion S29PL032J,
+ S29PL064J and S29PL127J parts.
+
+2005-02-20 Kurt Stremerch <kurt.stremerch@exys.be>
+
+ * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_S29GL064M):
+ * cdl/flash_amd_am29xxxxx.cdl: Add support for the S29GL064M part.
+
+2004-04-21 Sebastien Couret <sebastien.couret@elios-informatique.com>
+
+ * include/flash_am29xxxxx.inl: Minor changes to silence warnings.
+
+2004-04-08 Bob Koninckx <bob.koninckx@o-3s.com>
+ * include/flash_am29xxxxx_parts.inl: Added support for AM29PL160 top
+ boot block devices and corrected typo.
+
+2004-04-06 Gary Thomas <gary@mlbassoc.com>
+
+ * include/flash_am29xxxxx.inl (flash_program_buf): Buffered program
+ writes failed when configured for parallel devices.
+
+2003-10-21 Jay Foster <jay@systech.com>
+
+ * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_AM29LV033C):
+ Fixed device definition to allow erasing of the upper half of the
+ device. The Sector Protect Verify command would erroneously report
+ the upper half of the device as locked.
+
+2003-10-02 Jay Foster <jay@systech.com>
+
+ * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_AM29LV081B,
+ CYGHWR_DEVS_FLASH_AMD_AM29LV017D, CYGHWR_DEVS_FLASH_AMD_AM29LV033C,
+ CYGHWR_DEVS_FLASH_AMD_AM29LV065D):
+ * cdl/flash_amd_am29xxxxx.cdl: Add support for Am29LV081B, Am29LV017D,
+ Am29LV033C, and Am29LV065D parts.
+
+2003-09-09 Thomas Koeller <thomas.koeller@baslerweb.com>
+
+ * include/flash_am29xxxxx.inl:
+ * include/flash_am29xxxxx_parts.inl: Added support for write
+ buffer programming.
+
+2003-09-04 Thomas Koeller <thomas.koeller@baslerweb.com>
+
+ * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_AM29LV128):
+ * cdl/flash_amd_am29xxxxx.cdl: Add support for Am29LV128 part.
+
+2003-08-17 Bart Veer <bartv@ecoscentric.com>
+
+ * include/flash_am29xxxxx.inl:
+ Allow platform-specific code to override the default loop counts
+ used for timeouts.
+
+ * include/flash_am29xxxxx_parts.inl, cdl/flash_amd_am29xxxxx.cdl:
+ Add AM29PL160 device
+
+2003-07-23 Chris Garry <cgarry@sweeneydesign.co.uk>
+
+ * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_AM29LV400):
+ * cdl/flash_amd_am29xxxxx.cdl: Add support for Am29LV400 part.
+
+2003-04-03 Jani Monoses <jani@iv.ro>
+
+ * include/flash_am29xxxxx.inl:
+ Removed wrapper functions which enabled/disabled cache around query,
+ erase and program operations since the generic flash driver takes
+ care of the cache already.
+
+2003-02-11 Gary Thomas <gary@mlbassoc.com>
+
+ * include/flash_am29xxxxx_parts.inl:
+ Fix identifier code for AM29LV320DT.
+
+2002-12-23 Patrick Doyle <wpd@delcomsys.com>
+
+ * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_AM29DL640D):
+ * cdl/flash_amd_am29xxxxx.cdl:
+ Add support for AM29DL323 and for 16 bit operation of the
+ AM29DL322.
+
+2002-12-04 Mark Salter <msalter@redhat.com>
+
+ * include/flash_am29xxxxx_parts.inl:
+ * cdl/flash_amd_am29xxxxx.cdl: Add support for AM29DL322.
+
+2002-11-25 Gary Thomas <gthomas@ecoscentric.com>
+
+ * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_AM29DL640D):
+ Now tested in 16 bit configurations.
+
+ * include/flash_am29xxxxx.inl: Fix problems with CYGNUM_FLASH_16AS8.
+ The definition was inconsistent/confusing.
+
+2002-11-17 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * include/flash_am29xxxxx_parts.inl:
+ * cdl/flash_am29xxxxx.cdl: Definition for AM29F010 part added. Used by cme555.
+
+2002-10-11 Gary Thomas <gary@mlbassoc.com>
+
+ * include/flash_am29xxxxx_parts.inl:
+ * include/flash_am29xxxxx.inl: Better support for devices with
+ "bootblock" sections - some newer devices have more than one!
+
+2002-09-26 Ian Campbell <icampbell@arcomcontrols.com>
+
+ * include/flash_am29xxxxx_parts.inl:
+ * cdl/flash_amd_am29xxxxx.cdl: Add support for AM29DL640D.
+
+ * include/flash_am29xxxxx.inl: Add support for triple byte part id
+ numbers, such as those used by the AM29DL640D. Allow for parts
+ with up to 5 banks, rather than two -- also to support AM29DL640D
+ parts.
+
+2002-07-29 Gary Thomas <gary@chez-thomas.org>
+2002-07-29 Motoya Kurotsu <kurotsu@allied-telesis.co.jp>
+
+ * include/flash_am29xxxxx.inl: Force routines which actually use
+ the FLASH to run from RAM.
+
+2002-07-24 Gary Thomas <gary@chez-thomas.org>
+2002-07-24 Motoya Kurotsu <kurotsu@allied-telesis.co.jp>
+
+ * include/flash_am29xxxxx.inl (_flash_program_buf): Fix data
+ type for 'state' - needs to be flash_data_t.
+
+2002-06-20 Gary Thomas <gary@chez-thomas.org>
+
+ * include/flash_am29xxxxx.inl: Add cache disable/enable code
+ since this is required on most platforms.
+
+ * include/flash_am29xxxxx_parts.inl:
+ * cdl/flash_amd_am29xxxxx.cdl: Add support for AM29LV320D{T|B}
+
+2002-04-24 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * cdl/flash_amd_am29xxxxx.cdl: Support AM29LV200 and ST M29W200B.
+ * include/flash_am29xxxxx_parts.inl: Likewise.
+
+2002-01-03 Jonathan Larmour <jlarmour@redhat.com>
+2001-12-20 Koichi Nagashima <naga@r-lab.co.jp>
+
+ * cdl/flash_amd_am29xxxxx.cdl: Add support for Toshiba TC58FVB800 part.
+ * include/flash_am29xxxxx_parts.inl: Ditto.
+
+ * include/flash_am29xxxxx.inl: Fix FLASH_Reset definition.
+ Check sector erase timer correctly.
+
+2001-10-31 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_am29xxxxx_parts.inl: Removed fix me comments -
+ description is accurate.
+
+2001-10-30 Jesper Skov <jskov@redhat.com>
+ From Gary:
+ * include/flash_am29xxxxx_parts.inl: Added preliminary AM29LV640
+ support. Still needs some tweaks.
+ * cdl/flash_amd_am29xxxxx.cdl: Same.
+
+2001-09-26 Gary Thomas <gthomas@redhat.com>
+
+ * include/flash_am29xxxxx.inl (flash_erase_block):
+ New platform control - CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT.
+ Define this if the write-protect feature is non-functional/missing.
+
+2001-08-16 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/flash_am29xxxxx.inl: Double erase timeouts for faster CPUs.
+
+2001-08-10 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_am29xxxxx.inl (flash_hwr_init): Fix block number.
+
+2001-07-26 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_am29xxxxx.inl: Made code deal with multiple
+ banks. Use flag to identify banked devices.
+ * include/flash_am29xxxxx_parts.inl: Updated with banked flag.
+
+2001-07-23 David Howells <dhowells@redhat.com>
+
+ * include/flash_am29xxxxx.inl: Added support for chips divided
+ into banks, and added correct addresses for 16-bit chips
+ configured in 8-bit mode
+ * include/flash_am29xxxxx_parts.inl: Added data for chips divided
+ into banks
+
+2001-06-11 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_am29xxxxx.inl: Traverse by incrementing
+ driver-global pointer variable.
+
+2001-06-11 David Howells <dhowells@redhat.com>
+
+ * include/flash_am29xxxxx.inl: actually traverse the list of
+ supported devices, rather than checking the first entry several
+ times
+
+2001-06-08 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_am29xxxxx_parts.inl: New file with just part
+ data.
+
+ * include/flash_am29xxxxx.inl: Leave more space for bootblock
+ offsets. Moved part table data to separate file.
+
+ * cdl/flash_amd_am29xxxxx.cdl: Added config options to control
+ inclusion of table data for various parts.
+
+2001-05-29 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_am29xxxxx.inl (flash_hwr_init): Call platform init
+ code if defined.
+
+2001-05-28 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_am29xxxxx.inl: Rewritten to handle bootblock
+ parts, autodetect part and configure accordingly.
+ Fixed erase and program code to work with devices in parallel.
+ Fixed buglet in bootblock detect code.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_amd_am29xxxxx.cdl: Links function in RAM. IO driver
+ need not copy.
+
+ * include/flash_am29xxxxx.inl: Check for WP before trying to erase
+ block. Use P2V macro.
+
+2001-02-23 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_am29xxxxx.inl (flash_query): Allow device to
+ settle before returning.
+
+2001-02-22 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_am29xxxxx.inl: Fix typo. Cleaned up, almost
+ working with MBX. Times out when erasing from ROM version of RB.
+
+2001-02-20 Jesper Skov <jskov@redhat.com>
+
+ * .../amd/am29xxxxx: Cloned from hardwired am29f040b driver.
+
+2000-12-07 Jesper Skov <jskov@redhat.com>
+
+ * src/flash.h: Addresses and sizes are also affected by
+ interleaving.
+ * src/flash_erase_block.c: Plug in working loop.
+ * src/flash_program_buf.c: Same.
+
+2000-12-06 Jesper Skov <jskov@redhat.com>
+
+ * src/am29f040b_flash.c (flash_hwr_init): Use new query semantics.
+ * src/flash_query.c (flash_query): Changed accordingly.
+
+ * src/flash.h (FLASH_Sector_Erase_Timer): Added.
+
+ * src/flash_erase_block.c: Do not check error flag after operation
+ completes.
+ * src/flash_program_buf.c: Same.
+
+2000-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/am29f040b_flash.c (flash_code_overlaps): Define stext/etext
+ as array types so no assumptions can be made by the compiler about
+ location.
+
+2000-12-05 Jesper Skov <jskov@redhat.com>
+
+ * Cloned from MBX driver.
+
+2000-10-20 Gary Thomas <gthomas@redhat.com>
+
+ * src/mbx_flash.c:
+ * src/flash_query.c:
+ * src/flash_program_buf.c:
+ * src/flash_erase_block.c:
+ * src/flash.h:
+ * cdl/flash_mbx.cdl: New package/file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl b/ecos/packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl
new file mode 100644
index 0000000..73642bc
--- /dev/null
+++ b/ecos/packages/devs/flash/amd/am29xxxxx/current/cdl/flash_amd_am29xxxxx.cdl
@@ -0,0 +1,429 @@
+# ====================================================================
+#
+# flash_amd_am29xxxxx.cdl
+#
+# FLASH memory - Hardware support for AMD AM29xxxxx parts
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas, jskov, Koichi Nagashima
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_AMD_AM29XXXXX {
+ display "AMD AM29XXXXX FLASH memory support"
+ description "FLASH memory device support for AMD AM29XXXXX"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+
+ active_if CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ include_dir cyg/io
+
+ requires { CYGINT_DEVS_FLASH_AMD_VARIANTS != 0 }
+
+ cdl_interface CYGINT_DEVS_FLASH_AMD_VARIANTS {
+ display "Number of included variants"
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29F002T {
+ display "AMD AM29F002T flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29F002T (top boot block)
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29F010 {
+ display "AMD AM29F010 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29F010
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29F040B {
+ display "AMD AM29F040B flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29F040B
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV128 {
+ display "AMD AM29LV128 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29LV128
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_MX29LV128 {
+ display "MXIC MX29LV128 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the MX29LV128
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV160 {
+ display "AMD AM29LV160 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29LV160
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29PL160 {
+ display "AMD AM29PL160 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29PL160
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV320D {
+ display "AMD AM29LV320 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29LV320
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_ST_M29W320D {
+ display "ST M29W320D flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the ST M29W320D
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV200 {
+ display "AMD AM29LV200 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29LV200
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_ST_M29W200B {
+ display "ST M29W200B flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the ST M29W200B part. This
+ memory device is pin- and software compatible with the
+ AMD AM29LV200 device."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV640 {
+ display "AMD AM29LV640 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29LV640
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29DL322D {
+ display "AMD AM29DL322D flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AM29DL322D
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29DL323D {
+ display "AMD AM29DL323D flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AM29DL323D
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29DL324D {
+ display "AMD AM29DL324D flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AM29DL324D
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV400 {
+ display "AMD AM29LV400 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AM29LV400
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29DL640D {
+ display "AMD AM29DL640D flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AM29DL640D
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV640M {
+ display "AMD AM29LV640M flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AM29LV640M
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29F800 {
+ display "AMD AM29F800 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AM29F800
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV800 {
+ display "AMD AM29LV800 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AM29LV800
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_TC58FVB800 {
+ display "Toshiba TC58FVB800 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the Toshiba TC58FVB800."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV081B {
+ display "AMD AM29LV081B flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29LV081B
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV017D {
+ display "AMD AM29LV017D flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29LV017D
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV033C {
+ display "AMD AM29LV033C flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29LV033C
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV065D {
+ display "AMD AM29LV065D flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD29LV065D
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_AM29LV256 {
+ display "AMD AM29LV256 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the AMD AM29LV256
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_S29GL064M {
+ display "AMD/SPANSION S29GL064M flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD/SPANSION flash driver will be
+ able to recognize and handle the S29GL064M
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_S29PL032J {
+ display "Spansion S29PL032J flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the S29PL032J
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_S29PL064J {
+ display "Spansion S29PL064J flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the S29PL064J
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_S29PL127J {
+ display "Spansion S29PL127J flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD flash driver will be
+ able to recognize and handle the S29PL0127J
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_S29GL128N {
+ display "AMD/SPANSION S29GL128N flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD/SPANSION flash driver will be
+ able to recognize and handle the S29GL128N
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_S29GL256N {
+ display "AMD/SPANSION S29GL256N flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD/SPANSION flash driver will be
+ able to recognize and handle the S29GL256N
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_S29GL512N {
+ display "AMD/SPANSION S29GL512N flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD/SPANSION flash driver will be
+ able to recognize and handle the S29GL512N
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_S29GL128M {
+ display "AMD/SPANSION S29GL128M flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD/SPANSION flash driver will be
+ able to recognize and handle the S29GL128M
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_S29GL512P {
+ display "AMD/SPANSION S29GL512P flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD/SPANSION flash driver will be
+ able to recognize and handle the S29GL512P
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_AMD_S29GL01GP {
+ display "AMD/SPANSION S29GL01GP flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_AMD_VARIANTS
+ description "
+ When this option is enabled, the AMD/SPANSION flash driver will be
+ able to recognize and handle the S29GL01GP
+ part in the family."
+ }
+
+}
diff --git a/ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl b/ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl
new file mode 100644
index 0000000..9f5d236
--- /dev/null
+++ b/ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl
@@ -0,0 +1,633 @@
+#ifndef CYGONCE_DEVS_FLASH_AMD_AM29XXXXX_INL
+#define CYGONCE_DEVS_FLASH_AMD_AM29XXXXX_INL
+//==========================================================================
+//
+// am29xxxxx.inl
+//
+// AMD AM29xxxxx series flash driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov, Koichi Nagashima
+// Date: 2001-02-21
+// Purpose:
+// Description: AMD AM29xxxxx series flash device driver
+// Notes: While the parts support sector locking, some only do so
+// via crufty magic and the use of programmer hardware
+// (specifically by applying 12V to one of the address
+// pins) so the driver does not support write protection.
+//
+// FIXME: Should support SW locking on the newer devices.
+//
+// FIXME: Figure out how to do proper error checking when there are
+// devices in parallel. Presently the driver will return
+// driver timeout error on device errors which is not very
+// helpful.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_amd_am29xxxxx.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_misc.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+//----------------------------------------------------------------------------
+// Common device details.
+#define FLASH_Read_ID FLASHWORD( 0x90 )
+#define FLASH_WP_State FLASHWORD( 0x90 )
+#define FLASH_Reset FLASHWORD( 0xF0 )
+#define FLASH_Program FLASHWORD( 0xA0 )
+#define FLASH_Block_Erase FLASHWORD( 0x30 )
+#define FLASH_Load_Buffer FLASHWORD( 0x25 )
+#define FLASH_Flush_Buffer FLASHWORD( 0x29 )
+
+#define FLASH_Data FLASHWORD( 0x80 ) // Data complement
+#define FLASH_Busy FLASHWORD( 0x40 ) // "Toggle" bit
+#define FLASH_Err FLASHWORD( 0x20 )
+#define FLASH_Sector_Erase_Timer FLASHWORD( 0x08 )
+
+#define FLASH_unlocked FLASHWORD( 0x00 )
+
+#ifndef CYGNUM_FLASH_16AS8
+#define _16AS8 0
+#else
+#define _16AS8 CYGNUM_FLASH_16AS8
+#endif
+
+
+# if (_16AS8 == 0) || defined(CYGHWR_DEVS_FLASH_ST_M29W320D)
+# define FLASH_Setup_Addr1 (0x555)
+# define FLASH_Setup_Addr2 (0x2AA)
+# define FLASH_VendorID_Addr (0)
+# define FLASH_DeviceID_Addr (1)
+# define FLASH_DeviceID_Addr2 (0x0e)
+# define FLASH_DeviceID_Addr3 (0x0f)
+# define FLASH_WP_Addr (2)
+#else
+# define FLASH_Setup_Addr1 (0xAAA)
+# define FLASH_Setup_Addr2 (0x555)
+# define FLASH_VendorID_Addr (0)
+# define FLASH_DeviceID_Addr (2)
+# define FLASH_DeviceID_Addr2 (0x1c)
+# define FLASH_DeviceID_Addr3 (0x1e)
+# define FLASH_WP_Addr (4)
+#endif
+
+#define FLASH_Setup_Code1 FLASHWORD( 0xAA )
+#define FLASH_Setup_Code2 FLASHWORD( 0x55 )
+#define FLASH_Setup_Erase FLASHWORD( 0x80 )
+
+// Platform code must define the below
+// #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel)
+// #define CYGNUM_FLASH_SERIES : Number of devices in series
+// #define CYGNUM_FLASH_WIDTH : Width of devices on platform
+// #define CYGNUM_FLASH_BASE : Address of first device
+
+// Platform code may define some or all of the below, to provide
+// timeouts appropriate to the target hardware. The timeout
+// values depend partly on the flash part being used, partly
+// on the target (including bus and cpu speeds).
+#ifndef CYGNUM_FLASH_TIMEOUT_QUERY
+# define CYGNUM_FLASH_TIMEOUT_QUERY 500000
+#endif
+#ifndef CYGNUM_FLASH_TIMEOUT_ERASE_TIMER
+# define CYGNUM_FLASH_TIMEOUT_ERASE_TIMER 10000000
+#endif
+#ifndef CYGNUM_FLASH_TIMEOUT_ERASE_COMPLETE
+# define CYGNUM_FLASH_TIMEOUT_ERASE_COMPLETE 10000000
+#endif
+#ifndef CYGNUM_FLASH_TIMEOUT_PROGRAM
+# define CYGNUM_FLASH_TIMEOUT_PROGRAM 10000000
+#endif
+
+#define CYGNUM_FLASH_BLANK (1)
+
+#ifndef FLASH_P2V
+# define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_)))
+#endif
+#ifndef CYGHWR_FLASH_AM29XXXXX_PLF_INIT
+# define CYGHWR_FLASH_AM29XXXXX_PLF_INIT()
+#endif
+
+//----------------------------------------------------------------------------
+// Now that device properties are defined, include magic for defining
+// accessor type and constants.
+#include <cyg/io/flash_dev.h>
+
+//----------------------------------------------------------------------------
+// Information about supported devices
+typedef struct flash_dev_info {
+ cyg_bool long_device_id;
+ flash_data_t device_id;
+ flash_data_t device_id2;
+ flash_data_t device_id3;
+ cyg_uint32 block_size;
+ cyg_int32 block_count;
+ cyg_uint32 base_mask;
+ cyg_uint32 device_size;
+ cyg_bool bootblock;
+ cyg_uint32 bootblocks[64]; // 0 is bootblock offset, 1-11 sub-sector sizes (or 0)
+ cyg_bool banked;
+ cyg_uint32 banks[8]; // bank offsets, highest to lowest (lowest should be 0)
+ // (only one entry for now, increase to support devices
+ // with more banks).
+ cyg_uint32 bufsiz; // write buffer size in units of flash_data_t
+} flash_dev_info_t;
+
+static const flash_dev_info_t* flash_dev_info;
+static const flash_dev_info_t supported_devices[] = {
+#include <cyg/io/flash_am29xxxxx_parts.inl>
+};
+#define NUM_DEVICES (sizeof(supported_devices)/sizeof(flash_dev_info_t))
+
+//----------------------------------------------------------------------------
+// Functions that put the flash device into non-read mode must reside
+// in RAM.
+void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
+int flash_erase_block(void* block, unsigned int size)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int flash_program_buf(void* addr, void* data, int len)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+
+//----------------------------------------------------------------------------
+// Auxiliary functions
+static volatile flash_data_t * find_bank(volatile flash_data_t * base, void * addr, CYG_ADDRWORD * bo)
+ __attribute__ ((section (".2ram.find_bank")));
+static flash_data_t * find_sector(volatile flash_data_t * addr, unsigned long *remain_size)
+ __attribute__ ((section (".2ram.find_sector")));
+
+//----------------------------------------------------------------------------
+// Flash Query
+//
+// Only reads the manufacturer and part number codes for the first
+// device(s) in series. It is assumed that any devices in series
+// will be of the same type.
+
+void
+flash_query(void* data)
+{
+ volatile flash_data_t *ROM;
+ volatile flash_data_t *f_s1, *f_s2;
+ flash_data_t* id = (flash_data_t*) data;
+ flash_data_t w;
+ long timeout = CYGNUM_FLASH_TIMEOUT_QUERY;
+
+ ROM = (flash_data_t*) CYGNUM_FLASH_BASE;
+ f_s1 = FLASH_P2V(ROM+FLASH_Setup_Addr1);
+ f_s2 = FLASH_P2V(ROM+FLASH_Setup_Addr2);
+
+ *f_s1 = FLASH_Reset;
+ w = *(FLASH_P2V(ROM));
+
+ *f_s1 = FLASH_Setup_Code1;
+ *f_s2 = FLASH_Setup_Code2;
+ *f_s1 = FLASH_Read_ID;
+
+ id[0] = -1;
+ id[1] = -1;
+
+ // Manufacturers' code
+ id[0] = *(FLASH_P2V(ROM+FLASH_VendorID_Addr));
+ // Part number
+ id[1] = *(FLASH_P2V(ROM+FLASH_DeviceID_Addr));
+ id[2] = *(FLASH_P2V(ROM+FLASH_DeviceID_Addr2));
+ id[3] = *(FLASH_P2V(ROM+FLASH_DeviceID_Addr3));
+
+
+ *(FLASH_P2V(ROM)) = FLASH_Reset;
+
+ // Stall, waiting for flash to return to read mode.
+ while ((--timeout != 0) && (w != *(FLASH_P2V(ROM)))) ;
+}
+
+
+//----------------------------------------------------------------------------
+// Initialize driver details
+int
+flash_hwr_init(void)
+{
+ flash_data_t id[4];
+ int i;
+
+ CYGHWR_FLASH_AM29XXXXX_PLF_INIT();
+
+ flash_dev_query(id);
+
+ // Look through table for device data
+ flash_dev_info = supported_devices;
+ for (i = 0; i < NUM_DEVICES; i++) {
+ if (!flash_dev_info->long_device_id && flash_dev_info->device_id == id[1])
+ break;
+ else if ( flash_dev_info->long_device_id && flash_dev_info->device_id == id[1]
+ && flash_dev_info->device_id2 == id[2]
+ && flash_dev_info->device_id3 == id[3] )
+ break;
+ flash_dev_info++;
+ }
+
+ // Did we find the device? If not, return error.
+ if (NUM_DEVICES == i)
+ return FLASH_ERR_DRV_WRONG_PART;
+
+ // Hard wired for now
+ flash_info.block_size = flash_dev_info->block_size;
+ flash_info.blocks = flash_dev_info->block_count * CYGNUM_FLASH_SERIES;
+ flash_info.start = (void *)CYGNUM_FLASH_BASE;
+ flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (flash_dev_info->device_size * CYGNUM_FLASH_SERIES));
+ return FLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int e)
+{
+ return e;
+}
+
+
+//----------------------------------------------------------------------------
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern unsigned char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
+
+//----------------------------------------------------------------------------
+// Erase Block
+
+int
+flash_erase_block(void* block, unsigned int size)
+{
+ volatile flash_data_t* ROM, *BANK;
+ volatile flash_data_t* b_p = (flash_data_t*) block;
+ volatile flash_data_t *b_v;
+ volatile flash_data_t *f_s0, *f_s1, *f_s2;
+ int timeout = CYGNUM_FLASH_TIMEOUT_QUERY;
+ int len = 0;
+ int res = FLASH_ERR_OK;
+ flash_data_t state;
+ cyg_bool bootblock = false;
+ cyg_uint32 *bootblocks = (cyg_uint32 *)0;
+ CYG_ADDRWORD bank_offset;
+ ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask);
+ BANK = find_bank(ROM, block, &bank_offset);
+
+ f_s0 = FLASH_P2V(BANK);
+ f_s1 = FLASH_P2V(BANK + FLASH_Setup_Addr1);
+ f_s2 = FLASH_P2V(BANK + FLASH_Setup_Addr2);
+
+ // Assume not "boot" sector, full size
+ bootblock = false;
+ len = flash_dev_info->block_size;
+
+ // Is this in a "boot" sector?
+ if (flash_dev_info->bootblock) {
+ bootblocks = (cyg_uint32 *)&flash_dev_info->bootblocks[0];
+ while (*bootblocks != _LAST_BOOTBLOCK) {
+ if (*bootblocks++ == ((unsigned long)block - (unsigned long)ROM)) {
+ len = *bootblocks++; // Size of first sub-block
+ bootblock = true;
+ break;
+ } else {
+ int ls = flash_dev_info->block_size;
+ // Skip over segment
+ while ((ls -= *bootblocks++) > 0) ;
+ }
+ }
+ }
+
+ while (size > 0) {
+#ifndef CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT
+ // First check whether the block is protected
+ *f_s1 = FLASH_Setup_Code1;
+ *f_s2 = FLASH_Setup_Code2;
+ *f_s1 = FLASH_WP_State;
+ state = *FLASH_P2V(b_p+FLASH_WP_Addr);
+ *f_s0 = FLASH_Reset;
+
+ if (FLASH_unlocked != state)
+ return FLASH_ERR_PROTECT;
+#endif
+
+ b_v = FLASH_P2V(b_p);
+
+ // Send erase block command - six step sequence
+ *f_s1 = FLASH_Setup_Code1;
+ *f_s2 = FLASH_Setup_Code2;
+ *f_s1 = FLASH_Setup_Erase;
+ *f_s1 = FLASH_Setup_Code1;
+ *f_s2 = FLASH_Setup_Code2;
+ *b_v = FLASH_Block_Erase;
+
+ // Now poll for the completion of the sector erase timer (50us)
+ timeout = CYGNUM_FLASH_TIMEOUT_ERASE_TIMER; // how many retries?
+ while (true) {
+ state = *b_v;
+ if ((state & FLASH_Sector_Erase_Timer)
+ == FLASH_Sector_Erase_Timer) break;
+
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ }
+
+ // Then wait for erase completion.
+ if (FLASH_ERR_OK == res) {
+ timeout = CYGNUM_FLASH_TIMEOUT_ERASE_COMPLETE;
+ while (true) {
+ state = *b_v;
+ if (FLASH_BlankValue == state) {
+ break;
+ }
+
+ // Don't check for FLASH_Err here since it will fail
+ // with devices in parallel because these may finish
+ // at different times.
+
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ }
+ }
+
+ if (FLASH_ERR_OK != res)
+ *FLASH_P2V(ROM) = FLASH_Reset;
+
+ size -= len; // This much has been erased
+
+ // Verify erase operation
+ while (len > 0) {
+ b_v = FLASH_P2V(b_p++);
+ if (*b_v != FLASH_BlankValue) {
+ // Only update return value if erase operation was OK
+ if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
+ return res;
+ }
+ len -= sizeof(*b_p);
+ }
+
+ if (bootblock) {
+ len = *bootblocks++;
+ }
+ }
+ return res;
+}
+
+
+//----------------------------------------------------------------------------
+// Program Buffer
+int
+flash_program_buf(void* addr, void* data, int len)
+{
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* BANK;
+ volatile flash_data_t* SECT=NULL;
+ volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
+ volatile flash_data_t* addr_p = (flash_data_t*) addr;
+ volatile flash_data_t* addr_v = FLASH_P2V(addr_p);
+ volatile flash_data_t *f_s1, *f_s2;
+ CYG_ADDRWORD bank_offset;
+ int timeout;
+ int res = FLASH_ERR_OK;
+ const CYG_ADDRWORD mask =
+ flash_dev_info->bufsiz * sizeof (flash_data_t) - 1;
+ unsigned long rem_sect_size;
+ int remain;
+
+ // check the address is suitably aligned
+ if ((unsigned long)addr & (CYGNUM_FLASH_INTERLEAVE * CYGNUM_FLASH_WIDTH / 8 - 1))
+ return FLASH_ERR_INVALID;
+
+ // Base address of device(s) being programmed.
+ ROM = (volatile flash_data_t*)((unsigned long)addr_p & flash_dev_info->base_mask);
+ BANK = find_bank(ROM, addr, &bank_offset);
+
+ f_s1 = FLASH_P2V(BANK + FLASH_Setup_Addr1);
+ f_s2 = FLASH_P2V(BANK + FLASH_Setup_Addr2);
+ rem_sect_size = 0;
+ remain = len % sizeof (flash_data_t);
+ len /= sizeof (flash_data_t);
+
+ while (len > 0) {
+ flash_data_t state;
+ unsigned int nwords;
+
+ addr_v = FLASH_P2V(addr_p);
+
+ if (flash_dev_info->bufsiz > 1) {
+ // Assume buffer size is power of two
+ unsigned int i;
+
+ if (rem_sect_size == 0) {
+ SECT = find_sector(addr_v, &rem_sect_size);
+ rem_sect_size /= sizeof (flash_data_t);
+ }
+
+ // Compute word count to write
+ nwords = flash_dev_info->bufsiz
+ - (((CYG_ADDRWORD) addr_v & mask) / sizeof (flash_data_t));
+ if (nwords > len)
+ nwords = len;
+
+ // Initiate buffered write
+ *f_s1 = FLASH_Setup_Code1;
+ *f_s2 = FLASH_Setup_Code2;
+ *SECT = FLASH_Load_Buffer;
+ *SECT = FLASHWORD(nwords - 1); // All devices need to see this
+
+ // Load data into write buffer, flush buffer
+ for(i = 0; i < nwords; i++)
+ *addr_v++ = *data_ptr++;
+ --addr_v; --data_ptr;
+ *SECT = FLASH_Flush_Buffer;
+ rem_sect_size -= nwords;
+ } else {
+ // Program data [byte] - 4 step sequence
+ *f_s1 = FLASH_Setup_Code1;
+ *f_s2 = FLASH_Setup_Code2;
+ *f_s1 = FLASH_Program;
+ *addr_v = *data_ptr;
+
+ nwords = 1;
+ }
+
+ addr_p += nwords;
+ timeout = CYGNUM_FLASH_TIMEOUT_PROGRAM;
+ while (true) {
+ state = *addr_v;
+ if (*data_ptr == state) {
+ break;
+ }
+
+ // Can't check for FLASH_Err since it'll fail in parallel
+ // configurations.
+
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ }
+
+ if (FLASH_ERR_OK != res)
+ *FLASH_P2V(ROM) = FLASH_Reset;
+
+ if (*addr_v != *data_ptr++) {
+ // Only update return value if erase operation was OK
+ if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
+ break;
+ }
+ len -= nwords;
+ }
+
+ // Program remaining bytes if len not a multiple of flash word size
+ if ((FLASH_ERR_OK == res) && remain)
+ {
+ // construct final word to be programmed with 0xff in the
+ // remaining bytes
+ flash_data_t final = (flash_data_t)-1;
+ unsigned char *src = (unsigned char *) data_ptr;
+ unsigned char *dst = (unsigned char *) &final;
+
+ while (remain--)
+ *dst++ = *src++;
+
+ addr_v = FLASH_P2V(addr_p);
+
+ // Program data [byte] - 4 step sequence
+ *f_s1 = FLASH_Setup_Code1;
+ *f_s2 = FLASH_Setup_Code2;
+ *f_s1 = FLASH_Program;
+ *addr_v = final;
+
+ timeout = CYGNUM_FLASH_TIMEOUT_PROGRAM;
+ while (true) {
+ flash_data_t state = *addr_v;
+ if (final == state) {
+ break;
+ }
+
+ // Can't check for FLASH_Err since it'll fail in parallel
+ // configurations.
+
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ }
+
+ if (FLASH_ERR_OK != res)
+ *FLASH_P2V(ROM) = FLASH_Reset;
+
+ if (*addr_v != final) {
+ // Only update return value if write operation was OK
+ if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
+ }
+ }
+
+ // Ideally, we'd want to return not only the failure code, but also
+ // the address/device that reported the error.
+ return res;
+}
+
+static volatile flash_data_t *
+find_bank(volatile flash_data_t * base, void * addr, CYG_ADDRWORD * bo)
+{
+ volatile flash_data_t * res = base;
+
+ if (flash_dev_info->banked) {
+ int b = 0;
+ *bo = (unsigned long)addr & ~(flash_dev_info->block_size-1);
+ *bo -= (unsigned long) base;
+ for(;;) {
+ if (*bo >= flash_dev_info->banks[b]) {
+ res = (volatile flash_data_t*) ((unsigned long)base + flash_dev_info->banks[b]);
+ break;
+ }
+ b++;
+ }
+ }
+
+ return res;
+}
+
+static flash_data_t *
+find_sector(volatile flash_data_t * addr, unsigned long *remain_size)
+{
+ const CYG_ADDRESS mask = flash_dev_info->block_size - 1;
+ const CYG_ADDRESS a = (CYG_ADDRESS) addr;
+ const CYG_ADDRESS base = a & flash_dev_info->base_mask;
+ CYG_ADDRESS res = a & ~mask;
+
+ *remain_size = flash_dev_info->block_size - (a & mask);
+
+ if (flash_dev_info->bootblock) {
+ cyg_uint32 * bootblocks = flash_dev_info->bootblocks;
+ while (*bootblocks != _LAST_BOOTBLOCK) {
+ if (*bootblocks++ == (res - base)) { /* Matching offset marker */
+ while (res + *bootblocks <= a) {
+ res += *bootblocks++;
+ }
+ *remain_size = *bootblocks - (a - res);
+ break;
+ } else {
+ int ls = flash_dev_info->block_size;
+ // Skip over segment
+ while ((ls -= *bootblocks++) > 0) ;
+ }
+ }
+ }
+
+ return (flash_data_t *) res;
+}
+
+#endif // CYGONCE_DEVS_FLASH_AMD_AM29XXXXX_INL
diff --git a/ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl b/ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl
new file mode 100644
index 0000000..d9c2ae1
--- /dev/null
+++ b/ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl
@@ -0,0 +1,1547 @@
+#ifndef CYGONCE_DEVS_FLASH_AMD_AM29XXXXX_PARTS_INL
+#define CYGONCE_DEVS_FLASH_AMD_AM29XXXXX_PARTS_INL
+//==========================================================================
+//
+// am29xxxxx_parts.inl
+//
+// AMD AM29xxxxx part descriptors
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov, Koichi Nagashima
+// Date: 2001-06-08
+// Purpose:
+// Description: AMD AM29xxxxx part descriptors
+// Usage: Should be included from the flash_am29xxxxx.inl file only.
+//
+// FIXME: Add configury for selecting bottom/top bootblocks
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//
+// Note: 'bootblocks' are a set of blocks which are treated by
+// the driver as a single larger block. This simplifies the driver
+// so as to only have to deal with single size blocks (even though
+// the physical device may differ). The data structure is laid out as:
+// <address of start of boot block area 1>
+// <size of sub-block 1>
+// <size of sub-block 2>
+// ...
+// <size of sub-block n>
+// <address of start of boot block area 2>
+// <size of sub-block 1>
+// <size of sub-block 2>
+// ...
+// <size of sub-block n>
+// _LAST_BOOTBLOCK
+//
+// Finally, when specifying a device with bootblocks, the total number
+// of blocks should reflect this collapse, i.e. if the device has 15
+// full size blocks and 8 blocks which are 1/8 each, then the total
+// should be 16 blocks.
+//
+#define _LAST_BOOTBLOCK (-1)
+
+#if CYGNUM_FLASH_WIDTH == 8
+#ifdef CYGHWR_DEVS_FLASH_AMD_MX29LV128
+ { // MX29LV128M-B (Bottom-boot)
+ long_device_id: true,
+ device_id : FLASHWORD(0x7e),
+ device_id2 : FLASHWORD(0x11),
+ device_id3 : FLASHWORD(0x00),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 256,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 32
+ },
+ { // MX29LV128M-T (Top-boot)
+ long_device_id: true,
+ device_id : FLASHWORD(0x7e),
+ device_id2 : FLASHWORD(0x11),
+ device_id3 : FLASHWORD(0x01),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 256,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0xff0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 32
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29F002T
+ { // AM29F002T
+ device_id : FLASHWORD(0xb0),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 4,
+ device_size: 0x40000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x40000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x030000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29F010
+ { // AM29F010
+ device_id : FLASHWORD(0x20),
+ block_size : 0x4000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 8,
+ device_size: 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x20000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29F040B
+ { // AM29F040B
+ device_id : FLASHWORD(0xa4),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 8,
+ device_size: 0x80000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x80000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV160
+ { // MBM29LV160-T | AM29LV160-T
+ device_id : FLASHWORD(0xc4),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x1f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // MBM29LV160-B | AM29LV160-B
+ device_id : FLASHWORD(0x49),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV200
+ { // AM29LV200-T
+ device_id : FLASHWORD(0x3b),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 4,
+ device_size: 0x40000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x40000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x030000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // AM29LV200-B
+ device_id : FLASHWORD(0xbf),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 4,
+ device_size: 0x40000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x40000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV320D
+ { // AM29LV320DT
+ device_id : FLASHWORD(0xF6),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // AM29LV320D
+ device_id : FLASHWORD(0xF9),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL322D
+ { // AM29DL322D-T
+ device_id : FLASHWORD(0x55),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x380000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+ { // AM29DL322D-B
+ device_id : FLASHWORD(0x56),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x80000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL323D
+ { // AM29DL323D-T
+ device_id : FLASHWORD(0x50),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x300000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+ { // AM29DL323D-B
+ device_id : FLASHWORD(0x53),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL324D
+ { // AM29DL324D-T
+ device_id : FLASHWORD(0x5c),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+ { // AM29DL324D-B
+ device_id : FLASHWORD(0x5f),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL640D
+{ // AM29DL640D
+ long_device_id: true,
+ device_id : FLASHWORD(0x7e),
+ device_id2 : FLASHWORD(0x02),
+ device_id3 : FLASHWORD(0x01),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x0800000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x8000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x7F0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x0700000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x0400000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x0100000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29F800
+ { // AM29F800-T
+ device_id : FLASHWORD(0xd6),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0xf0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x08000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x02000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x02000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x04000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // AM29F800-B
+ device_id : FLASHWORD(0x58),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV800
+ { // AM29LV800-T
+ device_id : FLASHWORD(0xda),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0xf0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x08000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x02000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x02000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x04000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // AM29LV800-B
+ device_id : FLASHWORD(0x5b),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_TC58FVB800
+ { // Toshiba TC58FVB800 (compatible with AM29LV800-B except for IDs.)
+ device_id : FLASHWORD(0xCE),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV081B
+ { // AM29LV081B
+ device_id : FLASHWORD(0x38),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV017D
+ { // AM29LV017D
+ device_id : FLASHWORD(0xC8),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV033C
+ { // AM29LV033C
+ device_id : FLASHWORD(0xA3),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ // Although this device is not a true banked device, we
+ // treat the device as having two banks to get the
+ // Sector Protect Verify to work for the upper half of
+ // the device. Reference Note 9 for Table 9 in the
+ // AMD data sheet.
+ banked : true,
+ banks : { 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV065D
+ { // AM29LV065D
+ device_id : FLASHWORD(0x93),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x800000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x800000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29GL128N
+ { // AMD/SPANSION S29GL128N
+ long_device_id: true,
+ device_id : FLASHWORD(0x7e),
+ device_id2 : FLASHWORD(0x21),
+ device_id3 : FLASHWORD(0x01),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 32,
+ },
+#endif
+
+#else // 16 bit devices
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV128
+ { // AM29LV128
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2212),
+ device_id3 : FLASHWORD(0x2200),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 256,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 16
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_MX29LV128
+ { // MX29LV128M-B
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2211),
+ device_id3 : FLASHWORD(0x2200),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 256,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 16
+ },
+ { // MX29LV128M-T
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2211),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 256,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0xff0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 16
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV160
+ { // MBM29LV160-T | AM29LV160-T
+ device_id : FLASHWORD(0x22c4),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x1f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // MBM29LV160-B | AM29LV160-B
+ device_id : FLASHWORD(0x2249),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29PL160
+ { // AM29PL160-T
+ device_id : FLASHWORD(0x2227),
+ block_size : 0x00040000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 8,
+ device_size: 0x00200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x00200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x1c0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x038000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // AM29PL160-B
+ device_id : FLASHWORD(0x2245),
+ block_size : 0x00040000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 8,
+ device_size: 0x00200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x00200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x038000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV200
+ { // AM29LV200-T
+ device_id : FLASHWORD(0x223b),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 4,
+ device_size: 0x40000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x40000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x030000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // AM29LV200-B
+ device_id : FLASHWORD(0x22bf),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 4,
+ device_size: 0x40000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x40000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_ST_M29W200B
+ { // ST M29W200BT
+ device_id : FLASHWORD(0x0051),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 4,
+ device_size: 0x40000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x40000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x030000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // ST M29W200BB
+ device_id : FLASHWORD(0x0057),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 4,
+ device_size: 0x40000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x40000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_ST_M29W320D
+ { // M29W320DT
+ device_id : FLASHWORD(0x22ca),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE, // offset
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE, // size 1
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE, // size 2
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE, // size 3
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE, // size 4
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // M29W320DB
+ device_id : FLASHWORD(0x22cb),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE, // offset
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE, // size 1
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE, // size 2
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE, // size 3
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE, // size 4
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV320D
+ { // AM29LV320DT
+ device_id : FLASHWORD(0x22F6),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // AM29LV320D
+ device_id : FLASHWORD(0x22F9),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL322D
+ { // AM29DL322D-T
+ device_id : FLASHWORD(0x2255),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x380000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+ { // AM29DL322D-B
+ device_id : FLASHWORD(0x2256),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x80000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL323D
+ { // AM29DL323D-T
+ device_id : FLASHWORD(0x2250),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x300000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+ { // AM29DL323D-B
+ device_id : FLASHWORD(0x2253),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL324D
+ { // AM29DL324D-T
+ device_id : FLASHWORD(0x225c),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+ { // AM29DL324D-B
+ device_id : FLASHWORD(0x225f),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL640D
+{ // AM29DL640D
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2202),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x800000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x800000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x7F0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x700000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV400
+ { // AM29LV400-T
+ device_id : FLASHWORD(0x22b9),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 8,
+ device_size: 0x80000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x80000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0xf0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x08000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x02000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x02000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x04000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // AM29LV400-B
+ device_id : FLASHWORD(0x22ba),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 8,
+ device_size: 0x80000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x80000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29F800
+ { // AM29F800-T
+ device_id : FLASHWORD(0x22d6),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0xf0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x08000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x02000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x02000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x04000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // AM29F800-B
+ device_id : FLASHWORD(0x2258),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV800
+ { // AM29LV800-T
+ device_id : FLASHWORD(0x22da),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0xf0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x08000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x02000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x02000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x04000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+ { // AM29LV800-B
+ device_id : FLASHWORD(0x225b),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV640
+ { // MBM29LV640xx
+ device_id : FLASHWORD(0x22d7),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x800000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x800000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV640M
+ { // MBM29LV640xx
+ device_id : FLASHWORD(0x227e),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x800000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x800000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_TC58FVB800
+ { // Toshiba TC58FVB800 (compatible with AM29LV800-B except for IDs.)
+ device_id : FLASHWORD(0xCE),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV256
+ { // AMD AM29LV256
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2212),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 512,
+ device_size: 0x2000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x2000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 16,
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29PL032J
+ { // S29PL032J
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x220a),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x0400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x4000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x3F0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x0380000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x0200000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x0080000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29PL064J
+ { // S29PL064J
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2202),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x0800000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x8000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x7F0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x0700000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x0400000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x0100000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29PL127J
+ { // S29PL127J
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2220),
+ device_id3 : FLASHWORD(0x2200),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 256,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0xFF0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x0e00000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x0800000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x0200000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29GL064M
+ { // AMD/SPANSION S29GL064M
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2210),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x0800000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x8000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x00000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x7F0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x2000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : true,
+ banks : { 0x0700000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x0400000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x0100000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ bufsiz : 1
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29GL128N
+ { // AMD/SPANSION S29GL128N
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2221),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 16,
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29GL256N
+ { // AMD/SPANSION S29GL256N
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2222),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 256,
+ device_size: 0x2000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x2000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 16,
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29GL512N
+ { // AMD/SPANSION S29GL512N
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2223),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 512,
+ device_size: 0x4000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x4000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 16,
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29GL128M
+ { // AMD/SPANSION S29GL128M
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2212),
+ device_id3 : FLASHWORD(0x2200),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 256,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 16,
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29GL512P
+ { // AMD/SPANSION S29GL512P
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2223),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 512,
+ device_size: 0x4000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x4000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 32,
+ },
+#endif
+#ifdef CYGHWR_DEVS_FLASH_AMD_S29GL01GP
+ { // AMD/SPANSION S29GL01GP
+ long_device_id: true,
+ device_id : FLASHWORD(0x227e),
+ device_id2 : FLASHWORD(0x2228),
+ device_id3 : FLASHWORD(0x2201),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 1024,
+ device_size: 0x8000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x8000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ banked : false,
+ bufsiz : 32,
+ },
+#endif
+
+#endif // 16 bit devices
+
+#endif // CYGONCE_DEVS_FLASH_AMD_AM29XXXXX_PARTS_INL
diff --git a/ecos/packages/devs/flash/amd/am29xxxxxv2/current/ChangeLog b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/ChangeLog
new file mode 100644
index 0000000..f3d9a9d
--- /dev/null
+++ b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/ChangeLog
@@ -0,0 +1,220 @@
+2009-04-20 Rene Schipp von Branitz Nielsen <rbn@vitesse.com>
+
+ * src/am29xxxxx.c: Added set of parentheses around macro
+ parameters used in multiplications. Fixes 16as8 bug.
+
+2008-12-19 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_am29xxxxx_v2.cdl: Doh, fix doc link properly.
+
+2008-11-20 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_am29xxxxx_v2.cdl: Fix doc link.
+
+2008-09-24 Bart Veer <bartv@ecoscentric.com>
+
+ * src/am29xxxxx_aux.c (am29_hw_program): fix handling of parallel
+ chips. Get the debug diagnostics to build cleanly.
+
+2008-05-13 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/am29xxxxx_aux.c (am29_hw_query): Allow devices to return
+ device IDs of larger than a byte.
+
+2007-07-08 Bart Veer <bartv@ecoscentric.com>
+
+ * src/am29xxxxx.c, src/am29xxxxx_aux.c: add 2ram entry and exit
+ hooks to give HALs some extra control over the low-level flash
+ operations.
+
+2007-06-21 Bart Veer <bartv@ecoscentric.com>
+
+ * src/am29xxxxx_aux.c: issue a memory barrier after every command
+ that gets sent to the flash, to avoid problems with pipelines that
+ mess about with write ordering.
+
+2007-05-31 Bart Veer <bartv@ecoscentric.com>
+
+ * src/am29xxxxx.c: skip data cache manipulation on architectures
+ which do not have a data cache.
+
+2007-05-29 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_am29xxxxx_v2.cdl
+ (CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_RESET_NEEDS_RESUME): New option.
+ Allow Flash devices to indicate that they should be sent a "resume"
+ command on startup.
+ * src/am29xxxxx_aux.c (am29_hw_force_all_suspended_resume): New
+ function to implement above CDL.
+ (cyg_am29xxxxx_init_check_dev): Call the new function.
+ (cyg_am29xxxxx_init_cfi): Ditto.
+ (am29_hw_cfi): manufacturer_id and vendor private areas need only
+ lowest byte taken, to handle multiple parallel devices.
+
+2007-03-29 Bart Veer <bartv@ecoscentric.com>
+
+ * src/am29xxxxx_aux.c (am29_hw_erase): use DQ7 to detect
+ termination instead of DQ6. This avoids hardware problems where
+ the toggling of DQ6 is not detected.
+
+2007-03-05 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/am29xxxxx_aux.c (am29_hw_cfi): Added missing AM29_SWAP() to
+ fetch of offset of vendor specific data.
+
+2006-09-27 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/am29xxxxx_aux.c (am29_hw_cfi): Added generic code to deal
+ with flash parts that may specify their erase regions in reverse
+ order to reality. Removed older code that was too specific to
+ particular devices.
+ A few changes to the diagnostics in various places.
+
+ * cdl/flash_am29xxxxx_v2.cdl: Replaced
+ CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_AT49_CFI with
+ CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CFI_BOGOSITY. This option
+ performs much the same purpose, but is generic to many more flash
+ parts.
+
+2006-08-31 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/am29xxxxx_aux.c: Added support for ST flash parts which have
+ similar, but not identical, peculiarities in their CFI data to the
+ Atmel parts supported earlier.
+
+2006-08-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/am29xxxxx.c: Provide a default HAL_MEMORY_BARRIER()
+ define if the HAL hasn't provided one.
+ * src/am29xxxxx_aux.c: Use HAL_MEMORY_BARRIER() any time the
+ flash is reset back to read array mode. Some processors
+ need to have their write buffers flushed.
+
+2006-06-29 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/flash_am29xxxxx_v2.cdl:
+ * src/am29xxxxx_aux.c:
+ Added configurable delay between each word during
+ programming. Some targets seem to need this.
+ Also added some simple diagnostics.
+
+2006-05-15 John Dallaway <jld@ecoscentric.com>
+
+ * doc/am29xxxxx.sgml: Fix missing </refentry> tag.
+ * cdl/flash_am29xxxx_v2.cdl: Reference package documentation.
+
+2005-09-26 Bart Veer <bartv@ecoscentric.com>
+
+ * src/am29xxxxx.c, src/am29xxxxx_aux.c: add AM29_SWAP() support for
+ platforms where the bus connection is wired up strangely.
+
+ * src/am29xxxxx_aux.c, cdl/flash_am29xxxxx_v2.cdl: add optional
+ support for certain Atmel chips which have a peculiar
+ implementation of CFI.
+
+2005-08-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_am29xxxx_v2.cdl: Provide new
+ CYGIMP_DEVS_FLASH_AMD_AM29XXXXX_V2_LEAVE_INTERRUPTS_ENABLED
+ and CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CACHED_ONLY options
+ to provide better control of when to enable/disable interrupts
+ or caches. Taken from the Strata flash example.
+ * include/am29xxxxx_dev.h: Declare cyg_at49xxxx_softlock, _hardlock
+ and _unlock variants.
+ * src/am29xxxxx.c: Define AT49 locking commands.
+ Provide AM29_UNCACHE_ADDRESS in line with the Strata driver,
+ to be controlled by the above new CDL options, in place of
+ AM29_P2V.
+ * src/am29xxxxx_aux.c: Provide AT49 lock status definition.
+ Provide AT49 softlock/hardlock/unlock API functions and
+ underlying implementation functions.
+ Adopt AM29_UNCACHED_ADDRESS rename.
+ * doc/am29xxxxx.sgml: Update documentation to cover AT49xxxx
+ locking operations and above new CDL options.
+
+2005-06-12 Bart Veer <bartv@ecoscentric.com>
+
+ * src/am29xxxxx_aux.c (cyg_am29xxxxx_program): remove unnecessary
+ loops variable
+ * cdl/flash_am29xxxxx_v2.cdl: minor reorganization to put the
+ important config option first
+ * doc/am29xxxxx.sgml: document the important config options
+
+2005-02-23 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/am29xxxxx.sgml: bring up to date.
+
+2005-01-19 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/am29xxxxx_aux.c (am29_hw_erase): Handle interleaved
+ (parallel) flash correctly when one device finishes before another.
+ (am29_hw_program): Similar.
+ (cyg_am29xxxxx_program): Use assert correctly.
+
+ * src/am29xxxxx.c (AM29_NEXT_DATUM_32): Use cyg_uint32, not
+ cyg_uint16.
+
+2004-12-02 Bart Veer <bartv@ecoscentric.com>
+
+ * src/am29xxxxx.c, include/am29xxxxx_dev.h: <cyg/io/flash_priv.h>
+ no longer exists, use <cyg/io/flash_dev.h> instead.
+
+2004-11-29 Bart Veer <bartv@ecoscentric.com>
+
+ * include/am29xxxxx_dev.h, src/am29xxxxx.c: eliminate
+ hwr_map_error() support, no longer needed
+
+ * include/am29xxxxx_dev.h, src/am29xxxxx.c, src/am29xxxxx_aux.c:
+ The dummy init/query/lock/unlock functions have been moved to the
+ generic flash package. That also now exports an anonymizer
+ function.
+
+2004-11-25 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_am29xxxxx_v2.cdl, src/am29xxxxx.c,
+ src/am29xxxxx_aux.c: this driver can manage the flash and
+ interrupts itself, without support from the generic flash code.
+
+2004-11-22 Bart Veer <bartv@ecoscentric.com>
+
+ * include/am29xxxxx_dev.h, src/am29xxxxx.c, src/am29xxxxx_aux.c,
+ doc/am29xxxxx.sgml: implement changes to the interface between the
+ generic flash code and the device drivers.
+ * include/am29xxxxx_dev.h: rename cyg_block_info to
+ cyg_flash_block_info
+
+2004-11-21 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/am29xxxxx.sgml: describe CDL implications for custom locking
+ functions and additional devices.
+
+ * cdl/flash_am29xxxxx_v2.cdl: CYGHWR_IO_FLASH_DEVICE_V2 is now
+ implicit
+
+2004-11-05 Bart Veer <bartv@ecoscentric.com>
+
+ * New AM29xxxxx flash driver created
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/amd/am29xxxxxv2/current/cdl/flash_am29xxxxx_v2.cdl b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/cdl/flash_am29xxxxx_v2.cdl
new file mode 100644
index 0000000..f59b383
--- /dev/null
+++ b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/cdl/flash_am29xxxxx_v2.cdl
@@ -0,0 +1,222 @@
+# ====================================================================
+#
+# flash_am29xxxxx_v2.cdl
+#
+# Device driver for AMD am29xxxxx flash chips and compatibles
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Contributors:
+# Date: 2004-11-05
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2 {
+ display "AMD am29xxxxx flash memory support"
+ doc ref/devs-flash-am29xxxxx.html
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ implements CYGHWR_IO_FLASH_DEVICE
+ include_dir cyg/io
+ compile am29xxxxx.c
+
+ description "
+ Flash memory support for AMD AM29xxxxx devices and compatibles.
+ This driver implements the V2 flash driver API"
+
+ cdl_option CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_PROGRAM_TIMEOUT {
+ display "Maximum number of iterations during a write"
+ flavor data
+ default_value 100000000
+ legal_values 1024 to 0x7fffffff
+ description "
+ Flash program operations may take a long time, and the driver
+ needs to poll the device to detect when the operation has
+ completed. This option controls the maximum number of iterations
+ of the polling loop, before the driver will give up. The timeout
+ should never actually trigger, as long as the hardware is
+ functioning correctly. If a timeout does occur the flash device
+ may be left in an inconsistent state. If very slow flash devices
+ are used then the platform HAL may require a larger timeout."
+ }
+
+ cdl_option CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_PROGRAM_DELAY {
+ display "Delay between words while programming"
+ flavor data
+ default_value 0
+ legal_values 0 to 0x7fffffff
+ description "The timings of certain processors and flash devices mean that
+ a short delay may be required between each word as it is programmed.
+ This option defines that delay in terms of iterations of a delay
+ loop."
+ }
+
+ cdl_option CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_ERASE_TIMEOUT {
+ display "Maximum number of iterations during a block erase"
+ flavor data
+ default_value 100000000
+ legal_values 1024 to 0x7fffffff
+ description "
+ The driver needs to poll the flash device during a block erase
+ to detect when the operation has completed. This option controls
+ the maximum number of iterations of the polling loop, before the
+ driver will give up. The timeout should never actually trigger,
+ as long as the hardware is functioning correctly. If a timeout
+ does occur the flash device may be left in an inconsistent state.
+ If very slow flash devices are used then the platform HAL may
+ require a larger timeout."
+ }
+
+ cdl_option CYGIMP_DEVS_FLASH_AMD_AM29XXXXX_V2_LEAVE_INTERRUPTS_ENABLED {
+ display "Leave interrupts enabled during flash operations"
+ active_if { ! CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CACHED_ONLY }
+ default_value 0
+ description "
+ On typical hardware erasing or programming a flash block requires
+ disabling interrupts and possibly the cache. During these operations
+ some or all of the flash hardware will be unusable, and disabling
+ interrupts is the only reliable way of ensuring that no interrupt
+ handler or other thread will try to access the flash in the middle
+ of the operation. This can have a major impact on the real-time
+ responsiveness of typical applications.
+
+ In some circumstances it is possible to leave interrupts enabled.
+ The application must run in RAM, not in flash. There must be some
+ way of accessing the flash which bypasses the cache. The application
+ must only access the flash using the proper API, for example
+ cyg_flash_read(), which ensures that only one thread at a time can
+ access a flash device. Finally there must be no possibility of
+ entering a ROM monitor running in flash. This can happen if RedBoot
+ is used as the ROM monitor and virtual vectors are enabled. It can
+ also happen when debugging the application via RedBoot or gdb stubs.
+
+ If the application can absolutely guarantee that the flash will not be
+ accessed during a flash operation then it is possible to enable this option,
+ improving interrupt latency. Any unexpected flash accesses are likely
+ to cause a system crash. If in doubt leave this option disabled."
+ }
+
+ cdl_interface CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CACHED_ONLY {
+ display "Flash memory accesses are always cached"
+ flavor bool
+ description "
+ Flash memory devices are usually accessed via the cache to achieve
+ acceptable performance. However erase and program operations need
+ to access the flash directly, bypassing the cache. On some targets
+ it is possible to access the flash in an uncached part of the
+ address space, for example by suitable MMU settings. On other
+ targets it is necessary to disable the cache while erasing or
+ programming blocks of flash. In the latter case the platform HAL
+ will implement this interface."
+ }
+
+ cdl_interface CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CFI_BOGOSITY {
+ display "Include support for unusual CFI implementation"
+ flavor bool
+ description "
+ CFI, Common Flash Interface, is a standard allowing device drivers
+ to query the hardware for characteristics such as the erase region
+ layout. Some flash chips have a somewhat strange implementation of CFI,
+ requiring extra code within the device driver. If CFI is used for device
+ initialization and if the platform may come with one of these flash chips
+ then the platform HAL will implement this interface."
+ }
+
+ cdl_interface CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_RESET_NEEDS_RESUME {
+ display "Erase/program resume is needed after reset"
+ flavor bool
+ description "
+ With true AMD-compatible flash parts, a reset command will also
+ abort any suspended erase or program operations. But on some
+ parts which are nearly but not quite compatible, such as AT49xxxxx,
+ this does not happen, and so an erase/program resume command is
+ needed after a soft reset in order to be able to use the chip."
+ }
+
+ cdl_option CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_ERASE_REGIONS {
+ display "Number of different erase regions"
+ flavor data
+ default_value 4
+ legal_values 1 to 64
+ description "
+ Flash devices vary widely in the way the various flash blocks are
+ laid out. In uniform devices all flash blocks are the same size,
+ for example 64 blocks of 64K each. Other devices have a boot block,
+ where one of the big blocks is subdivided into a number of smaller
+ ones. For example there could be a 16K block, followed by two 8K blocks,
+ then a 32K block, and finally 63 64K blocks. Each sequence of blocks
+ of a given size is known as an erase region, so a uniform device has
+ a single erase region and the above boot block device has four
+ erase regions. The driver needs to know the maximum number of erase
+ regions that may be present, especially if CFI is used to determine
+ the block details at run-time. Typically this option is controlled
+ by a requires property in the platform HAL, so users do not need
+ to edit it."
+ }
+
+ cdl_component CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2_OPTIONS {
+ display "AMD AM29xxxxx driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building the AMD am29xxxxx
+ flash driver, and details of which tests are built."
+
+ cdl_option CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the AMD am29xxxxx flash driver. These flags
+ are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the AMD am29xxxxx flash driver. These flags
+ are removed from the set of global flags if present."
+ }
+ }
+}
diff --git a/ecos/packages/devs/flash/amd/am29xxxxxv2/current/doc/am29xxxxx.sgml b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/doc/am29xxxxx.sgml
new file mode 100644
index 0000000..cbe7e29
--- /dev/null
+++ b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/doc/am29xxxxx.sgml
@@ -0,0 +1,789 @@
+<!-- DOCTYPE part PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- am29xxxxx.sgml -->
+<!-- -->
+<!-- Documentation for the am29xxxxx flash device driver. -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Date: 2004/11/05 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-flash-am29xxxxx"><title>AMD AM29xxxxx Flash Device Driver</title>
+
+<refentry id="am29xxxxx">
+ <refmeta>
+ <refentrytitle>Overview</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Overview</refname>
+ <refpurpose>eCos Support for AMD AM29xxxxx Flash Devices and Compatibles</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="am29xxxxx-description"><title>Description</title>
+ <para>
+The <varname>CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2</varname> AMD
+AM29xxxxx V2 flash driver package implements support for the AM29xxxxx
+family of flash devices and compatibles. Normally the driver is not
+accessed directly. Instead application code will use the API provided
+by the generic flash driver package
+<varname>CYGPKG_IO_FLASH</varname>, for example by calling functions
+like <function>cyg_flash_program</function>.
+ </para>
+ <para>
+The driver imposes one restriction on application code which
+developers should be aware of: when programming the flash the
+destination addresses must be aligned to a bus boundary. For example
+if the target hardware has a single flash device attached to a 16-bit
+bus then program operations must involve a multiple of 16-bit values
+aligned to a 16-bit boundary. Note that it is the bus width that
+matters, not the device width. If the target hardware has two 16-bit
+devices attached to a 32-bit bus then program operations must still be
+aligned to a 32-bit boundary, even though in theory a 16-bit boundary
+would suffice. In practice this is rarely an issue, and requiring the
+larger boundary greatly simplifies the code and improves performance.
+ </para>
+ <note><para>
+Many eCos targets with AM29xxxxx or compatible flash devices will
+still use the older driver package
+<varname>CYGPKG_DEVS_FLASH_AMD_AM29XXXXX</varname>. Only newer ports
+and some older ports that have been converted will use the V2 driver.
+This documentation only applies to the V2 driver.
+ </para></note>
+ </refsect1>
+
+ <refsect1 id="am29xxxxx-config"><title>Configuration Options</title>
+ <para>
+The AM29xxxxx flash driver package will be loaded automatically when
+configuring eCos for a target with suitable hardware. However the
+driver will be inactive unless the generic flash package
+<varname>CYGPKG_IO_FLASH</varname> is loaded. It may be necessary to
+add this generic package to the configuration explicitly before the
+driver functionality becomes available. There should never be any need
+to load or unload the AM29xxxx driver package.
+ </para>
+ <para>
+There are a number of configuration options, relating mostly to hardware
+characteristics. It is very rare that application developers need to
+change any of these. For example the option
+<varname>CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_ERASE_REGIONS</varname>
+may need a non-default value if the flash devices used on the target
+have an unusual boot block layout. If so the platform HAL will impose
+a requires constraint on this option and the configuration system will
+resolve the constraint. The only time it might be necessary to change
+the value manually is if the actual board being used is a variant of
+the one supported by the platform HAL and uses a different flash chip.
+ </para>
+ </refsect1>
+</refentry>
+
+<refentry id="am29xxxxx-instance">
+ <refmeta>
+ <refentrytitle>Instantiating an AM29xxxxx Device</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Instantiating</refname>
+ <refpurpose>including the driver in an eCos target</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>
+#include &lt;cyg/io/am29xxxxx_dev.h&gt;
+ </funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>int <function>cyg_am29xxxxx_init_check_devid_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_am29xxxxx_init_cfi_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_am29xxxxx_erase_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_am29xxxxx_program_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ <paramdef>const void* <parameter>data</parameter></paramdef>
+ <paramdef>size_t <parameter>len</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_at49xxxx_softlock</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>const cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_at49xxxx_hardlock</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>const cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_at49xxxx_unlock</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>const cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_am29xxxxx_read_devid_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="am29xxxxx-instance-description"><title>Description</title>
+ <para>
+The AM29xxxxx family contains some hundreds of different flash
+devices, all supporting the same basic set of operations but with
+various common or uncommon extensions. The devices vary in capacity,
+performance, boot block layout, and width. There are also
+platform-specific issues such as how many devices are actually present
+on the board and where they are mapped in the address space. The
+AM29xxxxx driver package cannot know the details of every chip and
+every platform. Instead it is the responsibility of another package,
+usually the platform HAL, to supply the necessary information by
+instantiating some data structures. Two pieces of information are
+especially important: the bus configuration and the boot block layout.
+ </para>
+ <para>
+Flash devices are typically 8-bits, 16-bits, or 32-bits wide (64-bit
+devices are not yet in common use). Most 16-bit devices will also
+support 8-bit accesses, but not all. Similarly 32-bit devices can be
+accessed 16-bits at a time or 8-bits at a time. A board will have one
+or more of these devices on the bus. For example there may be a single
+16-bit device on a 16-bit bus, or two 16-bit devices on a 32-bit bus.
+The processor's bus logic determines which combinations are possible,
+and there will be a trade off between cost and performance: two 16-bit
+devices in parallel can provide twice the memory bandwidth of a single
+device. The driver supports the following combinations:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>8</term>
+ <listitem><para>
+A single 8-bit flash device on an 8-bit bus.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>16</term>
+ <listitem><para>
+A single 16-bit flash device on a 16-bit bus.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>32</term>
+ <listitem><para>
+A single 32-bit flash device on an 32-bit bus.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>88</term>
+ <listitem><para>
+Two parallel 8-bit devices on an 16-bit bus.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>8888</term>
+ <listitem><para>
+Four parallel 8-bit devices on a 32-bit bus.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>1616</term>
+ <listitem><para>
+Two parallel 16-bit devices on a 32-bit bus, with one device providing
+the bottom two bytes of each 32-bit datum and the other device
+providing the top two bytes.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>16as8</term>
+ <listitem><para>
+A single 16-bit flash device connected to an 8-bit bus.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+These configuration all require slightly different code to manipulate
+the hardware. The AM29xxxxx driver package provides separate functions
+for each configuration, for example
+<function>cyg_am29xxxxx_erase_16</function> and
+<function>cyg_am29xxxxx_program_1616</function>.
+ </para>
+ <caution><para>
+At the time of writing not all the configurations have been tested.
+ </para></caution>
+ <para>
+The second piece of information is the boot block layout. Flash
+devices are subdivided into blocks (also known as sectors - both terms
+are in common use). Some operations such as erase work on a whole
+block at a time, and for most applications a block is the smallest
+unit that gets updated. A typical block size is 64K. It is inefficient
+to use an entire 64K block for small bits of configuration data and
+similar information, so many flash devices also support a number of
+smaller boot blocks. A typical 2MB flash device could have a single
+16K block, followed by two 8K blocks, then a 32K block, and finally 31
+full-size 64K blocks. The boot blocks may appear at the bottom or the
+top of the device. So-called uniform devices do not have boot blocks,
+just full-size ones. The driver needs to know the boot block layout.
+With modern devices it can work this out at run-time, but often it is
+better to provide the information statically.
+ </para>
+ </refsect1>
+
+ <refsect1 id="am29xxxxx-instance-example"><title>Example</title>
+ <para>
+In most cases flash support is specific to a platform. Even if two
+platforms happen to use the same flash device there are likely to be
+differences such as the location in the address map. Hence there is
+little possibility of re-using the platform-specific code, and this
+code should be placed in the platform HAL rather than in a separate
+package. Typically this involves a separate file and a corresponding
+compile property in the platform HAL's CDL:
+ </para>
+ <programlisting width=72>
+cdl_package CYGPKG_HAL_M68K_ALAIA {
+ &hellip;
+ compile -library=libextras.a alaia_flash.c
+ &hellip;
+}
+ </programlisting>
+ <para>
+The contents of this file will not be accessed directly, only
+indirectly via the generic flash API, so normally it would be removed
+by link-time garbage collection. To avoid this the object file has to
+go into <filename>libextras.a</filename>.
+ </para>
+ <para>
+The actual file <filename>alaia_flash.c</filename> will look something like:
+ </para>
+ <programlisting>
+#include &lt;pkgconf/system.h&gt;
+#ifdef CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2
+
+#include &lt;cyg/io/flash.h&gt;
+#include &lt;cyg/io/flash_dev.h&gt;
+#include &lt;cyg/io/am29xxxxx_dev.h&gt;
+
+static const CYG_FLASH_FUNS(hal_alaia_flash_amd_funs,
+ &amp;cyg_am29xxxxx_init_check_devid_16,
+ &amp;cyg_flash_devfn_query_nop,
+ &amp;cyg_am29xxxxx_erase_16,
+ &amp;cyg_am29xxxxx_program_16,
+ (int (*)(struct cyg_flash_dev*, const cyg_flashaddr_t, void*, size_t))0,
+ &amp;cyg_flash_devfn_lock_nop,
+ &amp;cyg_flash_devfn_unlock_nop);
+
+static const cyg_am29xxxxx_dev hal_alaia_flash_priv = {
+ .devid = 0x45,
+ .block_info = {
+ { 0x00004000, 1 },
+ { 0x00002000, 2 },
+ { 0x00008000, 1 },
+ { 0x00010000, 63 }
+ }
+};
+
+CYG_FLASH_DRIVER(hal_alaia_flash,
+ &amp;hal_alaia_flash_amd_funs,
+ 0,
+ 0xFFC00000,
+ 0xFFFFFFFF,
+ 4,
+ hal_alaia_flash_priv.block_info,
+ &amp;hal_alaia_flash_priv
+);
+#endif
+ </programlisting>
+ <para>
+The bulk of the file is protected by an <literal>#ifdef</literal> for
+the AM29xxxxx flash driver. That driver will only be active if the
+generic flash support is enabled. Without that support there will be
+no way of accessing the device so instantiating the data structures
+would serve no purpose. The rest of the file is split into three
+structure definitions. The first supplies the functions which will be
+used to perform the actual flash accesses, using a macro provided by
+the generic flash code in <filename
+class="headerfile">cyg/io/flash_dev.h</filename>. The relevant ones
+have an <literal>_16</literal> suffix, indicating that on this board
+there is a single 16-bit flash device on a 16-bit bus. The second
+provides information specific to AM29xxxxx flash devices.
+The third provides the <structname>cyg_flash_dev</structname>
+structure needed by the generic flash code, which contains pointers to
+the previous two.
+ </para>
+ </refsect1>
+
+ <refsect1 id="am29xxxxx-instance-functions"><title>Functions</title>
+ <para>
+All eCos flash device drivers must implement a standard interface,
+defined by the generic flash code <varname>CYGPKG_IO_FLASH</varname>.
+This interface includes a table of seven function pointers for various
+operations: initialization, query, erase, program, read, locking and
+unlocking. The query operation is optional and the generic flash
+support provides a dummy implementation
+<function>cyg_flash_devfn_query_nop</function>. AM29xxxxx flash
+devices are always directly accessible so there is no need for a
+separate read function. The remaining functions are more complicated.
+ </para>
+ <para>
+Usually the table can be declared <literal>const</literal>. In a ROM
+startup application this avoids both ROM and RAM copies of the table,
+saving a small amount of memory. <literal>const</literal> should not
+be used if the table may be modified by a platform-specific
+initialization routine.
+ </para>
+
+ <refsect2 id="am29xxxxx-instance-functions-init"><title>Initialization</title>
+ <para>
+There is a choice of three main initialization functions. The simplest
+is <function>cyg_flash_devfn_init_nop</function>, which does nothing.
+It can be used if the <structname>cyg_am29xxxxx_dev</structname> and
+<structname>cyg_flash_dev</structname> structures are fully
+initialized statically and the flash will just work without special
+effort. This is useful if it is guaranteed that the board will always
+be manufactured using the same flash chip, since the nop function
+involves the smallest code size and run-time overheads.
+ </para>
+ <para>
+The next step up is
+<function>cyg_am29xxxxx_init_check_devid_XX</function>, where
+<literal>XX</literal> will be replaced by the suffix appropriate for
+the bus configuration. It is still necessary to provide all the device
+information statically, including the <structfield>devid</structfield>
+field in the <structname>cyg_am29xxxxx_dev</structname> structure.
+This initialization function will attempt to query the flash device
+and check that the provided device id matches the actual hardware. If
+there is a mismatch the device will be marked uninitialized and
+subsequent attempts to manipulate the flash will fail.
+ </para>
+ <para>
+If the board may end up being manufactured with any of a number of
+different flash chips then the driver can perform run-time
+initialization, using a <function>cyg_am29xxxxx_init_cfi_XX</function>
+function. This queries the flash device as per the Common Flash Memory
+Interface Specification, supported by all current devices (although
+not necessarily by older devices). The
+<structfield>block_info</structfield> field in the
+<structname>cyg_am29xxxxx_dev</structname> structure and the
+<structfield>end</structfield> and
+<structfield>num_block_infos</structfield> fields in the
+<structname>cyg_flash_dev</structname> structure will be filled in.
+It is still necessary to supply the <structfield>start</structfield>
+field statically since otherwise the driver will not know how to
+access the flash device. The main disadvantage of using CFI is that it
+increases the code size.
+ </para>
+ <caution><para>
+If CFI is used then the <structname>cyg_am29xxxxx_dev</structname>
+structure must not be declared <literal>const</literal>. The CFI code
+will attempt to update the structure and will fail if the structure is
+held in read-only memory. This would leave the flash driver
+non-functional.
+ </para></caution>
+ <para>
+A final option is to use a platform-specific initialization function.
+This may be useful if the board may be manufactured with one of a
+small number of different flash devices and the platform HAL needs to
+adapt to this. The AM29xxxxx driver provides a utility function to
+read the device id, <function>cyg_am29xxxxx_read_devid_XX</function>:
+ </para>
+ <programlisting width=72>
+static int
+alaia_flash_init(struct cyg_flash_dev* dev)
+{
+ int devid = cyg_am29xxxxx_read_devid_1616(dev);
+ switch(devid) {
+ case 0x0042 :
+ &hellip;
+ case 0x0084 :
+ &hellip;
+ default:
+ return CYG_FLASH_ERR_DRV_WRONG_PART;
+ }
+}
+ </programlisting>
+ <para>
+There are many other possible uses for a platform-specific
+initialization function. For example initial prototype boards might
+have only supported 8-bit access to a 16-bit flash device rather than
+16-bit access, but this problem was fixed in the next revision. The
+platform-specific initialization function can figure out which model
+board it is running on and replace the default
+<literal>16as8</literal> functions with faster <literal>16</literal>
+ones.
+ </para>
+ </refsect2>
+
+ <refsect2 id="am29xxxxx-instance-functions-erase-program"><title>Erase and Program</title>
+ <para>
+The AM29xxxxx driver provides erase and program functions appropriate
+for the various bus configurations. On most targets these can be used
+directly. On some targets it may be necessary to do some extra work
+before and after the erase and program operations. For example if the
+hardware has an MMU then the part of the address map containing the
+flash may have been set to read-only, in an attempt to catch spurious
+memory accesses. Erasing or programming the flash requires
+write-access, so the MMU settings have to be changed temporarily. As
+another example some flash device may require a higher voltage to be
+applied during an erase or program operation. or a higher voltage may
+be desirable to make the operation proceed faster. A typical
+platform-specific erase function would look like this:
+ </para>
+ <programlisting width=72>
+static int
+alaia_flash_erase(struct cyg_flash_dev* dev, cyg_flashaddr_t addr)
+{
+ int result;
+ &hellip; // Set up the hardware for an erase
+ result = cyg_am29xxxxx_erase_32(dev, addr);
+ &hellip; // Revert the hardware change
+ return result;
+}
+ </programlisting>
+ <para>
+There are two configurations which affect the erase and program
+functions, and which a platform HAL may wish to change:
+<varname>CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_ERASE_TIMEOUT</varname>
+and
+<varname>CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_PROGRAM_TIMEOUT</varname>.
+The erase and program operations both involve polling for completion,
+and these timeout impose an upper bound on the polling loop. Normally
+these operations should never take anywhere close to the timeout
+period, so a timeout indicates a catastrophic failure that should
+really be handled by a watchdog reset. A reset is particularly
+appropriate because there will be no clean way of aborting the flash
+operation. The main reason for the timeouts is to help with debugging
+when porting to new hardware. If there is a valid reason why a
+particular platform needs different timeouts then the platform HAL's
+CDL can require appropriate values for these options.
+ </para>
+ </refsect2>
+
+ <refsect2 id="am29xxxxx-instance-functions-locking"><title>Locking</title>
+ <para>
+There is no single way of implementing the block lock and unlock
+operations on all AM29xxxxx devices. If these operations are supported at
+all then usually they involve manipulating the voltages on certain
+pins. This would not be able to be handled by generic driver code since it requires
+knowing how these pins can be manipulated via the processor's GPIO
+lines. Therefore the AM29xxxxx driver does not usually provide lock and unlock
+functions, and instead the generic dummy functions
+<function>cyg_flash_devfn_lock_nop</function> and
+<function>cyg_flash_devfn_unlock_nop</function> should be used. An <link
+linkend="am29xxxxx-at49xxxx-locking">exception</link> exists for
+the AT49xxxx family of devices which are sufficiently AMD
+compatible in other respects. Otherwise, if a
+platform does provide a way of implementing the locking then this can
+be handled by platform-specific functions.
+ </para>
+ <programlisting width=72>
+static int
+alaia_lock(struct cyg_flash_dev* dev, const cyg_flashaddr_t addr)
+{
+ &hellip;
+}
+
+static int
+alaia_unlock(struct cyg_flash_dev* dev, const cyg_flashaddr_t addr)
+{
+ &hellip;
+}
+ </programlisting>
+ <para>
+If real locking functions are implemented then the platform HAL's CDL
+script should implement the CDL interface
+<varname>CYGHWR_IO_FLASH_BLOCK_LOCKING</varname>. Otherwise the
+generic flash package may believe that none of the flash drivers in the
+system provide locking functionality and disable the interface functions.
+ </para>
+ <refsect3 id="am29xxxxx-at49xxxx-locking">
+ <title>AT49xxxx locking</title>
+ <para>
+As locking is standardised across the AT49xxxx family of AMD AM29xxxxx
+compatible Flash parts, a method supporting this is included within this
+driver. <function>cyg_at49xxxx_softlock_XX</function> provides a means of
+locking a Flash sector such that it may be subsequently unlocked.
+<function>cyg_at49xxxx_hardlock_XX</function> locks a sector such that
+it cannot be unlocked until after reset or a power cycle.
+<function>cyg_at49xxxx_unlock_XX</function> unlocks a sector that has
+previously been softlocked. At power on or Flash device reset, all sectors
+default to being softlocked.
+ </para>
+ </refsect3>
+ </refsect2>
+
+ <refsect2 id="am29xxxxx-instance-functions-other"><title>Other</title>
+ <para>
+The driver provides a set of functions
+<function>cyg_am29xxxxx_read_devid_XX</function>, one per supported
+bus configuration. These functions take a single argument, a pointer
+to the <structname>cyg_flash_dev</structname> structure, and return
+the chip's device id. For older devices this id is a single byte. For
+more recent devices the id is a 3-byte value, 0x7E followed by a
+further two bytes that actually identify the device.
+<function>cyg_am29xxxxx_read_devid_XX</function> is usually called
+only from inside a platform-specific driver initialization routine,
+allowing the platform HAL to adapt to the actual device present on the
+board.
+ </para>
+ </refsect2>
+ </refsect1>
+
+ <refsect1 id="am29xxxxx-instance-devpriv"><title>Device-Specific Structure</title>
+ <para>
+The <structname>cyg_am29xxxxx_dev</structname> structure provides
+information specific to AM29xxxxx flash devices, as opposed to the
+more generic flash information which goes into the
+<structname>cyg_flash_dev</structname> structure. There are only two
+fields: <structfield>devid</structfield> and
+<structfield>block_info</structfield>.
+ </para>
+ <para>
+<structfield>devid</structfield> is only needed if the driver's
+initialization function is set to
+<function>cyg_am29xxxxx_init_check_devid_XX</function>. That function
+will extract the actual device info from the flash chip and compare it
+with the <structfield>devid</structfield> field. If there is a
+mismatch then subsequent operations on the device will fail.
+ </para>
+ <para>
+The <structfield>block_info</structfield> field consists of one or
+more pairs of the block size in bytes and the number of blocks of that
+size. The order must match the actual hardware device since the flash
+code will use the table to determine the start and end locations of
+each block. The table can be initialized in one of three ways:
+ </para>
+ <orderedlist>
+ <listitem><para>
+If the driver initialization function is set to
+<function>cyg_flash_devfn_init_nop</function> or
+<function>cyg_am29xxxxx_init_check_devid_XX</function> then the block
+information should be provided statically. This is appropriate if the
+board will also be manufactured using the same flash chip.
+ </para></listitem>
+ <listitem><para>
+If <function>cyg_am29xxxxx_init_cfi_XX</function> is used then this
+will fill in the block info table. Hence there is no need for static
+initialization.
+ </para></listitem>
+ <listitem><para>
+If a platform-specific initialization function is used then either
+this should fill in the block info table, or the info should be
+provided statically.
+ </para></listitem>
+ </orderedlist>
+ <para>
+The size of the <structfield>block_info</structfield> table is
+determined by the configuration option
+<varname>CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_ERASE_REGIONS</varname>.
+This has a default value of 4, which should suffice for nearly all
+AM29xxxxx flash devices. If more entries are needed then the platform
+HAL's CDL script should require a larger value.
+ </para>
+ <para>
+If the <structname>cyg_am29xxxxx_dev</structname> structure is
+statically initialized then it can be <literal>const</literal>. This
+saves a small amount of memory in ROM startup applications. If the
+structure is updated at run-time, either by
+<function>cyg_am29xxxxx_init_cfi_XX</function> or by a
+platform-specific initialization routine, then it cannot be
+<literal>const</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="am29xxxxx-instance-flash"><title>Flash Structure</title>
+ <para>
+Internally the generic flash code works in terms of
+<structname>cyg_flash_dev</structname> structures, and the platform
+HAL should define one of these. The structure should be placed in the
+<literal>cyg_flashdev</literal> table. The following fields need to be
+provided:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><structfield>funs</structfield></term>
+ <listitem><para>
+This should point at the table of functions.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>start</structfield></term>
+ <listitem><para>
+The base address of the flash in the address map. On
+some board the flash may be mapped into memory several times, for
+example it may appear in both cached and uncached parts of the address
+space. The <structfield>start</structfield> field should correspond to
+the cached address.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>end</structfield></term>
+ <listitem><para>
+The address of the last byte in the flash. It can
+either be statically initialized, or
+<function>cyg_am29xxxxx_init_cfi_XX</function> will calculate
+its value at run-time.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>num_block_infos</structfield></term>
+ <listitem><para>
+This should be the number of entries in the
+<structfield>block_info</structfield> table. It can either be
+statically initialized or it will be filled in by
+<function>cyg_am29xxxxx_init_cfi_XX</function>.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>block_info</structfield></term>
+ <listitem><para>
+The table with the block information is held in the
+<structname>cyg_am29xxxxx_dev</structname> structure, so this field
+should just point into that structure.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>priv</structfield></term>
+ <listitem><para>
+This field is reserved for use by the device driver. For the AM29xxxxx
+driver it should point at the appropriate
+<structname>cyg_am29xxxxx_dev</structname> structure.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+The <structname>cyg_flash_dev</structname> structure contains a number
+of other fields which are manipulated only by the generic flash code.
+Some of these fields will be updated at run-time so the structure
+cannot be declared <literal>const</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="am29xxxxx-instance-serial"><title>Multiple Devices</title>
+ <para>
+A board may have several flash devices in parallel, for example two
+16-bit devices on a 32-bit bus. It may also have several such banks
+to increase the total amount of flash. If each device provides 2MB,
+there could be one bank of 2 parallel flash devices at 0xFF800000 and
+another bank at 0xFFC00000, giving a total of 8MB. This setup can be
+described in several ways. One approach is to define two
+<structname>cyg_flash_dev</structname> structures. The table of
+function pointers can usually be shared, as can the
+<structname>cyg_am29xxxxx_dev</structname> structure. Another approach
+is to define a single <structname>cyg_flash_dev</structname>
+structure but with a larger <structfield>block_info</structfield>
+table, covering the blocks in both banks of devices. The second
+approach makes more efficient use of memory.
+ </para>
+ <para>
+Many variations are possible, for example a small slow flash device
+may be used for initial bootstrap and holding the configuration data,
+while there is also a much larger and faster device to hold a file
+system. Such variations are usually best described by separate
+<structname>cyg_flash_dev</structname> structures.
+ </para>
+ <para>
+If more than one <structname>cyg_flash_dev</structname> structure is
+instantiated then the platform HAL's CDL script should implement the
+CDL interface <varname>CYGHWR_IO_FLASH_DEVICE</varname> once for every
+device past the first. Otherwise the generic code may default to the
+case of a single flash device and optimize for that.
+ </para>
+ </refsect1>
+
+ <refsect1 id="am29xxxxx-instance-platform"><title>Platform-Specific Macros</title>
+ <para>
+The AM29xxxxx driver source code includes the header files
+<filename class="headerfile">cyg/hal/hal_arch.h</filename> and
+<filename class="headerfile">cyg/hal/hal_io.h</filename>, and hence
+indirectly the corresponding platform header files (if defined).
+Optionally these headers can define macros which are used inside the
+driver, thus giving the HAL limited control over how the driver works.
+ </para>
+ </refsect1>
+
+ <refsect1 id="am29xxxxx-instance-cache"><title>Cache Management</title>
+ <para>
+By default the AM29xxxxx driver assumes that the flash can be accessed
+uncached, and it will use the HAL
+<function>CYGARC_UNCACHED_ADDRESS</function> macro to map the cached
+address in the <structfield>start</structfield> field of the
+<structname>cyg_flash_dev</structname> structure into an uncached
+address. If for any reason this HAL macro is inappropriate for the
+flash then an alternative macro
+<function>HAL_AM29XXXXX_UNCACHED_ADDRESS</function> can be defined
+instead. However fixing the
+<function>CYGARC_UNCACHED_ADDRESS</function> macro is normally the
+better solution.
+ </para>
+ <para>
+If there is no way of bypassing the cache then the platform HAL should
+implement the CDL interface
+<varname>CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CACHED_ONLY</varname>. The flash
+driver will now disable and re-enable the cache as required. For
+example a program operation will involve the following:
+ </para>
+ <programlisting width=72>
+ AM29_INTSCACHE_STATE;
+ AM29_INTSCACHE_BEGIN();
+ while ( ! finished ) {
+ program data
+ }
+ AM29_INTSCACHE_END();
+ </programlisting>
+ <para>
+The default implementations of these INTSCACHE macros are as follows:
+<varname>STATE</varname> defines any local variables that may be
+needed, e.g. to save the current interrupt state;
+<function>BEGIN</function> disables interrupts, synchronizes the data
+caches, disables it, and invalidates the current contents;
+<function>END</function> re-enables the cache and then
+interrupts. The cache is only disabled when interrupts are disabled,
+so there is no possibility of an interrupt handler running or a
+context switch occurring while the cache is disabled, potentially
+leaving the system running very slowly. The data cache synchronization
+ensures that there are no dirty cache lines, so when the cache is
+disabled the low-level flash write code will not see stale data in
+memory. The invalidate ensures that at the end of the operation
+higher-level code will not pick up stale cache contents instead of the
+newly written flash data.
+ </para>
+ <para>
+Some implementations of the HAL cache macros may not provide the exact
+semantics required by the flash driver. For example
+<function>HAL_DCACHE_DISABLE</function> may have an unwanted side
+effect, or it may do more work than is needed here. The driver will
+check for alternative macros
+<function>HAL_AM29XXXXX_INTSCACHE_STATE</function>,
+<function>HAL_AM29XXXXX_INTSCACHE_BEGIN</function> and
+<function>HAL_AM29XXXXX_INTSCACHE_END</function>, using these instead of
+the defaults.
+ </para>
+ </refsect1>
+ </refentry>
+</part>
diff --git a/ecos/packages/devs/flash/amd/am29xxxxxv2/current/include/am29xxxxx_dev.h b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/include/am29xxxxx_dev.h
new file mode 100644
index 0000000..695b0da
--- /dev/null
+++ b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/include/am29xxxxx_dev.h
@@ -0,0 +1,138 @@
+#ifndef CYGONCE_DEVS_FLASH_AM29xxxxx_dev_V2_H
+# define CYGONCE_DEVS_FLASH_AM29xxxxx_dev_V2_H
+//==========================================================================
+//
+// am29xxxxx_dev.h
+//
+// Flash driver for the AMD family - driver details
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors:
+// Date: 2004-11-05
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_flash_amd_am29xxxxx_v2.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+externC int cyg_am29xxxxx_read_devid_8( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_read_devid_16( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_read_devid_32( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_read_devid_88( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_read_devid_8888( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_read_devid_1616( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_read_devid_16as8( struct cyg_flash_dev*);
+
+externC int cyg_am29xxxxx_init_check_devid_8( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_check_devid_16( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_check_devid_32( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_check_devid_88( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_check_devid_8888( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_check_devid_1616( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_check_devid_16as8( struct cyg_flash_dev*);
+
+externC int cyg_am29xxxxx_init_cfi_8( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_cfi_16( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_cfi_32( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_cfi_88( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_cfi_8888( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_cfi_1616( struct cyg_flash_dev*);
+externC int cyg_am29xxxxx_init_cfi_16as8( struct cyg_flash_dev*);
+
+externC int cyg_am29xxxxx_erase_8( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_am29xxxxx_erase_16( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_am29xxxxx_erase_32( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_am29xxxxx_erase_88( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_am29xxxxx_erase_8888( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_am29xxxxx_erase_1616( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_am29xxxxx_erase_16as8( struct cyg_flash_dev*, cyg_flashaddr_t);
+
+externC int cyg_am29xxxxx_program_8( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_am29xxxxx_program_16( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_am29xxxxx_program_32( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_am29xxxxx_program_88( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_am29xxxxx_program_8888( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_am29xxxxx_program_1616( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_am29xxxxx_program_16as8( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+
+externC int cyg_at49xxxx_softlock_8( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_softlock_16( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_softlock_32( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_softlock_88( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_softlock_8888( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_softlock_1616( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_softlock_16as8( struct cyg_flash_dev*, const cyg_flashaddr_t );
+
+externC int cyg_at49xxxx_hardlock_8( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_hardlock_16( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_hardlock_32( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_hardlock_88( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_hardlock_8888( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_hardlock_1616( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_hardlock_16as8( struct cyg_flash_dev*, const cyg_flashaddr_t );
+
+externC int cyg_at49xxxx_unlock_8( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_unlock_16( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_unlock_32( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_unlock_88( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_unlock_8888( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_unlock_1616( struct cyg_flash_dev*, const cyg_flashaddr_t );
+externC int cyg_at49xxxx_unlock_16as8( struct cyg_flash_dev*, const cyg_flashaddr_t );
+
+// FIXME: add program_buffered() support as per e.g. the AM29LV128
+// FIXME: add software lock/unlock support as per e.g. the AM29BDS640
+
+// The driver-specific data, pointed at by the priv field in a
+// a cyg_flash_dev structure.
+typedef struct cyg_am29xxxxx_dev {
+ // The device id, mainly for use by the init_check_devid() routines
+ cyg_uint32 devid;
+ // Space for the block_info fields needed for the cyg_flash_dev.
+ // These can be statically initialized, or dynamically via
+ // init_cfi().
+ cyg_flash_block_info_t block_info[CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_ERASE_REGIONS];
+} cyg_am29xxxxx_dev;
+
+// TODO: An AM29 specific macro could optimise the common case of CYG_FLASH_FUNS.
+// Bart and Jifl discussed this in mid July/start Aug 2005.
+
+#endif // CYGONCE_DEVS_FLASH_AM29xxxxx_dev_V2_H
diff --git a/ecos/packages/devs/flash/amd/am29xxxxxv2/current/src/am29xxxxx.c b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/src/am29xxxxx.c
new file mode 100644
index 0000000..f6ebcd9
--- /dev/null
+++ b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/src/am29xxxxx.c
@@ -0,0 +1,514 @@
+//==========================================================================
+//
+// am29xxxxx.c
+//
+// Flash driver for the AMD family
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors:
+// Date: 2004-11-05
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_flash_amd_am29xxxxx_v2.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+#include <cyg/io/am29xxxxx_dev.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_io.h>
+
+// This driver supports multiple banks of AMD am29xxxxx flash devices
+// or compatibles. These are NOR-flash devices, requiring explicit
+// erase operations with an erase value of 0xff.
+//
+// The devices may be 8-bit, 16-bit, or 32-bit (64-bit devices are not
+// yet supported). Most but not all 16-bit devices can also be
+// accessed as 8-bit, in which case the chip may be hooked up to an
+// 8-bit bus. A bank of flash may involve just a single chip, or there
+// may be several chips in parallel. Typical combinations are 88 to
+// get 16-bit, 8888 for 32-bit, and 1616 for 32-bit. It is assumed
+// that all chips within a bank are the same device. There may also be
+// several banks of flash, and different banks may use different
+// devices.
+//
+// This driver instantiates support for the various bus
+// configurations: 8, 16, 16AS8, 32, 88, 8888, and 1616. On any given
+// platform only one or two of these combinations will be of interest,
+// but the remainder will be eliminated via linker garbage collection.
+// To avoid excessive duplication an auxiliary file contains the
+// actual implementations. Compiler optimization should eliminate any
+// unnecessary code.
+
+// A flash driver is supposed to provide the following functions:
+// int (*init)(...)
+// size_t (*query)(...)
+// int (*erase)(...)
+// int (*program)(...)
+// int (*block_lock)(...)
+// int (*block_unlock)(...)
+//
+// The devices do not need any special initialization. However a given
+// board may be manufactured with any one of several devices, which
+// complicates things. The main complication is that there may be
+// different bootsector layouts. The primary job of the init function
+// is to check the device id, possibly fill in the bootsector info,
+// or even to use the CFI support to get the bootsector info from the
+// device itself. There may be other complications, e.g. minor variations
+// of a given board design. These can be handled by h/w specific init
+// functions in the platform HAL.
+//
+// The query function need not do anything useful, it is
+// driver-defined.
+//
+// No read function need be supplied because the flash memory is
+// always directly accessible to the cpu.
+//
+// Erase, program, and the locking functions need real
+// implementations, although locking is not always available.
+
+// ----------------------------------------------------------------------------
+// The protocol understood by AMD flash chips and compatibles.
+// The AM29_PARALLEL() macro is used in bus configurations with multiple
+// devices in parallel, to issue commands to all the devices in a single
+// write. In theory some of the operations, e.g. READ_DEVID, only need
+// to access a single chip but then you get into complications for the
+// SETUP commands. The AM29_SWAP() macro deals with endianness issues
+// on some targets and can also help with h/w where things are just not
+// wired right.
+#define AM29_COMMAND_SETUP1 AM29_SWAP(AM29_PARALLEL(0x00AA))
+#define AM29_COMMAND_SETUP2 AM29_SWAP(AM29_PARALLEL(0x0055))
+#define AM29_COMMAND_RESET AM29_SWAP(AM29_PARALLEL(0x00F0))
+#define AM29_COMMAND_AUTOSELECT AM29_SWAP(AM29_PARALLEL(0x0090))
+#define AM29_COMMAND_ERASE AM29_SWAP(AM29_PARALLEL(0x0080))
+#define AM29_COMMAND_ERASE_SECTOR AM29_SWAP(AM29_PARALLEL(0x0030))
+#define AM29_COMMAND_ERASE_RESUME AM29_SWAP(AM29_PARALLEL(0x0030))
+#define AM29_COMMAND_CFI AM29_SWAP(AM29_PARALLEL(0x0098))
+#define AM29_COMMAND_PROGRAM AM29_SWAP(AM29_PARALLEL(0x00A0))
+// Following are specific to AT49 derivatives
+#define AM29_COMMAND_AT49_SOFTLOCK_BLOCK_0 AM29_SWAP(AM29_PARALLEL(0x0080))
+#define AM29_COMMAND_AT49_SOFTLOCK_BLOCK_1 AM29_SWAP(AM29_PARALLEL(0x0040))
+#define AM29_COMMAND_AT49_HARDLOCK_BLOCK_0 AM29_SWAP(AM29_PARALLEL(0x0080))
+#define AM29_COMMAND_AT49_HARDLOCK_BLOCK_1 AM29_SWAP(AM29_PARALLEL(0x0060))
+#define AM29_COMMAND_AT49_UNLOCK_BLOCK AM29_SWAP(AM29_PARALLEL(0x0070))
+
+// CFI offsets of interest. This assumes that the standard query table
+// has not been replaced by the extended query table, although the
+// CFI standard allows that behaviour.
+#define AM29_OFFSET_CFI_Q AM29_OFFSET_CFI_DATA(0x0010)
+#define AM29_OFFSET_CFI_SIZE AM29_OFFSET_CFI_DATA(0x0027)
+#define AM29_OFFSET_CFI_BLOCK_REGIONS AM29_OFFSET_CFI_DATA(0x002C)
+#define AM29_OFFSET_CFI_BLOCK_COUNT_LSB(_i_) AM29_OFFSET_CFI_DATA(0x002D + (4 * (_i_)))
+#define AM29_OFFSET_CFI_BLOCK_COUNT_MSB(_i_) AM29_OFFSET_CFI_DATA(0x002E + (4 * (_i_)))
+#define AM29_OFFSET_CFI_BLOCK_SIZE_LSB(_i_) AM29_OFFSET_CFI_DATA(0x002F + (4 * (_i_)))
+#define AM29_OFFSET_CFI_BLOCK_SIZE_MSB(_i_) AM29_OFFSET_CFI_DATA(0x0030 + (4 * (_i_)))
+
+#define AM29_STATUS_DQ7 AM29_SWAP(AM29_PARALLEL(0x0080))
+#define AM29_STATUS_DQ6 AM29_SWAP(AM29_PARALLEL(0x0040))
+#define AM29_STATUS_DQ5 AM29_SWAP(AM29_PARALLEL(0x0020))
+#define AM29_STATUS_DQ4 AM29_SWAP(AM29_PARALLEL(0x0010))
+#define AM29_STATUS_DQ3 AM29_SWAP(AM29_PARALLEL(0x0008))
+#define AM29_STATUS_DQ2 AM29_SWAP(AM29_PARALLEL(0x0004))
+#define AM29_STATUS_DQ1 AM29_SWAP(AM29_PARALLEL(0x0002))
+#define AM29_STATUS_DQ0 AM29_SWAP(AM29_PARALLEL(0x0001))
+#define AM29_ID_LOCKED AM29_SWAP(AM29_PARALLEL(0x03))
+
+// When programming the flash the source data may not be aligned
+// correctly (although usually it will be). Hence it is necessary to
+// construct the 16-bit or 32-bit numbers to be written to the flash
+// from individual bytes, allowing for endianness.
+#define AM29_NEXT_DATUM_8(_ptr_) (*_ptr_++)
+#if CYG_BYTEORDER == CYG_LSBFIRST
+# define AM29_NEXT_DATUM_16(_ptr_) \
+ ({ \
+ cyg_uint16 _result_; \
+ _result_ = (_ptr_[1] << 8) | _ptr_[0]; \
+ _ptr_ += 2; \
+ _result_; })
+
+# define AM29_NEXT_DATUM_32(_ptr_) \
+ ({ \
+ cyg_uint32 _result_; \
+ _result_ = (_ptr_[3] << 24) | (_ptr_[2] << 16) | (_ptr_[1] << 8) | _ptr_[0]; \
+ _ptr_ += 4; \
+ _result_; })
+#else
+# define AM29_NEXT_DATUM_16(_ptr_) \
+ ({ \
+ cyg_uint16 _result_; \
+ _result_ = (_ptr_[0] << 8) | _ptr_[1]; \
+ _ptr_ += 2; \
+ _result_; })
+
+# define AM29_NEXT_DATUM_32(_ptr_) \
+ ({ \
+ cyg_uint32 _result_; \
+ _result_ = (_ptr_[0] << 24) | (_ptr_[1] << 16) | (_ptr_[2] << 8) | _ptr_[3]; \
+ _ptr_ += 4; \
+ _result_; })
+
+#endif
+
+// The addresses used for programming the flash may be different from
+// the ones used to read the flash. The macro
+// HAL_AM29XXXXX_UNCACHED_ADDRESS() can be supplied by one of the HAL
+// packages. Otherwise if CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CACHED_ONLY
+// is not implemented then the macro CYGARC_UNCACHED_ADDRESS()
+// will be used. If there is no way of bypassing the cache then
+// the addresses will remain unchanged and instead the INTSCACHE
+// macros will disable the cache.
+
+#if defined(HAL_AM29XXXXX_UNCACHED_ADDRESS)
+# define AM29_UNCACHED_ADDRESS(_addr_) ((volatile AM29_TYPE*)HAL_AM29XXXXX_UNCACHED_ADDRESS(_addr_))
+#elif !defined(CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CACHED_ONLY)
+# ifndef CYGARC_UNCACHED_ADDRESS
+# error Cache should be bypassed but CYGARC_UNCACHED_ADDRESS is not defined.
+# endif
+# define AM29_UNCACHED_ADDRESS(_addr_) ((volatile AM29_TYPE*)CYGARC_UNCACHED_ADDRESS(_addr_))
+#elif defined(HAL_AM29XXXXX_P2V)
+// HAL_AM29XXXXX_P2V is a deprecated macro that is only retained for
+// backward compatibility.
+# define AM29_UNCACHED_ADDRESS(_addr_) ((volatile AM29_TYPE*)HAL_AM29XXXXX_P2V(_addr_))
+#else
+# define AM29_UNCACHED_ADDRESS(_addr_) ((volatile AM29_TYPE*)(_addr_))
+#endif
+
+// The bits on the data bus may need swapping, either because of
+// endianness issues or because some lines are just wired wrong.
+// SWAP is for commands going to the flash chip. UNSWAP is for
+// data coming back from the flash chip. The swapping takes
+// effect after allowing for AM29_PARALLEL(). Data is never
+// swapped, it does not matter if bit 5 of a datum is actually
+// stored in bit 3 of the flash as long as the data reads back
+// right.
+#if defined(HAL_AM29XXXXX_SWAP)
+# define AM29_SWAP(_data_) HAL_AM29XXXXX_SWAP(_data_)
+#else
+# define AM29_SWAP(_data_) (_data_)
+#endif
+#if defined(HAL_AM29XXXXX_UNSWAP)
+# define AM29_UNSWAP(_data_) HAL_AM29XXXXX_UNSWAP(_data_)
+#else
+# define AM29_UNSWAP(_data_) (_data_)
+#endif
+
+// On some platforms there may be almost inexplicable failures, caused
+// by very subtle effects such as instruction cache lines still being
+// filled from flash memory which the _hw routines in .2ram sections are
+// already running and have taken the flash out of read-array mode.
+// These are very rare effects and not amenable to a generic solution,
+// so instead the platform HAL (usually) can define additional hook
+// macros that get invoked by the .2ram functions. These can e.g.
+// add a short delay or invalidate a couple of instruction cache lines,
+// but only if the code is executing from flash. Any such hooks will
+// affect interrupt latency so should only be used when absolutely
+// necessary. They must also be simple code, e.g. no calls to other
+// functions that may be in flash.
+
+#ifdef HAL_AM29XXXXX_2RAM_ENTRY_HOOK
+# define AM29_2RAM_ENTRY_HOOK() HAL_AM29XXXXX_2RAM_ENTRY_HOOK()
+#else
+# define AM29_2RAM_ENTRY_HOOK() CYG_EMPTY_STATEMENT
+#endif
+#ifdef HAL_AM29XXXXX_2RAM_EXIT_HOOK
+# define AM29_2RAM_EXIT_HOOK() HAL_AM29XXXXX_2RAM_EXIT_HOOK()
+#else
+# define AM29_2RAM_EXIT_HOOK() CYG_EMPTY_STATEMENT
+#endif
+
+// Cache and interrupt manipulation. This driver supports fine-grained
+// control over interrupts and the cache, using three macros. These may
+// be provided by the platform HAL, or by defaults here. There are
+// three variants:
+//
+// 1) control both interrupts and cache. This is necessary if
+// CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CACHED_ONLY is implemented,
+// i.e. if the cache cannot be bypassed. The cache must be temporarily
+// disabled for flash operations, and interrupts have to be disabled
+// while the cache is disabled to prevent interrupts and context switches.
+// 2) control interrupts only, the default if the cache can be bypassed
+// when accessing the flash. The flash is still in an unusable
+// state during flash operations so interrupts and context switches
+// should be avoided.
+// 3) only invalidate at the end, if the cache can be bypassed and the
+// application guarantees that the flash will not be accessed by any interrupt
+// handlers or other threads.
+
+#if defined(CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CACHED_ONLY)
+
+// First, the amount of state that should be preserved. By default
+// this means the interrupt state and the data cache state.
+# define AM29_INTSCACHE_DEFAULT_STATE int _saved_ints_, _saved_dcache_
+
+// Start an operation on the flash. Make sure that interrupts are
+// disabled and then save the current state of the data cache. The
+// actual flash manipulation should happen with the cache disabled.
+// There may still be data in the cache that has not yet been flushed
+// to memory, so take care of that first. The invalidate the cache
+// lines so that when the cache is re-enabled later on the processor
+// gets everything from memory, rather than reusing old data in the
+// cache.
+# define AM29_INTSCACHE_DEFAULT_BEGIN() \
+ CYG_MACRO_START \
+ HAL_DISABLE_INTERRUPTS(_saved_ints_); \
+ HAL_DCACHE_IS_ENABLED(_saved_dcache_); \
+ HAL_DCACHE_SYNC(); \
+ if (_saved_dcache_) { \
+ HAL_DCACHE_DISABLE(); \
+ } \
+ HAL_DCACHE_INVALIDATE_ALL(); \
+ CYG_MACRO_END
+
+// A flash operation has completed. Restore the situation to what it
+// was before. Because of suspend/resume support interrupt handlers
+// and other threads may have run, filling various cache lines with
+// useful data. However it is assumed that none of those cache
+// lines contain any of the data that has been manipulated by this
+// flash operation (the stack and the flash block), so there is
+// no need for another sync or invalidate. It is also assumed that
+// we have not been executing any code out of the block of flash
+// that has just been erased or programmed, so no need to worry
+// about the icache.
+#define AM29_INTSCACHE_DEFAULT_END() \
+ CYG_MACRO_START \
+ if (_saved_dcache_) { \
+ HAL_DCACHE_ENABLE(); \
+ } \
+ HAL_RESTORE_INTERRUPTS(_saved_ints_); \
+ CYG_MACRO_END
+
+#elif !defined(CYGIMP_DEVS_FLASH_AMD_AM29XXXXX_V2_LEAVE_INTERRUPTS_ENABLED)
+
+# define AM29_INTSCACHE_DEFAULT_STATE int _saved_ints_
+# define AM29_INTSCACHE_DEFAULT_BEGIN() HAL_DISABLE_INTERRUPTS(_saved_ints_)
+
+# if defined(HAL_DCACHE_SYNC) && defined(HAL_DCACHE_INVALIDATE_ALL)
+// The following blips the interrupt enable to allow pending interrupts
+// to run, which will reduce interrupt latency given the dcache sync/invalidate
+// may be relatively lengthy.
+# define AM29_INTSCACHE_DEFAULT_END() \
+ CYG_MACRO_START \
+ HAL_RESTORE_INTERRUPTS(_saved_ints_); \
+ HAL_DISABLE_INTERRUPTS(_saved_ints_); \
+ HAL_DCACHE_SYNC(); \
+ HAL_DCACHE_INVALIDATE_ALL(); \
+ HAL_RESTORE_INTERRUPTS(_saved_ints_); \
+ CYG_MACRO_END
+# else
+# define AM29_INTSCACHE_DEFAULT_END() HAL_RESTORE_INTERRUPTS(_saved_ints_)
+# endif
+#else
+
+# define AM29_INTSCACHE_DEFAULT_STATE CYG_EMPTY_STATEMENT
+# define AM29_INTSCACHE_DEFAULT_BEGIN() CYG_EMPTY_STATEMENT
+# if defined(HAL_DCACHE_SYNC) && defined(HAL_DCACHE_INVALIDATE_ALL)
+# define AM29_INTSCACHE_DEFAULT_END() \
+ CYG_MACRO_START \
+ int _saved_ints_; \
+ HAL_DISABLE_INTERRUPTS(_saved_ints_); \
+ HAL_DCACHE_SYNC(); \
+ HAL_DCACHE_INVALIDATE_ALL(); \
+ HAL_RESTORE_INTERRUPTS(_saved_ints_); \
+ CYG_MACRO_END
+# else
+# define AM29_INTSCACHE_DEFAULT_END() CYG_EMPTY_STATEMENT
+# endif
+#endif
+
+#ifdef HAL_AM29XXXXX_INTSCACHE_STATE
+# define AM29_INTSCACHE_STATE HAL_AM29XXXXX_INTSCACHE_STATE
+#else
+# define AM29_INTSCACHE_STATE AM29_INTSCACHE_DEFAULT_STATE
+#endif
+#ifdef HAL_AM29XXXXX_INTSCACHE_BEGIN
+# define AM29_INTSCACHE_BEGIN HAL_AM29XXXXX_INTSCACHE_BEGIN
+#else
+# define AM29_INTSCACHE_BEGIN AM29_INTSCACHE_DEFAULT_BEGIN
+#endif
+#ifdef HAL_AM29XXXXX_INTSCACHE_END
+# define AM29_INTSCACHE_END HAL_AM29XXXXX_INTSCACHE_END
+#else
+# define AM29_INTSCACHE_END AM29_INTSCACHE_DEFAULT_END
+#endif
+
+// Some HALs require a special instruction to flush write buffers.
+// Not all HALs do though, so we define it empty if it isn't already present.
+#ifndef HAL_MEMORY_BARRIER
+# define HAL_MEMORY_BARRIER() CYG_EMPTY_STATEMENT
+#endif
+
+// ----------------------------------------------------------------------------
+// Generic code.
+
+// Get info about the current block, i.e. base and size.
+static void
+am29_get_block_info(struct cyg_flash_dev* dev, const cyg_flashaddr_t addr, cyg_flashaddr_t* block_start, size_t* block_size)
+{
+ cyg_uint32 i;
+ size_t offset = addr - dev->start;
+ cyg_flashaddr_t result;
+
+ result = dev->start;
+
+ for (i = 0; i < dev->num_block_infos; i++) {
+ if (offset < (dev->block_info[i].blocks * dev->block_info[i].block_size)) {
+ offset -= (offset % dev->block_info[i].block_size);
+ *block_start = result + offset;
+ *block_size = dev->block_info[i].block_size;
+ return;
+ }
+ result += (dev->block_info[i].blocks * dev->block_info[i].block_size);
+ offset -= (dev->block_info[i].blocks * dev->block_info[i].block_size);
+ }
+ CYG_FAIL("Address out of range of selected flash device");
+}
+
+// ----------------------------------------------------------------------------
+// Instantiate all of the h/w functions appropriate for the various
+// configurations.
+// The suffix is used to construct the function names.
+// Types for the width of the bus, controlling the granularity of access.
+// devcount specifies the number of devices in parallel, and is used for looping
+// The NEXT_DATUM() macro allows for misaligned source data.
+// The PARALLEL macro, if defined, is used for sending commands and reading
+// status bits from all devices in the bank in one operation.
+
+// A single 8-bit device on an 8-bit bus.
+#define AM29_SUFFIX 8
+#define AM29_TYPE cyg_uint8
+#define AM29_DEVCOUNT 1
+#define AM29_NEXT_DATUM(_ptr_) AM29_NEXT_DATUM_8(_ptr_)
+
+#include "am29xxxxx_aux.c"
+
+#undef AM29_SUFFIX
+#undef AM29_TYPE
+#undef AM29_DEVCOUNT
+#undef AM29_NEXT_DATUM
+
+// A single 16-bit device.
+#define AM29_SUFFIX 16
+#define AM29_TYPE cyg_uint16
+#define AM29_DEVCOUNT 1
+#define AM29_NEXT_DATUM(_ptr_) AM29_NEXT_DATUM_16(_ptr_)
+
+#include "am29xxxxx_aux.c"
+
+#undef AM29_SUFFIX
+#undef AM29_TYPE
+#undef AM29_DEVCOUNT
+#undef AM29_NEXT_DATUM
+
+// A single 32-bit device.
+#define AM29_SUFFIX 32
+#define AM29_TYPE cyg_uint32
+#define AM29_DEVCOUNT 1
+#define AM29_NEXT_DATUM(_ptr_) AM29_NEXT_DATUM_32(_ptr_)
+
+#include "am29xxxxx_aux.c"
+
+#undef AM29_SUFFIX
+#undef AM29_TYPE
+#undef AM29_DEVCOUNT
+#undef AM29_NEXT_DATUM
+
+// Two 8-bit devices, giving a 16-bit bus.
+#define AM29_SUFFIX 88
+#define AM29_TYPE cyg_uint16
+#define AM29_DEVCOUNT 2
+#define AM29_NEXT_DATUM(_ptr_) AM29_NEXT_DATUM_16(_ptr_)
+#define AM29_PARALLEL(_cmd_) ((_cmd_ << 8) | _cmd_)
+
+#include "am29xxxxx_aux.c"
+
+#undef AM29_SUFFIX
+#undef AM29_TYPE
+#undef AM29_DEVCOUNT
+#undef AM29_NEXT_DATUM
+
+// Four 8-bit devices, giving a 32-bit bus.
+#define AM29_SUFFIX 8888
+#define AM29_TYPE cyg_uint32
+#define AM29_DEVCOUNT 4
+#define AM29_NEXT_DATUM(_ptr_) AM29_NEXT_DATUM_32(_ptr_)
+#define AM29_PARALLEL(_cmd_) ((_cmd_ << 24) | (_cmd_ << 16) | (_cmd_ << 8) | _cmd_)
+
+#include "am29xxxxx_aux.c"
+
+#undef AM29_SUFFIX
+#undef AM29_TYPE
+#undef AM29_DEVCOUNT
+#undef AM29_NEXT_DATUM
+
+// Two 16-bit devices, giving a 32-bit bus.
+#define AM29_SUFFIX 1616
+#define AM29_TYPE cyg_uint32
+#define AM29_DEVCOUNT 2
+#define AM29_NEXT_DATUM(_ptr_) AM29_NEXT_DATUM_32(_ptr_)
+#define AM29_PARALLEL(_cmd_) ((_cmd_ << 16) | _cmd_)
+
+#include "am29xxxxx_aux.c"
+
+#undef AM29_SUFFIX
+#undef AM29_TYPE
+#undef AM29_DEVCOUNT
+#undef AM29_NEXT_DATUM
+
+// 16AS8. A 16-bit device hooked up so that only byte accesses are
+// allowed. This requires unusual offsets
+#define AM29_SUFFIX 16as8
+#define AM29_TYPE cyg_uint8
+#define AM29_DEVCOUNT 1
+#define AM29_NEXT_DATUM(_ptr_) AM29_NEXT_DATUM_8(_ptr_)
+#define AM29_OFFSET_COMMAND 0x0AAA
+#define AM29_OFFSET_COMMAND2 0x0555
+#define AM29_OFFSET_MANUFACTURER_ID 0x0000
+#define AM29_OFFSET_DEVID 0x0002
+#define AM29_OFFSET_DEVID2 0x001C
+#define AM29_OFFSET_DEVID3 0x001E
+#define AM29_OFFSET_AT49_LOCK_STATUS 04
+#define AM29_OFFSET_CFI 0x00AA
+#define AM29_OFFSET_CFI_DATA(_idx_) (2 * (_idx_))
+
+#include "am29xxxxx_aux.c"
diff --git a/ecos/packages/devs/flash/amd/am29xxxxxv2/current/src/am29xxxxx_aux.c b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/src/am29xxxxx_aux.c
new file mode 100644
index 0000000..c5f392c
--- /dev/null
+++ b/ecos/packages/devs/flash/amd/am29xxxxxv2/current/src/am29xxxxx_aux.c
@@ -0,0 +1,985 @@
+//==========================================================================
+//
+// am29xxxxx_aux.c
+//
+// Flash driver for the AMD family - implementation.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors:
+// Date: 2004-11-05
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// This file is #include'd multiple times from the main am29xxxxx.c file,
+// It serves to instantiate the various hardware operations in ways
+// appropriate for all the bus configurations.
+
+// The following macros are used to construct suitable function names
+// for the current bus configuration. AM29_SUFFIX is #define'd before
+// each #include of am29xxxxx_aux.c
+
+#ifndef AM29_STR
+# define AM29_STR1(_a_) # _a_
+# define AM29_STR(_a_) AM29_STR1(_a_)
+# define AM29_CONCAT3_AUX(_a_, _b_, _c_) _a_##_b_##_c_
+# define AM29_CONCAT3(_a_, _b_, _c_) AM29_CONCAT3_AUX(_a_, _b_, _c_)
+#endif
+
+#define AM29_FNNAME(_base_) AM29_CONCAT3(_base_, _, AM29_SUFFIX)
+
+// Similarly construct a forward declaration, placing the function in
+// the .2ram section. Each function must still be in a separate section
+// for linker garbage collection.
+
+# define AM29_RAMFNDECL(_base_, _args_) \
+ AM29_FNNAME(_base_) _args_ __attribute__((section (".2ram." AM29_STR(_base_) "_" AM29_STR(AM29_SUFFIX))))
+
+// Calculate the various offsets, based on the device count.
+// The main code may override these settings for specific
+// configurations, e.g. 16as8
+#ifndef AM29_OFFSET_COMMAND
+# define AM29_OFFSET_COMMAND 0x0555
+#endif
+#ifndef AM29_OFFSET_COMMAND2
+# define AM29_OFFSET_COMMAND2 0x02AA
+#endif
+#ifndef AM29_OFFSET_MANUFACTURER_ID
+# define AM29_OFFSET_MANUFACTURER_ID 0x0000
+#endif
+#ifndef AM29_OFFSET_DEVID
+# define AM29_OFFSET_DEVID 0x0001
+#endif
+#ifndef AM29_OFFSET_DEVID2
+# define AM29_OFFSET_DEVID2 0x000E
+#endif
+#ifndef AM29_OFFSET_DEVID3
+# define AM29_OFFSET_DEVID3 0x000F
+#endif
+#ifndef AM29_OFFSET_CFI
+# define AM29_OFFSET_CFI 0x0055
+#endif
+#ifndef AM29_OFFSET_CFI_DATA
+# define AM29_OFFSET_CFI_DATA(_idx_) _idx_
+#endif
+#ifndef AM29_OFFSET_AT49_LOCK_STATUS
+# define AM29_OFFSET_AT49_LOCK_STATUS 0x02
+#endif
+
+// For parallel operation commands are issued in parallel and status
+// bits are checked in parallel.
+#ifndef AM29_PARALLEL
+# define AM29_PARALLEL(_cmd_) (_cmd_)
+#endif
+
+// ----------------------------------------------------------------------------
+// Diagnostic routines.
+
+#if 0
+#define amd_diag( __fmt, ... ) diag_printf("AMD: %s[%d]: " __fmt, __FUNCTION__, __LINE__, ## __VA_ARGS__ );
+#define amd_dump_buf( __addr, __size ) diag_dump_buf( __addr, __size )
+#else
+#define amd_diag( __fmt, ... )
+#define amd_dump_buf( __addr, __size )
+#endif
+
+// ----------------------------------------------------------------------------
+// When performing the various low-level operations like erase the flash
+// chip can no longer support ordinary data reads. Obviously this is a
+// problem if the current code is executing out of flash. The solution is
+// to store the key functions in RAM rather than flash, via a special
+// linker section .2ram which usually gets placed in the same area as
+// .data.
+//
+// In a ROM startup application anything in .2ram will consume space
+// in both the flash and RAM. Hence it is desirable to keep the .2ram
+// functions as small as possible, responsible only for the actual
+// hardware manipulation.
+//
+// All these .2ram functions should be invoked with interrupts
+// disabled. Depending on the hardware it may also be necessary to
+// have the data cache disabled. The .2ram functions must be
+// self-contained, even macro invocations like HAL_DELAY_US() are
+// banned because on some platforms those could be implemented as
+// function calls.
+
+// gcc requires forward declarations with the attributes, then the actual
+// definitions.
+static int AM29_RAMFNDECL(am29_hw_query, (volatile AM29_TYPE*));
+static int AM29_RAMFNDECL(am29_hw_cfi, (struct cyg_flash_dev*, cyg_am29xxxxx_dev*, volatile AM29_TYPE*));
+static int AM29_RAMFNDECL(am29_hw_erase, (volatile AM29_TYPE*));
+static int AM29_RAMFNDECL(am29_hw_program, (volatile AM29_TYPE*, volatile AM29_TYPE*, const cyg_uint8*, cyg_uint32 count, int retries));
+static int AM29_RAMFNDECL(at49_hw_softlock, (volatile AM29_TYPE*));
+static int AM29_RAMFNDECL(at49_hw_hardlock, (volatile AM29_TYPE*));
+static int AM29_RAMFNDECL(at49_hw_unlock, (volatile AM29_TYPE*));
+
+
+// ----------------------------------------------------------------------------
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_RESET_NEEDS_RESUME
+// With this flash component (e.g. AT49xxxxx), the reset does not
+// cause a suspended erase/program to be aborted. Instead all we
+// can do is resume any suspended operations. We do this on each
+// block as some parts have different granularity.
+
+static void
+AM29_FNNAME(am29_hw_force_all_suspended_resume)(struct cyg_flash_dev* dev, cyg_am29xxxxx_dev* am29_dev, volatile AM29_TYPE* addr)
+{
+ cyg_ucount16 i,j;
+ AM29_TYPE datum1, datum2;
+
+ AM29_2RAM_ENTRY_HOOK();
+
+ for (i=0; i<dev->num_block_infos; i++)
+ {
+ for (j=0; j<am29_dev->block_info[i].blocks; j++)
+ {
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_ERASE_RESUME;
+ HAL_MEMORY_BARRIER();
+ // We don't know if the suspended operation was an erase or
+ // program, so just compare the whole word to spot _any_ toggling.
+ do {
+ datum1 = addr[AM29_OFFSET_COMMAND];
+ datum2 = addr[AM29_OFFSET_COMMAND];
+ } while (datum1 != datum2);
+
+ addr += am29_dev->block_info[i].block_size/sizeof(AM29_TYPE);
+ }
+ }
+
+ AM29_2RAM_EXIT_HOOK();
+}
+#endif // ifdef CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_RESET_NEEDS_RESUME
+
+// Read the device id. This involves a straightforward command
+// sequence, followed by a reset to get back into array mode.
+// All chips are accessed in parallel, but only the response
+// from the least significant is used.
+static int
+AM29_FNNAME(am29_hw_query)(volatile AM29_TYPE* addr)
+{
+ int devid;
+ cyg_uint32 onedevmask;
+
+ AM29_2RAM_ENTRY_HOOK();
+
+ // Fortunately the compiler should optimise the below
+ // tests such that onedevmask is a constant.
+ if ( 1 == (sizeof(AM29_TYPE) / AM29_DEVCOUNT) )
+ onedevmask = 0xFF;
+ else if ( 2 == (sizeof(AM29_TYPE) / AM29_DEVCOUNT) )
+ onedevmask = 0xFFFF;
+ else {
+ CYG_ASSERT( 4 == (sizeof(AM29_TYPE) / AM29_DEVCOUNT),
+ "Unexpected flash width per device" );
+ onedevmask = 0xFFFFFFFF;
+ }
+
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND2] = AM29_COMMAND_SETUP2;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_AUTOSELECT;
+ HAL_MEMORY_BARRIER();
+
+ devid = AM29_UNSWAP(addr[AM29_OFFSET_DEVID]) & onedevmask;
+
+// amd_diag("devid %x\n", devid );
+// amd_dump_buf(addr, 64 );
+
+ // The original AMD chips only used a single-byte device id, but
+ // all codes have now been used up. Newer devices use a 3-byte
+ // devid. The above devid read will have returned 0x007E. The
+ // test allows for boards with a mixture of old and new chips.
+ // The amount of code involved is too small to warrant a config
+ // option.
+ // FIXME by jifl: What happens when a single device is connected 16-bits
+ // (or 32-bits) wide per device? Is the code still 0x7E, and all the
+ // other devids are 8-bits only?
+ if (0x007E == devid) {
+ devid <<= 16;
+ devid |= ((AM29_UNSWAP(addr[AM29_OFFSET_DEVID2]) & 0x00FF) << 8);
+ devid |= (AM29_UNSWAP(addr[AM29_OFFSET_DEVID3]) & 0x00FF);
+ }
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+
+// amd_diag("devid %x\n", devid );
+
+ AM29_2RAM_EXIT_HOOK();
+ return devid;
+}
+
+// Perform a CFI query. This involves placing the device(s) into CFI
+// mode, checking that this has really happened, and then reading the
+// size and block info. The address corresponds to the start of the
+// flash.
+static int
+AM29_FNNAME(am29_hw_cfi)(struct cyg_flash_dev* dev, cyg_am29xxxxx_dev* am29_dev, volatile AM29_TYPE* addr)
+{
+ int dev_size;
+ int i;
+ int erase_regions;
+
+ AM29_2RAM_ENTRY_HOOK();
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CFI_BOGOSITY
+ int manufacturer_id;
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND2] = AM29_COMMAND_SETUP2;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_AUTOSELECT;
+ HAL_MEMORY_BARRIER();
+
+ manufacturer_id = AM29_UNSWAP(addr[AM29_OFFSET_MANUFACTURER_ID]) & 0x00FF;
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+#endif
+
+ // Just a single write is needed to put the device into CFI mode
+ addr[AM29_OFFSET_CFI] = AM29_COMMAND_CFI;
+ HAL_MEMORY_BARRIER();
+// amd_diag("CFI data:\n");
+// amd_dump_buf( addr, 256 );
+ // Now check that we really are in CFI mode. There should be a 'Q'
+ // at a specific address. This test is not 100% reliable, but should
+ // be good enough.
+ if ('Q' != (AM29_UNSWAP(addr[AM29_OFFSET_CFI_Q]) & 0x00FF)) {
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+ AM29_2RAM_EXIT_HOOK();
+ return CYG_FLASH_ERR_PROTOCOL;
+ }
+ // Device sizes are always a power of 2, and the shift is encoded
+ // in a single byte
+ dev_size = 0x01 << (AM29_UNSWAP(addr[AM29_OFFSET_CFI_SIZE]) & 0x00FF);
+ dev->end = dev->start + dev_size - 1;
+
+ // The number of erase regions is also encoded in a single byte.
+ // Usually this is no more than 4. A value of 0 indicates that
+ // only chip erase is supported, but the driver does not cope
+ // with that.
+ erase_regions = AM29_UNSWAP(addr[AM29_OFFSET_CFI_BLOCK_REGIONS]) & 0x00FF;
+ if (erase_regions > CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_ERASE_REGIONS) {
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+ AM29_2RAM_EXIT_HOOK();
+ return CYG_FLASH_ERR_PROTOCOL;
+ }
+ dev->num_block_infos = erase_regions;
+
+ for (i = 0; i < erase_regions; i++) {
+ cyg_uint32 count, size;
+ cyg_uint32 count_lsb = AM29_UNSWAP(addr[AM29_OFFSET_CFI_BLOCK_COUNT_LSB(i)]) & 0x00FF;
+ cyg_uint32 count_msb = AM29_UNSWAP(addr[AM29_OFFSET_CFI_BLOCK_COUNT_MSB(i)]) & 0x00FF;
+ cyg_uint32 size_lsb = AM29_UNSWAP(addr[AM29_OFFSET_CFI_BLOCK_SIZE_LSB(i)]) & 0x00FF;
+ cyg_uint32 size_msb = AM29_UNSWAP(addr[AM29_OFFSET_CFI_BLOCK_SIZE_MSB(i)]) & 0x00FF;
+
+ count = ((count_msb << 8) | count_lsb) + 1;
+ size = (size_msb << 16) | (size_lsb << 8);
+ am29_dev->block_info[i].block_size = (size_t) size * AM29_DEVCOUNT;
+ am29_dev->block_info[i].blocks = count;
+ }
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_CFI_BOGOSITY
+
+ // Some flash parts have a peculiar implementation of CFI. The
+ // device erase regions may not be in the order specified in the
+ // main CFI area. Instead the erase regions are given in a
+ // manufacturer dependent fixed order, regardless of whether this
+ // is a top or bottom boot block device. A vendor-specific
+ // extended query block has an entry saying whether the boot
+ // blocks are at the top or bottom. This code works out whether
+ // the erase regions appear to be specified in the wrong order,
+ // and then swaps them over.
+
+ {
+ enum { bottom, symmetric, top } boot_type = symmetric;
+ cyg_uint32 vspec = AM29_SWAP(addr[AM29_OFFSET_CFI_DATA(0x15)]) & 0x00FF;
+
+ // Take a look at the vendor specific area for the boot block
+ // order.
+
+ switch( manufacturer_id )
+ {
+ // Atmel appear to have their own layout for the vendor
+ // specific area. Offset 0x06 of the vendor specific area
+ // contains a single bit: 0x00 = top boot, 0x01 = bottom
+ // boot. There appears to be no way of specifying
+ // symmetric formats.
+ case 0x1F:
+ if( (addr[AM29_OFFSET_CFI_DATA(vspec+0x06)] & AM29_SWAP(0x1)) == AM29_SWAP(0x1) )
+ boot_type = bottom;
+ else boot_type = top;
+ break;
+
+ // Most other manufacturers seem to follow the same layout
+ // and encoding. Offset 0xF of the vendor specific area
+ // contains the boot sector layout: 0x00 = uniform, 0x01 =
+ // 8x8k top and bottom, 0x02 = bottom boot, 0x03 = top
+ // boot, 0x04 = both top and bottom.
+ //
+ // The following manufacturers support this layout:
+ // AMD, Spansion, ST, Macronix.
+ default:
+ if( (addr[AM29_OFFSET_CFI_DATA(vspec+0xF)] == AM29_SWAP(0x2)) )
+ boot_type = bottom;
+ else if( (addr[AM29_OFFSET_CFI_DATA(vspec+0xF)] == AM29_SWAP(0x3)) )
+ boot_type = top;
+ // All other options are symmetric
+ break;
+ }
+
+ // If the device is marked as top boot, but the erase region
+ // list appears to be in bottom boot order, then reverse the
+ // list. Also swap, if it is marked as bottom boot but the
+ // erase regions appear to be in top boot order. This code
+ // assumes that the first boot block is always smaller than
+ // regular blocks; it is possible to imagine flash layouts for
+ // which that is not true.
+
+ if( ((boot_type == top) &&
+ (am29_dev->block_info[0].block_size < am29_dev->block_info[erase_regions-1].block_size)) ||
+ ((boot_type == bottom) &&
+ (am29_dev->block_info[0].block_size > am29_dev->block_info[erase_regions-1].block_size)))
+ {
+ int lo, hi;
+
+ for( lo = 0, hi = erase_regions-1 ; lo < hi ; lo++, hi-- )
+ {
+ size_t size = am29_dev->block_info[lo].block_size;
+ cyg_uint32 count = am29_dev->block_info[lo].blocks;
+ am29_dev->block_info[lo].block_size = am29_dev->block_info[hi].block_size;
+ am29_dev->block_info[lo].blocks = am29_dev->block_info[hi].blocks;
+ am29_dev->block_info[hi].block_size = size;
+ am29_dev->block_info[hi].blocks = count;
+ }
+ }
+ }
+#endif
+
+ // Get out of CFI mode
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+
+ AM29_2RAM_EXIT_HOOK();
+ return CYG_FLASH_ERR_OK;
+}
+
+// Erase a single sector. There is no API support for chip-erase. The
+// generic code operates one sector at a time, invoking the driver for
+// each sector, so there is no opportunity inside the driver for
+// erasing multiple sectors in a single call. The address argument
+// points at the start of the sector.
+static int
+AM29_FNNAME(am29_hw_erase)(volatile AM29_TYPE* addr)
+{
+ int retries;
+ AM29_TYPE datum;
+
+ AM29_2RAM_ENTRY_HOOK();
+
+ // Start the erase operation
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND2] = AM29_COMMAND_SETUP2;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_ERASE;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND2] = AM29_COMMAND_SETUP2;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_ERASE_SECTOR;
+ HAL_MEMORY_BARRIER();
+ // There is now a 50us window in which we could send additional
+ // ERASE_SECTOR commands, but the driver API does not allow this
+
+ // All chips are now erasing in parallel. Loop until all have
+ // completed. This can be detected in a number of ways. The DQ7
+ // bit will be 0 until the erase is complete, but there is a
+ // problem if something went wrong (e.g. the sector is locked),
+ // the erase has not actually started, and the relevant bit was 0
+ // already. More useful is DQ6. This will toggle during the 50us
+ // window and while the erase is in progress, then stop toggling.
+ // If the erase does not actually start then the bit won't toggle
+ // at all so the operation completes rather quickly.
+ //
+ // If at any time DQ5 is set (indicating a timeout inside the
+ // chip) then a reset command must be issued and the erase is
+ // aborted. It is not clear this can actually happen during an
+ // erase, but just in case.
+ for (retries = CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_ERASE_TIMEOUT;
+ retries > 0;
+ retries--) {
+
+ datum = addr[AM29_OFFSET_COMMAND];
+ // The operation completes when all DQ7 bits are set.
+ if ((datum & AM29_STATUS_DQ7) == AM29_STATUS_DQ7) {
+ break;
+ }
+ // Otherwise, for any flash chips where DQ7 is still clear, it is
+ // necessary to test DQ5.
+ if (((datum ^ AM29_STATUS_DQ7) >> 2) & datum & AM29_STATUS_DQ5) {
+ // DQ5 is set, indicating a hardware error. The calling code
+ // will always verify that the erase really was successful
+ // so we do not need to distinguish between error conditions.
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+ break;
+ }
+ }
+
+ // A result of 0 indicates a timeout.
+ // A non-zero result indicates
+ // that the erase completed or there has been a fatal error.
+ AM29_2RAM_EXIT_HOOK();
+ return retries;
+}
+
+// Write data to flash. At most one block will be processed at a time,
+// but the write may be for a subset of the write. The destination
+// address will be aligned in a way suitable for the bus. The source
+// address need not be aligned. The count is in AM29_TYPE's, i.e.
+// as per the bus alignment, not in bytes.
+static int
+AM29_FNNAME(am29_hw_program)(volatile AM29_TYPE* block_start, volatile AM29_TYPE* addr, const cyg_uint8* buf, cyg_uint32 count, int retries)
+{
+ int i;
+
+ AM29_2RAM_ENTRY_HOOK();
+
+ for (i = 0; (i < count) && (retries > 0); i++) {
+ AM29_TYPE datum, current, active_dq7s;
+
+ // We can only clear bits, not set them, so any bits that were
+ // already clear need to be preserved.
+ current = addr[i];
+ datum = AM29_NEXT_DATUM(buf) & current;
+ if (datum == current) {
+ // No change, so just move on.
+ continue;
+ }
+
+ block_start[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ block_start[AM29_OFFSET_COMMAND2] = AM29_COMMAND_SETUP2;
+ HAL_MEMORY_BARRIER();
+ block_start[AM29_OFFSET_COMMAND] = AM29_COMMAND_PROGRAM;
+ HAL_MEMORY_BARRIER();
+ addr[i] = datum;
+ HAL_MEMORY_BARRIER();
+
+ // The data is now being written. The official algorithm is
+ // to poll either DQ7 or DQ6, checking DQ5 along the way for
+ // error conditions. This gets complicated with parallel
+ // flash chips because they may finish at different times.
+ // The alternative approach is to ignore the status bits
+ // completely and just look for current==datum until the
+ // retry count is exceeded. However that does not cope
+ // cleanly with cases where the flash chip reports an error
+ // early on, e.g. because a flash block is locked.
+
+ while (--retries > 0) {
+#if CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_PROGRAM_DELAY > 0
+ // Some chips want a delay between polling
+ { int j; for( j = 0; j < CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_PROGRAM_DELAY; j++ ); }
+#endif
+ // While the program operation is in progress DQ7 will read
+ // back inverted from datum.
+ current = addr[i];
+ if ((current & AM29_STATUS_DQ7) == (datum & AM29_STATUS_DQ7)) {
+ // All DQ7 bits now match datum, so the operation has completed.
+ // But not necessarily successfully. On some chips DQ7 may
+ // toggle before DQ0-6 are valid, so we need to read the
+ // data one more time.
+ current = addr[i];
+ if (current != datum) {
+ retries = 0; // Abort this burst.
+ }
+ break;
+ }
+
+ // Now we want to check the DQ5 status bits, but only for those
+ // chips which are still programming. ((current^datum) & DQ7) gives
+ // ones for chips which are still programming, zeroes for chips when
+ // the programming is complete.
+ active_dq7s = (current ^ datum) & AM29_STATUS_DQ7;
+
+ if (0 != (current & (active_dq7s >> 2))) {
+ // Unfortunately this is not sufficient to prove an error. On
+ // some chips DQ0-6 switch to the data while DQ7 is still a
+ // status flag, so the set DQ5 bit detected above may be data
+ // instead of an error. Check again, this time DQ7 may
+ // indicate completion.
+ //
+ // Next problem. Suppose chip A gave a bogus DQ5 result earlier
+ // because it was just finishing. For this read chip A gives
+ // back datum, but now chip B is finishing and has reported a
+ // bogus DQ5.
+ //
+ // Solution: if any of the DQ7 lines have changed since the last
+ // time, go around the loop again. When an error occurs DQ5
+ // remains set and DQ7 remains toggled, so there is no harm
+ // in one more polling loop.
+
+ current = addr[i];
+ if (((current ^ datum) & AM29_STATUS_DQ7) != active_dq7s) {
+ continue;
+ }
+
+ // DQ5 has been set in a chip where DQ7 indicates an ongoing
+ // program operation for two successive reads. That is an error.
+ // The hardware is in a strange state so must be reset.
+ block_start[AM29_OFFSET_COMMAND] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+ retries = 0;
+ break;
+ }
+ // No DQ5 bits set in chips which are still programming. Poll again.
+ } // Retry for current word
+ } // Next word
+
+ // At this point retries holds the total number of retries left.
+ // 0 indicates a timeout or fatal error.
+ // >0 indicates success.
+ AM29_2RAM_EXIT_HOOK();
+ return retries;
+}
+
+// FIXME: implement a separate program routine for buffered writes.
+
+#if 0
+// Unused for now, but might be useful later
+static int
+AM29_FNNAME(at49_hw_is_locked)(volatile AM29_TYPE* addr)
+{
+ int result;
+ AM29_TYPE plane;
+
+ AM29_2RAM_ENTRY_HOOK();
+
+ // Plane is bits A21-A20 for AT49BV6416
+ // A more generic formula is needed.
+ plane = AM29_PARALLEL( ((((CYG_ADDRESS)addr)>>21) & 0x3) );
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND2] = AM29_COMMAND_SETUP2;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND + plane] = AM29_COMMAND_AUTOSELECT;
+ HAL_MEMORY_BARRIER();
+ result = addr[AM29_OFFSET_AT49_LOCK_STATUS];
+ addr[0] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+ // The bottom two bits hold the lock status, LSB indicates
+ // soft lock, next bit indicates hard lock. We don't distinguish
+ // in this function.
+ AM29_2RAM_EXIT_HOOK();
+ return (0 != (result & AM29_ID_LOCKED));
+}
+#endif
+
+static int
+AM29_FNNAME(at49_hw_softlock)(volatile AM29_TYPE* addr)
+{
+ int result = CYG_FLASH_ERR_OK;
+
+ AM29_2RAM_ENTRY_HOOK();
+
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND2] = AM29_COMMAND_SETUP2;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_AT49_SOFTLOCK_BLOCK_0;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND2] = AM29_COMMAND_SETUP2;
+ HAL_MEMORY_BARRIER();
+ addr[0] = AM29_COMMAND_AT49_SOFTLOCK_BLOCK_1;
+ HAL_MEMORY_BARRIER();
+ // not sure if this is required:
+ addr[0] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+ AM29_2RAM_EXIT_HOOK();
+ return result;
+}
+
+static int
+AM29_FNNAME(at49_hw_hardlock)(volatile AM29_TYPE* addr)
+{
+ int result = CYG_FLASH_ERR_OK;
+
+ AM29_2RAM_ENTRY_HOOK();
+
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND2] = AM29_COMMAND_SETUP2;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_AT49_HARDLOCK_BLOCK_0;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ addr[AM29_OFFSET_COMMAND2] = AM29_COMMAND_SETUP2;
+ HAL_MEMORY_BARRIER();
+ addr[0] = AM29_COMMAND_AT49_HARDLOCK_BLOCK_1;
+ HAL_MEMORY_BARRIER();
+ // not sure if this is required:
+ addr[0] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+ AM29_2RAM_EXIT_HOOK();
+ return result;
+}
+
+static int
+AM29_FNNAME(at49_hw_unlock)(volatile AM29_TYPE* addr)
+{
+ int result = CYG_FLASH_ERR_OK;
+
+ AM29_2RAM_ENTRY_HOOK();
+
+ addr[AM29_OFFSET_COMMAND] = AM29_COMMAND_SETUP1;
+ HAL_MEMORY_BARRIER();
+ addr[0] = AM29_COMMAND_AT49_UNLOCK_BLOCK;
+ HAL_MEMORY_BARRIER();
+ // not sure if this is required:
+ addr[0] = AM29_COMMAND_RESET;
+ HAL_MEMORY_BARRIER();
+ AM29_2RAM_EXIT_HOOK();
+ return result;
+}
+
+
+// ----------------------------------------------------------------------------
+// Exported code, mostly for placing in a cyg_flash_dev_funs structure.
+
+// Just read the device id, either for sanity checking that the system
+// has been configured for the right device, or for filling in the
+// block info by a platform-specific init routine if the platform may
+// be manufactured with one of several different chips.
+int
+AM29_FNNAME(cyg_am29xxxxx_read_devid) (struct cyg_flash_dev* dev)
+{
+ int (*query_fn)(volatile AM29_TYPE*);
+ int devid;
+ volatile AM29_TYPE* addr;
+ AM29_INTSCACHE_STATE;
+
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+
+ amd_diag("\n");
+
+ addr = AM29_UNCACHED_ADDRESS(dev->start);
+ query_fn = (int (*)(volatile AM29_TYPE*)) cyg_flash_anonymizer( & AM29_FNNAME(am29_hw_query) );
+ AM29_INTSCACHE_BEGIN();
+ devid = (*query_fn)(addr);
+ AM29_INTSCACHE_END();
+ return devid;
+}
+
+// Validate that the device statically configured is the one on the
+// board.
+int
+AM29_FNNAME(cyg_am29xxxxx_init_check_devid)(struct cyg_flash_dev* dev)
+{
+ cyg_am29xxxxx_dev* am29_dev;
+ int devid;
+
+ amd_diag("\n");
+
+ am29_dev = (cyg_am29xxxxx_dev*) dev->priv;
+ devid = AM29_FNNAME(cyg_am29xxxxx_read_devid)(dev);
+ if (devid != am29_dev->devid) {
+ return CYG_FLASH_ERR_DRV_WRONG_PART;
+ }
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_RESET_NEEDS_RESUME
+ {
+ volatile AM29_TYPE *addr = AM29_UNCACHED_ADDRESS(dev->start);
+ void (*resume_fn)(struct cyg_flash_dev*, cyg_am29xxxxx_dev*, volatile AM29_TYPE*);
+ resume_fn = (void (*)(struct cyg_flash_dev*, cyg_am29xxxxx_dev*, volatile AM29_TYPE*))
+ cyg_flash_anonymizer( &AM29_FNNAME(am29_hw_force_all_suspended_resume) );
+ AM29_INTSCACHE_STATE;
+
+ AM29_INTSCACHE_BEGIN();
+ (*resume_fn)(dev, am29_dev, addr);
+ AM29_INTSCACHE_END();
+ }
+#endif
+
+ // Successfully queried the device, and the id's match. That
+ // should be a good enough indication that the flash is working.
+ return CYG_FLASH_ERR_OK;
+}
+
+// Initialize via a CFI query, instead of statically specifying the
+// boot block layout.
+int
+AM29_FNNAME(cyg_am29xxxxx_init_cfi)(struct cyg_flash_dev* dev)
+{
+ int (*cfi_fn)(struct cyg_flash_dev*, cyg_am29xxxxx_dev*, volatile AM29_TYPE*);
+ volatile AM29_TYPE* addr;
+ cyg_am29xxxxx_dev* am29_dev;
+ int result;
+ AM29_INTSCACHE_STATE;
+
+ amd_diag("\n");
+
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ am29_dev = (cyg_am29xxxxx_dev*) dev->priv; // Remove const, only place where this is needed.
+ addr = AM29_UNCACHED_ADDRESS(dev->start);
+ cfi_fn = (int (*)(struct cyg_flash_dev*, cyg_am29xxxxx_dev*, volatile AM29_TYPE*))
+ cyg_flash_anonymizer( & AM29_FNNAME(am29_hw_cfi));
+
+ AM29_INTSCACHE_BEGIN();
+ result = (*cfi_fn)(dev, am29_dev, addr);
+ AM29_INTSCACHE_END();
+
+ // Now calculate the device size, and hence the end field.
+ if (CYG_FLASH_ERR_OK == result) {
+ int i;
+ int size = 0;
+ for (i = 0; i < dev->num_block_infos; i++) {
+ amd_diag("region %d: 0x%08x * %d\n", i, (int)dev->block_info[i].block_size, dev->block_info[i].blocks );
+ size += (dev->block_info[i].block_size * dev->block_info[i].blocks);
+ }
+ dev->end = dev->start + size - 1;
+
+#ifdef CYGHWR_DEVS_FLASH_AMD_AM29XXXXX_V2_RESET_NEEDS_RESUME
+ {
+ void (*resume_fn)(struct cyg_flash_dev*, cyg_am29xxxxx_dev*, volatile AM29_TYPE*);
+ resume_fn = (void (*)(struct cyg_flash_dev*, cyg_am29xxxxx_dev*, volatile AM29_TYPE*))
+ cyg_flash_anonymizer( &AM29_FNNAME(am29_hw_force_all_suspended_resume) );
+
+ AM29_INTSCACHE_BEGIN();
+ (*resume_fn)(dev, am29_dev, addr);
+ AM29_INTSCACHE_END();
+ }
+#endif
+ }
+ return result;
+}
+
+// Erase a single block. The calling code will have supplied a pointer
+// aligned to a block boundary.
+int
+AM29_FNNAME(cyg_am29xxxxx_erase)(struct cyg_flash_dev* dev, cyg_flashaddr_t addr)
+{
+ int (*erase_fn)(volatile AM29_TYPE*);
+ volatile AM29_TYPE* block;
+ cyg_flashaddr_t block_start;
+ size_t block_size;
+ int i;
+ int result;
+ AM29_INTSCACHE_STATE;
+
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((addr >= dev->start) && (addr <= dev->end), "flash address out of device range");
+
+ am29_get_block_info(dev, addr, &block_start, &block_size);
+ CYG_ASSERT(addr == block_start, "erase address should be the start of a flash block");
+
+ amd_diag("addr %p block %p[%d]\n", (void*)addr, (void*)block_start, (int)block_size );
+
+ block = AM29_UNCACHED_ADDRESS(addr);
+ erase_fn = (int (*)(volatile AM29_TYPE*)) cyg_flash_anonymizer( & AM29_FNNAME(am29_hw_erase) );
+
+ AM29_INTSCACHE_BEGIN();
+ result = (*erase_fn)(block);
+ AM29_INTSCACHE_END();
+
+ // The erase may have failed for a number of reasons, e.g. because
+ // of a locked sector. The best thing to do here is to check that the
+ // erase has succeeded.
+ block = (AM29_TYPE*) addr;
+ for (i = 0; i < (block_size / sizeof(AM29_TYPE)); i++) {
+ if (block[i] != (AM29_TYPE)~0) {
+ // There is no easy way of detecting the specific error,
+ // e.g. locked flash block, timeout, ... So return a
+ // useless catch-all error.
+ return CYG_FLASH_ERR_ERASE;
+ }
+ }
+ return CYG_FLASH_ERR_OK;
+}
+
+// Write some data to the flash. The destination must be aligned
+// appropriately for the bus width (not the device width).
+int
+AM29_FNNAME(cyg_am29xxxxx_program)(struct cyg_flash_dev* dev, cyg_flashaddr_t dest, const void* src, size_t len)
+{
+ int (*program_fn)(volatile AM29_TYPE*, volatile AM29_TYPE*, const cyg_uint8*, cyg_uint32, int);
+ volatile AM29_TYPE* block;
+ volatile AM29_TYPE* addr;
+ cyg_flashaddr_t block_start;
+ size_t block_size;
+ const cyg_uint8* data;
+ int retries;
+ int i;
+
+ AM29_INTSCACHE_STATE;
+
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+
+ amd_diag("dest %p src %p len %d\n", (void*)dest, (void*)src, (int)len );
+
+ // Only support writes that are aligned to the bus boundary. This
+ // may be more restrictive than what the hardware is capable of.
+ // However it ensures that the hw_program routine can write as
+ // much data as possible each iteration, and hence significantly
+ // improves performance. The length had better be a multiple of
+ // the bus width as well
+ if ((0 != ((CYG_ADDRWORD)dest & (sizeof(AM29_TYPE) - 1))) ||
+ (0 != (len & (sizeof(AM29_TYPE) - 1)))) {
+ return CYG_FLASH_ERR_INVALID;
+ }
+
+ addr = AM29_UNCACHED_ADDRESS(dest);
+ CYG_ASSERT((dest >= dev->start) && (dest <= dev->end), "flash address out of device range");
+
+ am29_get_block_info(dev, dest, &block_start, &block_size);
+ CYG_ASSERT(((dest - block_start) + len) <= block_size, "write cannot cross block boundary");
+
+ block = AM29_UNCACHED_ADDRESS(block_start);
+ data = (const cyg_uint8*) src;
+ retries = CYGNUM_DEVS_FLASH_AMD_AM29XXXXX_V2_PROGRAM_TIMEOUT;
+
+ program_fn = (int (*)(volatile AM29_TYPE*, volatile AM29_TYPE*, const cyg_uint8*, cyg_uint32, int))
+ cyg_flash_anonymizer( & AM29_FNNAME(am29_hw_program) );
+
+ AM29_INTSCACHE_BEGIN();
+ (*program_fn)(block, addr, data, len / sizeof(AM29_TYPE), retries);
+ AM29_INTSCACHE_END();
+
+ // Too many things can go wrong when manipulating the h/w, so
+ // verify the operation by actually checking the data.
+ addr = (volatile AM29_TYPE*) dest;
+ data = (const cyg_uint8*) src;
+ for (i = 0; i < (len / sizeof(AM29_TYPE)); i++) {
+ AM29_TYPE datum = AM29_NEXT_DATUM(data);
+ AM29_TYPE current = addr[i];
+ if ((datum & current) != current) {
+ amd_diag("data %p addr[i] %p datum %08x current %08x\n", data-sizeof(AM29_TYPE), &addr[i], datum, current );
+ return CYG_FLASH_ERR_PROGRAM;
+ }
+ }
+ return CYG_FLASH_ERR_OK;
+}
+
+int
+AM29_FNNAME(cyg_at49xxxx_softlock)(struct cyg_flash_dev* dev, const cyg_flashaddr_t dest)
+{
+ volatile AM29_TYPE* uncached;
+ int result;
+ int (*lock_fn)(volatile AM29_TYPE*);
+ AM29_INTSCACHE_STATE;
+
+ amd_diag("\n");
+
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= (cyg_flashaddr_t)dev->start) &&
+ ((CYG_ADDRESS)dest <= dev->end), "flash address out of device range");
+
+ uncached = AM29_UNCACHED_ADDRESS(dest);
+ lock_fn = (int (*)(volatile AM29_TYPE*)) cyg_flash_anonymizer( & AM29_FNNAME(at49_hw_softlock) );
+ AM29_INTSCACHE_BEGIN();
+ result = (*lock_fn)(uncached);
+ AM29_INTSCACHE_END();
+ return result;
+}
+
+int
+AM29_FNNAME(cyg_at49xxxx_hardlock)(struct cyg_flash_dev* dev, const cyg_flashaddr_t dest)
+{
+ volatile AM29_TYPE* uncached;
+ int result;
+ int (*lock_fn)(volatile AM29_TYPE*);
+ AM29_INTSCACHE_STATE;
+
+ amd_diag("\n");
+
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= (cyg_flashaddr_t)dev->start) &&
+ ((CYG_ADDRESS)dest <= dev->end), "flash address out of device range");
+
+ uncached = AM29_UNCACHED_ADDRESS(dest);
+ lock_fn = (int (*)(volatile AM29_TYPE*)) cyg_flash_anonymizer( & AM29_FNNAME(at49_hw_hardlock) );
+ AM29_INTSCACHE_BEGIN();
+ result = (*lock_fn)(uncached);
+ AM29_INTSCACHE_END();
+ return result;
+}
+
+int
+AM29_FNNAME(cyg_at49xxxx_unlock)(struct cyg_flash_dev* dev, const cyg_flashaddr_t dest)
+{
+ volatile AM29_TYPE* uncached;
+ int result;
+ int (*unlock_fn)(volatile AM29_TYPE*);
+ AM29_INTSCACHE_STATE;
+
+ amd_diag("\n");
+
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= (cyg_flashaddr_t)dev->start) &&
+ ((CYG_ADDRESS)dest <= dev->end), "flash address out of device range");
+
+ uncached = AM29_UNCACHED_ADDRESS(dest);
+ unlock_fn = (int (*)(volatile AM29_TYPE*)) cyg_flash_anonymizer( & AM29_FNNAME(at49_hw_unlock) );
+
+ AM29_INTSCACHE_BEGIN();
+ result = (*unlock_fn)(uncached);
+ AM29_INTSCACHE_END();
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// Clean up the various #define's so this file can be #include'd again
+#undef AM29_FNNAME
+#undef AM29_RAMFNDECL
+#undef AM29_OFFSET_COMMAND
+#undef AM29_OFFSET_COMMAND2
+#undef AM29_OFFSET_DEVID
+#undef AM29_OFFSET_DEVID2
+#undef AM29_OFFSET_DEVID3
+#undef AM29_OFFSET_CFI
+#undef AM29_OFFSET_CFI_DATA
+#undef AM29_OFFSET_AT49_LOCK_STATUS
+#undef AM29_PARALLEL
diff --git a/ecos/packages/devs/flash/arm/aaed2000/current/ChangeLog b/ecos/packages/devs/flash/arm/aaed2000/current/ChangeLog
new file mode 100644
index 0000000..84f87ce
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/aaed2000/current/ChangeLog
@@ -0,0 +1,43 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_arm_aaed2000.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2001-11-08 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_arm_aaed2000.cdl: Removed ARM Boot Monitor protection
+ requirement.
+
+2001-10-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_arm_aaed2000.cdl: Require protection from ARM Boot
+ Monitor.
+
+2001-10-30 Jesper Skov <jskov@redhat.com>
+
+ * Imported sources from Gary Thomas.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/aaed2000/current/cdl/flash_arm_aaed2000.cdl b/ecos/packages/devs/flash/arm/aaed2000/current/cdl/flash_arm_aaed2000.cdl
new file mode 100644
index 0000000..bd7d45e
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/aaed2000/current/cdl/flash_arm_aaed2000.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_arm_aaed2000.cdl
+#
+# FLASH memory - Hardware support on Agilent AAED2000
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov, gthomas
+# Original data: jskov
+# Contributors:
+# Date: 2001-10-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_AAED2000 {
+ display "Agilent AAED2000 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_ARM9_AAED2000
+
+ compile aaed2000_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV640
+}
diff --git a/ecos/packages/devs/flash/arm/aaed2000/current/src/aaed2000_flash.c b/ecos/packages/devs/flash/arm/aaed2000/current/src/aaed2000_flash.c
new file mode 100644
index 0000000..1dc9032
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/aaed2000/current/src/aaed2000_flash.c
@@ -0,0 +1,73 @@
+//==========================================================================
+//
+// aaed2000_flash.c
+//
+// Flash programming for Fujitsu/AMD device on Agilent AAED2000
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, gthomas
+// Contributors: jskov
+// Date: 2001-10-27
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_SERIES (2)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x60000000)
+
+//static cyg_uint32 plf_flash_base;
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT // This feature fails :-(
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF aaed2000_flash.c
diff --git a/ecos/packages/devs/flash/arm/aim711/current/ChangeLog b/ecos/packages/devs/flash/arm/aim711/current/ChangeLog
new file mode 100755
index 0000000..cdb279a
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/aim711/current/ChangeLog
@@ -0,0 +1,39 @@
+2004-11-22 Bart Veer <bartv@ecoscentric.com>
+
+ * src/arm_aim711_flash.c: use updated CYG_FLASH_DRIVER() macro for
+ completely static initialization.
+
+2004-07-16 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/arm_aim711_flash.c: Make us of the new sst driver which uses
+ the new flash device driver API.
+
+2003-10-02 Roland Cassebohm <r.cassebohm@visionsystems.de>
+
+ * src/arm_aim711_flash.c:
+ * cdl/flash_arm_aim711.cdl: New package. FLASH memory support for
+ ARM Industrial Module AIM 711.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/aim711/current/cdl/flash_arm_aim711.cdl b/ecos/packages/devs/flash/arm/aim711/current/cdl/flash_arm_aim711.cdl
new file mode 100755
index 0000000..066922d
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/aim711/current/cdl/flash_arm_aim711.cdl
@@ -0,0 +1,78 @@
+# ====================================================================
+#
+# flash_arm_aim711.cdl
+#
+# FLASH memory - Hardware support on ARM Industrial Module AIM 711
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov, rcassebohm
+# Original data: gthomas
+# Contributors: gthomas, rcassebohm
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_AIM711 {
+ display "ARM Industrial Module AIM 711 FLASH memory support"
+ description "FLASH memory device support for ARM Industrial Module AIM 711"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_AIM711
+
+ compile -library=libextras.a arm_aim711_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED {
+ display "Generic SST 39VFxxx driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED
+
+ cdl_option CYGNUM_DEVS_FLASH_ARM_AIM711_SIZE {
+ display "Flash size in Mbytes"
+ flavor data
+ legal_values { 1 2 }
+ default_value 2
+ description "
+ This option specifies the size of the flash device
+ of the AIM 711."
+ }
+}
diff --git a/ecos/packages/devs/flash/arm/aim711/current/src/arm_aim711_flash.c b/ecos/packages/devs/flash/arm/aim711/current/src/arm_aim711_flash.c
new file mode 100755
index 0000000..b1a0dd8
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/aim711/current/src/arm_aim711_flash.c
@@ -0,0 +1,86 @@
+//==========================================================================
+//
+// arm_aim711_flash.c
+//
+// Flash programming for ARM Industrial Module AIM 711
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, rcassebohm
+// Contributors: jskov, rcassebohm, andrew lunn
+// Date: 2001-02-21
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_flash_arm_aim711.h>
+
+#if (CYGNUM_DEVS_FLASH_ARM_AIM711_SIZE == 1)
+
+#define CYGPKG_DEVS_FLASH_SST_39VF080
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0x2000000u)
+
+#elif (CYGNUM_DEVS_FLASH_ARM_AIM711_SIZE == 2)
+
+#define CYGPKG_DEVS_FLASH_SST_39VF016
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0x2000000u)
+
+#endif
+
+#include "cyg/io/flash_sst_39vfxxx.inl"
+
+static const cyg_flash_block_info_t cyg_flash_sst_block_info[1] = {
+ { FLASH_BLOCK_SIZE, FLASH_NUM_REGIONS * CYGNUM_FLASH_SERIES }
+};
+CYG_FLASH_DRIVER(cyg_flash_sst_flashdev,
+ &cyg_sst_funs,
+ 0, // Flags
+ CYGNUM_FLASH_BASE, // Start
+ CYGNUM_FLASH_BASE + (FLASH_BLOCK_SIZE * FLASH_NUM_REGIONS * CYGNUM_FLASH_SERIES) - 1, // End
+ 1, // Number of block infos
+ cyg_flash_sst_block_info,
+ NULL // priv
+ );
+
+// ------------------------------------------------------------------------
+// EOF arm_aim711_flash.c
diff --git a/ecos/packages/devs/flash/arm/assabet/current/ChangeLog b/ecos/packages/devs/flash/arm/assabet/current/ChangeLog
new file mode 100644
index 0000000..603c168
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/assabet/current/ChangeLog
@@ -0,0 +1,67 @@
+2001-03-17 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_unlock_block.c:
+ * src/flash_query.c:
+ * src/flash_program_buf.c:
+ * src/flash_lock_block.c:
+ * src/flash_erase_block.c:
+ * src/flash.h:
+ * src/assabet_flash.c: Removed - everything now generic.
+
+ * include/assabet_strataflash.inl:
+ * cdl/flash_assabet.cdl: Change to use generic StrataFLASH driver.
+
+2000-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/assabet_flash.c (flash_code_overlaps): Define stext/etext
+ as array types so no assumptions can be made by the compiler about
+ location.
+
+2000-10-24 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_program_buf.c (flash_program_buf):
+ * src/flash_erase_block.c (flash_erase_block): Support up to 32M FLASH.
+
+2000-09-10 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_unlock_block.c:
+ * src/flash_lock_block.c: New file(s).
+
+ * src/flash.h:
+ * cdl/flash_assabet.cdl: Add region locking functions.
+
+2000-08-29 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_flash.c: Improve error decoding.
+
+2000-08-24 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_query.c:
+ * src/flash_erase_block.c:
+ * src/flash.h: FLASH support for Intel SA1110 Assabet.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/assabet/current/cdl/flash_assabet.cdl b/ecos/packages/devs/flash/arm/assabet/current/cdl/flash_assabet.cdl
new file mode 100644
index 0000000..5914417
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/assabet/current/cdl/flash_assabet.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_assabet.cdl
+#
+# FLASH memory - Hardware support on Intel StrongARM SA1110
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ASSABET {
+ display "Intel SA1110 (Assabet) FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_SA11X0_ASSABET
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/assabet_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_assabet.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
+
diff --git a/ecos/packages/devs/flash/arm/assabet/current/include/assabet_strataflash.inl b/ecos/packages/devs/flash/arm/assabet/current/include/assabet_strataflash.inl
new file mode 100644
index 0000000..9fe45ab
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/assabet/current/include/assabet_strataflash.inl
@@ -0,0 +1,67 @@
+#ifndef CYGONCE_DEVS_FLASH_ASSABET_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_ASSABET_STRATAFLASH_INL
+//==========================================================================
+//
+// assabet_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// The assabet system has two 16-bit devices.
+// Doc says: a StrataFlash 28F320J3A. The 320 means 32Mbit, so 4Mbyte.
+// Reality: a StrataFlash 28F640J3A. The 640 means 64Mbit, so 8Mbyte.
+
+#define CYGNUM_FLASH_DEVICES (2)
+#define CYGNUM_FLASH_BASE (0x50000000u)
+#define CYGNUM_FLASH_BASE_MASK (0xFE000000u) // 32Mb devices
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_ASSABET_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF assabet_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/at91/current/ChangeLog b/ecos/packages/devs/flash/arm/at91/current/ChangeLog
new file mode 100644
index 0000000..a417e74
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/at91/current/ChangeLog
@@ -0,0 +1,65 @@
+2009-07-03 Oliver Munz <munz@speag.ch>
+
+ * src/at91_flash.c: Enable use of the second flash in 512k devices.
+ Resolve potential problem with late PIT-initalisation. Prevent changes
+ to system clock when booting from a boot monitor.
+
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/at91_flash.c: Explicitly include <cyg/io/flash_dev.h> rather
+ than just defining _FLASH_PRIVATE_
+
+ * cdl/flash_at91.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2008-11-03 Gabor Toeroek <tgabor84@gmail.com>
+
+ * src/at91_flash.c (flash_hwr_init): Add partial support for
+ AT91SAM7SE. This can have a second embedded flash controller and
+ maybe ROM as well as FLASH. Only writing to the first controller
+ is currently supported.
+
+2008-10-19 Oliver Munz <munz@speag.ch>
+
+ * src/at91_flash.c (flash_hwr_init): Add support for AT91SAM7XC.
+
+2006-05-23 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/at91_flash.c: Support for the AT91SAM7X devices.
+
+2006-02-19 Oliver Munz <munz@speag.ch>
+
+ * src/at91_flash.c: Optimize the cyg_uint32 page.
+ Make the lock/unlock functions work.
+
+2006-02-19 Oliver Munz <munz@speag.ch>
+ Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/at91_flash.c:
+ * cdl/flash_at91.cdl: .
+ * ChangeLog: Flash driver for the AT91 Embedded Flash controller,
+ e.g. the AT91SAM7S devices.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/at91/current/cdl/flash_at91.cdl b/ecos/packages/devs/flash/arm/at91/current/cdl/flash_at91.cdl
new file mode 100644
index 0000000..be6b8e4
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/at91/current/cdl/flash_at91.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_at91.cdl
+#
+# FLASH programming for devices with the Embedded Flash Controller
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): dmoseley
+# Original data: gthomas
+# Contributors: Andrew Lunn, Oliver Munz
+# Date: 2000-10-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_AT91 {
+ display "AT91 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ include_dir .
+ description "FLASH memory device support for AT91 EFC"
+ compile at91_flash.c
+
+ cdl_option CYGBLD_DEV_FLASH_AT91_LOCKING {
+ display "Support block locking"
+ default_value 1
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ description "
+ The driver will implement flash block locking when this
+ option is enabled. Note that the device implements sector
+ locking, not block locking, where sectors are bigger than
+ blocks. So the sector which contains the block will be
+ locked/unlocked
+
+ WARNING: The errata says that these lock bits only have
+ a life of 100 cycles for the AT91SAM7S devices."
+ }
+}
+
diff --git a/ecos/packages/devs/flash/arm/at91/current/src/at91_flash.c b/ecos/packages/devs/flash/arm/at91/current/src/at91_flash.c
new file mode 100644
index 0000000..c575107
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/at91/current/src/at91_flash.c
@@ -0,0 +1,499 @@
+//==========================================================================
+//
+// at91_flash.c
+//
+// Flash programming for the at91 devices which have the
+// Embedded Flash Controller.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, dmoseley, Andrew Lunn, Oliver Munz, Kasim Malla
+// Date: 2009-06-03
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_at91.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include <string.h>
+
+/* timeout depends on the CPU clock speed */
+#define FLASH_TIMEOUT 100000
+#define AT91_FLASH_FMCN_VALUE \
+ (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 15 / 10000000 + 1)
+
+#ifdef CYGBLD_DEV_FLASH_AT91_LOCKING
+static cyg_uint32 sector_size;
+#endif
+
+// Disable the flash controller from erasing the page before
+// programming it
+
+#ifdef AT91_MC_FMR1
+ #define PAGE_AT_WHICH_WE_USE_THE_EFC1 1024
+ #define SECTOR_AT_WHICH_WE_USE_THE_EFC1 16
+#endif
+
+
+static void
+flash_erase_before_write_disable (void)
+{
+ cyg_uint32 fmr;
+
+ HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, fmr);
+ fmr = fmr | AT91_MC_FMR_NEBP;
+ HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, fmr);
+#ifdef AT91_MC_FMR1 /* or in other words at91sam7x512 */
+ HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR1, fmr);
+#endif
+}
+
+// Enable the flash controller to erase the page before programming
+// it
+static void
+flash_erase_before_write_enable (void)
+{
+
+ cyg_uint32 fmr;
+
+ HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, fmr);
+ fmr = fmr & ~((cyg_uint32) AT91_MC_FMR_NEBP);
+ HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, fmr);
+#ifdef AT91_MC_FMR1 /* or in other words at91sam7x512 */
+ HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR1, fmr);
+#endif
+}
+
+// Is the flash controller ready to accept the next command?
+static __inline__ cyg_bool
+flash_controller_is_ready(cyg_uint32 page)
+CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
+
+static __inline__ cyg_bool
+flash_controller_is_ready(cyg_uint32 page)
+{
+ cyg_uint32 fsr;
+#ifdef AT91_MC_FMR1
+ if (page >= PAGE_AT_WHICH_WE_USE_THE_EFC1){
+ HAL_READ_UINT32(AT91_MC+AT91_MC_FSR1, fsr);
+ } else
+#endif
+ HAL_READ_UINT32(AT91_MC+AT91_MC_FSR, fsr);
+
+ return (fsr & AT91_MC_FSR_FRDY ? true : false);
+}
+
+// Busy loop waiting for the controller to finish the command.
+// Wait a maximum of timeout loops and then return an error.
+static __inline__ int
+flash_wait_for_controller (cyg_uint32 page, cyg_uint32 timeout)
+CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
+
+static __inline__ int
+flash_wait_for_controller (cyg_uint32 page, cyg_uint32 timeout)
+{
+ while (!flash_controller_is_ready(page)){
+ timeout--;
+ if (!timeout) {
+ return FLASH_ERR_DRV_TIMEOUT;
+ }
+ }
+ return FLASH_ERR_OK;
+}
+
+// Execute one command on the flash controller. This code should
+// probably not be in flash
+
+static int
+flash_run_command(cyg_uint32 address,
+ cyg_uint32 command,
+ cyg_uint32 timeout)
+CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command");
+
+static int
+flash_run_command(cyg_uint32 address,
+ cyg_uint32 command,
+ cyg_uint32 timeout)
+{
+ cyg_uint32 retcode;
+ cyg_uint32 fsr;
+ cyg_uint32 mask;
+ cyg_uint32 page;
+ cyg_uint32 page_in_flash;
+ cyg_uint32 fcr_addr = AT91_MC+AT91_MC_FCR;
+ cyg_uint32 fsr_addr= AT91_MC+AT91_MC_FSR;
+
+ page = ((cyg_uint32) address - (cyg_uint32) flash_info.start) /
+ flash_info.block_size;
+ page_in_flash = page;
+
+#ifdef AT91_MC_FMR1
+ if (page >= PAGE_AT_WHICH_WE_USE_THE_EFC1){
+ fcr_addr = AT91_MC+AT91_MC_FCR1;
+ fsr_addr = AT91_MC+AT91_MC_FSR1;
+ page_in_flash = page - PAGE_AT_WHICH_WE_USE_THE_EFC1;
+ }
+#endif
+
+ // Wait for the last command to finish
+ retcode = flash_wait_for_controller(page, timeout);
+ if (retcode != FLASH_ERR_OK){
+ return retcode;
+ }
+
+ HAL_DISABLE_INTERRUPTS(mask);
+
+ HAL_WRITE_UINT32(fcr_addr,
+ command |
+ ((page_in_flash & AT91_MC_FCR_PAGE_MASK)
+ << AT91_MC_FCR_PAGE_SHIFT) |
+ AT91_MC_FCR_KEY);
+
+ retcode = flash_wait_for_controller(page, timeout);
+
+ HAL_RESTORE_INTERRUPTS(mask);
+
+ if (retcode != FLASH_ERR_OK){
+ return retcode;
+ }
+
+ // Check for an error
+ HAL_READ_UINT32(fsr_addr, fsr);
+
+ if ((fsr & AT91_MC_FSR_LOCKE) == AT91_MC_FSR_LOCKE)
+ return FLASH_ERR_PROTECT;
+ if ((fsr & AT91_MC_FSR_PROGE) == AT91_MC_FSR_PROGE)
+ return FLASH_ERR_PROGRAM;
+
+ return FLASH_ERR_OK;
+}
+
+// The flash is embedded in the CPU package. So return the chip
+// ID. This allows us to determine if the chip is one we support and
+// the size of the flash
+int flash_query(void *data)
+{
+ cyg_uint32 chipID1r;
+
+ HAL_READ_UINT32(AT91_DBG+AT91_DBG_C1R, chipID1r);
+
+ memcpy(data, &chipID1r, sizeof(chipID1r));
+ return FLASH_ERR_OK;
+}
+
+// Initialize the hardware. Make sure we have a flash device we know
+// how to program and determine its size, the size of the blocks, and
+// the number of blocks. The query function returns the chip ID 1
+// register which tells us about the CPU we are running on, the flash
+// size etc. Use this information to determine we have a valid setup.
+int
+flash_hwr_init(void){
+
+ cyg_uint32 chipID1r;
+ cyg_uint32 flash_mode;
+ cyg_uint32 lock_bits;
+
+ flash_query (&chipID1r);
+
+ if ((chipID1r & AT91_DBG_C1R_CPU_MASK) != AT91_DBG_C1R_ARM7TDMI)
+ goto out;
+
+ if (((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7Sxx) &&
+ ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7Xxx) &&
+ ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7XC) &&
+ ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7SExx))
+ goto out;
+
+ if ((chipID1r & AT91_DBG_C1R_FLASH_MASK) == AT91_DBG_C1R_FLASH_0K)
+ goto out;
+
+
+ if ((chipID1r & AT91_DBG_C1R_NVPTYP_MASK) != AT91_DBG_C1R_NVPTYP_ROMFLASH) {
+ switch (chipID1r & AT91_DBG_C1R_FLASH_MASK) {
+ case AT91_DBG_C1R_FLASH_32K:
+ flash_info.block_size = 128;
+ flash_info.blocks = 256;
+ lock_bits = 8;
+ break;
+ case AT91_DBG_C1R_FLASH_64K:
+ flash_info.block_size = 128;
+ flash_info.blocks = 512;
+ lock_bits = 16;
+ break;
+ case AT91_DBG_C1R_FLASH_128K:
+ flash_info.block_size = 256;
+ flash_info.blocks = 512;
+ lock_bits = 8;
+ break;
+ case AT91_DBG_C1R_FLASH_256K:
+ flash_info.block_size = 256;
+ flash_info.blocks = 1024;
+ lock_bits = 16;
+ break;
+ case AT91_DBG_C1R_FLASH_512K:
+ flash_info.block_size = 256;
+#ifdef AT91_MC_FMR1
+ flash_info.blocks = 2048;
+ lock_bits = 32;
+#else
+ flash_info.blocks = 1024;
+ lock_bits = 16;
+ (*flash_info.pf)
+ ("at91_flash: Only EFC0 is supported for writes and locks");
+#endif
+ break;
+ default:
+ goto out;
+ }
+ } else {
+ // if there is both flash & ROM then:
+ // ROM=AT91_DBG_C1R_FLASH, flash=AT91_DBG_C1R_FLASH2
+ switch (chipID1r & AT91_DBG_C1R_FLASH2_MASK) {
+ case AT91_DBG_C1R_FLASH2_32K:
+ flash_info.block_size = 128;
+ flash_info.blocks = 256;
+ lock_bits = 8;
+ break;
+ case AT91_DBG_C1R_FLASH2_64K:
+ flash_info.block_size = 128;
+ flash_info.blocks = 512;
+ lock_bits = 16;
+ break;
+ case AT91_DBG_C1R_FLASH2_128K:
+ flash_info.block_size = 256;
+ flash_info.blocks = 512;
+ lock_bits = 8;
+ break;
+ case AT91_DBG_C1R_FLASH2_256K:
+ flash_info.block_size = 256;
+ flash_info.blocks = 1024;
+ lock_bits = 16;
+ break;
+ case AT91_DBG_C1R_FLASH2_512K:
+ flash_info.block_size = 256;
+#ifdef AT91_MC_FMR1
+ flash_info.blocks = 2048;
+ lock_bits = 32;
+#else
+ flash_info.blocks = 1024;
+ lock_bits = 16;
+ (*flash_info.pf)
+ ("at91_flash: Only EFC0 is supported for writes and locks");
+#endif
+ break;
+ default:
+ goto out;
+ }
+ }
+ flash_info.buffer_size = 0;
+ flash_info.start = (void *) 0x00100000;
+ flash_info.end = (void *)(((cyg_uint32) flash_info.start) +
+ flash_info.block_size * flash_info.blocks);
+#ifdef CYGBLD_DEV_FLASH_AT91_LOCKING
+ sector_size = flash_info.block_size * flash_info.blocks / lock_bits;
+#endif
+ // Set the FLASH clock to 1.5 microseconds based on the MCLK. This
+ // assumes the CPU is still running from the PLL clock as defined in
+ // the HAL CDL and the HAL startup code.
+ HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, flash_mode);
+ flash_mode = flash_mode & ~AT91_MC_FMR_FMCN_MASK;
+ flash_mode = flash_mode | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT);
+ HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, flash_mode);
+#ifdef AT91_MC_FMR1
+ HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR1, flash_mode);
+#endif
+
+ return FLASH_ERR_OK;
+
+ out:
+ (*flash_info.pf)("Can't identify FLASH, sorry, ChipID1 %x\n",
+ chipID1r );
+ return FLASH_ERR_HWR;
+}
+
+// Erase a block. The flash controller does not have a command to
+// erase a block. So instead we setup the controller to do a program
+// writing all 0xff with an erase operation first.
+int
+flash_erase_block (volatile unsigned long block)
+{
+ cyg_uint32 retcode;
+ cyg_uint32 *buffer;
+ cyg_uint32 *end;
+
+ buffer = (cyg_uint32 *) block;
+ end = (cyg_uint32 *) (block + flash_info.block_size);
+
+ while (buffer < end){
+ *buffer = (cyg_uint32) 0xffffffff;
+ buffer++;
+ }
+
+ flash_erase_before_write_enable();
+ retcode = flash_run_command(block,
+ AT91_MC_FCR_START_PROG,
+ FLASH_TIMEOUT);
+
+ return retcode;
+}
+
+// Write into the flash. The datasheet says that performing 8 or 16bit
+// accesses results in unpredictable corruption. So the current code
+// checks that these conditions are upheld. It would be possible to
+// perform extra reads and masking operation to support writing to
+// none word assigned addresses or not multiple or a word length.
+int
+flash_program_buf (volatile unsigned long addr, unsigned long *data, int len)
+{
+ cyg_uint32 retcode;
+ volatile unsigned long *target;
+
+ CYG_ASSERT(len % 4 == 0, "Only word writes allowed by current code");
+ CYG_ASSERT(addr % 4 == 0, "Address must be word aligned for current code");
+
+ target = (volatile unsigned long *)addr;
+
+ while (len > 0) {
+ *target = *data;
+ data++;
+ target++;
+ len = len - sizeof(unsigned long);
+ }
+
+ flash_erase_before_write_disable();
+ retcode = flash_run_command(addr,
+ AT91_MC_FCR_START_PROG,
+ FLASH_TIMEOUT);
+
+ return retcode;
+}
+
+#ifdef CYGBLD_DEV_FLASH_AT91_LOCKING
+// Unlock a block. This is not strictly possible, we can only lock and
+// unlock sectors. This will unlock the sector which contains the
+// block.
+int
+flash_unlock_block(volatile unsigned long block, int block_size, int blocks)
+{
+ cyg_uint32 sector;
+ cyg_uint32 retcode;
+ cyg_uint32 status;
+ cyg_uint32 fsr_addr = AT91_MC + AT91_MC_FSR;
+
+ sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) /
+ sector_size;
+
+#ifdef AT91_MC_FMR1 /* or in other words at91sam7x512 */
+ if (sector >= SECTOR_AT_WHICH_WE_USE_THE_EFC1){
+ fsr_addr = AT91_MC + AT91_MC_FSR1;
+ sector -= SECTOR_AT_WHICH_WE_USE_THE_EFC1;
+ }
+#endif
+ HAL_READ_UINT32(fsr_addr, status);
+
+ if (status & (1 << (sector + 16))){
+ retcode = flash_run_command(block,
+ AT91_MC_FCR_UNLOCK,
+ FLASH_TIMEOUT);
+ return retcode;
+ } else {
+ return FLASH_ERR_OK;
+ }
+}
+
+// Lock a block. This is not strictly possible, we can only lock and
+// unlock sectors. This will lock the sector which contains the
+// block.
+int
+flash_lock_block(volatile unsigned long block, int block_size, int blocks)
+{
+ cyg_uint32 sector;
+ cyg_uint32 retcode;
+ cyg_uint32 status;
+ cyg_uint32 fsr_addr = AT91_MC + AT91_MC_FSR;
+
+ sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) /
+ sector_size;
+
+#ifdef AT91_MC_FMR1 /* or in other words at91sam7x512 */
+ if (sector >= SECTOR_AT_WHICH_WE_USE_THE_EFC1){
+ fsr_addr = AT91_MC + AT91_MC_FSR1;
+ sector -= SECTOR_AT_WHICH_WE_USE_THE_EFC1;
+ }
+#endif
+ HAL_READ_UINT32(fsr_addr, status);
+
+ if (!(status & (1 << (sector + 16)))){
+ retcode = flash_run_command(block,
+ AT91_MC_FCR_LOCK,
+ FLASH_TIMEOUT);
+
+ return retcode;
+ } else {
+ return FLASH_ERR_OK;
+ }
+}
+#endif /*CYGBLD_DEV_FLASH_AT91_LOCKING */
+
+// Map a hardware status to a package error. NOP since the errors are
+// already mapped.
+int flash_hwr_map_error(int err){
+
+ return err;
+}
+
+// See if a range of FLASH addresses overlaps currently running code
+bool flash_code_overlaps(void *start, void *end){
+
+ extern char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
diff --git a/ecos/packages/devs/flash/arm/cerf/current/ChangeLog b/ecos/packages/devs/flash/arm/cerf/current/ChangeLog
new file mode 100644
index 0000000..60c6f75
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/cerf/current/ChangeLog
@@ -0,0 +1,28 @@
+2002-02-04 Gary Thomas <gthomas@redhat.com>
+
+ * include/cerf_strataflash.inl:
+ * cdl/flash_cerf.cdl: New file(s) - port to Intrinsyc CerfCube.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/cerf/current/cdl/flash_cerf.cdl b/ecos/packages/devs/flash/arm/cerf/current/cdl/flash_cerf.cdl
new file mode 100644
index 0000000..84f49b0
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/cerf/current/cdl/flash_cerf.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_cerf.cdl
+#
+# FLASH memory - Hardware support on Intrinsyc CerfCube
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_CERF {
+ display "Intrinsyc SA1110 (Cerf) FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_SA11X0_CERF
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/cerf_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_cerf.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
+
diff --git a/ecos/packages/devs/flash/arm/cerf/current/include/cerf_strataflash.inl b/ecos/packages/devs/flash/arm/cerf/current/include/cerf_strataflash.inl
new file mode 100644
index 0000000..dee0216
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/cerf/current/include/cerf_strataflash.inl
@@ -0,0 +1,69 @@
+#ifndef CYGONCE_DEVS_FLASH_CERF_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_CERF_STRATAFLASH_INL
+//==========================================================================
+//
+// cerf_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+#include <cyg/hal/hal_sa11x0.h> // Hardware definitions
+#include <pkgconf/hal_arm_sa11x0_cerf.h> // Platform specifics
+
+
+// The cerf has one 16-bit device.
+// StrataFlash 28F128.
+
+#define CYGNUM_FLASH_DEVICES (1)
+#define CYGNUM_FLASH_BASE_MASK (0xFF000000u) // 16Mb
+
+#define CYGNUM_FLASH_BASE (0x50000000u)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_CERF_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF cerf_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/cerfpda/current/ChangeLog b/ecos/packages/devs/flash/arm/cerfpda/current/ChangeLog
new file mode 100644
index 0000000..756ee5e
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/cerfpda/current/ChangeLog
@@ -0,0 +1,28 @@
+2002-02-04 Gary Thomas <gthomas@redhat.com>
+
+ * include/cerfpda_strataflash.inl:
+ * cdl/flash_cerfpda.cdl: New file(s) - port to Intrinsyc CerfPDA.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/cerfpda/current/cdl/flash_cerfpda.cdl b/ecos/packages/devs/flash/arm/cerfpda/current/cdl/flash_cerfpda.cdl
new file mode 100644
index 0000000..9ce7725
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/cerfpda/current/cdl/flash_cerfpda.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_cerfpda.cdl
+#
+# FLASH memory - Hardware support on Intrinsyc CerfPDA
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_CERFPDA {
+ display "Intrinsyc cerfpda FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_SA11X0_CERFPDA
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/cerfpda_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_cerfpda.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
+
diff --git a/ecos/packages/devs/flash/arm/cerfpda/current/include/cerfpda_strataflash.inl b/ecos/packages/devs/flash/arm/cerfpda/current/include/cerfpda_strataflash.inl
new file mode 100644
index 0000000..97d8ef8
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/cerfpda/current/include/cerfpda_strataflash.inl
@@ -0,0 +1,68 @@
+#ifndef CYGONCE_DEVS_FLASH_CERFPDA_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_CERFPDA_STRATAFLASH_INL
+//==========================================================================
+//
+// cerfpda_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+#include <cyg/hal/hal_sa11x0.h> // Hardware definitions
+#include <pkgconf/hal_arm_sa11x0_cerfpda.h> // Platform specifics
+
+
+// The cerfpda has 2 16-bit device.
+// StrataFlash 28F128. 16Mbyte.
+
+#define CYGNUM_FLASH_DEVICES (2)
+#define CYGNUM_FLASH_BASE_MASK (0xFE000000u) // 32Mb
+#define CYGNUM_FLASH_BASE (0x50000000u)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_CERFPDA_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF cerfpda_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/e7t/current/ChangeLog b/ecos/packages/devs/flash/arm/e7t/current/ChangeLog
new file mode 100755
index 0000000..419c17b
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/e7t/current/ChangeLog
@@ -0,0 +1,44 @@
+2004-11-22 Bart Veer <bartv@ecoscentric.com>
+
+ * src/arm_e7t_flash.c: use updated CYG_FLASH_DRIVER() macro for
+ completely static initialization.
+
+2004-08-03 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/flash_e7t.cdl:
+ * src/arm_e7t_flash.c: Make use of the new sst driver which uses
+ the new flash driver API.
+
+2003-11-04 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/flash_e7t.cdl:
+ * src/arm_e7t_flash.c: Updates to use the new 39VFXXX generic driver.
+
+2003-07-03 Chris Garry <cgarry@sweeneydesign.co.uk>
+
+ * src/arm_e7t_flash.h:
+ * cdl/flash_e7t.cdl: New package/file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/e7t/current/cdl/flash_e7t.cdl b/ecos/packages/devs/flash/arm/e7t/current/cdl/flash_e7t.cdl
new file mode 100755
index 0000000..3979d8a
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/e7t/current/cdl/flash_e7t.cdl
@@ -0,0 +1,76 @@
+# ====================================================================
+#
+# flash_e7t.cdl
+#
+# FLASH memory - Hardware support on ARM Evatuator-7T
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Chris Garry <cgarry@sweeneydesign.co.uk>
+# Contributors:
+# Date: 2003-04-21
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_E7T {
+ display "ARM Evaluator-7T FLASH memory support"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_E7T
+ requires CYGHWR_IO_FLASH_DEVICE
+
+ compile -library=libextras.a arm_e7t_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_option CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED {
+ display "E7T has SST39VF400 FLASH part fitted"
+ default_value 0
+ requires !CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ description "This option enables the driver for SST39VF400 FLASH"
+ }
+
+ cdl_option CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "E7T has Am29LV400 FLASH part fitted"
+ default_value 0
+ requires !CYGINT_DEVS_FLASH_SST_39VF400_REQUIRED
+ description "this option enables the driver for AMD AM29LV400 FLASH"
+ }
+}
+
+# EOF flash_e7t.cdl
diff --git a/ecos/packages/devs/flash/arm/e7t/current/src/arm_e7t_flash.c b/ecos/packages/devs/flash/arm/e7t/current/src/arm_e7t_flash.c
new file mode 100755
index 0000000..6d40edd
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/e7t/current/src/arm_e7t_flash.c
@@ -0,0 +1,91 @@
+//==========================================================================
+//
+// arm_e7t_flash.c
+//
+// Flash programming for SST Flash device on ARM Evaluator-7T board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Chris Garry <cgarry@sweeneydesign.co.uk>
+// Contributors: andrew.lunn@ascom.ch
+// Date: 2003-04-21
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+#include <pkgconf/devs_flash_arm_e7t.h>
+
+
+// The Evaluator-7T has either one SST 39VF400A part or one Am29LV400B part
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x01800000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGPKG_DEVS_FLASH_SST_39VF400
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#ifdef CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED
+#include "cyg/io/flash_sst_39vfxxx.inl"
+
+static const cyg_flash_block_info_t cyg_flash_sst_block_info[1] = {
+ { FLASH_BLOCK_SIZE, FLASH_NUM_REGIONS * CYGNUM_FLASH_SERIES }
+};
+CYG_FLASH_DRIVER(cyg_flash_sst_flashdev,
+ &cyg_sst_funs,
+ 0, // Flags
+ CYGNUM_FLASH_BASE, // Start
+ CYGNUM_FLASH_BASE + (FLASH_BLOCK_SIZE * FLASH_NUM_REGIONS * CYGNUM_FLASH_SERIES) - 1, // End
+ 1, // Number of block infos
+ cyg_flash_sst_block_info,
+ NULL // priv
+ );
+#endif
+
+#ifdef CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+#include "cyg/io/flash_am29xxxxx.inl"
+#endif
+
+// ------------------------------------------------------------------------
+// EOF arm_e7t_flash.c
diff --git a/ecos/packages/devs/flash/arm/ea2468/current/ChangeLog b/ecos/packages/devs/flash/arm/ea2468/current/ChangeLog
new file mode 100755
index 0000000..2829784
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ea2468/current/ChangeLog
@@ -0,0 +1,34 @@
+2008-11-01 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/flash_ea2468.cdl: Added some constraints to force flash
+ entry size to <= 4096 bytes because the flash block size is 4096
+ bytes
+
+2008-07-08 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/flash_ea2468.c:
+ * cdl/flash_ea2468.cdl: New package/file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/ea2468/current/cdl/flash_ea2468.cdl b/ecos/packages/devs/flash/arm/ea2468/current/cdl/flash_ea2468.cdl
new file mode 100755
index 0000000..5e75464
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ea2468/current/cdl/flash_ea2468.cdl
@@ -0,0 +1,73 @@
+# ====================================================================
+#
+# flash_ea2468.cdl
+#
+# FLASH memory - Hardware support on EA LPC2468 OEM board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors:
+# Date: 2008-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_EA2468 {
+ display "EA LPC2468 OEM board FLASH memory support"
+ description "FLASH memory device support for Embedded Artists LPC2468 OEM board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_LPC24XX
+
+ compile -library=libextras.a flash_ea2468.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED {
+ display "Generic SST 39VFXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED
+ requires !CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG
+ requires CYGNUM_REDBOOT_FLASH_CONFIG_SIZE <= 4096
+ requires {(CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE *
+ CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT) <= 4096}
+}
+
+# EOF flash_ea2468.cdl
diff --git a/ecos/packages/devs/flash/arm/ea2468/current/src/flash_ea2468.c b/ecos/packages/devs/flash/arm/ea2468/current/src/flash_ea2468.c
new file mode 100755
index 0000000..0443995
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ea2468/current/src/flash_ea2468.c
@@ -0,0 +1,73 @@
+//==========================================================================
+//
+// flash_ea2468.c
+//
+// Flash programming for SST Flash device on EA LPC2468 OEM board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors:
+// Date: 2008-07-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+#include <pkgconf/devs_flash_ea2468.h>
+
+
+// The EA LPC2468 OEM board has one SST 39VF3201 part
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x80000000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGPKG_DEVS_FLASH_SST_39VF3201
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_sst_39vfxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF flash_ea2468.c
diff --git a/ecos/packages/devs/flash/arm/eb40/current/ChangeLog b/ecos/packages/devs/flash/arm/eb40/current/ChangeLog
new file mode 100644
index 0000000..6e6e23e
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb40/current/ChangeLog
@@ -0,0 +1,28 @@
+2003-07-30 Thomas Koeller <thomas.koeller@baslerweb.com>
+
+ * devs/flash/arm/eb40/...: new package. FLASH memory support for
+ Atmel EB40 board. Created from EB40A code by Tim Drury.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/eb40/current/cdl/flash_eb40.cdl b/ecos/packages/devs/flash/arm/eb40/current/cdl/flash_eb40.cdl
new file mode 100644
index 0000000..37d9a47
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb40/current/cdl/flash_eb40.cdl
@@ -0,0 +1,69 @@
+# ====================================================================
+#
+# flash_eb40.cdl
+#
+# FLASH memory - Hardware support on Atmel ARM EB40 board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov, tdrury, nickg
+# Original data: gthomas
+# Contributors: gthomas, tkoeller
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_EB40 {
+ display "Atmel EB40 board FLASH memory support"
+ description "FLASH memory device support for Atmel EB40 board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_AT91
+ requires CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX
+
+ compile eb40_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED {
+ display "Generic Atmel AT29CXXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED
+}
diff --git a/ecos/packages/devs/flash/arm/eb40/current/src/eb40_flash.c b/ecos/packages/devs/flash/arm/eb40/current/src/eb40_flash.c
new file mode 100644
index 0000000..c44e82d
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb40/current/src/eb40_flash.c
@@ -0,0 +1,64 @@
+//==========================================================================
+//
+// eb40_flash.c
+//
+// Flash programming for Atmel device on Atmel EB40 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, tdrury
+// Contributors: jskov, nickg, tkoeller
+// Date: 2002-07-08
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// The EB40 is equipped with one single AT29LV1024 flash chip.
+
+#define CYGPKG_DEVS_FLASH_ATMEL_AT29LV1024
+#define CYGNUM_FLASH_INTERLEAVE 1
+#define CYGNUM_FLASH_SERIES 1
+#define CYGNUM_FLASH_BASE 0x01000000
+
+#include "cyg/io/flash_at29cxxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF eb40_flash.c
diff --git a/ecos/packages/devs/flash/arm/eb40a/current/ChangeLog b/ecos/packages/devs/flash/arm/eb40a/current/ChangeLog
new file mode 100644
index 0000000..55f658d
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb40a/current/ChangeLog
@@ -0,0 +1,42 @@
+2004-11-12 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/flash_eb40a.cdl: Enable the hardware bug workaround in the
+ flash driver.
+
+2003-07-15 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/eb40a_flash.c: Generic Atmel driver now supports boot blocks.
+ Other tweaks for the generic Atmel driver changes.
+
+2002-07-08 Tim Drury <tdrury@siliconmotorsports.com>
+
+ * devs/flash/arm/eb40a/...: new package. FLASH memory support for
+ Atmel EB40a board.
+
+ * include/arm_eb40a_flash.inl: New file
+
+ * cdl/flash_eb40a_pid.cdl: New file.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/eb40a/current/cdl/flash_eb40a.cdl b/ecos/packages/devs/flash/arm/eb40a/current/cdl/flash_eb40a.cdl
new file mode 100644
index 0000000..aa7309e
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb40a/current/cdl/flash_eb40a.cdl
@@ -0,0 +1,69 @@
+# ====================================================================
+#
+# flash_eb40a.cdl
+#
+# FLASH memory - Hardware support on Atmel ARM EB40a board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov, tdrury, nickg
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_EB40A {
+ display "Atmel EB40A board FLASH memory support"
+ description "FLASH memory device support for Atmel EB40A board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_AT91
+ requires CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND
+
+ compile eb40a_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED {
+ display "Generic Atmel AM49XXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED
+}
diff --git a/ecos/packages/devs/flash/arm/eb40a/current/src/eb40a_flash.c b/ecos/packages/devs/flash/arm/eb40a/current/src/eb40a_flash.c
new file mode 100644
index 0000000..8d85cf0
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb40a/current/src/eb40a_flash.c
@@ -0,0 +1,66 @@
+//==========================================================================
+//
+// eb40a_flash.c
+//
+// Flash programming for Atmel device on Atmel EB40A board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, tdrury
+// Contributors: jskov, nickg
+// Date: 2002-07-08
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// The EB40 can either contain a AT49LV1604 or a AT49LV1614. For now we just
+// treat both as a 1614.
+
+#define CYGHWR_DEVS_FLASH_ATMEL_AT49LV1614A
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0x01000000u)
+
+#include "cyg/io/flash_at49xxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF eb40a_flash.c
diff --git a/ecos/packages/devs/flash/arm/eb42/current/ChangeLog b/ecos/packages/devs/flash/arm/eb42/current/ChangeLog
new file mode 100644
index 0000000..4acf839
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb42/current/ChangeLog
@@ -0,0 +1,39 @@
+2004-11-12 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/flash_eb42.cdl: Enable the bug workaround for the flash
+ device.
+
+2003-07-15 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/eb42_flash.c: Generic Atmel driver now supports boot blocks.
+ Other tweaks for the generic Atmel driver changes.
+
+2003-05-12 Nick Garnett <nickg@balti.calivar.com>
+
+ * cdl/flash_eb42.cdl:
+ * src/eb42_flash.c:
+ Added Flash driver for Atmel EB42 board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/eb42/current/cdl/flash_eb42.cdl b/ecos/packages/devs/flash/arm/eb42/current/cdl/flash_eb42.cdl
new file mode 100644
index 0000000..fac1de4
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb42/current/cdl/flash_eb42.cdl
@@ -0,0 +1,69 @@
+# ====================================================================
+#
+# flash_eb42.cdl
+#
+# FLASH memory - Hardware support on Atmel ARM EB42 board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov, tdrury, nickg
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_EB42 {
+ display "Atmel EB42 board FLASH memory support"
+ description "FLASH memory device support for Atmel EB42 board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_AT91
+ requires CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND
+
+ compile eb42_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED {
+ display "Generic Atmel AM49XXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED
+}
diff --git a/ecos/packages/devs/flash/arm/eb42/current/src/eb42_flash.c b/ecos/packages/devs/flash/arm/eb42/current/src/eb42_flash.c
new file mode 100644
index 0000000..bfcb551
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb42/current/src/eb42_flash.c
@@ -0,0 +1,65 @@
+//==========================================================================
+//
+// eb42_flash.c
+//
+// Flash programming for Atmel device on Atmel EB42 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, tdrury
+// Contributors: jskov, nickg
+// Date: 2002-07-08
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// There's a single AT49LV16X4 on the EB42 board.
+
+#define CYGHWR_DEVS_FLASH_ATMEL_AT49LV1614A
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0x01000000u)
+
+#include "cyg/io/flash_at49xxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF eb42_flash.c
diff --git a/ecos/packages/devs/flash/arm/eb55/current/ChangeLog b/ecos/packages/devs/flash/arm/eb55/current/ChangeLog
new file mode 100644
index 0000000..73511c5
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb55/current/ChangeLog
@@ -0,0 +1,53 @@
+2009-02-12 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/eb55_flash.c: Fix linkage problems in reference to SPI
+ device for dataflash.
+
+2005-08-08 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/eb55_flash.c: Removed unnecessary external reference.
+
+2005-08-04 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/flash_eb55.cdl:
+ * src/eb55_flash.c: Added configuration for dataflash driver.
+
+2004-11-12 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/flash_eb55.cdl: Enable the hardware bug workaround in the
+ generic flash driver
+
+2003-07-15 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/eb55_flash.c: Generic Atmel driver now supports boot blocks.
+ Other tweaks for the generic Atmel driver changes.
+
+2003-05-12 Nick Garnett <nickg@balti.calivar.com>
+
+ * src/eb55_flash.c:
+ * cdl/flash_eb55.cdl:
+ Added Flash driver for Atmel EB55 board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/eb55/current/cdl/flash_eb55.cdl b/ecos/packages/devs/flash/arm/eb55/current/cdl/flash_eb55.cdl
new file mode 100644
index 0000000..0150a55
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb55/current/cdl/flash_eb55.cdl
@@ -0,0 +1,74 @@
+# ====================================================================
+#
+# flash_eb55.cdl
+#
+# FLASH memory - Hardware support on Atmel ARM EB55 board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov, tdrury, nickg
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_EB55 {
+ display "Atmel EB55 board FLASH memory support"
+ description "FLASH memory device support for Atmel EB55 board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_AT91
+ requires CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND
+
+ compile eb55_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED {
+ display "Generic Atmel AM49XXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED
+
+ implements CYGPKG_DEVS_FLASH_ATMEL_DATAFLASH_FLASH_DEV
+
+}
+
+# EOF flash_eb55.cdl
diff --git a/ecos/packages/devs/flash/arm/eb55/current/src/eb55_flash.c b/ecos/packages/devs/flash/arm/eb55/current/src/eb55_flash.c
new file mode 100644
index 0000000..b58faf8
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/eb55/current/src/eb55_flash.c
@@ -0,0 +1,85 @@
+//==========================================================================
+//
+// eb55_flash.c
+//
+// Flash programming for Atmel device on Atmel EB55 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, tdrury
+// Contributors: jskov, nickg,jlarmour
+// Date: 2002-07-08
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// There's a single AT49BV1604A on the EB55 board.
+
+#define CYGHWR_DEVS_FLASH_ATMEL_AT49BV1604A
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0x01000000u)
+
+#include "cyg/io/flash_at49xxxx.inl"
+
+// ------------------------------------------------------------------------
+// There is also an AT45DB321B DataFlash on the SPI bus
+
+#include <pkgconf/system.h>
+
+#if defined(CYGPKG_IO_SPI) && defined(CYGPKG_DEVS_FLASH_ATMEL_DATAFLASH)
+
+#include <cyg/io/spi.h>
+#include <cyg/io/spi_at91.h>
+#include <cyg/io/dataflash.h>
+
+__externC cyg_spi_at91_device_t spi_dataflash_dev0;
+
+CYG_DATAFLASH_FLASH_DRIVER( cyg_eb55_dataflash,
+ &spi_dataflash_dev0,
+ 0x08000000,
+ 0,
+ 16 );
+
+#endif
+
+// ------------------------------------------------------------------------
+// EOF eb55_flash.c
diff --git a/ecos/packages/devs/flash/arm/ebsa285/current/ChangeLog b/ecos/packages/devs/flash/arm/ebsa285/current/ChangeLog
new file mode 100644
index 0000000..7816d94
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ebsa285/current/ChangeLog
@@ -0,0 +1,99 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/ebsa285_flash.c:
+ Explicitly include <cyg/io/flash_dev.h> rather than just
+ defining _FLASH_PRIVATE_. (From bartv in flash_v2 branch)
+
+ * cdl/flash_ebsa285.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2003-09-14 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash_query.c (flash_query): Casts to stop warnings.
+ * src/flash_program_buf.c (flash_program_buf): Fixed compiler warning.
+ * src/ebsa285_flash.c: include diag.h header file to stop warning.
+
+2003-09-12 Jani Monoses <jani@iv.ro>
+
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf): Put flash functions
+ in RAM using section attributes instead of the old method.
+ * src/ebsa285_flash.c (flash_hwr_init): Use generic flash_query_dev.
+
+2003-04-03 Jani Monoses <jani@iv.ro>
+
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf):
+ Cache enabling and disabling are already handled by generic flash
+
+2001-09-28 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/ebsa285_flash.c (flash_hwr_init): Only re-enable icache if it
+ was enabled before.
+
+2001-07-11 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash.h:
+ * src/ebsa285_flash.c (flash_hwr_init): Support new device 28F008SC.
+
+2001-06-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/ebsa285_flash.c: Remove dependency on printf() via user functions.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_ebsa285.cdl: Needs IO controller to copy functions to
+ RAM.
+
+2000-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/ebsa285_flash.c (flash_code_overlaps): Define stext/etext
+ as array types so no assumptions can be made by the compiler about
+ location.
+
+2000-08-29 Gary Thomas <gthomas@redhat.com>
+
+ * src/ebsa285_flash.c: Improve error decoding.
+
+2000-08-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/ebsa285_flash.c (flash_hwr_init): Add
+ HAL_ICACHE_DISABLE/ENABLE pairs around calls to RAM copy of query
+ function - this is necessary to get reliable operation on EBSA285
+ and similar. Otherwise, what is in the instruction cache might be
+ run instead.
+
+2000-08-15 Gary Thomas <gthomas@redhat.com>
+
+ * src/ebsa285_flash.c (flash_code_overlaps):
+ stext,etext now are _stext,_etext
+
+2000-08-14 Gary Thomas <gthomas@redhat.com>
+
+ * src/ebsa285_flash.c: New file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/ebsa285/current/cdl/flash_ebsa285.cdl b/ecos/packages/devs/flash/arm/ebsa285/current/cdl/flash_ebsa285.cdl
new file mode 100644
index 0000000..1cb77f6
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ebsa285/current/cdl/flash_ebsa285.cdl
@@ -0,0 +1,67 @@
+# ====================================================================
+#
+# flash_ebsa285.cdl
+#
+# FLASH memory - Hardware support on StrongARM EBSA-285
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_EBSA285 {
+ display "StrongARM EBSA-285 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_EBSA285
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "FLASH memory device support for StrongARM EBSA-285"
+ compile ebsa285_flash.c flash_query.c flash_erase_block.c flash_program_buf.c
+
+}
+
diff --git a/ecos/packages/devs/flash/arm/ebsa285/current/src/ebsa285_flash.c b/ecos/packages/devs/flash/arm/ebsa285/current/src/ebsa285_flash.c
new file mode 100644
index 0000000..d34d631
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ebsa285/current/src/ebsa285_flash.c
@@ -0,0 +1,112 @@
+//==========================================================================
+//
+// ebsa285_flash.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include "flash.h"
+
+int
+flash_hwr_init(void)
+{
+ unsigned char data[96];
+ int num_regions, region_size;
+
+ flash_dev_query(&data);
+
+ if ((data[0] == FLASH_Intel_code) && ((data[4] == FLASH_28F008SA) ||
+ (data[4] == FLASH_28F008SC))) {
+ num_regions = 16;
+ region_size = 0x40000;
+ flash_info.block_size = region_size;
+ flash_info.blocks = num_regions;
+ flash_info.start = (void *)0x41000000;
+ flash_info.end = (void *)(0x41000000+(num_regions*region_size));
+ return FLASH_ERR_OK;
+ } else {
+ (*flash_info.pf)("Can't identify FLASH, sorry\n");
+ diag_dump_buf(data, sizeof(data));
+ return FLASH_ERR_HWR;
+ }
+}
+
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int err)
+{
+ if (err & 0x7E) {
+ if (err & 0x10) {
+ return FLASH_ERR_PROGRAM;
+ } else
+ if (err & 0x20) {
+ return FLASH_ERR_ERASE;
+ } else
+ return FLASH_ERR_HWR; // FIXME
+ } else {
+ return FLASH_ERR_OK;
+ }
+}
+
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
diff --git a/ecos/packages/devs/flash/arm/ebsa285/current/src/flash.h b/ecos/packages/devs/flash/arm/ebsa285/current/src/flash.h
new file mode 100644
index 0000000..d67d254
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ebsa285/current/src/flash.h
@@ -0,0 +1,73 @@
+//==========================================================================
+//
+// flash.h
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef _FLASH_HWR_H_
+#define _FLASH_HWR_H_
+
+// EBSA-285 FLASH layout
+// 4x 28F008SA, one device per byte-lane
+// each device is 16x64k blocks
+
+#define FLASH_Read_ID 0x90909090
+#define FLASH_Read_Status 0x70707070
+#define FLASH_Clear_Status 0x50505050
+#define FLASH_Status_Ready 0x80808080
+#define FLASH_Program 0x10101010
+#define FLASH_Block_Erase 0x20202020
+#define FLASH_Confirm 0xD0D0D0D0
+#define FLASH_Reset 0xFFFFFFFF
+
+#define FLASH_BLOCK_SIZE 0x40000
+
+#define FLASH_Intel_code 0x89
+#define FLASH_28F008SA 0xA2
+#define FLASH_28F008SC 0xA6
+#endif // _FLASH_HWR_H_
diff --git a/ecos/packages/devs/flash/arm/ebsa285/current/src/flash_erase_block.c b/ecos/packages/devs/flash/arm/ebsa285/current/src/flash_erase_block.c
new file mode 100644
index 0000000..37518fe
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ebsa285/current/src/flash_erase_block.c
@@ -0,0 +1,80 @@
+//==========================================================================
+//
+// flash_erase_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+int
+flash_erase_block(volatile unsigned long *block)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int
+flash_erase_block(volatile unsigned long *block)
+{
+ unsigned long stat;
+ int timeout = 5000000;
+
+ // Clear any error conditions
+ *block = FLASH_Clear_Status;
+
+ // Set to erase
+ *block = FLASH_Block_Erase;
+ *block = FLASH_Confirm;
+ while(((stat = *block) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore ROM to "normal" mode
+ *block = FLASH_Reset;
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/arm/ebsa285/current/src/flash_program_buf.c b/ecos/packages/devs/flash/arm/ebsa285/current/src/flash_program_buf.c
new file mode 100644
index 0000000..6479748
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ebsa285/current/src/flash_program_buf.c
@@ -0,0 +1,89 @@
+//==========================================================================
+//
+// flash_program_buf.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+
+int
+flash_program_buf(volatile unsigned long *addr, unsigned long *data, int len)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+int
+flash_program_buf(volatile unsigned long *addr, unsigned long *data, int len)
+{
+ unsigned long stat=0;
+ int timeout = 5000000;
+ volatile unsigned long *orig_addr = addr;
+
+ // Clear any error conditions
+ *addr = FLASH_Clear_Status;
+
+ while (len > 0) {
+ *addr = FLASH_Program;
+ *addr = *data++;
+ timeout = 5000000;
+ while(((stat = *addr) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ goto bad;
+ }
+ }
+ addr++;
+ len -= sizeof(unsigned long);
+ }
+
+ // Restore ROM to "normal" mode
+ bad:
+ *orig_addr = FLASH_Reset;
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/arm/ebsa285/current/src/flash_query.c b/ecos/packages/devs/flash/arm/ebsa285/current/src/flash_query.c
new file mode 100644
index 0000000..fcd78c6
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ebsa285/current/src/flash_query.c
@@ -0,0 +1,81 @@
+//==========================================================================
+//
+// flash_query.c
+//
+// Flash programming - query device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+
+#define CNT 20*1000*10 // Approx 200ms
+
+int
+flash_query(unsigned char *data)
+ __attribute__ ((section (".2ram.flash_query")));
+int
+flash_query(unsigned char *data)
+{
+ volatile unsigned long *lROM;
+ volatile unsigned char *cROM;
+ int i, cnt;
+
+ lROM = (unsigned long *)0x41000000;
+ cROM = (unsigned char *)0x41000000;
+
+ lROM[0] = FLASH_Read_ID;
+ for (cnt = CNT; cnt > 0; cnt--) ;
+ for (i = 0; i < 8; i++) {
+ *data++ = cROM[i];
+ }
+ lROM[0] = FLASH_Reset;
+
+ return 0;
+}
diff --git a/ecos/packages/devs/flash/arm/edb7xxx/current/ChangeLog b/ecos/packages/devs/flash/arm/edb7xxx/current/ChangeLog
new file mode 100644
index 0000000..a689741
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/edb7xxx/current/ChangeLog
@@ -0,0 +1,95 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/edb7xxx_flash.c:
+ Explicitly include <cyg/io/flash_dev.h> rather than just
+ defining _FLASH_PRIVATE_. (From bartv in flash_v2 branch)
+
+ * cdl/flash_edb7xxx.cdl (CYGPKG_DEVS_FLASH_EP72XX): Indicate that
+ this part of the driver (i.e. not EDB7312) uses the legacy flash
+ device API.
+
+2003-11-20 Jani Monoses <jani@iv.ro>
+
+ * cdl/flash_edb7xxx.cdl:
+ * src/edb7xxx_flash.c.c:
+ * src/flash_query.c:
+ * src/flash_erase_block.c:
+ * src/flash_program_buf.c: Place flash functions in RAM sections
+ and no longer implement CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM. Use
+ generic flash_dev_query().
+
+2001-10-14 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/flash_edb7xxx.cdl: Missed change in include file location
+ for StrataFLASH changes.
+
+2001-10-12 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/flash_edb7xxx.cdl: Move EP72xx flash into separate subcomponent.
+ Clarify package description strings.
+ Move EP73xx strataflash support into here as another subcomponent.
+
+ * cdl/flash_strata_edb7xxx.cdl: Delete.
+
+2001-09-25 Gary Thomas <gthomas@redhat.com>
+
+ * include/edb7xxx_strataflash.inl:
+ * cdl/flash_strata_edb7xxx.cdl: New setup for EDB7312 which uses
+ Intel StrataFlash devices.
+
+2001-06-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/edb7xxx_flash.c: Remove dependency on printf() via user functions.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_edb7xxx.cdl: Needs IO controller to copy functions to
+ RAM.
+
+2000-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/edb7xxx_flash.c (flash_code_overlaps): Define stext/etext
+ as array types so no assumptions can be made by the compiler about
+ location.
+
+2000-12-04 Gary Thomas <gthomas@redhat.com>
+
+ * src/edb7xxx_flash.c (flash_hwr_init): Additional debugging
+ (*flash_info.pf) statments - in case this stuff fails in the future.
+
+2000-11-21 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_query.c: Increase startup timing - didn't always work.
+
+2000-08-29 Gary Thomas <gthomas@redhat.com>
+
+ * src/edb7xxx_flash.c: Improve error decoding.
+
+2000-08-15 Gary Thomas <gthomas@redhat.com>
+
+ * src/edb7xxx_flash.c (flash_code_overlaps):
+ stext,etext now are _stext,_etext
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/edb7xxx/current/cdl/flash_edb7xxx.cdl b/ecos/packages/devs/flash/arm/edb7xxx/current/cdl/flash_edb7xxx.cdl
new file mode 100644
index 0000000..e907542
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/edb7xxx/current/cdl/flash_edb7xxx.cdl
@@ -0,0 +1,101 @@
+# ====================================================================
+#
+# flash_edb7xxx.cdl
+#
+# FLASH memory - Hardware support on Cirrus Logic EDB7xxx
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_EDB7XXX {
+ display "FLASH support for Cirrus Logic EP7xxx based boards"
+ description "FLASH memory device support for Cirrus Logic EP7xxx based
+ development boards"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_EDB7XXX
+ include_dir cyg/io
+
+ cdl_component CYGPKG_DEVS_FLASH_EP72XX {
+ display "Cirrus Logic EP72xx based boards"
+ description "FLASH memory device support for EP72xx based boards
+ specifically"
+ active_if { CYGHWR_HAL_ARM_EDB7XXX_BOARD_VARIANT != "EDB7312" }
+ calculated 1
+ no_define
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ compile edb7xxx_flash.c flash_query.c flash_program_buf.c flash_erase_block.c
+
+ }
+ cdl_component CYGPKG_DEVS_FLASH_STRATA_EDB7XXX {
+ display "Cirrus Logic EDB7xxx StrataFLASH memory support"
+ description "FLASH memory device support for Cirrus Logic EP73xx"
+
+ # Note: currently only available on 7312 boards
+ active_if { CYGHWR_HAL_ARM_EDB7XXX_BOARD_VARIANT == "EDB7312" }
+ requires CYGPKG_DEVS_FLASH_STRATA
+ calculated 1
+ no_define
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/edb7xxx_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_edb7xxx.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+ }
+}
diff --git a/ecos/packages/devs/flash/arm/edb7xxx/current/include/edb7xxx_strataflash.inl b/ecos/packages/devs/flash/arm/edb7xxx/current/include/edb7xxx_strataflash.inl
new file mode 100644
index 0000000..42d3bf0
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/edb7xxx/current/include/edb7xxx_strataflash.inl
@@ -0,0 +1,65 @@
+#ifndef CYGONCE_DEVS_FLASH_EDB7XXX_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_EDB7XXX_STRATAFLASH_INL
+//==========================================================================
+//
+// edb7xxx_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2001-09-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// The edb7xxx system has one 16-bit device.
+
+#define CYGNUM_FLASH_DEVICES (1)
+#define CYGNUM_FLASH_BASE (0xE0000000u)
+#define CYGNUM_FLASH_BASE_MASK (0xFE000000u) // 32Mb devices
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_EDB7XXX_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF edb7xxx_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/edb7xxx/current/src/edb7xxx_flash.c b/ecos/packages/devs/flash/arm/edb7xxx/current/src/edb7xxx_flash.c
new file mode 100644
index 0000000..3183991
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/edb7xxx/current/src/edb7xxx_flash.c
@@ -0,0 +1,169 @@
+//==========================================================================
+//
+// edb7xxx_flash.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include "flash.h"
+
+#define _si(p) ((p[0]<<8)|p[1])
+
+int
+flash_hwr_init(void)
+{
+ unsigned short data[4];
+ int num_regions, region_size;
+
+#if 0
+ {
+ volatile int cache_test;
+ volatile int *cp = 0xE0000000;
+ // See if the data cache is working
+ *cp = 0x12345678;
+ (*flash_info.pf)("ROM cache:\n");
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_DISABLE();
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ *cp = 0xDEADDEAD;
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ HAL_DCACHE_ENABLE();
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ cp = 0x00100000;
+ // See if the data cache is working
+ *cp = 0x12345678;
+ (*flash_info.pf)("RAM cache:\n");
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ HAL_DCACHE_DISABLE();
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ *cp = 0xDEADDEAD;
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ HAL_DCACHE_ENABLE();
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ }
+#endif
+
+ flash_dev_query(data);
+#if 0
+ dump_buf(data, sizeof(data));
+#endif
+
+#if 0
+ {
+ volatile int cache_test;
+ volatile int *cp = 0xE0000000;
+ // See if the data cache is working
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ *cp = 0x56781234;
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_DCACHE_DISABLE();
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ *cp = 0xDEADDEAD;
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ HAL_DCACHE_ENABLE();
+ (*flash_info.pf)("cache test = %x\n", *cp);
+ }
+#endif
+
+ if (data[0] != FLASH_Intel_code) {
+ (*flash_info.pf)("Not Intel = %x\n", data[0]);
+ return FLASH_ERR_HWR;
+ }
+
+ if (data[1] == (unsigned short)0x8897) {
+ num_regions = 64*2;
+ region_size = 0x20000;
+ } else {
+ (*flash_info.pf)("Unknown device type: %x\n", data[1]);
+ return FLASH_ERR_HWR;
+ }
+
+ // Hard wired for now
+ flash_info.block_size = region_size;
+ flash_info.blocks = num_regions;
+ flash_info.start = (void *)0xE0000000;
+ flash_info.end = (void *)(0xE0000000+(num_regions*region_size));
+ return FLASH_ERR_OK;
+}
+
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int err)
+{
+ if (err & 0x007E007E) {
+ (*flash_info.pf)("Err = %x\n", err);
+ if (err & 0x00100010) {
+ return FLASH_ERR_PROGRAM;
+ } else
+ if (err & 0x00200020) {
+ return FLASH_ERR_ERASE;
+ } else
+ return FLASH_ERR_HWR; // FIXME
+ } else {
+ return FLASH_ERR_OK;
+ }
+}
+
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
diff --git a/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash.h b/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash.h
new file mode 100644
index 0000000..8753959
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash.h
@@ -0,0 +1,69 @@
+//==========================================================================
+//
+// flash.h
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef _FLASH_HWR_H_
+#define _FLASH_HWR_H_
+
+#define FLASH_Read_ID 0x90909090
+#define FLASH_Read_Status 0x00700070
+#define FLASH_Clear_Status 0x50505050
+#define FLASH_Status_Ready 0x00800080 // Only low 8 bits
+#define FLASH_Program 0x40404040
+#define FLASH_Block_Erase 0x20202020
+#define FLASH_Confirm 0xD0D0D0D0
+#define FLASH_Reset 0xFFFFFFFF
+
+#define FLASH_BLOCK_SIZE 0x20000
+#define FLASH_BOOT_BLOCK_SIZE 0x4000
+
+#define FLASH_Intel_code 0x89
+
+#endif // _FLASH_HWR_H_
diff --git a/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_erase_block.c b/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_erase_block.c
new file mode 100644
index 0000000..5acf7d1
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_erase_block.c
@@ -0,0 +1,107 @@
+//==========================================================================
+//
+// flash_erase_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+int flash_erase_block(volatile unsigned long * block)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+
+int flash_erase_block(volatile unsigned long *block)
+{
+ volatile unsigned long *ROM, *sb;
+ unsigned long stat;
+ int timeout = 50000;
+ int len, block_size;
+
+ ROM = (volatile unsigned long *)((unsigned long)block & 0xFF800000);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ len = FLASH_BLOCK_SIZE;
+ if (((unsigned long)block - (unsigned long)ROM) < FLASH_BLOCK_SIZE) {
+ block_size = FLASH_BOOT_BLOCK_SIZE; // First 8 blocks are only 8Kx2 each
+ } else {
+ block_size = FLASH_BLOCK_SIZE;
+ }
+ sb = block;
+ while (len > 0) {
+ // Erase block
+ ROM[0] = FLASH_Block_Erase;
+ *block = FLASH_Confirm;
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ len -= block_size;
+ block += block_size / sizeof(*block);
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ // If an error was reported, see if the block erased anyway
+ if (stat & 0x007E007E) {
+ len = FLASH_BLOCK_SIZE;
+ block = sb;
+ while (len > 0) {
+ if (*block++ != 0xFFFFFFFF) break;
+ len -= sizeof(*block);
+ }
+ if (len == 0) stat = 0;
+ }
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_program_buf.c b/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_program_buf.c
new file mode 100644
index 0000000..b48ea63
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_program_buf.c
@@ -0,0 +1,97 @@
+//==========================================================================
+//
+// flash_program_buf.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+int flash_program_buf(volatile unsigned long* addr, unsigned long* data, int len)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+
+int
+flash_program_buf(volatile unsigned long *addr, unsigned long *data, int len)
+{
+ volatile unsigned long *ROM;
+ unsigned long stat = 0;
+ int timeout = 50000;
+
+ ROM = (volatile unsigned long *)((unsigned long)addr & 0xFF800000);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ while (len > 0) {
+ ROM[0] = FLASH_Program;
+ *addr = *data;
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ goto bad;
+ }
+ }
+ if (stat & 0x007E007E) {
+ break;
+ }
+ ROM[0] = FLASH_Reset;
+ if (*addr++ != *data++) {
+ stat = 0x99109910;
+ break;
+ }
+ len -= 4;
+ }
+
+ // Restore ROM to "normal" mode
+ bad:
+ ROM[0] = FLASH_Reset;
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_query.c b/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_query.c
new file mode 100644
index 0000000..b82227b
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/edb7xxx/current/src/flash_query.c
@@ -0,0 +1,79 @@
+//==========================================================================
+//
+// flash_query.c
+//
+// Flash programming - query device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+
+#define CNT 2000*1000*10 // At least 20ms
+
+int flash_query(unsigned short* data) __attribute__ ((section (".2ram.flash_query")));
+
+int
+flash_query(unsigned short *data)
+{
+ volatile unsigned long *ROM;
+ int cnt;
+
+ ROM = (volatile unsigned long *)0xE0000000;
+
+ ROM[0] = FLASH_Read_ID;
+ for (cnt = CNT; cnt > 0; cnt--) ;
+ *data++ = *ROM++; // Manufacturer code
+ *data++ = *ROM++; // Device identifier
+
+ ROM[0] = FLASH_Reset;
+
+ return 0;
+}
diff --git a/ecos/packages/devs/flash/arm/excalibur/current/ChangeLog b/ecos/packages/devs/flash/arm/excalibur/current/ChangeLog
new file mode 100644
index 0000000..2d3afa4
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/excalibur/current/ChangeLog
@@ -0,0 +1,39 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_excalibur.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2001-08-17 Jesper Skov <jskov@redhat.com>
+ [from branch]
+ * src/arm_excalibur_flash.c: Use all 4 flash parts.
+
+ * cdl/flash_excalibur.cdl: Fix typo.
+
+2001-08-10 Jesper Skov <jskov@redhat.com>
+
+ * Created.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/excalibur/current/cdl/flash_excalibur.cdl b/ecos/packages/devs/flash/arm/excalibur/current/cdl/flash_excalibur.cdl
new file mode 100644
index 0000000..e656341
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/excalibur/current/cdl/flash_excalibur.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_excalibur.cdl
+#
+# FLASH memory - Hardware support on Altera ARM9/Excalibur
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-08-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_EXCALIBUR {
+ display "Altera ARM9/Excalibur FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_ARM9_EXCALIBUR
+
+ compile arm_excalibur_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED {
+ display "Generic Intel FlashFile driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED
+
+ requires CYGHWR_DEVS_FLASH_INTEL_28F320C3
+}
diff --git a/ecos/packages/devs/flash/arm/excalibur/current/src/arm_excalibur_flash.c b/ecos/packages/devs/flash/arm/excalibur/current/src/arm_excalibur_flash.c
new file mode 100644
index 0000000..7d821d7
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/excalibur/current/src/arm_excalibur_flash.c
@@ -0,0 +1,71 @@
+//==========================================================================
+//
+// arm_excalibur_flash.c
+//
+// Flash programming for Intel FlashFile devices on ARM Excalibur board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-08-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/excalibur.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+// We use the four Intel 28F320C3 parts on the Excalibur board.
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (4)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (EXCALIBUR_FLASH_PHYS_BASE)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_28fxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF arm_excalibur_flash.c
diff --git a/ecos/packages/devs/flash/arm/flexanet/current/ChangeLog b/ecos/packages/devs/flash/arm/flexanet/current/ChangeLog
new file mode 100644
index 0000000..777a3e1
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/flexanet/current/ChangeLog
@@ -0,0 +1,27 @@
+2001-07-27 Jordi Colomer <jco@ict.es>
+
+ * Add SA11x0/Flexanet flash driver support
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/flexanet/current/cdl/flash_flexanet.cdl b/ecos/packages/devs/flash/arm/flexanet/current/cdl/flash_flexanet.cdl
new file mode 100644
index 0000000..4c483d0
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/flexanet/current/cdl/flash_flexanet.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_flexanet.cdl
+#
+# FLASH memory - Hardware support on Intel StrongARM SA1110
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_FLEXANET {
+ display "SA1110/Flexanet FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_SA11X0_FLEXANET
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/flexanet_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_flexanet.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
+
diff --git a/ecos/packages/devs/flash/arm/flexanet/current/include/flexanet_strataflash.inl b/ecos/packages/devs/flash/arm/flexanet/current/include/flexanet_strataflash.inl
new file mode 100644
index 0000000..957bb66
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/flexanet/current/include/flexanet_strataflash.inl
@@ -0,0 +1,67 @@
+#ifndef CYGONCE_DEVS_FLASH_FLEXANET_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_FLEXANET_STRATAFLASH_INL
+//==========================================================================
+//
+// flexanet_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// The flexanet system has two 16-bit devices.
+// Doc says: a StrataFlash 28F320J3A. The 320 means 32Mbit, so 4Mbyte.
+// Reality: a StrataFlash 28F640J3A. The 640 means 64Mbit, so 8Mbyte.
+
+#define CYGNUM_FLASH_DEVICES (2)
+#define CYGNUM_FLASH_BASE (0x50000000u)
+#define CYGNUM_FLASH_BASE_MASK (0xFE000000u) // 32Mb devices
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_FLEXANET_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF flexanet_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/gps4020/current/ChangeLog b/ecos/packages/devs/flash/arm/gps4020/current/ChangeLog
new file mode 100644
index 0000000..e1761b4
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/gps4020/current/ChangeLog
@@ -0,0 +1,28 @@
+2003-11-10 Gary Thomas <gary@mlbassoc.com>
+
+ * src/gps4020_flash.c:
+ * cdl/flash_gps4020.cdl: New package - flash driver for GPS-4020
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/gps4020/current/cdl/flash_gps4020.cdl b/ecos/packages/devs/flash/arm/gps4020/current/cdl/flash_gps4020.cdl
new file mode 100644
index 0000000..0b26a58
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/gps4020/current/cdl/flash_gps4020.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_gps4020.cdl
+#
+# FLASH memory - Hardware support on GPS4020 board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov, tdrury, nickg
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_GPS4020 {
+ display "GPS4020 board FLASH memory support"
+ description "FLASH memory device support for GPS4020 board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_GPS4020
+
+ compile gps4020_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED {
+ display "Generic Atmel AM49XXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED
+}
diff --git a/ecos/packages/devs/flash/arm/gps4020/current/src/gps4020_flash.c b/ecos/packages/devs/flash/arm/gps4020/current/src/gps4020_flash.c
new file mode 100644
index 0000000..781c657
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/gps4020/current/src/gps4020_flash.c
@@ -0,0 +1,66 @@
+//==========================================================================
+//
+// gps4020_flash.c
+//
+// Flash programming for Atmel device on GPS4020 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, tdrury
+// Contributors: jskov, nickg
+// Date: 2002-07-08
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// There's a single AT29LV200BB on the GPS4020 board.
+
+#define CYGHWR_DEVS_FLASH_ATMEL_AT29LV200BB
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0x60000000u)
+#define CYGNUM_FLASH_ID_MANUFACTURER (0x01)
+
+#include "cyg/io/flash_at49xxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF gps4020_flash.c
diff --git a/ecos/packages/devs/flash/arm/grg/current/ChangeLog b/ecos/packages/devs/flash/arm/grg/current/ChangeLog
new file mode 100644
index 0000000..686019d
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/grg/current/ChangeLog
@@ -0,0 +1,35 @@
+2004-09-02 Mark Salter <msalter@redhat.com>
+
+ * include/grg_strataflash.inl: Add little-endian support.
+
+2003-03-24 Mark Salter <msalter@redhat.com>
+
+ * cdl/flash_grg.cdl: Fix copyright notice.
+
+2003-02-07 Mark Salter <msalter@redhat.com>
+
+ * Initial checkin.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/grg/current/cdl/flash_grg.cdl b/ecos/packages/devs/flash/arm/grg/current/cdl/flash_grg.cdl
new file mode 100644
index 0000000..66faa79
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/grg/current/cdl/flash_grg.cdl
@@ -0,0 +1,77 @@
+# ====================================================================
+#
+# flash_grg.cdl
+#
+# FLASH memory - Hardware support on GRG board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):
+# Original data: msalter
+# Contributors:
+# Date: 2003-02-05
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_GRG {
+ display "GRG board FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_XSCALE_GRG
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** grg flash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/grg_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_grg.h>"
+ puts $::cdl_system_header "/***** GRG flash driver proc output end *****/"
+ }
+}
diff --git a/ecos/packages/devs/flash/arm/grg/current/include/grg_strataflash.inl b/ecos/packages/devs/flash/arm/grg/current/include/grg_strataflash.inl
new file mode 100644
index 0000000..12cd77b
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/grg/current/include/grg_strataflash.inl
@@ -0,0 +1,75 @@
+#ifndef CYGONCE_DEVS_FLASH_GRG_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_GRG_STRATAFLASH_INL
+//==========================================================================
+//
+// grg_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: msalter
+// Date: 2003-02-05
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// The grg has one 16-bit device.
+// StrataFlash 28F128.
+
+#define CYGNUM_FLASH_DEVICES (1)
+#define CYGNUM_FLASH_BASE_MASK (0xFF000000u) // 16Mb
+
+#define CYGNUM_FLASH_BASE (0x50000000u)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#include <pkgconf/hal.h> // for CYGHWR_HAL_ARM_BIGENDIAN
+
+// We have to do some address gymnastics in little-endian mode
+#ifndef CYGHWR_HAL_ARM_BIGENDIAN
+#define __INV(a) ((flash_t *)((unsigned)(a) ^ 0x2))
+#define CYGHWR_FLASH_WRITE_BUF(a,b) (*__INV(a) = *__INV(b))
+#define CYGHWR_FLASH_READ_QUERY(a) (*__INV(a))
+#endif
+
+#endif // CYGONCE_DEVS_FLASH_GRG_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF grg_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/innovator/current/ChangeLog b/ecos/packages/devs/flash/arm/innovator/current/ChangeLog
new file mode 100644
index 0000000..12ac0ae
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/innovator/current/ChangeLog
@@ -0,0 +1,34 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_innovator.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2003-02-05 Patrick Doyle <wpd@delcomsys.com>
+ * cdl/flash_innovator.cdl
+ * src/arm_innovator_flash.c: New package - support for Texas
+ Instruments Innovator board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/innovator/current/cdl/flash_innovator.cdl b/ecos/packages/devs/flash/arm/innovator/current/cdl/flash_innovator.cdl
new file mode 100644
index 0000000..483bb7d
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/innovator/current/cdl/flash_innovator.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_innovator.cdl
+#
+# FLASH memory - Hardware support on OMAP1510DC EVM
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Patrick Doyle <wpd@delcomsys.com>
+# Contributors: Patrick Doyle <wpd@delcomsys.com>
+# Date: 2002-11-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_INNOVATOR {
+ display "TI OMAP1510DC EVM FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_ARM9_INNOVATOR
+
+ compile arm_innovator_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic Intel FlashFile driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL323D
+}
diff --git a/ecos/packages/devs/flash/arm/innovator/current/src/arm_innovator_flash.c b/ecos/packages/devs/flash/arm/innovator/current/src/arm_innovator_flash.c
new file mode 100644
index 0000000..9679953
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/innovator/current/src/arm_innovator_flash.c
@@ -0,0 +1,71 @@
+//==========================================================================
+//
+// arm_innovator_flash.c
+//
+// Flash programming for AMD Flash devices on TI OMAP1510DC EVM board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Patrick Doyle <wpd@delcomsys.com>
+// Contributors: Patrick Doyle <wpd@delcomsys.com>
+// Date: 2002-11-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/innovator.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+// We use the one AMD Am29DL323D part on the Innovator.
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (INNOVATOR_FLASH_VIRT_BASE)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF arm_innovator_flash.c
diff --git a/ecos/packages/devs/flash/arm/integrator/current/ChangeLog b/ecos/packages/devs/flash/arm/integrator/current/ChangeLog
new file mode 100644
index 0000000..8a8f43a
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/integrator/current/ChangeLog
@@ -0,0 +1,50 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_integrator.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2002-03-06 Nick Garnett <nickg@redhat.com>
+
+ * cdl/flash_integrator.cdl: Converted to use generic 28Fxxx flash
+ driver.
+
+ * src/arm_integrator_flash.c:
+ This file added to parameterize generic FLASH driver. Also define
+ here CYGHWR_FLASH_WRITE_ENABLE() and CYGHWR_FLASH_WRITE_DISABLE()
+ to turn FLASH writing on and off.
+
+ * src/flash.h:
+ * src/flash_erase_block.c:
+ * src/flash_program_buf.c:
+ * src/flash_query.c:
+ Files removed. These are the old flash driver.
+
+2001-10-30 Philippe Robin <Philippe.Robin@arm.com>
+2001-10-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * Initial version of ARM Integrator flash driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/integrator/current/cdl/flash_integrator.cdl b/ecos/packages/devs/flash/arm/integrator/current/cdl/flash_integrator.cdl
new file mode 100644
index 0000000..40fb837
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/integrator/current/cdl/flash_integrator.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_integrator.cdl
+#
+# FLASH memory - Hardware support on ARM Integrator
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov, nickg
+# Contributors: jskov
+# Date: 2002-02-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_INTEGRATOR {
+ display "ARM Integrator FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_INTEGRATOR
+
+ compile arm_integrator_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED {
+ display "Generic Intel FlashFile driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED
+
+ requires CYGHWR_DEVS_FLASH_INTEL_28F320S3
+}
diff --git a/ecos/packages/devs/flash/arm/integrator/current/src/arm_integrator_flash.c b/ecos/packages/devs/flash/arm/integrator/current/src/arm_integrator_flash.c
new file mode 100644
index 0000000..951ea15
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/integrator/current/src/arm_integrator_flash.c
@@ -0,0 +1,105 @@
+//==========================================================================
+//
+// arm_integrator_flash.c
+//
+// Flash programming for Intel FlashFile devices on ARM Integrator board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-08-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+// We use the eight Intel 28F320S3 parts on the Integrator board.
+// These are arranged in a 2x4 grid, giving 32 bits wide by 32MB long.
+
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_SERIES (4)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x24000000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+#define CYGHWR_FLASH_WRITE_ENABLE() \
+ { \
+ volatile cyg_uint32 *ebi_csr1 = (volatile cyg_uint32 *)INTEGRATOR_EBI_CSR1; \
+ \
+ /* allow write access to EBI_CSR1 area (Flash) */ \
+ *ebi_csr1 |= INTEGRATOR_EBI_WRITE_ENABLE; \
+ \
+ if (!(*ebi_csr1 & INTEGRATOR_EBI_WRITE_ENABLE)) { \
+ *(volatile cyg_uint32 *)INTEGRATOR_EBI_LOCK = 0xA05F; \
+ *ebi_csr1 |= INTEGRATOR_EBI_WRITE_ENABLE; \
+ *(volatile cyg_uint32 *)INTEGRATOR_EBI_LOCK = 0; \
+ } \
+ \
+ /* Enable Vpp and allow write access to Flash in system controller */ \
+ *(volatile unsigned int *)INTEGRATOR_SC_CTRLS = FL_SC_CONTROL; \
+ }
+
+#define CYGHWR_FLASH_WRITE_DISABLE() \
+ { \
+ volatile cyg_uint32 *ebi_csr1 = (volatile cyg_uint32 *)INTEGRATOR_EBI_CSR1; \
+ \
+ /* disable write access to EBI_CSR1 area (Flash) */ \
+ *ebi_csr1 &= ~INTEGRATOR_EBI_WRITE_ENABLE; \
+ \
+ if (*ebi_csr1 & INTEGRATOR_EBI_WRITE_ENABLE) { \
+ *(volatile cyg_uint32 *)INTEGRATOR_EBI_LOCK = 0xA05F; \
+ *ebi_csr1 &= ~INTEGRATOR_EBI_WRITE_ENABLE; \
+ *(volatile cyg_uint32 *)INTEGRATOR_EBI_LOCK = 1; \
+ } \
+ \
+ /* Disable Vpp and disable write access to Flash in system controller */ \
+ *(volatile unsigned int *)INTEGRATOR_SC_CTRLS = 0; \
+ }
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_28fxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF arm_integrator_flash.c
diff --git a/ecos/packages/devs/flash/arm/ipaq/current/ChangeLog b/ecos/packages/devs/flash/arm/ipaq/current/ChangeLog
new file mode 100644
index 0000000..da2883a
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ipaq/current/ChangeLog
@@ -0,0 +1,35 @@
+2001-03-01 Gary Thomas <gthomas@redhat.com>
+
+ * src/ipaq_flash.c: New file - defines enable/disable functions.
+
+ * cdl/flash_ipaq.cdl: Add special functions required to enable and
+ disable FLASH programming.
+
+2001-02-24 Gary Thomas <gthomas@redhat.com>
+
+ * include/ipaq_strataflash.inl:
+ * cdl/flash_ipaq.cdl: New file(s) - FLASH support on iPAQ.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/ipaq/current/cdl/flash_ipaq.cdl b/ecos/packages/devs/flash/arm/ipaq/current/cdl/flash_ipaq.cdl
new file mode 100644
index 0000000..61e9e69
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ipaq/current/cdl/flash_ipaq.cdl
@@ -0,0 +1,84 @@
+#====================================================================
+#
+# flash_ipaq.cdl
+#
+# FLASH memory - Hardware support on Intel StrongARM SA1110
+#
+#====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-14
+#
+#####DESCRIPTIONEND####
+#
+#====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_IPAQ {
+ display "Intel SA1110 (iPAQ) FLASH memory support"
+ description "FLASH memory device support for Intel StrongARM SA-1110"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_SA11X0_IPAQ
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ compile ipaq_flash.c
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/ipaq_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_ipaq.h>"
+ puts $::cdl_system_header "// External functions"
+ puts $::cdl_system_header "#define CYGIMP_FLASH_ENABLE ipaq_flash_enable"
+ puts $::cdl_system_header "#define CYGIMP_FLASH_DISABLE ipaq_flash_disable"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
diff --git a/ecos/packages/devs/flash/arm/ipaq/current/include/ipaq_strataflash.inl b/ecos/packages/devs/flash/arm/ipaq/current/include/ipaq_strataflash.inl
new file mode 100644
index 0000000..cd184a3
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ipaq/current/include/ipaq_strataflash.inl
@@ -0,0 +1,67 @@
+#ifndef CYGONCE_DEVS_FLASH_IPAQ_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_IPAQ_STRATAFLASH_INL
+//==========================================================================
+//
+// ipaq_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// The iPAQ system has two 16-bit devices.
+// Doc says: a StrataFlash 28F320J3A. The 320 means 32Mbit, so 4Mbyte.
+// Reality: a StrataFlash 28F640J3A. The 640 means 64Mbit, so 8Mbyte.
+
+#define CYGNUM_FLASH_DEVICES (2)
+#define CYGNUM_FLASH_BASE (0x50000000u)
+#define CYGNUM_FLASH_BASE_MASK (0xFE000000u) // 32Mb devices
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_IPAQ_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF ipaq_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/ipaq/current/src/ipaq_flash.c b/ecos/packages/devs/flash/arm/ipaq/current/src/ipaq_flash.c
new file mode 100644
index 0000000..9fc2d4a
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ipaq/current/src/ipaq_flash.c
@@ -0,0 +1,64 @@
+//====================================================================
+//
+// ipaq_flash.c
+//
+// FLASH memory - Hardware support on Intel StrongARM SA1110
+//
+//====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Original data: gthomas
+// Contributors: gthomas
+// Date: 2001-03-01
+//
+//####DESCRIPTIONEND####
+//
+//====================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/ipaq.h>
+
+void
+ipaq_flash_enable(void *start, void *end)
+{
+ ipaq_EGPIO(SA1110_EIO_VPP, SA1110_EIO_VPP_ON);
+}
+
+void
+ipaq_flash_disable(void *start, void *end)
+{
+ ipaq_EGPIO(SA1110_EIO_VPP, SA1110_EIO_VPP_OFF);
+}
diff --git a/ecos/packages/devs/flash/arm/iq80310/current/ChangeLog b/ecos/packages/devs/flash/arm/iq80310/current/ChangeLog
new file mode 100644
index 0000000..f7d6096
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80310/current/ChangeLog
@@ -0,0 +1,98 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/iq80310_flash.c: Explicitly include <cyg/io/flash_dev.h>
+ rather than just defining _FLASH_PRIVATE_.
+ (From bartv in flash_v2 branch)
+
+ * cdl/flash_iq80310.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2003-09-16 Jani Monoses <jani@iv.ro>
+
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf): Put flash functions
+ in RAM using section attributes instead of the old method.
+ * src/iq80310_flash.c (flash_hwr_init): Use generic flash_query_dev.
+
+2003-04-04 Jani Monoses <jani@iv.ro>
+
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf):
+ Cache enabling and disabling are already handled by generic flash
+
+2002-11-12 Gary Thomas <gary@mlbassoc.com>
+
+ * cdl/flash_iq80310.cdl: New Xscale platforms layout.
+
+2002-04-16 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/flash_iq80310.cdl: Invoke $(CC) with $(CFLAGS) to ensure the
+ correct flags are passed.
+
+2001-09-28 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/iq80310_flash.c (flash_hwr_init): Only re-enable icache if it
+ was enabled before.
+
+2001-08-04 Mark Salter <msalter@redhat.com>
+
+ * src/flash.h (FLASH_P2V): First 4K of flash now mapped at 0xd0000000.
+
+2001-06-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/iq80310_flash.c: Remove dependency on printf() via user functions.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_iq80310.cdl: Needs IO controller to copy functions to
+ RAM.
+
+2000-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/iq80310_flash.c (flash_code_overlaps): Define stext/etext
+ as array types so no assumptions can be made by the compiler about
+ location.
+
+2000-11-22 Mark Salter <msalter@redhat.com>
+
+ * src/flash_unlock_block.c (flash_unlock_block): Fix broken
+ read of lock bits.
+
+2000-11-19 Mark Salter <msalter@redhat.com>
+
+ * src/flash_unlock_block.c (flash_unlock_block): Fix lock state
+ query to properly use FLASH_P2V macro. Don't issue lock state
+ query for block we are unlocking.
+
+ * src/flash_program_buf.c (flash_program_buf): Fix code to skip
+ over Yavapai registers in flash memory space.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/iq80310/current/cdl/flash_iq80310.cdl b/ecos/packages/devs/flash/arm/iq80310/current/cdl/flash_iq80310.cdl
new file mode 100644
index 0000000..9262f7b
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80310/current/cdl/flash_iq80310.cdl
@@ -0,0 +1,74 @@
+# ====================================================================
+#
+# flash_iq80310.cdl
+#
+# FLASH memory - Hardware support on IQ80200/80310
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data: msalter, gthomas
+# Contributors:
+# Date: 2000-10-10
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_XSCALE_IQ80310 {
+ display "Cyclone IQ80310 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_XSCALE_IOP310
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "FLASH memory device support for Cyclone IQ80310"
+ compile iq80310_flash.c flash_erase_block.c flash_program_buf.c flash_query.c
+
+ cdl_component CYGPKG_DEVS_FLASH_IQ80310_LOCKING {
+ display "Flash device implements locking"
+ active_if 0 < CYGHWR_IO_FLASH_BLOCK_LOCKING
+ calculated 1
+ compile flash_lock_block.c flash_unlock_block.c
+ }
+}
+
diff --git a/ecos/packages/devs/flash/arm/iq80310/current/src/flash.h b/ecos/packages/devs/flash/arm/iq80310/current/src/flash.h
new file mode 100644
index 0000000..32059e8
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80310/current/src/flash.h
@@ -0,0 +1,105 @@
+//==========================================================================
+//
+// flash.h
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, msalter
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef _FLASH_HWR_H_
+#define _FLASH_HWR_H_
+
+// First 4K page of flash at physical address zero is
+// virtually mapped at address 0xa0000000.
+#define FLASH_P2V(x) ((volatile unsigned char *)(((unsigned)(x) < 0x1000) ? \
+ ((unsigned)(x) | 0xd0000000) : \
+ (unsigned)(x)))
+
+#define FLASH_BOOT_BLOCK_SIZE 0x4000
+
+#define FLASH_Intel_code 0x89
+
+#define FLASH_Read_ID 0x90
+#define FLASH_Read_Query 0x98
+#define FLASH_Read_Status 0x70
+#define FLASH_Clear_Status 0x50
+#define FLASH_Status_Ready 0x80
+#define FLASH_Write_Buffer 0xE8
+#define FLASH_Program 0x10
+#define FLASH_Block_Erase 0x20
+#define FLASH_Set_Lock 0x60
+#define FLASH_Set_Lock_Confirm 0x01
+#define FLASH_Clear_Locks 0x60
+#define FLASH_Clear_Locks_Confirm 0xD0
+#define FLASH_Confirm 0xD0
+#define FLASH_Configure 0xB8
+#define FLASH_Configure_ReadyWait 0x00
+#define FLASH_Configure_PulseOnErase 0x01
+#define FLASH_Configure_PulseOnProgram 0x02
+#define FLASH_Configure_PulseOnBoth 0x03
+#define FLASH_Reset 0xFF
+
+#define FLASH_BLOCK_SIZE 0x10000
+#define FLASH_WBUF_SIZE 32
+
+#define FLASH_Intel_code 0x89
+
+// Extended query information
+struct FLASH_query {
+ unsigned char manuf_code;
+ unsigned char device_code;
+ unsigned char _unused0[14];
+ unsigned char id[3]; // Q Q R
+ unsigned char _unused1[20];
+ unsigned char device_size;
+ unsigned char device_interface[2];
+ unsigned char buffer_size[2];
+ unsigned char is_block_oriented;
+ unsigned char num_regions[2];
+ unsigned char region_size[2];
+};
+
+#endif // _FLASH_HWR_H_
diff --git a/ecos/packages/devs/flash/arm/iq80310/current/src/flash_erase_block.c b/ecos/packages/devs/flash/arm/iq80310/current/src/flash_erase_block.c
new file mode 100644
index 0000000..dfa1e33
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80310/current/src/flash_erase_block.c
@@ -0,0 +1,98 @@
+//==========================================================================
+//
+// flash_erase_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, msalter
+// Date: 2000-07-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+
+int flash_erase_block(volatile unsigned char *block)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int flash_erase_block(volatile unsigned char *block)
+{
+ volatile unsigned char *ROM;
+ unsigned short stat;
+ int timeout = 50000;
+ int len;
+
+ // First 4K page of flash at physcial address zero is
+ // virtually mapped to address 0xa0000000.
+ ROM = FLASH_P2V((unsigned)block & 0xFF800000);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Erase block
+ ROM[0] = FLASH_Block_Erase;
+ *FLASH_P2V(block) = FLASH_Confirm;
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ // If an error was reported, see if the block erased anyway
+ if (stat & 0x7E) {
+ len = FLASH_BLOCK_SIZE;
+ while (len > 0) {
+ if (*FLASH_P2V(block) != 0xFF)
+ break;
+ block++;
+ len -= sizeof(*block);
+ }
+ if (len == 0) stat = 0;
+ }
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/arm/iq80310/current/src/flash_lock_block.c b/ecos/packages/devs/flash/arm/iq80310/current/src/flash_lock_block.c
new file mode 100644
index 0000000..49a7555
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80310/current/src/flash_lock_block.c
@@ -0,0 +1,82 @@
+//==========================================================================
+//
+// flash_lock_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, msalter
+// Date: 2000-09-10
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+
+
+int
+flash_lock_block(volatile unsigned char *block)
+ __attribute__ ((section (".2ram.flash_lock_block")));
+int
+flash_lock_block(volatile unsigned char *block)
+{
+ volatile unsigned char *ROM;
+ unsigned short stat;
+ int timeout = 5000000;
+
+ ROM = FLASH_P2V((unsigned long)block & 0xFF800000);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Set lock bit
+ FLASH_P2V(block)[0] = FLASH_Set_Lock;
+ FLASH_P2V(block)[0] = FLASH_Set_Lock_Confirm; // Confirmation
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/arm/iq80310/current/src/flash_program_buf.c b/ecos/packages/devs/flash/arm/iq80310/current/src/flash_program_buf.c
new file mode 100644
index 0000000..d60ee84
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80310/current/src/flash_program_buf.c
@@ -0,0 +1,143 @@
+//==========================================================================
+//
+// flash_program_buf.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, msalter
+// Date: 2000-07-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+
+int
+flash_program_buf(volatile unsigned char *addr, unsigned char *data, int len)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+int
+flash_program_buf(volatile unsigned char *addr, unsigned char *data, int len)
+{
+ volatile unsigned char *ROM;
+ volatile unsigned char *BA;
+ unsigned short stat;
+ int timeout = 5000000;
+ int i, wc;
+
+ ROM = FLASH_P2V((unsigned long)addr & 0xFF800000);
+ BA = FLASH_P2V((unsigned long)addr & 0xFFFE0000);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ wc = 32;
+ while (len >= wc) {
+ len -= wc;
+
+ // The IQ803010 has a hole in flash which must be avoided.
+ if (((unsigned char *)0x1000) <= addr && addr < ((unsigned char *)0x2000)) {
+ addr += wc;
+ data += wc;
+ continue;
+ }
+
+ *BA = FLASH_Write_Buffer;
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ stat |= 0x0100;
+ goto bad;
+ }
+ *BA = FLASH_Write_Buffer;
+ }
+ *BA = wc-1; // Count is 0..N-1
+ if (FLASH_P2V(addr) != addr) {
+ volatile unsigned char *tmp;
+
+ tmp = FLASH_P2V(addr);
+ for (i = 0; i < wc; i++)
+ *tmp++ = *data++;
+ addr += wc;
+ } else {
+ for (i = 0; i < wc; i++)
+ *addr++ = *data++;
+ }
+ *BA = FLASH_Confirm;
+ stat = *BA;
+ }
+
+ ROM[0] = FLASH_Read_Status;
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ stat |= 0x0200;
+ goto bad;
+ }
+ }
+
+ while (len > 0) {
+ ROM[0] = FLASH_Program;
+
+ *FLASH_P2V(addr) = *data++;
+ addr++;
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ stat |= 0x0300;
+ goto bad;
+ }
+ }
+ --len;
+ }
+
+ // Restore ROM to "normal" mode
+ bad:
+ ROM[0] = FLASH_Reset;
+
+ return stat;
+}
+
+
diff --git a/ecos/packages/devs/flash/arm/iq80310/current/src/flash_query.c b/ecos/packages/devs/flash/arm/iq80310/current/src/flash_query.c
new file mode 100644
index 0000000..69fbcf6
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80310/current/src/flash_query.c
@@ -0,0 +1,79 @@
+//==========================================================================
+//
+// flash_query.c
+//
+// Flash programming - query device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+
+#define CNT 200*1000*10 // Approx 20ms
+
+int
+flash_query(unsigned char *data) __attribute__ ((section (".2ram.flash_query")));
+int
+flash_query(unsigned char *data)
+{
+ volatile unsigned short *ROM;
+ int i, cnt;
+
+ ROM = (unsigned short *) FLASH_P2V(0);
+ ROM[0] = FLASH_Read_Query;
+ for (cnt = CNT; cnt > 0; cnt--) ;
+ for (i = 0; i < sizeof(struct FLASH_query); i++) {
+ *data++ = ROM[i];
+ }
+
+ ROM[0] = FLASH_Reset;
+
+ return 0;
+}
diff --git a/ecos/packages/devs/flash/arm/iq80310/current/src/flash_unlock_block.c b/ecos/packages/devs/flash/arm/iq80310/current/src/flash_unlock_block.c
new file mode 100644
index 0000000..5f1bc41
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80310/current/src/flash_unlock_block.c
@@ -0,0 +1,123 @@
+//==========================================================================
+//
+// flash_unlock_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, msalter
+// Date: 2000-09-10
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+
+
+//
+// The difficulty with this operation is that the hardware does not support
+// unlocking single blocks. However, the logical layer would like this to
+// be the case, so this routine emulates it. The hardware can clear all of
+// the locks in the device at once. This routine will use that approach and
+// then reset the regions which are known to be locked.
+//
+
+#define MAX_FLASH_BLOCKS 128
+
+int
+flash_unlock_block(volatile unsigned char *block, int block_size, int blocks)
+ __attribute__ ((section (".2ram.flash_unlock_block")));
+int
+flash_unlock_block(volatile unsigned char *block, int block_size, int blocks)
+{
+ volatile unsigned short *ROM, *bp;
+ unsigned short stat;
+ int timeout = 5000000;
+ unsigned short is_locked[MAX_FLASH_BLOCKS];
+ int i;
+
+ ROM = (unsigned short *) FLASH_P2V((unsigned long)block & 0xFF800000);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Get current block lock state. This needs to access each block on
+ // the device so currently locked blocks can be re-locked.
+ bp = (unsigned short *)((unsigned long)block & 0xFF800000);
+ for (i = 0; i < blocks; i++) {
+ if (bp == (unsigned short *) block) {
+ is_locked[i] = 0;
+ } else {
+ *(volatile unsigned short *)FLASH_P2V(bp) = FLASH_Read_Query;
+ is_locked[i] = ((volatile unsigned short *)FLASH_P2V(bp))[2];
+ }
+ bp += block_size / sizeof(*bp);
+ }
+
+ // Clears all lock bits
+ FLASH_P2V(block)[0] = FLASH_Clear_Locks;
+ FLASH_P2V(block)[0] = FLASH_Clear_Locks_Confirm; // Confirmation
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) goto done;
+ }
+
+ // Restore the lock state
+ bp = (unsigned short *)((unsigned long)block & 0xFF800000);
+ for (i = 0; i < blocks; i++) {
+ if (is_locked[i]) {
+ *FLASH_P2V(bp) = FLASH_Set_Lock;
+ *FLASH_P2V(bp) = FLASH_Set_Lock_Confirm; // Confirmation
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) goto done;
+ }
+ }
+ bp += block_size / sizeof(*bp);
+ }
+
+ done:
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/arm/iq80310/current/src/iq80310_flash.c b/ecos/packages/devs/flash/arm/iq80310/current/src/iq80310_flash.c
new file mode 100644
index 0000000..0cd7af6
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80310/current/src/iq80310_flash.c
@@ -0,0 +1,118 @@
+//==========================================================================
+//
+// iq80310_flash.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, msalter
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include "flash.h"
+
+#define _si(p) ((p[1]<<8)|p[0])
+
+extern int strncmp(const char *s1, const char *s2, size_t len);
+int
+flash_hwr_init(void)
+{
+ struct FLASH_query data, *qp;
+ int num_regions, region_size;
+
+ flash_dev_query((void*)&data);
+
+ qp = &data;
+ if (/*(qp->manuf_code == FLASH_Intel_code) && */
+ (strncmp(qp->id, "QRY", 3) == 0)) {
+ num_regions = _si(qp->num_regions)+1;
+ region_size = _si(qp->region_size)*256;
+
+ flash_info.block_size = region_size;
+ flash_info.blocks = num_regions;
+ flash_info.start = (void *)0x00000000;
+ flash_info.end = (void *)(0x00000000+(num_regions*region_size));
+ return FLASH_ERR_OK;
+ } else {
+ (*flash_info.pf)("Can't identify FLASH sorry\n");
+ diag_dump_buf((void*)&data, sizeof(data));
+ return FLASH_ERR_HWR;
+ }
+}
+
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int err)
+{
+ if (err & 0x7E) {
+ (*flash_info.pf)("Err = %x\n", err);
+ if (err & 0x10) {
+ return FLASH_ERR_PROGRAM;
+ } else
+ if (err & 0x20) {
+ return FLASH_ERR_ERASE;
+ } else
+ return FLASH_ERR_HWR; // FIXME
+ } else {
+ return FLASH_ERR_OK;
+ }
+}
+
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
diff --git a/ecos/packages/devs/flash/arm/iq80321/current/ChangeLog b/ecos/packages/devs/flash/arm/iq80321/current/ChangeLog
new file mode 100644
index 0000000..25e5e61
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80321/current/ChangeLog
@@ -0,0 +1,37 @@
+2003-04-14 Mark Salter <msalter@redhat.com>
+
+ * include/iq80321_strataflash.inl: Include iq80321.h for IQ80321_FLASH_ADDR.
+
+2002-01-28 Mark Salter <msalter@redhat.com>
+
+ * include/iq80321_strataflash.inl: Include cyg/hal/plf_io.h.
+ * include/iq80321_strataflash.inl: Doh. Just remove it as unneccessary.
+
+2002-01-09 Mark Salter <msalter@redhat.com>
+
+ * include/iq80321_strataflash.inl: Use platform provided FLASH addr.
+
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/iq80321/current/cdl/flash_iq80321.cdl b/ecos/packages/devs/flash/arm/iq80321/current/cdl/flash_iq80321.cdl
new file mode 100644
index 0000000..76fdd3a
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80321/current/cdl/flash_iq80321.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_iq80321.cdl
+#
+# FLASH memory - Hardware support on Intel IQ80321 board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data: gthomas
+# Contributors:
+# Date: 2001-12-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_IQ80321 {
+ display "Intel IQ80321 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_XSCALE_IQ80321
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/iq80321_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_iq80321.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
+
diff --git a/ecos/packages/devs/flash/arm/iq80321/current/include/iq80321_strataflash.inl b/ecos/packages/devs/flash/arm/iq80321/current/include/iq80321_strataflash.inl
new file mode 100644
index 0000000..1ccd143
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/iq80321/current/include/iq80321_strataflash.inl
@@ -0,0 +1,66 @@
+#ifndef CYGONCE_DEVS_FLASH_IQ80321_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_IQ80321_STRATAFLASH_INL
+//==========================================================================
+//
+// iq80321_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: gthomas
+// Date: 2001-12-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/iq80321.h> // IQ80321_FLASH_ADDR
+
+// The iq80321 system has one 16-bit device.
+
+#define CYGNUM_FLASH_DEVICES (1)
+#define CYGNUM_FLASH_BASE IQ80321_FLASH_ADDR
+#define CYGNUM_FLASH_BASE_MASK (0xFF800000u) // 8Mb devices
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_IQ80321_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF iq80321_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/ixdp425/current/ChangeLog b/ecos/packages/devs/flash/arm/ixdp425/current/ChangeLog
new file mode 100644
index 0000000..1917825
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ixdp425/current/ChangeLog
@@ -0,0 +1,31 @@
+2004-09-02 Mark Salter <msalter@redhat.com>
+
+ * include/ixdp425_strataflash.inl: Support little-endian.
+
+2003-03-24 Mark Salter <msalter@redhat.com>
+
+ * cdl/flash_ixdp425.cdl: Fix copyright notice.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/ixdp425/current/cdl/flash_ixdp425.cdl b/ecos/packages/devs/flash/arm/ixdp425/current/cdl/flash_ixdp425.cdl
new file mode 100755
index 0000000..ed96f6c
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ixdp425/current/cdl/flash_ixdp425.cdl
@@ -0,0 +1,77 @@
+# ====================================================================
+#
+# flash_ixdp425.cdl
+#
+# FLASH memory - Hardware support on IXDP425 board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):
+# Original data: msalter
+# Contributors:
+# Date: 2002-12-11
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_IXDP425 {
+ display "IXDP425 board FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_XSCALE_IXDP425
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** ixdp425 flash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/ixdp425_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_ixdp425.h>"
+ puts $::cdl_system_header "/***** ixdp425 flash driver proc output end *****/"
+ }
+}
diff --git a/ecos/packages/devs/flash/arm/ixdp425/current/include/ixdp425_strataflash.inl b/ecos/packages/devs/flash/arm/ixdp425/current/include/ixdp425_strataflash.inl
new file mode 100644
index 0000000..0de9a88
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/ixdp425/current/include/ixdp425_strataflash.inl
@@ -0,0 +1,75 @@
+#ifndef CYGONCE_DEVS_FLASH_IXDP425_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_IXDP425_STRATAFLASH_INL
+//==========================================================================
+//
+// ixdp425_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// The ixdp425 has one 16-bit device.
+// StrataFlash 28F128.
+
+#define CYGNUM_FLASH_DEVICES (1)
+#define CYGNUM_FLASH_BASE_MASK (0xFF000000u) // 16Mb
+
+#define CYGNUM_FLASH_BASE (0x50000000u)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#include <pkgconf/hal.h> // for CYGHWR_HAL_ARM_BIGENDIAN
+
+// We have to do some address gymnastics in little-endian mode
+#ifndef CYGHWR_HAL_ARM_BIGENDIAN
+#define __INV(a) ((flash_t *)((unsigned)(a) ^ 0x2))
+#define CYGHWR_FLASH_WRITE_BUF(a,b) (*__INV(a) = *__INV(b))
+#define CYGHWR_FLASH_READ_QUERY(a) (*__INV(a))
+#endif
+
+#endif // CYGONCE_DEVS_FLASH_IXDP425_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF ixdp425_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/jtst/current/ChangeLog b/ecos/packages/devs/flash/arm/jtst/current/ChangeLog
new file mode 100644
index 0000000..1033a30
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/jtst/current/ChangeLog
@@ -0,0 +1,29 @@
+2004-06-6 Andrea Michelotti <amichelotti@atmel.com>
+
+ * src/jsts_flash.c:
+ * cdl/flash_jtst.cdl:
+ Added Flash driver for Atmel JTST Diopsis board; based on eb55_flash
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/jtst/current/cdl/flash_jtst.cdl b/ecos/packages/devs/flash/arm/jtst/current/cdl/flash_jtst.cdl
new file mode 100644
index 0000000..0315602
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/jtst/current/cdl/flash_jtst.cdl
@@ -0,0 +1,71 @@
+# ====================================================================
+#
+# flash_jtst.cdl
+#
+# FLASH memory - Hardware support on Atmel ARM JTST board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov, tdrury, nickg
+# Original data: gthomas,amichelotti
+# Contributors: gthomas
+# Date: 2004-06-6
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_JTST {
+ display "Atmel JTST board FLASH memory support"
+ description "FLASH memory device support for Atmel JTST board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_AT91
+ requires CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND
+
+ compile jtst_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED {
+ display "Generic Atmel AM49XXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED
+}
+
+# EOF flash_jtst.cdl
diff --git a/ecos/packages/devs/flash/arm/jtst/current/src/jtst_flash.c b/ecos/packages/devs/flash/arm/jtst/current/src/jtst_flash.c
new file mode 100644
index 0000000..822f998
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/jtst/current/src/jtst_flash.c
@@ -0,0 +1,65 @@
+//==========================================================================
+//
+// jtst_flash.c
+//
+// Flash programming for Atmel device on Atmel JTST board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, tdrury
+// Contributors: jskov, nickg,jlarmour
+// Date: 2002-07-08
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// There's a single AT49BV1604A on the JTST board.
+
+#define CYGHWR_DEVS_FLASH_ATMEL_AT49BV1604A
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0x00500000u)
+
+#include "cyg/io/flash_at49xxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF jtst_flash.c
diff --git a/ecos/packages/devs/flash/arm/lpc2xxx/current/ChangeLog b/ecos/packages/devs/flash/arm/lpc2xxx/current/ChangeLog
new file mode 100644
index 0000000..785dac3
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/lpc2xxx/current/ChangeLog
@@ -0,0 +1,36 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash_arm_lpc2xxx.c:
+ Explicitly include <cyg/io/flash_dev.h> rather than just
+ defining _FLASH_PRIVATE_. (From bartv in flash_v2 branch)
+
+ * cdl/flash_arm_lpc2xxx.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2007-07-12 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+
+ * lpc2xxx: driver for on-chip flash memory
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/lpc2xxx/current/cdl/flash_arm_lpc2xxx.cdl b/ecos/packages/devs/flash/arm/lpc2xxx/current/cdl/flash_arm_lpc2xxx.cdl
new file mode 100644
index 0000000..3b67029
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/lpc2xxx/current/cdl/flash_arm_lpc2xxx.cdl
@@ -0,0 +1,86 @@
+# ====================================================================
+#
+# flash_arm_lpc2xxx.cdl
+#
+# Philips LPC2XXX flash memory package
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors:
+# Date: 2007-07-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_LPC2XXX {
+ display "LPC2xxx internal FLASH memory support"
+ description "Support for the internal FLASH memory of LPC2xxx controllers"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_LPC2XXX
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ # These chips use two erase block sizes, the access to flash is
+ # limited to the last few of the 8k blocks. I don't have a chip
+ # using only 8k block sizes, so I can't test and therefore won't
+ # implement support for these devices.
+ active_if {
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2124" ||
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2129" ||
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2194" ||
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2214" ||
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2292" ||
+ CYGHWR_HAL_ARM_LPC2XXX == "LPC2294"
+ }
+
+ compile flash_arm_lpc2xxx.c
+ include_dir .
+
+ cdl_option CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE {
+ display "copy buffer size"
+ description "
+ Size of the buffer reserved at the end of the internal
+ SRAM area for flash writing (copy) operations. Additional
+ 32 bytes are reserved for use by the IAP routine."
+ flavor data
+ legal_values 512 1024 4096 8192
+ default_value 8192
+ }
+}
diff --git a/ecos/packages/devs/flash/arm/lpc2xxx/current/include/flash_arm_lpc2xxx.h b/ecos/packages/devs/flash/arm/lpc2xxx/current/include/flash_arm_lpc2xxx.h
new file mode 100644
index 0000000..75b106a
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/lpc2xxx/current/include/flash_arm_lpc2xxx.h
@@ -0,0 +1,83 @@
+#ifndef CYGONCE_FLASH_ARM_LPC2XXX_H
+#define CYGONCE_FLASH_ARM_LPC2XXX_H
+
+//==========================================================================
+//
+// flash_arm_lpc2xxx.h
+//
+// Flash programming for LPC2xxx
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:
+// Date: 2007-07-12
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+struct iap_param {
+ cyg_uint32 code;
+ cyg_uint32 p[4];
+};
+
+#define IAP_PREPARE 50
+#define IAP_COPY 51
+#define IAP_ERASE 52
+#define IAP_CHECK 53
+#define IAP_PARTID 54
+#define IAP_VERSION 55
+#define IAP_COMPARE 56
+
+#define IAP_CMD_SUCCESS 0
+#define IAP_CMD_INVALID 1
+#define IAP_SRC_ADDRERR 2
+#define IAP_DST_ADDRERR 3
+#define IAP_SRC_ADDRMAP 4
+#define IAP_DST_ADDRMAP 5
+#define IAP_CNT_INVALID 6
+#define IAP_SEC_INVALID 7
+#define IAP_SEC_NOTBLNK 8
+#define IAP_SEC_NOTPREP 9
+#define IAP_CMP_INEQUAL 10
+#define IAP_BSY 11
+
+#define IAP_LOCATION 0x7ffffff1
+
+#endif
diff --git a/ecos/packages/devs/flash/arm/lpc2xxx/current/src/flash_arm_lpc2xxx.c b/ecos/packages/devs/flash/arm/lpc2xxx/current/src/flash_arm_lpc2xxx.c
new file mode 100644
index 0000000..85b6dcc
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/lpc2xxx/current/src/flash_arm_lpc2xxx.c
@@ -0,0 +1,218 @@
+//==========================================================================
+//
+// flash_arm_lpc2xxx.c
+//
+// Flash programming for LPC2xxx
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:
+// Date: 2007-07-12
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_flash_arm_lpc2xxx.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm.h>
+#include <cyg/hal/hal_intr.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include "flash_arm_lpc2xxx.h"
+
+/* gcc builtins */
+extern void* memcpy(void *, const void *, size_t);
+extern void* memset(void *, int, size_t);
+
+/* wrapper for simpler IAP access */
+static void
+iap(struct iap_param *param, struct iap_param *result)
+{
+ static void (* const iap)(struct iap_param *, struct iap_param *)
+ = (void (*)(struct iap_param *, struct iap_param *)) IAP_LOCATION;
+ cyg_uint32 cpsr;
+
+ HAL_DISABLE_INTERRUPTS(cpsr);
+ iap(param, result);
+ HAL_RESTORE_INTERRUPTS(cpsr);
+}
+
+void
+flash_query(void *data)
+{
+ /* nothing to do here */
+}
+
+/*
+ * 248k in 31 blocks by 8k there actually less blocks since two of
+ * them are 64k, but accessing anything but the last few 8k blocks is
+ * not supported anyway
+ */
+int
+flash_hwr_init(void)
+{
+ flash_info.block_size = 8 * 1024;
+ flash_info.blocks = 31;
+ flash_info.start = (void *) 0;
+ flash_info.end = (void *) (248 * 1024);
+
+ return FLASH_ERR_OK;
+}
+
+
+static const cyg_uint8 flash_errors[12] = {
+ FLASH_ERR_OK, /* IAP_CMD_SUCCESS */
+ FLASH_ERR_PROTOCOL, /* IAP_INV_COMMAND */
+ FLASH_ERR_INVALID, /* IAP_SRC_ADDRERR */
+ FLASH_ERR_INVALID, /* IAP_DST_ADDRERR */
+ FLASH_ERR_INVALID, /* IAP_SRC_ADDRMAP */
+ FLASH_ERR_INVALID, /* IAP_DST_ADDRMAP */
+ FLASH_ERR_INVALID, /* IAP_CNT_INVALID */
+ FLASH_ERR_INVALID, /* IAP_SEC_INVALID */
+ FLASH_ERR_PROTOCOL, /* IAP_SEC_NOTBLNK */
+ FLASH_ERR_PROTOCOL, /* IAP_SEC_NOTPREP */
+ FLASH_ERR_DRV_VERIFY, /* IAP_CMP_INEQUAL */
+ FLASH_ERR_DRV_TIMEOUT, /* IAP_BSY */
+};
+
+int
+flash_hwr_map_error(e)
+{
+ if(e > 11)
+ return FLASH_ERR_PROTOCOL;
+ return flash_errors[e];
+}
+
+/* this will not work for flash addresses < 0x30000 */
+static int
+block_by_addr(cyg_uint32 addr)
+{
+ int block;
+
+ block = (addr >> 13) & 0x1f;
+ block -= 14;
+
+ return block;
+}
+
+int
+flash_erase_block(void *block, unsigned int size)
+{
+ struct iap_param param, result;
+
+ param.code = IAP_PREPARE;
+
+ param.p[0] = param.p[1] = block_by_addr((cyg_uint32) block);
+ if(param.p[0] < 10)
+ return FLASH_ERR_INVALID;
+
+ /* prepare sector(s) */
+ iap(&param, &result);
+ if(result.code != IAP_CMD_SUCCESS)
+ return result.code;
+
+ param.code = IAP_ERASE;
+ param.p[2] = CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 1000;
+
+ /* erase sector(s) */
+ iap(&param, &result);
+ return result.code;
+}
+
+int
+flash_program_buf(void *addr, void *data, int len)
+{
+ static const int size = CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE;
+ static const cyg_uint32 b = (0x40004000 - 32 -
+ CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE);
+ static void * const buf = (void *) (0x40004000 - 32 -
+ CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE);
+ cyg_uint32 a = (cyg_uint32) addr;
+ char *d = (char *) data;
+ struct iap_param param, result;
+
+ param.code = IAP_PREPARE;
+ param.p[0] = block_by_addr(a);
+ param.p[1] = block_by_addr(a + len - 1);
+ if(param.p[0] < 10 || param.p[1] > 16)
+ return FLASH_ERR_INVALID;
+
+ do {
+ /* prepare sector(s) */
+ iap(&param, &result);
+ if(result.code != IAP_CMD_SUCCESS)
+ return result.code;
+
+ if(len < size)
+ memset(buf, 0xff, size);
+ memcpy(buf, d, size);
+
+ param.code = IAP_COPY;
+ param.p[0] = a;
+ param.p[1] = b;
+ param.p[2] = size;
+ param.p[3] = CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 1000;
+
+ /* copy ram to flash */
+ iap(&param, &result);
+ if(result.code != IAP_CMD_SUCCESS)
+ return result.code;
+
+ len -= size;
+ a += size;
+ d += size;
+ } while(len > 0);
+
+ return(result.code);
+}
+
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern unsigned char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
diff --git a/ecos/packages/devs/flash/arm/mpc50/current/ChangeLog b/ecos/packages/devs/flash/arm/mpc50/current/ChangeLog
new file mode 100644
index 0000000..435e2f0
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/mpc50/current/ChangeLog
@@ -0,0 +1,28 @@
+2003-01-24 Knud Woehler <knud.woehler@microplex.de>
+2003-01-24 Mark Salter <msalter@redhat.com>
+
+ * Initial import from Knud Woehler.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/mpc50/current/cdl/flash_mpc50.cdl b/ecos/packages/devs/flash/arm/mpc50/current/cdl/flash_mpc50.cdl
new file mode 100644
index 0000000..be04089
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/mpc50/current/cdl/flash_mpc50.cdl
@@ -0,0 +1,70 @@
+# ====================================================================
+#
+# flash_mpc50.cdl
+#
+# MPC 5.0 flash package configuration data
+#
+# ====================================================================
+# ####ECOSGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+#
+# eCos is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 or (at your option) any later
+# version.
+#
+# eCos is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with eCos; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered by
+# the GNU General Public License. However the source code for this file
+# must still be made available in accordance with section (3) of the GNU
+# General Public License v2.
+#
+# This exception does not invalidate any other reasons why a work based
+# on this file might be covered by the GNU General Public License.
+# -------------------------------------------
+# ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): woehler
+# Date: 2002-09-02
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_MPC50 {
+ display "MPC 5.0 FLASH memory support"
+ description "FLASH memory device support for MPC 5.0"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_XSCALE_MPC50
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ include_dir cyg/io
+
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/mpc50_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_mpc50.h>"
+ }
+}
diff --git a/ecos/packages/devs/flash/arm/mpc50/current/include/mpc50_strataflash.inl b/ecos/packages/devs/flash/arm/mpc50/current/include/mpc50_strataflash.inl
new file mode 100644
index 0000000..b4382c8
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/mpc50/current/include/mpc50_strataflash.inl
@@ -0,0 +1,62 @@
+#ifndef CYGONCE_DEVS_FLASH_MPC50_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_MPC50_STRATAFLASH_INL
+//==========================================================================
+//
+// mpc50_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): woehler
+// Date: 2002-09-02
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// There is a single 16-bit device, on the MPC 5.0
+// a StrataFlash RC28F128J3A. -> 128Mb Chip
+
+#define CYGNUM_FLASH_DEVICES (1)
+#define CYGNUM_FLASH_BASE (0x50000000u)
+#define CYGNUM_FLASH_BASE_MASK (0xFC000000u)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_MPC50_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF mpc50_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/nano/current/ChangeLog b/ecos/packages/devs/flash/arm/nano/current/ChangeLog
new file mode 100644
index 0000000..be911c6
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/nano/current/ChangeLog
@@ -0,0 +1,32 @@
+2001-02-15 Hugo Tyson <hmt@redhat.com>
+
+ * devs/flash/arm/nano/...: new package. FLASH memory support for
+ SA1110 nanoEngine from Bright Star Engineering.
+
+ * include/nano_strataflash.inl: New file
+
+ * cdl/flash_nano.cdl: New file.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/nano/current/cdl/flash_nano.cdl b/ecos/packages/devs/flash/arm/nano/current/cdl/flash_nano.cdl
new file mode 100644
index 0000000..fdcc7c8
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/nano/current/cdl/flash_nano.cdl
@@ -0,0 +1,77 @@
+# ====================================================================
+#
+# flash_nano.cdl
+#
+# FLASH memory - Hardware support on Intel StrongARM SA1110
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-15
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_NANO {
+ display "Intel SA1110 nanoEngine FLASH memory support"
+ description "FLASH memory device support for Intel StrongARM SA-1110"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_SA11X0_NANO
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/nano_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_nano.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
diff --git a/ecos/packages/devs/flash/arm/nano/current/include/nano_strataflash.inl b/ecos/packages/devs/flash/arm/nano/current/include/nano_strataflash.inl
new file mode 100644
index 0000000..ddaa083
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/nano/current/include/nano_strataflash.inl
@@ -0,0 +1,70 @@
+#ifndef CYGONCE_DEVS_FLASH_NANO_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_NANO_STRATAFLASH_INL
+//==========================================================================
+//
+// nano_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-15
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// This is a single 16-bit device, on the nanoEngine
+// a StrataFlash 28F320B3A. The 320 means 32Mbit, so 4Mbyte.
+// The B near the end means Boot Block oriented.
+
+#define CYGNUM_FLASH_DEVICES (1)
+#define CYGNUM_FLASH_BASE (0x50000000u)
+#define CYGNUM_FLASH_BASE_MASK (0xFE000000u) // 32Mb devices
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#define CYGOPT_FLASH_IS_BOOTBLOCK 1
+
+
+#endif // CYGONCE_DEVS_FLASH_NANO_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF nano_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/olpcx2294/current/ChangeLog b/ecos/packages/devs/flash/arm/olpcx2294/current/ChangeLog
new file mode 100644
index 0000000..828a355
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/olpcx2294/current/ChangeLog
@@ -0,0 +1,34 @@
+2010-11-24 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * cdl/flash_olpcx2294.cdl: Add support for Olimex LPC-L2294-8M board.
+
+2008-08-31 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * Flash driver for LPC-E2294, LPC-H2294, LPC-L2294-1M boards
+ * cdl/flash_olpcx2294.cdl
+ * src/arm_olpcx2294_flash.c
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
diff --git a/ecos/packages/devs/flash/arm/olpcx2294/current/cdl/flash_olpcx2294.cdl b/ecos/packages/devs/flash/arm/olpcx2294/current/cdl/flash_olpcx2294.cdl
new file mode 100644
index 0000000..5f842bf
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/olpcx2294/current/cdl/flash_olpcx2294.cdl
@@ -0,0 +1,82 @@
+# ====================================================================
+#
+# flash_olpcx2294.cdl
+#
+# FLASH memory - Hardware support on Olimex LPC-X2294 boards
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Sergei Gavrikov
+# Contributors: Sergei Gavrikov
+# Date: 2008-08-31
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_OLPCX2294 {
+ display "ARM OLPCE2294, OLPCH2294, OLPCL2294 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires (CYGPKG_HAL_ARM_LPC2XXX_OLPCE2294 || \
+ CYGPKG_HAL_ARM_LPC2XXX_OLPCH2294 || \
+ CYGPKG_HAL_ARM_LPC2XXX_OLPCL2294)
+
+ compile arm_olpcx2294_flash.c
+
+ cdl_interface CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED {
+ display "Generic Intel FlashFile driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED
+
+ cdl_option CYGSEM_DEVS_FLASH_INTEL_28F320C3_PARTS {
+ display "Intel 28F320C3 parts used"
+ flavor bool
+ calculated { CYGPKG_HAL_ARM_LPC2XXX_OLPCE2294 || CYGPKG_HAL_ARM_LPC2XXX_OLPCH2294 || (CYGHWR_HAL_ARM_LPC2XXX_OLPCL2294_VARIANT == "OLPCL2294_8M") }
+ requires CYGHWR_DEVS_FLASH_INTEL_28F320C3
+ }
+
+ cdl_option CYGSEM_DEVS_FLASH_INTEL_28F160C3_PARTS {
+ display "Intel 28F160C3 parts used"
+ flavor bool
+ calculated { (CYGHWR_HAL_ARM_LPC2XXX_OLPCL2294_VARIANT == "OLPCL2294_1M") }
+ active_if CYGPKG_HAL_ARM_LPC2XXX_OLPCL2294
+ requires CYGHWR_DEVS_FLASH_INTEL_28F160C3B
+ }
+}
+
diff --git a/ecos/packages/devs/flash/arm/olpcx2294/current/src/arm_olpcx2294_flash.c b/ecos/packages/devs/flash/arm/olpcx2294/current/src/arm_olpcx2294_flash.c
new file mode 100644
index 0000000..2db6429
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/olpcx2294/current/src/arm_olpcx2294_flash.c
@@ -0,0 +1,67 @@
+//==========================================================================
+//
+// arm_olpcx2294_flash.c
+//
+// Flash programming for Intel FlashFile devices on Olimex LPC-X2294
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Sergei Gavrikov
+// Contributors: Sergei Gavrikov
+// Date: 2008-08-31
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+// The Olimex LPC-E2294 eval. board, and Olimex LPC-H2294 header board have
+// Intel 28F320C3 flash memory part, Olimex LPC-L2294-1M has Intel 28F160C3
+// flash memory part.
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x80000000u)
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_28fxxx.inl"
+
+// indent: --indent-level4 -br -nut; vim: expandtab tabstop=4 shiftwidth=4
+// ------------------------------------------------------------------------
+// EOF arm_olpcx2294_flash.c
diff --git a/ecos/packages/devs/flash/arm/olpcx2294v2/current/ChangeLog b/ecos/packages/devs/flash/arm/olpcx2294v2/current/ChangeLog
new file mode 100644
index 0000000..dbc5851
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/olpcx2294v2/current/ChangeLog
@@ -0,0 +1,8 @@
+2010-11-03 JF Argentino <jf.argentino@osean.fr>
+
+ * src/arm_olpcx2294_flash.c: Add support for LPC-L2294-8M board.
+
+2008-11-22 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * Flash driver v2 for LPC-E2294, LPC-H2294, LPC-L2294-1M boards
+ * cdl/flash_olpcx2294.cdl, src/arm_olpcx2294_flash.c: New files.
diff --git a/ecos/packages/devs/flash/arm/olpcx2294v2/current/cdl/flash_olpcx2294.cdl b/ecos/packages/devs/flash/arm/olpcx2294v2/current/cdl/flash_olpcx2294.cdl
new file mode 100644
index 0000000..c98f30e
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/olpcx2294v2/current/cdl/flash_olpcx2294.cdl
@@ -0,0 +1,73 @@
+# ====================================================================
+#
+# flash_olpcx2294.cdl
+#
+# FLASH memory - Hardware support on Olimex LPC-X2294 boards
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Sergei Gavrikov
+# Contributors: Sergei Gavrikov
+# Date: 2008-11-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_OLPCX2294_V2 {
+ display "Support for FLASH memory parts on OLPC-X2294 boards."
+
+ compile -library=libextras.a arm_olpcx2294_flash.c
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+
+ requires (CYGPKG_HAL_ARM_LPC2XXX_OLPCE2294 || \
+ CYGPKG_HAL_ARM_LPC2XXX_OLPCH2294 || \
+ CYGPKG_HAL_ARM_LPC2XXX_OLPCL2294)
+
+ requires CYGPKG_DEVS_FLASH_STRATA_V2
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ description "
+ Olimex LPC-X2294 boards all have strata family 28FxxxC3 flash
+ memory parts. These parts have boot blocks. There is no buffered
+ write capability. Individual blocks can be locked and unlocked
+ in software"
+
+}
+
diff --git a/ecos/packages/devs/flash/arm/olpcx2294v2/current/src/arm_olpcx2294_flash.c b/ecos/packages/devs/flash/arm/olpcx2294v2/current/src/arm_olpcx2294_flash.c
new file mode 100644
index 0000000..648e575
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/olpcx2294v2/current/src/arm_olpcx2294_flash.c
@@ -0,0 +1,122 @@
+//==========================================================================
+//
+// arm_olpcx2294_flash.c
+//
+// Flash programming for Intel FlashFile devices on Olimex LPC-X2294
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Sergei Gavrikov
+// Contributors: Sergei Gavrikov
+// Date: 2008-11-28
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/system.h>
+
+#if !defined(CYGPKG_HAL_ARM_LPC2XXX_OLPCE2294) && \
+ !defined(CYGPKG_HAL_ARM_LPC2XXX_OLPCH2294) && \
+ !defined(CYGPKG_HAL_ARM_LPC2XXX_OLPCL2294)
+# error Unsupported target
+#endif
+
+#ifdef CYGPKG_DEVS_FLASH_STRATA_V2
+
+#include <cyg/io/flash.h>
+#include <cyg/io/strata_dev.h>
+
+// Olimex LPC-E2294 development board and Olimex LPC-H2294 header board both
+// have 28F320C3-B flash memory part, Olimex LPC-L2294-1M development board has
+// 28F160C3-B flash memory part and Olimex LPC-L2294-8M development board has
+// 28F320C3-B flash memory part. All boards have 16-bit access to it's flash
+// devices.
+static const CYG_FLASH_FUNS(hal_olpcx2294_flash_strata_funs,
+ &cyg_strata_init_check_devid_16,
+ &cyg_flash_devfn_query_nop,
+ &cyg_strata_erase_16,
+ &cyg_strata_program_16,
+ (int (*)(struct cyg_flash_dev*, const cyg_flashaddr_t, void*, size_t))0,
+ &cyg_strata_lock_k3_16,
+ &cyg_strata_unlock_k3_16);
+
+static const cyg_strata_dev hal_olpcx2294_flash_priv = {
+ .manufacturer_code = CYG_FLASH_STRATA_MANUFACTURER_INTEL,
+#if defined(CYGHWR_OLIMEX_BOARD_OLPCL2294_1M)
+ .device_code = 0x88c3, /* 16-Mbit x 16-B, 28F160C3-B */
+#else
+ .device_code = 0x88c5, /* 32-Mbit x 16-B, 28F320C3-B */
+#endif
+ .bufsize = 1,
+ .block_info = {
+#if defined(CYGHWR_OLIMEX_BOARD_OLPCL2294_1M)
+ { 0x00002000, 8 },/* boot bottom 8 x 8K blocks */
+ { 0x00010000, 31 } /* 31 x 64K blocks */
+#else
+ { 0x00002000, 8 },/* boot bottom 8 x 8K blocks */
+ { 0x00010000, 63 } /* 63 x 64K blocks */
+#endif
+ }
+};
+
+#if defined(CYGHWR_OLIMEX_BOARD_OLPCL2294_1M)
+CYG_FLASH_DRIVER(hal_olpcx2294_flash,
+ &hal_olpcx2294_flash_strata_funs,
+ 0,
+ 0x80000000,
+ 0x801fffff,
+ 2,
+ hal_olpcx2294_flash_priv.block_info,
+ &hal_olpcx2294_flash_priv
+);
+#else
+CYG_FLASH_DRIVER(hal_olpcx2294_flash,
+ &hal_olpcx2294_flash_strata_funs,
+ 0,
+ 0x80000000,
+ 0x803fffff,
+ 2,
+ hal_olpcx2294_flash_priv.block_info,
+ &hal_olpcx2294_flash_priv
+);
+#endif
+
+#endif//CYGPKG_DEVS_FLASH_STRATA_V2
+// ------------------------------------------------------------------------
+// EOF arm_olpcx2294_flash.c
diff --git a/ecos/packages/devs/flash/arm/phycore/current/ChangeLog b/ecos/packages/devs/flash/arm/phycore/current/ChangeLog
new file mode 100644
index 0000000..65c600c
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/phycore/current/ChangeLog
@@ -0,0 +1,29 @@
+2004-10-13 Sebastian Block <sebastianblock@gmx.net>
+
+ * src/phycore_flash.c:
+ * cdl/flash_phycore.cdl:
+ Added Flash driver for Phytec phycore AT91M55800A board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/phycore/current/cdl/flash_phycore.cdl b/ecos/packages/devs/flash/arm/phycore/current/cdl/flash_phycore.cdl
new file mode 100644
index 0000000..2bba3c1
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/phycore/current/cdl/flash_phycore.cdl
@@ -0,0 +1,71 @@
+# ====================================================================
+#
+# flash_phycore.cdl
+#
+# FLASH memory - Hardware support on PHYTEC phycore board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov, tdrury, nickg, block
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_PHYCORE {
+ display "phycore board FLASH memory support"
+ description "FLASH memory device support for PHYTEC phyCORE board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_AT91
+
+ compile -library=libextras.a phycore_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29XXXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV320D
+}
+
+# EOF flash_phycore.cdl
diff --git a/ecos/packages/devs/flash/arm/phycore/current/src/phycore_flash.c b/ecos/packages/devs/flash/arm/phycore/current/src/phycore_flash.c
new file mode 100644
index 0000000..b769224
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/phycore/current/src/phycore_flash.c
@@ -0,0 +1,64 @@
+//==========================================================================
+//
+// phycore_flash.c
+//
+// Flash programming for AMD device on Phytec phycore board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, tdrury
+// Contributors: jskov, nickg,jlarmour, block
+// Date: 2002-07-08
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// There's a single AM29LV320D on the phycore board.
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0x01000000u)
+
+#include "cyg/io/flash_am29xxxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF phycore_flash.c
diff --git a/ecos/packages/devs/flash/arm/phycore229x/current/ChangeLog b/ecos/packages/devs/flash/arm/phycore229x/current/ChangeLog
new file mode 100755
index 0000000..6b2a79b
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/phycore229x/current/ChangeLog
@@ -0,0 +1,29 @@
+2007-11-24 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/flash_phycore229x.c:
+ * cdl/flash_phycore229x.cdl:
+ Initial release of FLASH driver for Phytec phyCORE-LPC229x board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/phycore229x/current/cdl/flash_phycore229x.cdl b/ecos/packages/devs/flash/arm/phycore229x/current/cdl/flash_phycore229x.cdl
new file mode 100755
index 0000000..693cdc8
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/phycore229x/current/cdl/flash_phycore229x.cdl
@@ -0,0 +1,102 @@
+# ====================================================================
+#
+# flash_phycore229x.cdl
+#
+# FLASH memory - Hardware support on Phytec phyCORE LPC229x board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2007-11-21
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_PHYCORE229X {
+ display "phyCORE-LPC229x board FLASH memory support"
+ description "FLASH memory device support for Phytec phyCORE-LPC229x board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_LPC2XXX
+
+ compile -library=libextras.a flash_phycore229x.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29XXXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+
+ cdl_option CYGHWR_DEVS_FLASH_PHYCORE229X_AM29DL800 {
+ display "AMD AM29DL800 device fitted"
+ flavor bool
+ active_if { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29DL800" }
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL800
+ calculated { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29DL800" ? 1 : 0 }
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_PHYCORE229X_AM29LV800 {
+ display "AMD AM29LV800 device fitted"
+ flavor bool
+ active_if { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV800" }
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV800
+ calculated { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV800" ? 1 : 0 }
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_PHYCORE229X_AM29LV160 {
+ display "AMD AM29LV160 device fitted"
+ flavor bool
+ active_if { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV160" }
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV160
+ calculated { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV160" ? 1 : 0 }
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_PHYCORE229X_AM29LV320 {
+ display "AMD AM29LV320 device fitted"
+ flavor bool
+ active_if { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV320" }
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV320D
+ calculated { CYGHWR_HAL_ARM_PHYCORE229X_FLASH == "AM29LV320" ? 1 : 0 }
+ }
+}
+
+# EOF flash_phycore229x.cdl
diff --git a/ecos/packages/devs/flash/arm/phycore229x/current/src/flash_phycore229x.c b/ecos/packages/devs/flash/arm/phycore229x/current/src/flash_phycore229x.c
new file mode 100755
index 0000000..296462e
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/phycore229x/current/src/flash_phycore229x.c
@@ -0,0 +1,67 @@
+//==========================================================================
+//
+// flash_phycore229x.c
+//
+// Flash programming for AMD device on Phytec phyCORE-LPC229x board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: jskov, nickg,jlarmour, block
+// Date: 2007-11-21
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal_arm_lpc2xxx_phycore229x.h>
+#include <pkgconf/devs_flash_phycore229x.h>
+
+//
+// There are pairs of
+//
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_SERIES (CYGHWR_HAL_ARM_PHYCORE229X_FLASH_CNT >> 1)
+#define CYGNUM_FLASH_BASE (0x80000000u)
+
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF phycore_flash.c
diff --git a/ecos/packages/devs/flash/arm/picasso/current/ChangeLog b/ecos/packages/devs/flash/arm/picasso/current/ChangeLog
new file mode 100644
index 0000000..c78144c
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/picasso/current/ChangeLog
@@ -0,0 +1,29 @@
+2003-08-22 Gary Thomas <gary@mind.be>
+
+ * include/picasso_strataflash.inl:
+ * cdl/flash_picasso.cdl:
+ New package - support for NMI uEngine based "picasso" board
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/picasso/current/cdl/flash_picasso.cdl b/ecos/packages/devs/flash/arm/picasso/current/cdl/flash_picasso.cdl
new file mode 100644
index 0000000..ddec165
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/picasso/current/cdl/flash_picasso.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_picasso.cdl
+#
+# FLASH memory - Hardware support on NMI picasso (Xscale PXA250)
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data: gthomas
+# Contributors:
+# Date: 2001-12-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_PICASSO {
+ display "Intel PICASSO FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_XSCALE_PICASSO
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/picasso_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_picasso.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
+
diff --git a/ecos/packages/devs/flash/arm/picasso/current/include/picasso_strataflash.inl b/ecos/packages/devs/flash/arm/picasso/current/include/picasso_strataflash.inl
new file mode 100644
index 0000000..fe9f045
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/picasso/current/include/picasso_strataflash.inl
@@ -0,0 +1,66 @@
+#ifndef CYGONCE_DEVS_FLASH_PICASSO_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_PICASSO_STRATAFLASH_INL
+//==========================================================================
+//
+// picasso_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: gthomas
+// Date: 2001-12-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// The uEngine picasso system has two 16-bit devices.
+
+#include <cyg/hal/picasso.h>
+
+#define CYGNUM_FLASH_DEVICES (2)
+#define CYGNUM_FLASH_BASE PICASSO_FLASH_ADDR
+#define CYGNUM_FLASH_BASE_MASK (0xFC000000u) // 32Mb total
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif
+// ------------------------------------------------------------------------
+// EOF picasso_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/pid/current/ChangeLog b/ecos/packages/devs/flash/arm/pid/current/ChangeLog
new file mode 100644
index 0000000..c5bc937
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/pid/current/ChangeLog
@@ -0,0 +1,32 @@
+2001-02-20 Jesper Skov <jskov@redhat.com>
+
+ * devs/flash/arm/pid/...: new package. FLASH memory support for
+ ARM PID board.
+
+ * include/arm_pid_flash.inl: New file
+
+ * cdl/flash_arm_pid.cdl: New file.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/pid/current/cdl/flash_arm_pid.cdl b/ecos/packages/devs/flash/arm/pid/current/cdl/flash_arm_pid.cdl
new file mode 100644
index 0000000..ea5d015
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/pid/current/cdl/flash_arm_pid.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_pid.cdl
+#
+# FLASH memory - Hardware support on ARM PID board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_PID {
+ display "ARM PID board FLASH memory support"
+ description "FLASH memory device support for ARM PID board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_PID
+
+ compile arm_pid_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED {
+ display "Generic AMD AM29F040 driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED
+}
diff --git a/ecos/packages/devs/flash/arm/pid/current/src/arm_pid_flash.c b/ecos/packages/devs/flash/arm/pid/current/src/arm_pid_flash.c
new file mode 100644
index 0000000..f85f51e
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/pid/current/src/arm_pid_flash.c
@@ -0,0 +1,64 @@
+//==========================================================================
+//
+// arm_pid_flash.c
+//
+// Flash programming for Atmel device on ARM PID board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-02-21
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// There's a single AT29C040 on the PID board.
+
+#define CYGPKG_DEVS_FLASH_ATMEL_AT29C040A
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0x4000000u)
+
+#include "cyg/io/flash_at29cxxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF arm_pid_flash.c
diff --git a/ecos/packages/devs/flash/arm/prpmc1100/current/ChangeLog b/ecos/packages/devs/flash/arm/prpmc1100/current/ChangeLog
new file mode 100644
index 0000000..c2422ba
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/prpmc1100/current/ChangeLog
@@ -0,0 +1,24 @@
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/prpmc1100/current/cdl/flash_prpmc1100.cdl b/ecos/packages/devs/flash/arm/prpmc1100/current/cdl/flash_prpmc1100.cdl
new file mode 100755
index 0000000..d728ae5
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/prpmc1100/current/cdl/flash_prpmc1100.cdl
@@ -0,0 +1,77 @@
+# ====================================================================
+#
+# flash_prpmc1100.cdl
+#
+# FLASH memory - Hardware support on PRPMC1100 board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):
+# Original data: msalter
+# Contributors:
+# Date: 2002-12-11
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_PRPMC1100 {
+ display "PRPMC1100 board FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_XSCALE_PRPMC1100
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** prpmc1100 flash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/prpmc1100_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_prpmc1100.h>"
+ puts $::cdl_system_header "/***** prpmc1100 flash driver proc output end *****/"
+ }
+}
diff --git a/ecos/packages/devs/flash/arm/prpmc1100/current/include/prpmc1100_strataflash.inl b/ecos/packages/devs/flash/arm/prpmc1100/current/include/prpmc1100_strataflash.inl
new file mode 100644
index 0000000..7674135
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/prpmc1100/current/include/prpmc1100_strataflash.inl
@@ -0,0 +1,66 @@
+#ifndef CYGONCE_DEVS_FLASH_PRPMC1100_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_PRPMC1100_STRATAFLASH_INL
+//==========================================================================
+//
+// prpmc1100_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// The prpmc1100 has one 16-bit device.
+// StrataFlash 28F128.
+
+#define CYGNUM_FLASH_DEVICES (1)
+#define CYGNUM_FLASH_BASE_MASK (0xFF000000u) // 16Mb
+
+#define CYGNUM_FLASH_BASE (0x50000000u)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_PRPMC1100_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF prpmc1100_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/sa1100mm/current/ChangeLog b/ecos/packages/devs/flash/arm/sa1100mm/current/ChangeLog
new file mode 100644
index 0000000..1d54415
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/sa1100mm/current/ChangeLog
@@ -0,0 +1,78 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/sa1100mm_flash.c:
+ Explicitly include <cyg/io/flash_dev.h> rather than just
+ defining _FLASH_PRIVATE_. (From bartv in flash_v2 branch)
+
+ * cdl/flash_sa1100mm.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2003-09-12 Jani Monoses <jani@iv.ro>
+
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf): Put flash functions
+ in RAM using section attributes instead of the old method.
+ * src/sa1100mm_flash.c (flash_hwr_init): Use generic flash_query_dev.
+
+2002-04-03 Jani Monoses <jani@iv.ro>
+
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf):
+ Cache enabling and disabling are already handled by generic flash
+
+2001-09-28 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/sa1100mm_flash.c (flash_hwr_init): Only re-enable icache if it
+ was enabled before.
+
+2001-06-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/sa1100mm_flash.c: Remove dependency on printf() via user functions.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_sa1100mm.cdl: Needs IO controller to copy functions to
+ RAM.
+
+2000-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/sa1100mm_flash.c (flash_code_overlaps): Define stext/etext
+ as array types so no assumptions can be made by the compiler about
+ location.
+
+2000-10-25 Drew Moseley <dmoseley@redhat.com>
+
+ * src/sa1100mm_flash.c: New file. Support for SA1100 Multimedia
+ board.
+ * src/flash_query.c: Ditto.
+ * src/flash_program_buf.c: Ditto.
+ * src/flash_erase_block.c: Ditto.
+ * src/flash.h: Ditto.
+ * cdl/flash_sa1100mm.cdl: Ditto.
+ * ChangeLog: Ditto.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/sa1100mm/current/cdl/flash_sa1100mm.cdl b/ecos/packages/devs/flash/arm/sa1100mm/current/cdl/flash_sa1100mm.cdl
new file mode 100644
index 0000000..c4cbfb2
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/sa1100mm/current/cdl/flash_sa1100mm.cdl
@@ -0,0 +1,67 @@
+# ====================================================================
+#
+# flash_sa1100mm.cdl
+#
+# FLASH memory - Hardware support on StrongARM SA1100 Multimedia
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): dmoseley
+# Original data: gthomas
+# Contributors:
+# Date: 2000-10-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SA1100MM {
+ display "StrongARM SA1100 Multimedia FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_SA11X0
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "FLASH memory device support for StrongARM SA1100 Multimedia"
+ compile sa1100mm_flash.c flash_query.c flash_erase_block.c flash_program_buf.c
+
+}
+
diff --git a/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash.h b/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash.h
new file mode 100644
index 0000000..414d4bb
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash.h
@@ -0,0 +1,74 @@
+//==========================================================================
+//
+// flash.h
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, dmoseley
+// Date: 2000-10-25
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef _FLASH_HWR_H_
+#define _FLASH_HWR_H_
+
+// SA1100 Multimedia FLASH layout
+// 2x 28F016SV
+// each device is 16x1M organized as 32x128K blocks
+
+#define FLASH_Read_ID 0x00900090
+#define FLASH_Read_Status 0x00700070
+#define FLASH_Clear_Status 0x00500050
+#define FLASH_Status_Ready 0x00800080
+#define FLASH_Program 0x00100010
+#define FLASH_Block_Erase 0x00200020
+#define FLASH_Confirm 0x00D000D0
+#define FLASH_Reset 0xFFFFFFFF
+
+#define FLASH_BLOCK_SIZE 0x40000
+
+#define FLASH_Intel_code 0x89
+#define FLASH_28F016SV_low 0xA0
+#define FLASH_28F016SV_hi 0x66
+
+#endif // _FLASH_HWR_H_
diff --git a/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_erase_block.c b/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_erase_block.c
new file mode 100644
index 0000000..58e1e64
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_erase_block.c
@@ -0,0 +1,81 @@
+//==========================================================================
+//
+// flash_erase_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, dmoseley
+// Date: 2000-07-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+
+int
+flash_erase_block(volatile unsigned long *block)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int
+flash_erase_block(volatile unsigned long *block)
+{
+ unsigned long stat;
+ int timeout = 5000000;
+
+ // Clear any error conditions
+ *block = FLASH_Clear_Status;
+
+ // Set to erase
+ *block = FLASH_Block_Erase;
+ *block = FLASH_Confirm;
+ while(((stat = *block) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore ROM to "normal" mode
+ *block = FLASH_Reset;
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_program_buf.c b/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_program_buf.c
new file mode 100644
index 0000000..32d1144
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_program_buf.c
@@ -0,0 +1,89 @@
+//==========================================================================
+//
+// flash_program_buf.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, dmoseley
+// Date: 2000-07-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+
+int
+flash_program_buf(volatile unsigned long *addr, unsigned long *data, int len)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+int
+flash_program_buf(volatile unsigned long *addr, unsigned long *data, int len)
+{
+ unsigned long stat = 0;
+ int timeout = 5000000;
+ volatile unsigned long *orig_addr = addr;
+
+ // Clear any error conditions
+ *addr = FLASH_Clear_Status;
+
+ while (len > 0) {
+ *addr = FLASH_Program;
+ *addr = *data++;
+ timeout = 5000000;
+ while (((stat = *addr) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ goto bad;
+ }
+ }
+ addr++;
+ len -= sizeof(unsigned long);
+ }
+
+ // Restore ROM to "normal" mode
+ bad:
+ *orig_addr = FLASH_Reset;
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_query.c b/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_query.c
new file mode 100644
index 0000000..0d07301
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/sa1100mm/current/src/flash_query.c
@@ -0,0 +1,81 @@
+//==========================================================================
+//
+// flash_query.c
+//
+// Flash programming - query device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, dmoseley
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+
+#define CNT 20*1000*10 // Approx 200ms
+
+int
+flash_query(unsigned char *data)
+ __attribute__ ((section (".2ram.flash_query")));
+int
+flash_query(unsigned char *data)
+{
+ volatile unsigned long *lROM;
+ volatile unsigned char *cROM;
+ int i, cnt;
+
+ lROM = (unsigned long *)0x08000000;
+ cROM = (unsigned char *)0x08000000;
+
+ lROM[0] = FLASH_Read_ID;
+ for (cnt = CNT; cnt > 0; cnt--) ;
+ for (i = 0; i < 8; i++) {
+ *data++ = cROM[i];
+ }
+ lROM[0] = FLASH_Reset;
+
+ return 0;
+}
diff --git a/ecos/packages/devs/flash/arm/sa1100mm/current/src/sa1100mm_flash.c b/ecos/packages/devs/flash/arm/sa1100mm/current/src/sa1100mm_flash.c
new file mode 100644
index 0000000..0b593fa
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/sa1100mm/current/src/sa1100mm_flash.c
@@ -0,0 +1,112 @@
+//==========================================================================
+//
+// sa1100mm_flash.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, dmoseley
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include "flash.h"
+
+int
+flash_hwr_init(void)
+{
+ unsigned char data[96];
+ int num_regions, region_size;
+
+ flash_dev_query(&data);
+
+ if ((data[0] == FLASH_Intel_code) &&
+ (data[4] == FLASH_28F016SV_low) &&
+ (data[5] == FLASH_28F016SV_hi)) {
+ num_regions = 32;
+ region_size = 0x20000;
+ flash_info.block_size = region_size;
+ flash_info.blocks = num_regions;
+ flash_info.start = (void *)0x08000000;
+ flash_info.end = (void *)(0x08000000+(num_regions*region_size));
+ return FLASH_ERR_OK;
+ } else {
+ (*flash_info.pf)("Can't identify FLASH, sorry\n");
+ diag_dump_buf(data, sizeof(data));
+ return FLASH_ERR_HWR;
+ }
+}
+
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int err)
+{
+ if (err & 0x7E) {
+ if (err & 0x10) {
+ return FLASH_ERR_PROGRAM;
+ } else
+ if (err & 0x20) {
+ return FLASH_ERR_ERASE;
+ } else
+ return FLASH_ERR_HWR; // FIXME
+ } else {
+ return FLASH_ERR_OK;
+ }
+}
+
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
diff --git a/ecos/packages/devs/flash/arm/smdk2410/current/ChangeLog b/ecos/packages/devs/flash/arm/smdk2410/current/ChangeLog
new file mode 100644
index 0000000..20d3944
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/smdk2410/current/ChangeLog
@@ -0,0 +1,12 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_smdk2410.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2003-08-06 Michael Anburaj <embeddedeng@hotmail.com>
+
+ * cdl/flash_smdk2410.cdl:
+ * src/smdk2410_flash.c:
+ New package to support the flash device on a Samsung ARM9/SMDK2410
+ development board.
diff --git a/ecos/packages/devs/flash/arm/smdk2410/current/cdl/flash_smdk2410.cdl b/ecos/packages/devs/flash/arm/smdk2410/current/cdl/flash_smdk2410.cdl
new file mode 100644
index 0000000..7acd188
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/smdk2410/current/cdl/flash_smdk2410.cdl
@@ -0,0 +1,72 @@
+# ====================================================================
+#
+# flash_smdk2410.cdl
+#
+# FLASH memory - Hardware support on Samsung SMDK2410
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): michael anburaj <michaelanburaj@hotmail.com>
+# Contributors: michael anburaj <michaelanburaj@hotmail.com>
+# Date: 2003-08-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_SMDK2410 {
+ display "FLASH support for Samsung S3c2410x based boards"
+ description "FLASH memory device support for Samsung S3c2410x based
+ development boards"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_ARM9_SMDK2410
+
+ compile smdk2410_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29LV800B driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV800
+}
+
+# EOF flash_smdk2410.cdl
diff --git a/ecos/packages/devs/flash/arm/smdk2410/current/src/smdk2410_flash.c b/ecos/packages/devs/flash/arm/smdk2410/current/src/smdk2410_flash.c
new file mode 100644
index 0000000..f16bb68
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/smdk2410/current/src/smdk2410_flash.c
@@ -0,0 +1,69 @@
+//==========================================================================
+//
+// smsk2410_flash.c
+//
+// Flash programming for AMD Flash devices on Samsung SMDK2410 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): michael anburaj <michaelanburaj@hotmail.com>
+// Contributors: michael anburaj <michaelanburaj@hotmail.com>
+// Date: 2003-08-01
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//--------------------------------------------------------------------------
+// Device properties
+
+// A AMD29LV800BB is equipped with the SMDK2410 platform.
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x80000000u)
+// #define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT
+
+//--------------------------------------------------------------------------
+// Now include the driver code
+#include "cyg/io/flash_am29xxxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF smdk2410_flash.c
diff --git a/ecos/packages/devs/flash/arm/uE250/current/ChangeLog b/ecos/packages/devs/flash/arm/uE250/current/ChangeLog
new file mode 100644
index 0000000..5b22368
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/uE250/current/ChangeLog
@@ -0,0 +1,34 @@
+2003-05-28 Gary Thomas <gary@mind.be>
+
+ * include/uE250_strataflash.inl: Fix compile error.
+
+2003-02-04 Gary Thomas <gary@mind.be>
+
+ * include/uE250_strataflash.inl:
+ * cdl/flash_uE250.cdl:
+ New package - support for NMI uE250 (Xscale PXA250)
+
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/uE250/current/cdl/flash_uE250.cdl b/ecos/packages/devs/flash/arm/uE250/current/cdl/flash_uE250.cdl
new file mode 100644
index 0000000..5d8b72c
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/uE250/current/cdl/flash_uE250.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_uE250.cdl
+#
+# FLASH memory - Hardware support on NMI uE250 (Xscale PXA250)
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data: gthomas
+# Contributors:
+# Date: 2001-12-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_UE250 {
+ display "Intel UE250 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_XSCALE_UE250
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/uE250_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_ue250.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
+
diff --git a/ecos/packages/devs/flash/arm/uE250/current/include/uE250_strataflash.inl b/ecos/packages/devs/flash/arm/uE250/current/include/uE250_strataflash.inl
new file mode 100644
index 0000000..c40d5c6
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/uE250/current/include/uE250_strataflash.inl
@@ -0,0 +1,66 @@
+#ifndef CYGONCE_DEVS_FLASH_UE250_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_UE250_STRATAFLASH_INL
+//==========================================================================
+//
+// uE250_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: gthomas
+// Date: 2001-12-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// The uEngine uE250 system has two 16-bit devices.
+
+#include <cyg/hal/uE250.h>
+
+#define CYGNUM_FLASH_DEVICES (2)
+#define CYGNUM_FLASH_BASE UE250_FLASH_ADDR
+#define CYGNUM_FLASH_BASE_MASK (0xFC000000u) // 32Mb total
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif
+// ------------------------------------------------------------------------
+// EOF uE250_strataflash.inl
diff --git a/ecos/packages/devs/flash/arm/xsengine/current/ChangeLog b/ecos/packages/devs/flash/arm/xsengine/current/ChangeLog
new file mode 100644
index 0000000..3b7cdbf
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/xsengine/current/ChangeLog
@@ -0,0 +1,36 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_xsengine.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2005-02-23 Kurt Stremerch <kurt.stremerch@exys.be>
+
+ * src/xsengine_flash.c:
+ * cdl/flash_xsengine.cdl:
+ New package - support for Exys XSEngine (Xscale PXA255)
+
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/arm/xsengine/current/cdl/flash_xsengine.cdl b/ecos/packages/devs/flash/arm/xsengine/current/cdl/flash_xsengine.cdl
new file mode 100644
index 0000000..498a54c
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/xsengine/current/cdl/flash_xsengine.cdl
@@ -0,0 +1,70 @@
+# ====================================================================
+#
+# flash_xsengine.cdl
+#
+# FLASH memory - Hardware support on Exys XSEngine (Xscale PXA255)
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Kurt Stremerch
+# Original data: gthomas
+# Contributors:
+# Date: 2005-02-23
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_XSENGINE {
+display "Exys XSEngine FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_ARM_XSCALE_XSENGINE
+
+ compile xsengine_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "AMD S29GL064M driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_S29GL064M
+}
+
+# EOF flash_xsengine.cdl
diff --git a/ecos/packages/devs/flash/arm/xsengine/current/src/xsengine_flash.c b/ecos/packages/devs/flash/arm/xsengine/current/src/xsengine_flash.c
new file mode 100644
index 0000000..776ddc2
--- /dev/null
+++ b/ecos/packages/devs/flash/arm/xsengine/current/src/xsengine_flash.c
@@ -0,0 +1,68 @@
+//==========================================================================
+//
+// xsengine_flash.c
+//
+// Flash programming for AMD Flash devices on Exys XSEngine board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Kurt Stremerch
+// Contributors: gthomas
+// Date: 2005-02-23
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x50000000)
+#define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT
+
+//--------------------------------------------------------------------------
+// Now include the driver code
+#include "cyg/io/flash_am29xxxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF xsengine_flash.c
diff --git a/ecos/packages/devs/flash/atmel/at29cxxxx/current/ChangeLog b/ecos/packages/devs/flash/atmel/at29cxxxx/current/ChangeLog
new file mode 100644
index 0000000..741f550
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/at29cxxxx/current/ChangeLog
@@ -0,0 +1,96 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_atmel_at29cxxxx.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2003-10-02 Roland Cassebohm <r.cassebohm@visionsystems.de>
+
+ * include/flash_at29cxxxx.inl: Improves driver, to work with 16 bit
+ wide access. The driver have to write 256 times after each command
+ sequence, but with two 8 bit divices parallel, the driver writes
+ only 128 times.
+
+2001-09-13 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_at29cxxxx.inl: Added support for AT29LV1024. Added
+ code to erase blocks. Made driver work with 16bit wide
+ parts. Fixed flash size calculations.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_atmel_at29cxxxx.cdl: Links functions to RAM. IO driver
+ need not copy.
+
+2001-02-23 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_at29cxxxx.inl: Include type macros from IO driver.
+
+2001-02-22 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_at29cxxxx.inl: Moved flash_query function. Call it
+ indirectly through the IO driver.
+
+2001-02-20 Jesper Skov <jskov@redhat.com>
+
+ * .../atmel/at29cxxxx: Cloned from am29xxxxx driver.
+
+2000-12-07 Jesper Skov <jskov@redhat.com>
+
+ * src/flash.h: Addresses and sizes are also affected by
+ interleaving.
+ * src/flash_erase_block.c: Plug in working loop.
+ * src/flash_program_buf.c: Same.
+
+2000-12-06 Jesper Skov <jskov@redhat.com>
+
+ * src/am29f040b_flash.c (flash_hwr_init): Use new query semantics.
+ * src/flash_query.c (flash_query): Changed accordingly.
+
+ * src/flash.h (FLASH_Sector_Erase_Timer): Added.
+
+ * src/flash_erase_block.c: Do not check error flag after operation
+ completes.
+ * src/flash_program_buf.c: Same.
+
+2000-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/am29f040b_flash.c (flash_code_overlaps): Define stext/etext
+ as array types so no assumptions can be made by the compiler about
+ location.
+
+2000-12-05 Jesper Skov <jskov@redhat.com>
+
+ * Cloned from MBX driver.
+
+2000-10-20 Gary Thomas <gthomas@redhat.com>
+
+ * src/mbx_flash.c:
+ * src/flash_query.c:
+ * src/flash_program_buf.c:
+ * src/flash_erase_block.c:
+ * src/flash.h:
+ * cdl/flash_mbx.cdl: New package/file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/atmel/at29cxxxx/current/cdl/flash_atmel_at29cxxxx.cdl b/ecos/packages/devs/flash/atmel/at29cxxxx/current/cdl/flash_atmel_at29cxxxx.cdl
new file mode 100644
index 0000000..0fbd3c9
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/at29cxxxx/current/cdl/flash_atmel_at29cxxxx.cdl
@@ -0,0 +1,62 @@
+# ====================================================================
+#
+# flash_atmel_at29cxxxx.cdl
+#
+# FLASH memory - Hardware support for Atmel AT29Cxxxx parts
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX {
+ display "Atmel AT29CXXXX FLASH memory support"
+ description "FLASH memory device support for Atmel AT29CXXXX"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+
+ active_if CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ include_dir cyg/io
+}
diff --git a/ecos/packages/devs/flash/atmel/at29cxxxx/current/include/flash_at29cxxxx.inl b/ecos/packages/devs/flash/atmel/at29cxxxx/current/include/flash_at29cxxxx.inl
new file mode 100644
index 0000000..a5292a5
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/at29cxxxx/current/include/flash_at29cxxxx.inl
@@ -0,0 +1,351 @@
+#ifndef CYGONCE_DEVS_FLASH_ATMEL_AT29CXXXX_INL
+#define CYGONCE_DEVS_FLASH_ATMEL_AT29CXXXX_INL
+//==========================================================================
+//
+// at29cxxxx.inl
+//
+// Atmel AT29Cxxxx series flash driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov
+// Date: 2001-02-21
+// Purpose:
+// Description:
+//
+// Notes: FLASH_P2V is not properly used.
+// Needs locking.
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+
+//----------------------------------------------------------------------------
+// Common device details.
+#define FLASH_Read_ID FLASHWORD( 0x90 )
+#define FLASH_Read_ID_Exit FLASHWORD( 0xF0 )
+#define FLASH_Reset FLASHWORD( 0xFF )
+#define FLASH_Program FLASHWORD( 0xA0 )
+#define FLASH_Block_Erase FLASHWORD( 0x30 )
+
+#define FLASH_Data FLASHWORD( 0x80 ) // Data complement
+#define FLASH_Busy FLASHWORD( 0x40 ) // "Toggle" bit
+#define FLASH_Err FLASHWORD( 0x20 )
+#define FLASH_Sector_Erase_Timer FLASHWORD( 0x08 )
+
+#define FLASH_Setup_Addr1 (0x5555)
+#define FLASH_Setup_Addr2 (0x2AAA)
+#define FLASH_Setup_Code1 FLASHWORD( 0xAA )
+#define FLASH_Setup_Code2 FLASHWORD( 0x55 )
+#define FLASH_Setup_Erase FLASHWORD( 0x80 )
+
+// Platform code must define the below
+// #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel)
+// #define CYGNUM_FLASH_SERIES : Number of devices in series
+// #define CYGNUM_FLASH_BASE : Address of first device
+// And select one of the below device variants
+
+#ifdef CYGPKG_DEVS_FLASH_ATMEL_AT29C040A
+# define FLASH_BLOCK_SIZE (0x10000*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS (8)
+# define CYGNUM_FLASH_BASE_MASK (0xFFF80000u) // 512kB devices
+# define CYGNUM_FLASH_WIDTH (8)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x1F)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0xA4)
+#endif
+#ifdef CYGPKG_DEVS_FLASH_ATMEL_AT29LV1024
+# define FLASH_BLOCK_SIZE (0x100*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS (512)
+# define CYGNUM_FLASH_BASE_MASK (0xFFFe0000u) // 128kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x1F)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x26)
+#endif
+
+#define FLASH_DEVICE_SIZE (FLASH_BLOCK_SIZE*FLASH_NUM_REGIONS)
+#define CYGNUM_FLASH_DEVICES (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
+
+//----------------------------------------------------------------------------
+// Now that device properties are defined, include magic for defining
+// accessor type and constants.
+#include <cyg/io/flash_dev.h>
+
+//----------------------------------------------------------------------------
+// Functions that put the flash device into non-read mode must reside
+// in RAM.
+void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
+int flash_erase_block(void* block, unsigned int size)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int flash_program_buf(void* addr, void* data, int len)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+
+
+//----------------------------------------------------------------------------
+// Initialize driver details
+int
+flash_hwr_init(void)
+{
+ flash_data_t id[2];
+
+ flash_dev_query(id);
+
+ // Check that flash_id data is matching the one the driver was
+ // configured for.
+ if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER
+ || id[1] != CYGNUM_FLASH_ID_DEVICE)
+ return FLASH_ERR_DRV_WRONG_PART;
+
+ // Hard wired for now
+ flash_info.block_size = FLASH_BLOCK_SIZE;
+ flash_info.blocks = FLASH_NUM_REGIONS;
+ flash_info.start = (void *)CYGNUM_FLASH_BASE;
+ flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (FLASH_NUM_REGIONS * FLASH_BLOCK_SIZE * CYGNUM_FLASH_SERIES));
+ return FLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int e)
+{
+ return e;
+}
+
+
+//----------------------------------------------------------------------------
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern unsigned char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
+
+//----------------------------------------------------------------------------
+// Flash Query
+//
+// Only reads the manufacturer and part number codes for the first
+// device(s) in series. It is assumed that any devices in series
+// will be of the same type.
+
+void
+flash_query(void* data)
+{
+ volatile flash_data_t *ROM;
+ flash_data_t* id = (flash_data_t*) data;
+ int i;
+
+ ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
+
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Read_ID;
+
+ // FIXME: 10ms delay
+ for (i = 10000; i > 0; i--);
+
+ // Manufacturers' code
+ id[0] = ROM[0];
+ // Part number
+ id[1] = ROM[1];
+
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Read_ID_Exit;
+
+ // FIXME: 10ms delay
+ for (i = 10000; i > 0; i--);
+}
+
+//----------------------------------------------------------------------------
+// Erase Block
+int
+flash_erase_block(void* block, unsigned int len)
+{
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* addr_ptr = (volatile flash_data_t*) block;
+ volatile flash_data_t* addr_ptr2;
+
+ int res = FLASH_ERR_OK;
+
+ while ((FLASH_ERR_OK == res) && (len > 0)) {
+ int len2, i, timeout;
+ flash_data_t state, prev_state;
+
+ // Base address of device(s) being programmed.
+ ROM = (volatile flash_data_t*)((unsigned long)block & ~(FLASH_DEVICE_SIZE-1));
+
+ // Program data [byte] - 4 step sequence
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Program;
+
+ addr_ptr2 = addr_ptr;
+ len2 = len;
+
+ // Always load 256 times
+ for (i = 0; i < 256; i++) {
+ *addr_ptr2++ = FLASH_BlankValue;
+ }
+
+ // Wait for completion (bit 6 stops toggling)
+ timeout = 5000000;
+ prev_state = *addr_ptr & FLASH_Busy;
+ while (true) {
+ state = *addr_ptr & FLASH_Busy;
+ if (prev_state == state) {
+ break;
+ }
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ prev_state = state;
+ }
+
+ // Verify loaded data bytes
+ for (i = 0; (len > 0) && (i < 256) ;) {
+ if (*addr_ptr != FLASH_BlankValue) {
+ // Only update return value if erase operation was OK
+ if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
+ break;
+ }
+ addr_ptr++;
+ len -= sizeof(*addr_ptr);
+ i += sizeof(*addr_ptr);
+ }
+ }
+
+ return FLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// Program Buffer
+int
+flash_program_buf(void* addr, void* data, int len)
+{
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr;
+ volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
+ volatile flash_data_t* addr_ptr2;
+ volatile flash_data_t* data_ptr2;
+
+ int res = FLASH_ERR_OK;
+
+#if 0
+ CYG_ASSERT((unsigned long)data_ptr & (sizeof(flash_data_t)-1) == 0,
+ "Data not properly aligned");
+ CYG_ASSERT((unsigned long)addr_ptr & (CYGNUM_FLASH_INTERLEAVE*sizeof(flash_data_t)-1) == 0,
+ "Addr not properly aligned (to first interleaved device)");
+#endif
+
+ while ((FLASH_ERR_OK == res) && (len > 0)) {
+ int len2, i, timeout;
+ flash_data_t state, prev_state;
+
+ // Base address of device(s) being programmed.
+ ROM = (volatile flash_data_t*)((unsigned long)addr & ~(FLASH_DEVICE_SIZE-1));
+
+ // Program data [byte] - 4 step sequence
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Program;
+
+ addr_ptr2 = addr_ptr;
+ data_ptr2 = data_ptr;
+ len2 = len;
+
+ // Always load 256 times
+ for (i = 0; i < 256; i++) {
+ if (len2 > 0) {
+ *addr_ptr2++ = *data_ptr2++;
+ len2 -= sizeof(*data_ptr2);
+ } else {
+ *addr_ptr2++ = FLASH_BlankValue;
+ }
+ }
+
+ // Wait for completion (bit 6 stops toggling)
+ timeout = 5000000;
+ prev_state = *addr_ptr & FLASH_Busy;
+ while (true) {
+ state = *addr_ptr & FLASH_Busy;
+ if (prev_state == state) {
+ break;
+ }
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ prev_state = state;
+ }
+
+ // Verify loaded data bytes
+ for (i = 0; (len > 0) && (i < 256) ;) {
+ if (*addr_ptr != *data_ptr) {
+ // Only update return value if erase operation was OK
+ if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
+ break;
+ }
+ addr_ptr++;
+ data_ptr++;
+ len -= sizeof(*data_ptr);
+ i += sizeof(*data_ptr);
+ }
+ }
+
+
+ // Ideally, we'd want to return not only the failure code, but also
+ // the address/device that reported the error.
+ return res;
+}
+
+#endif // CYGONCE_DEVS_FLASH_ATMEL_AT29CXXXX_INL
diff --git a/ecos/packages/devs/flash/atmel/at49xxxx/current/ChangeLog b/ecos/packages/devs/flash/atmel/at49xxxx/current/ChangeLog
new file mode 100644
index 0000000..b03405a
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/at49xxxx/current/ChangeLog
@@ -0,0 +1,88 @@
+2008-12-23 Evgeniy Dushistov <dushistov@mail.ru>
+
+ * include/flash_at49xxxx_parts.inl: Add support for
+ AT49BV642D.
+
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_atmel_at49xxxx.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2005-02-15 Jacques Tinembart <Jacques.Tinembart@eig.unige.ch>
+
+ * include/flash_at49xxxx.inl, include/flash_at49xxxx_parts.inl:
+ add support for AT49LV161 and AT49BV322A
+
+2004-11-12 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/flash_at49xxxx_parts.inl: Give a compiler error if the
+ bug workaround for the AT49BV16[01]4A is not enabled.
+
+2004-05-11 Thomas Koeller <thomas.koeller@baslerweb.com>
+
+ * cdl/flash_atmel_at49xxxx.cdl:
+ * include/flash_at49xxxx.inl: Added workaround for Atmel
+ AT91FR40162 erase bug.
+
+2003-11-10 Gary Thomas <gary@mlbassoc.com>
+
+ * include/flash_at49xxxx_parts.inl: Add AT29LV200BB
+
+2003-09-19 Gary Thomas <gary@mlbassoc.com>
+
+ * include/flash_at49xxxx_parts.inl: Add support for AT49LV040
+
+ * include/flash_at49xxxx.inl: Support devices which need "chip erase"
+ as opposed to "sector erase" operations.
+
+2003-08-08 Oyvind Harboe <oyvind.harboe@zylin.com>
+
+ * include/flash_at49xxxx.inl: the program/erase completion had a
+ race condtion. Changes algorithms to one that does not suffer
+ from potential race conditions.
+
+2003-07-15 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * include/flash_at49xxxx.inl: Reorganise to support boot blocks,
+ multiple flash types from the same driver, and do proper
+ verification.
+ * include/flash_at49xxxx_parts.inl: New file to describe flash
+ part information.
+
+2003-06-10 Øyvind Harboe <oyvind.harboe@zylin.com>
+
+ * include/flash_at49xxxx.inl: wait_while_busy needs to be in RAM
+ since its called while the flash is not readable.
+
+2002-07-12 Tim Drury (tdrury@siliconmotorsports.com>
+
+ * include/flash_at49xxxx.inl: added support for AT49LV1614
+
+2002-06-24 Jani Monoses <jani@iv.ro>
+
+ * include/flash_at49xxxx.inl: Added support for AT49BV8011
+ based on AT29XXXXX
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/atmel/at49xxxx/current/cdl/flash_atmel_at49xxxx.cdl b/ecos/packages/devs/flash/atmel/at49xxxx/current/cdl/flash_atmel_at49xxxx.cdl
new file mode 100644
index 0000000..a83888d
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/at49xxxx/current/cdl/flash_atmel_at49xxxx.cdl
@@ -0,0 +1,76 @@
+# ====================================================================
+#
+# flash_atmel_at49xxxx.cdl
+#
+# FLASH memory - Hardware support for Atmel AT49xxxx parts
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jani@iv.ro
+# Contributors:
+# Date: 2002-06-24
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ATMEL_AT49XXXX {
+ display "Atmel AT49XXXX FLASH memory support"
+ description "FLASH memory device support for Atmel AT49XXXX"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+
+ active_if CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ include_dir cyg/io
+
+ cdl_option CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND {
+ display "AT91FR40162 erase bug workaround"
+ flavor bool
+ default_value 0
+ description "
+ The flash chips used in Atmel AT91FR40162 microcontrollers have a silicon bug
+ that causes erase operations to be unreliable unless any data to be erased is
+ cleared first, see http://www.atmel.com/dyn/resources/prod_documents/doc6076.pdf.
+ Selecting this option enables that workaround. Of course, erase operations will be
+ slower then."
+ }
+}
+
+# EOF flash_atmel_49xxxx.cdl
diff --git a/ecos/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl b/ecos/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl
new file mode 100644
index 0000000..d12e7ec
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx.inl
@@ -0,0 +1,420 @@
+#ifndef CYGONCE_DEVS_FLASH_ATMEL_AT49XXXX_INL
+#define CYGONCE_DEVS_FLASH_ATMEL_AT49XXXX_INL
+//==========================================================================
+//
+// at49xxxx.inl
+//
+// Atmel AT49xxxx series flash driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Jani Monoses <jani@iv.ro>
+// Contributors: Cristian Vlasin <cris@iv.ro>, tdrury, jlarmour
+// J. Tinembart
+// Date: 2002-06-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_atmel_at49xxxx.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_diag.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+
+//----------------------------------------------------------------------------
+// Common device details.
+#define FLASH_Read_ID FLASHWORD( 0x90 )
+#define FLASH_Read_ID_Exit FLASHWORD( 0xF0 )
+#define FLASH_Program FLASHWORD( 0xA0 )
+#define FLASH_Sector_Erase FLASHWORD( 0x30 )
+#define FLASH_Chip_Erase FLASHWORD( 0x10 )
+
+#define FLASH_Busy FLASHWORD( 0x40 ) // "Toggle" bit, I/O 6
+#define FLASH_InverseData FLASHWORD( 0x80 ) // I/O 7, Inverse data
+
+#ifdef CYGHWR_DEVS_FLASH_ATMEL_AT49LV161
+#define FLASH_Setup_Addr1 (0x555)
+#define FLASH_Setup_Addr2 (0xAAA)
+#else
+#define FLASH_Setup_Addr1 (0x5555)
+#define FLASH_Setup_Addr2 (0x2AAA)
+#endif
+#define FLASH_Setup_Code1 FLASHWORD( 0xAA )
+#define FLASH_Setup_Code2 FLASHWORD( 0x55 )
+#define FLASH_Setup_Erase FLASHWORD( 0x80 )
+
+#define CYGNUM_FLASH_BLANK (1)
+
+#ifndef CYGNUM_FLASH_ID_MANUFACTURER
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x1F)
+#endif
+
+//----------------------------------------------------------------------------
+// Now that device properties are defined, include magic for defining
+// accessor type and constants.
+#include <cyg/io/flash_dev.h>
+
+//----------------------------------------------------------------------------
+// Information about supported devices
+typedef struct flash_dev_info {
+ flash_data_t device_id;
+#ifdef CYG_FLASH_LONG_DEVICE_NEEDED
+ cyg_bool long_device_id;
+ flash_data_t device_id2;
+ flash_data_t device_id3;
+#endif
+ cyg_uint32 block_size;
+ cyg_int32 block_count;
+ cyg_uint32 base_mask;
+ cyg_uint32 device_size;
+ cyg_bool bootblock;
+ cyg_bool chip_erase;
+ cyg_uint32 bootblocks[64]; // 0 is bootblock offset, 1-11 sub-sector sizes (or 0)
+#ifdef NOTYET // FIXME: not supported yet (use am29xxxxx for template)
+ cyg_bool banked;
+ cyg_uint32 banks[8]; // bank offsets, highest to lowest (lowest should be 0)
+ // (only one entry for now, increase to support devices
+ // with more banks).
+#endif
+} flash_dev_info_t;
+
+static const flash_dev_info_t* flash_dev_info;
+static const flash_dev_info_t supported_devices[] = {
+#include <cyg/io/flash_at49xxxx_parts.inl>
+};
+#define NUM_DEVICES (sizeof(supported_devices)/sizeof(flash_dev_info_t))
+
+//----------------------------------------------------------------------------
+// Functions that put the flash device into non-read mode must reside
+// in RAM.
+void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
+int flash_erase_block(void* block, unsigned int size)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int flash_program_buf(void* addr, void* data, int len)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+static int wait_while_busy(int timeout, volatile flash_data_t* addr_ptr, flash_data_t value)
+ __attribute__ ((section (".2ram.text")));
+
+//----------------------------------------------------------------------------
+// Initialize driver details
+int
+flash_hwr_init(void)
+{
+ flash_data_t id[4];
+ int i;
+
+#ifdef CYGHWR_FLASH_AT49XXXX_PLF_INIT
+ CYGHWR_FLASH_AT49XXXX_PLF_INIT();
+#endif
+
+ flash_dev_query(id);
+
+ // Check that flash_id data is matching the one the driver was
+ // configured for.
+
+ // Check manufacturer
+ if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER)
+ return FLASH_ERR_DRV_WRONG_PART;
+
+ // Look through table for device data
+ flash_dev_info = supported_devices;
+#ifdef CYG_FLASH_LONG_DEVICE_NEEDED
+ for (i = 0; i < NUM_DEVICES; i++) {
+ if (!flash_dev_info->long_device_id && flash_dev_info->device_id == id[1])
+ break;
+ else if ( flash_dev_info->long_device_id && flash_dev_info->device_id == id[1]
+ && flash_dev_info->device_id2 == id[2]
+ && flash_dev_info->device_id3 == id[3] )
+ break;
+ flash_dev_info++;
+ }
+#else
+ for (i = 0; i < NUM_DEVICES; i++) {
+ if (flash_dev_info->device_id == id[1])
+ break;
+ flash_dev_info++;
+ }
+#endif
+
+ // Did we find the device? If not, return error.
+ if (NUM_DEVICES == i)
+ return FLASH_ERR_DRV_WRONG_PART;
+
+ // Hard wired for now
+ flash_info.block_size = flash_dev_info->block_size;
+ flash_info.blocks = flash_dev_info->block_count * CYGNUM_FLASH_SERIES;
+ flash_info.start = (void *)CYGNUM_FLASH_BASE;
+ flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (flash_dev_info->device_size * CYGNUM_FLASH_SERIES));
+ return FLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int e)
+{
+ return e;
+}
+
+
+//----------------------------------------------------------------------------
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern unsigned char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
+
+//----------------------------------------------------------------------------
+// Flash Query
+//
+// Only reads the manufacturer and part number codes for the first
+// device(s) in series. It is assumed that any devices in series
+// will be of the same type.
+
+void
+flash_query(void* data)
+{
+ volatile flash_data_t *ROM;
+ flash_data_t* id = (flash_data_t*) data;
+
+ ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
+
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Read_ID;
+
+ // FIXME: 10ms delay?
+
+ // Manufacturers' code
+ id[0] = ROM[0];
+ // Part number
+ id[1] = ROM[1];
+
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Read_ID_Exit;
+
+ // FIXME: 10ms delay?
+}
+
+// Wait for completion. While programming/erasing check
+// that i/o 7 is inverse of data as described in Atmels examples.
+
+static int wait_while_busy(int timeout, volatile flash_data_t* addr_ptr, flash_data_t expected)
+{
+ int val;
+ flash_data_t state;
+ while (true) {
+ state = *addr_ptr & FLASH_InverseData;
+ if (state==(expected&FLASH_InverseData)) {
+ val=FLASH_ERR_OK;
+ break;
+ }
+ if (--timeout == 0) {
+ val=FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ }
+ return val;
+}
+
+//----------------------------------------------------------------------------
+// Erase Block
+int
+flash_erase_block(void* block, unsigned int size)
+{
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* b_p = (volatile flash_data_t*) block;
+
+ int res = FLASH_ERR_OK;
+ unsigned int len = 0;
+ cyg_bool bootblock = false;
+ cyg_uint32 *bootblocks = (cyg_uint32 *)0;
+
+ // diag_printf("\nERASE: Block %p, size: %u\n",block,size);
+
+ // Base address of device(s) being programmed.
+ ROM = (volatile flash_data_t*) ((unsigned long)block & flash_dev_info->base_mask);
+
+
+#if defined(CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND)
+
+ // Before erasing the data, overwrite it with all zeroes. This is a workaround
+ // for a silicon bug that affects erasing of some devices, see
+ // http://www.atmel.com/dyn/resources/prod_documents/doc6076.pdf.
+ for (len = size / sizeof *b_p; (FLASH_ERR_OK == res) && (len > 0); len--, b_p++) {
+ // Program data [byte] - 4 step sequence
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Program;
+ *b_p = 0;
+
+ res = wait_while_busy(5000000, b_p, 0);
+
+ if (*b_p != 0)
+ // Only update return value if operation was OK
+ if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
+ }
+
+ if (FLASH_ERR_OK != res)
+ return res;
+
+ b_p = (volatile flash_data_t*) block;
+
+#endif // defined(CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND)
+
+ // Assume not "boot" sector, full size
+ bootblock = false;
+ len = flash_dev_info->block_size;
+
+ // Is this in a "boot" sector?
+ if (flash_dev_info->bootblock) {
+ bootblocks = (cyg_uint32 *)&flash_dev_info->bootblocks[0];
+ while (*bootblocks != _LAST_BOOTBLOCK) {
+ if (*bootblocks++ == ((unsigned long)block - (unsigned long)ROM)) {
+ len = *bootblocks++; // Size of first sub-block
+ bootblock = true;
+ // diag_printf("\nERASE: Is Boot block - size: %d, ptr %p\n",len,b_p);
+ break;
+ } else {
+ int ls = flash_dev_info->block_size;
+ // Skip over segment
+ while ((ls -= *bootblocks++) > 0) ;
+ }
+ }
+ }
+
+ while (size > 0) {
+ //Erase sector 6-byte sequence
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Erase;
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ if (flash_dev_info->chip_erase) {
+ // Can only erase the entire device!
+ if (b_p == ROM) {
+ ROM[FLASH_Setup_Addr1] = FLASH_Chip_Erase;
+ } else {
+ res = FLASH_ERR_DRV_VERIFY;
+ }
+ } else {
+ *b_p = FLASH_Sector_Erase;
+ }
+
+ size -= len; // This much has been erased
+
+ res = wait_while_busy(66000000, b_p, FLASH_BlankValue);
+
+ // Verify erase operation
+ if (FLASH_ERR_OK == res) {
+ while (len > 0) {
+ if (*b_p != FLASH_BlankValue) {
+ break;
+ }
+ len -= sizeof(*b_p);
+ b_p++;
+ }
+ }
+
+ if (FLASH_ERR_OK != res)
+ break;
+
+ if (bootblock) {
+ len = *bootblocks++;
+ // diag_printf("\nERASE: Is Boot block - size: %d, len %d, ptr %p\n",size,len,b_p);
+ }
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------------
+// Program Buffer
+int
+flash_program_buf(void* addr, void* data, int len)
+{
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr;
+ volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
+ int res = FLASH_ERR_OK;
+
+ // check the address is suitably aligned
+ if ((unsigned long)addr & (CYGNUM_FLASH_INTERLEAVE * CYGNUM_FLASH_WIDTH / 8 - 1))
+ return FLASH_ERR_INVALID;
+
+ // Base address of device(s) being programmed.
+ ROM = (volatile flash_data_t*)((unsigned long)addr_ptr & flash_dev_info->base_mask);
+
+ while ((FLASH_ERR_OK == res) && (len > 0)) {
+ // Program data [byte] - 4 step sequence
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Program;
+ addr_ptr[0] = data_ptr[0];
+
+ res = wait_while_busy(5000000,addr_ptr, data_ptr[0]);
+
+ if (*addr_ptr++ != *data_ptr++) {
+ // Only update return value if operation was OK
+ if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
+ break;
+ }
+
+ len -= sizeof (*data_ptr);
+ }
+
+ return res;
+}
+
+#endif // CYGONCE_DEVS_FLASH_ATMEL_AT49XXXX_INL
+
+// EOF flash_at49xxxx.inl
diff --git a/ecos/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx_parts.inl b/ecos/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx_parts.inl
new file mode 100644
index 0000000..67d820f
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/at49xxxx/current/include/flash_at49xxxx_parts.inl
@@ -0,0 +1,247 @@
+#ifndef CYGONCE_DEVS_FLASH_ATMEL_AT49XXXX_PARTS_INL
+#define CYGONCE_DEVS_FLASH_ATMEL_AT49XXXX_PARTS_INL
+//==========================================================================
+//
+// at49xxxx_parts.inl
+//
+// Atmel AT49xxxx series part descriptions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour,Jani Monoses <jani@iv.ro>
+// Contributors: Jani Monoses <jani@iv.ro>, Cristian Vlasin <cris@iv.ro>, tdrury
+// J. Tinembart
+// Date: 2003-07-14
+// Purpose: Should be included from the flash_at49xxxx.inl file only.
+// Description: Atmel AT49xxxx part descriptions
+//
+// FIXME: Add configury for selecting bottom/top bootblocks
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//
+// Note: 'bootblocks' are a set of blocks which are treated by
+// the driver as a single larger block. This simplifies the driver
+// so as to only have to deal with single size blocks (even though
+// the physical device may differ). The data structure is laid out as:
+// <address of start of boot block area 1>
+// <size of sub-block 1>
+// <size of sub-block 2>
+// ...
+// <size of sub-block n>
+// <address of start of boot block area 2>
+// <size of sub-block 1>
+// <size of sub-block 2>
+// ...
+// <size of sub-block n>
+// _LAST_BOOTBLOCK
+//
+// Finally, when specifying a device with bootblocks, the total number
+// of blocks should reflect this collapse, i.e. if the device has 15
+// full size blocks and 8 blocks which are 1/8 each, then the total
+// should be 16 blocks.
+
+#define _LAST_BOOTBLOCK (-1)
+
+// Platform code must define the below
+// #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel)
+// #define CYGNUM_FLASH_SERIES : Number of devices in series
+// #define CYGNUM_FLASH_WIDTH : Width of devices on platform
+// #define CYGNUM_FLASH_BASE : Address of first device
+// And select one of the below device variants
+
+#if defined(CYGPKG_DEVS_FLASH_ATMEL_AT49LV040)
+//
+// Note: this device is not terribly useful for anything other than a bootstrap device
+// as it is only 512KB and has only one erase block.
+//
+ { // AT49LV040
+ device_id : FLASHWORD(0x13),
+ block_size : 0x80000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 1,
+ device_size: 0x80000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x80000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : false,
+ chip_erase : true
+ },
+#endif
+
+#if defined(CYGHWR_DEVS_FLASH_ATMEL_AT49LV8011) || \
+ defined(CYGHWR_DEVS_FLASH_ATMEL_AT49BV8011)
+ { // AT49BV/LV8011
+ // the following ID is true for both 8 and 16 bit CYGNUM_FLASH_WIDTH
+ device_id : FLASHWORD(0xCB),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ }
+ },
+#endif
+#if defined(CYGHWR_DEVS_FLASH_ATMEL_AT49LV8011T) || \
+ defined(CYGHWR_DEVS_FLASH_ATMEL_AT49BV8011T)
+ { // AT49BV/LV8011
+ // the following ID is true for both 8 and 16 bit CYGNUM_FLASH_WIDTH
+ device_id : FLASHWORD(0x4A),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 16,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x0E0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ }
+ },
+#endif
+#if defined(CYGHWR_DEVS_FLASH_ATMEL_AT49BV1604A) || \
+ defined(CYGHWR_DEVS_FLASH_ATMEL_AT49BV1614A) || \
+ defined(CYGHWR_DEVS_FLASH_ATMEL_AT49LV1614A) || \
+ defined(CYGHWR_DEVS_FLASH_ATMEL_AT49LV161)
+ { // AT49BV/LV8011
+ // the following ID is true for both 8 and 16 bit CYGNUM_FLASH_WIDTH
+ device_id : FLASHWORD(0xC0),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ }
+ },
+#endif
+#if defined(CYGHWR_DEVS_FLASH_ATMEL_AT49BV322A)
+ { // AT49BV322A
+ // the following ID is true for both 8 and 16 bit CYGNUM_FLASH_WIDTH
+ device_id : FLASHWORD(0xC8),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ }
+ },
+#endif
+#if defined(CYGHWR_DEVS_FLASH_ATMEL_AT29LV200BB)
+ { // AT29LV200BB
+ device_id : FLASHWORD(0x22BF),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 4,
+ device_size: 0x40000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x40000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE, // 0x00000..0x03FFF
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE, // 0x04000..0x05FFF
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE, // 0x06000..0x07FFF
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE, // 0x08000..0x0FFFF
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ }
+ },
+#endif
+#if defined(CYGHWR_DEVS_FLASH_ATMEL_AT49BV642D)
+ {
+ device_id : FLASHWORD(0x1D6),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x800000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x800000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ }
+ },
+#endif
+
+#if defined(CYGHWR_DEVS_FLASH_ATMEL_AT49BV1604A) || \
+ defined(CYGHWR_DEVS_FLASH_ATMEL_AT49BV1614A) || \
+ defined(CYGHWR_DEVS_FLASH_ATMEL_AT49LV1614A)
+#ifndef CYGHWR_DEVS_FLASH_ATMEL_AT49XXXX_ERASE_BUG_WORKAROUND
+#warning This flash device contains a hardware bug and you have not
+#warning enabled the workaround for it. See the CDL file.
+#endif
+#endif
+
+#endif // ifndef CYGONCE_DEVS_FLASH_ATMEL_AT49XXXX_PARTS_INL
+
+// EOF flash_at49xxxx_parts.inl
diff --git a/ecos/packages/devs/flash/atmel/dataflash/current/ChangeLog b/ecos/packages/devs/flash/atmel/dataflash/current/ChangeLog
new file mode 100644
index 0000000..8d01371
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/dataflash/current/ChangeLog
@@ -0,0 +1,94 @@
+2010-03-25 Daniel Helgason <dhelgason@shaw.ca>
+
+ * src/devs_flash_atmel_dataflash.c: Correct bad sector count for
+ AT45DB642 dataflash device.
+ * cdl/devs_flash_atmel_dataflash.cdl: Mark CYGPKG_IO_FLASH as the
+ parent of this package.
+
+2005-06-29 Jani Monoses <ani@iv.ro>
+
+ * include/dataflash.h: Allow the package to be compiled without
+ io/flash. Return correct value from cyg_dataflash_get_page_count()
+
+2004-12-02 Bart Veer <bartv@ecoscentric.com>
+
+ * include/dataflash.h,
+ src/devs_flash_atmel_dataflash_flash_dev_funs.c: include
+ <cyg/io/flash_dev.h> explicitly rather than using _FLASH_PRIVATE_
+
+2004-11-29 Bart Veer <bartv@ecoscentric.com>
+
+ (df_flash_hwr_map_error): this is now internal to the driver, no
+ longer needed by the generic flash code.
+ * src/devs_flash_atmel_dataflash_flash_dev_funs.c: use the dummy
+ query/lock/unlock functions provided by the generic flash code
+
+2004-11-22 Bart Veer <bartv@ecoscentric.com>
+
+ * include/dataflash.h, src/devs_flash_atmel_dataflash.c,
+ src/devs_flash_atmel_dataflash_flash_dev_funs.c: merge the config
+ and priv structures, removing the duplicate spi_dev data in the
+ process. Adjust device driver API as per changes to the generic
+ flash code.
+ * src/devs_flash_atmel_dataflash_flash_dev_funs.c (df_flash_init):
+ Rename cyg_block_info to cyg_flash_block_info
+
+2004-11-21 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/devs_flash_atmel_dataflash.cdl: CYGHWR_IO_FLASH_DEVICE_V2 is
+ now implicit
+
+2004-11-20 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/devs_flash_atmel_dataflash.cdl: data flash requires indirect
+ read support in the main flash code.
+
+2004-10-07 Savin Zlobec <savin@elatec.si>
+
+ * include/dataflash.h:
+ * src/devs_flash_atmel_dataflash.c:
+ Changed the API to be more consistent, included error
+ reporting and added blocking/non blocking mode of operation.
+ * src/devs_flash_atmel_dataflash_flash_dev_funs.c:
+ Synced with new API and set the block size to DataFlash's
+ native page size.
+
+2004-10-07 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/devs_flash_atmel_dataflash.cdl: Remove
+ CYGSEM_IO_FLASH_READ_INDIRECT which only legacy drivers should use
+ when they provide a flash_read_buf function. For V2 drivers
+ providing a read function in the device structure is sufficient.
+
+2004-09-07 Savin Zlobec <savin@elatec.si>
+
+ * cdl/devs_flash_atmel_dataflash.cdl:
+ * include/dataflash.h:
+ * src/devs_flash_atmel_dataflash.c:
+ * src/devs_flash_atmel_dataflash_flash_dev_funs.c:
+ Atmel DataFlash driver implementation.
+
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl b/ecos/packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl
new file mode 100644
index 0000000..e93a597
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl
@@ -0,0 +1,71 @@
+# ====================================================================
+#
+# devs_flash_atmel_dataflash.cdl
+#
+# Atmel DataFlash parts support
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Savin Zlobec <savin@elatec.si>
+# Date: 2004-08-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ATMEL_DATAFLASH {
+ display "Atmel DataFlash parts support"
+ description "Support for Atmel DataFlash"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_SPI
+ requires CYGPKG_ERROR
+ hardware
+ compile devs_flash_atmel_dataflash.c
+ include_dir cyg/io
+
+ cdl_interface CYGPKG_DEVS_FLASH_ATMEL_DATAFLASH_FLASH_DEV {
+ display "Support for DataFlash IO Flash interface"
+ flavor bool
+ active_if CYGPKG_IO_FLASH
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_INDIRECT_READS
+ compile devs_flash_atmel_dataflash_flash_dev_funs.c
+ description "This option will be enabled by platforms which
+ need to support access to DataFlash through IO Flash API."
+ }
+}
+
+# EOF devs_flash_atmel_dataflash.cdl
diff --git a/ecos/packages/devs/flash/atmel/dataflash/current/include/dataflash.h b/ecos/packages/devs/flash/atmel/dataflash/current/include/dataflash.h
new file mode 100644
index 0000000..7d6213f
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/dataflash/current/include/dataflash.h
@@ -0,0 +1,248 @@
+#ifndef CYGONCE_DATAFLASH_H
+#define CYGONCE_DATAFLASH_H
+//==========================================================================
+//
+// dataflash.h
+//
+// DataFlash series flash driver defines
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Savin Zlobec <savin@elatec.si>
+// Date: 2004-08-27
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_atmel_dataflash.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+
+//----------------------------------------------------------------------------
+
+enum {
+ CYG_DATAFLASH_ERR_OK = 0, // No error
+ CYG_DATAFLASH_ERR_INVALID = 1, // Invalid address error
+ CYG_DATAFLASH_ERR_WRONG_PART = 2, // Unsupported device error
+ CYG_DATAFLASH_ERR_TIMEOUT = 3, // Operation timeout error
+ CYG_DATAFLASH_ERR_COMPARE = 4 // Buffer - main memory compare error
+};
+
+enum {
+ CYG_DATAFLASH_STATE_IDLE = 0,
+ CYG_DATAFLASH_STATE_BUSY = 1
+};
+
+//----------------------------------------------------------------------------
+
+typedef struct cyg_dataflash_dev_info_s
+{
+ cyg_uint8 device_id; // Device ID
+ cyg_uint16 page_size; // Page size in bytes
+ cyg_uint16 page_count; // Total number of pages
+ cyg_uint8 baddr_bits; // Bits used for byte address in addressing seq
+ cyg_uint16 block_size; // Block size in pages
+ cyg_uint16 sector_sizes[64]; // Sector sizes in blocks
+ cyg_uint16 sector_count; // Total number of sectors
+} cyg_dataflash_dev_info_t;
+
+typedef struct cyg_dataflash_device_s
+{
+ const cyg_dataflash_dev_info_t *info; // DataFlash device info
+ cyg_spi_device *spi_dev; // SPI device
+ cyg_drv_mutex_t lock; // Access lock
+ cyg_bool polled; // Polled mode flag
+ cyg_bool blocking; // Blocking mode flag
+ int state; // Current state (IDLE, BUSY, ...)
+ cyg_uint8 busy_buf; // Current busy buffer number
+} cyg_dataflash_device_t;
+
+//----------------------------------------------------------------------------
+#ifdef CYGPKG_IO_FLASH
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+typedef struct cyg_dataflash_flash_dev_priv_s
+{
+ cyg_int16 start_sector; // Start sector of flash driver space
+ cyg_int16 end_sector; // End sector of flash driver space
+ cyg_dataflash_device_t dev; // DataFlash device
+ cyg_uint32 start_page; // Start page of flash driver space
+ cyg_uint32 end_page; // End page of flash driver space
+ cyg_flash_block_info_t block_info[1];
+} cyg_dataflash_flash_dev_priv_t;
+
+externC struct cyg_flash_dev_funs cyg_dataflash_flash_dev_funs;
+
+#define CYG_DATAFLASH_FLASH_DRIVER(name, _sdev, _addr, _start, _end) \
+ static cyg_dataflash_flash_dev_priv_t cyg_dataflash_priv_ ## name = { \
+ .start_sector = _start, \
+ .end_sector = _end, \
+ .dev.spi_dev = _sdev, \
+ }; \
+ CYG_FLASH_DRIVER(name, \
+ &cyg_dataflash_flash_dev_funs, \
+ 0, \
+ _addr, \
+ 0, \
+ 1, \
+ cyg_dataflash_priv_ ## name.block_info, \
+ & cyg_dataflash_priv_ ## name \
+ )
+
+#endif
+//----------------------------------------------------------------------------
+
+static inline cyg_uint8
+cyg_dataflash_get_device_id(cyg_dataflash_device_t *dev)
+{
+ return dev->info->device_id;
+}
+
+static inline cyg_uint16
+cyg_dataflash_get_page_size(cyg_dataflash_device_t *dev)
+{
+ return dev->info->page_size;
+}
+
+static inline cyg_uint16
+cyg_dataflash_get_page_count(cyg_dataflash_device_t *dev)
+{
+ return dev->info->page_count;
+}
+
+static inline cyg_uint16
+cyg_dataflash_get_block_size(cyg_dataflash_device_t *dev)
+{
+ return dev->info->block_size;
+}
+
+static inline cyg_uint16
+cyg_dataflash_get_sector_size(cyg_dataflash_device_t *dev, cyg_uint8 sector_num)
+{
+ return dev->info->sector_sizes[sector_num];
+}
+
+static inline cyg_uint16
+cyg_dataflash_get_sector_count(cyg_dataflash_device_t *dev)
+{
+ return dev->info->sector_count;
+}
+
+static inline void
+cyg_dataflash_set_polled_operation(cyg_dataflash_device_t *dev, cyg_bool polled)
+{
+ dev->polled = polled;
+}
+
+static inline void
+cyg_dataflash_set_blocking_operation(cyg_dataflash_device_t *dev, cyg_bool block)
+{
+ dev->blocking = block;
+}
+
+//----------------------------------------------------------------------------
+
+externC int cyg_dataflash_init(cyg_bool polled,
+ cyg_dataflash_device_t *dev);
+
+externC int cyg_dataflash_aquire(cyg_dataflash_device_t *dev);
+
+externC int cyg_dataflash_release(cyg_dataflash_device_t *dev);
+
+externC cyg_uint16 cyg_dataflash_get_sector_start(cyg_dataflash_device_t *dev,
+ cyg_uint16 sector_num);
+
+externC int cyg_dataflash_wait_ready(cyg_dataflash_device_t *dev);
+
+externC int cyg_dataflash_read_buf(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ cyg_uint8 *buf,
+ cyg_uint32 len,
+ cyg_uint32 pos);
+
+externC int cyg_dataflash_write_buf(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ const cyg_uint8 *buf,
+ cyg_uint32 len,
+ cyg_uint32 pos);
+
+externC int cyg_dataflash_mem_to_buf(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ cyg_uint32 page_num);
+
+externC int cyg_dataflash_program_buf(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ cyg_uint32 page_num,
+ cyg_bool erase);
+
+externC int cyg_dataflash_compare_buf(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ cyg_uint32 page_num);
+
+externC int cyg_dataflash_erase(cyg_dataflash_device_t *dev,
+ cyg_uint32 page_num);
+
+externC int cyg_dataflash_erase_block(cyg_dataflash_device_t *dev,
+ cyg_uint32 block_num);
+
+externC int cyg_dataflash_auto_rewrite(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ cyg_uint32 page_num);
+
+externC int cyg_dataflash_read(cyg_dataflash_device_t *dev,
+ cyg_uint8 *buf,
+ cyg_uint32 len,
+ cyg_uint32 pos);
+
+externC int cyg_dataflash_program(cyg_dataflash_device_t *dev,
+ const cyg_uint8 *buf,
+ cyg_uint32 *len,
+ cyg_uint32 pos,
+ cyg_bool erase,
+ cyg_bool verify);
+
+//----------------------------------------------------------------------------
+
+#endif // CYGONCE_DATAFLASH_H
+
+//----------------------------------------------------------------------------
+// End of dataflash.h
diff --git a/ecos/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c b/ecos/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c
new file mode 100644
index 0000000..e06095f
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c
@@ -0,0 +1,922 @@
+//==========================================================================
+//
+// devs_flash_atmel_dataflash.c
+//
+// Atmel DataFlash series flash driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Savin Zlobec <savin@elatec.si>
+// Date: 2004-08-27
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_atmel_dataflash.h>
+
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/dataflash.h>
+
+// --------------------------------------------------------------------------
+// DataFlash command opcodes
+
+// Read commands opcodes
+#define DF_CONT_ARRAY_READ_CMD 0x68
+#define DF_MMEM_PAGE_READ_CMD 0x52
+#define DF_BUF1_READ_CMD 0x54
+#define DF_BUF2_READ_CMD 0x56
+#define DF_STATUS_READ_CMD 0x57
+
+// Program and erase commands opcodes
+#define DF_BUF1_WRITE_CMD 0x84
+#define DF_BUF2_WRITE_CMD 0x87
+#define DF_BUF1_PROG_W_ERASE_CMD 0x83
+#define DF_BUF2_PROG_W_ERASE_CMD 0x86
+#define DF_BUF1_PROG_WO_ERASE_CMD 0x88
+#define DF_BUF2_PROG_WO_ERASE_CMD 0x89
+#define DF_PAGE_ERASE_CMD 0x81
+#define DF_BLOCK_ERASE_CMD 0x50
+#define DF_PROG_THROUGH_BUF1_CMD 0x82
+#define DF_PROG_THROUGH_BUF2_CMD 0x85
+
+// Additional commands opcodes
+#define DF_TRANSFER_TO_BUF1_CMD 0x53
+#define DF_TRANSFER_TO_BUF2_CMD 0x55
+#define DF_BUF1_COMPARE_CMD 0x60
+#define DF_BUF2_COMPARE_CMD 0x61
+#define DF_AUTO_REWRITE_THROUGH_BUF1_CMD 0x58
+#define DF_AUTO_REWRITE_THROUGH_BUF2_CMD 0x59
+
+//----------------------------------------------------------------------------
+
+#define DATA_BUF_NONE 0x00 // Data buffer number for no buffer
+#define DATA_BUF_ALL 0xFF // Data buffer number for all buffers
+
+//----------------------------------------------------------------------------
+
+typedef struct df_status_s
+{
+ cyg_uint8 reserved:2;
+ cyg_uint8 device_id:4;
+ cyg_uint8 compare_err:1;
+ cyg_uint8 ready:1;
+} df_status_t;
+
+//----------------------------------------------------------------------------
+
+static const cyg_dataflash_dev_info_t df_dev_info[] =
+{
+ { // AT45DB011B
+ device_id: 0x03,
+ page_size: 264,
+ page_count: 512,
+ baddr_bits: 9,
+ block_size: 8,
+ sector_sizes: { 1, 31, 32 },
+ sector_count: 3
+ },
+ { // AT45DB021B
+ device_id: 0x05,
+ page_size: 264,
+ page_count: 1024,
+ baddr_bits: 9,
+ block_size: 8,
+ sector_sizes: { 1, 31, 32, 64 },
+ sector_count: 4
+ },
+ { // AT45DB041B
+ device_id: 0x07,
+ page_size: 264,
+ page_count: 2048,
+ baddr_bits: 9,
+ block_size: 8,
+ sector_sizes: { 1, 31, 32, 64, 64, 64 },
+ sector_count: 6
+ },
+ { // AT45DB081B
+ device_id: 0x09,
+ page_size: 264,
+ page_count: 4096,
+ baddr_bits: 9,
+ block_size: 8,
+ sector_sizes: { 1, 31, 32, 64, 64, 64, 64, 64, 64, 64 },
+ sector_count: 10
+ },
+ { // AT45DB161B
+ device_id: 0x0B,
+ page_size: 528,
+ page_count: 4096,
+ baddr_bits: 10,
+ block_size: 8,
+ sector_sizes: { 1, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32 },
+ sector_count: 17
+ },
+ { // AT45DB321B
+ device_id: 0x0D,
+ page_size: 528,
+ page_count: 8192,
+ baddr_bits: 10,
+ block_size: 8,
+ sector_sizes: { 1, 63, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64 },
+ sector_count: 17
+ },
+ { // AT45DB642
+ device_id: 0x0F,
+ page_size: 1056,
+ page_count: 8192,
+ baddr_bits: 11,
+ block_size: 8,
+ sector_sizes: { 1, 31, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32 },
+ sector_count: 33
+ },
+ { 0 }
+};
+
+//----------------------------------------------------------------------------
+
+static void
+df_compose_addr(cyg_dataflash_device_t *dev,
+ cyg_uint8 *cmd_buf,
+ cyg_uint16 page_addr,
+ cyg_uint16 byte_addr)
+{
+ cyg_uint32 baddr_bits = dev->info->baddr_bits;
+ cyg_uint32 addr;
+
+ addr = (page_addr << baddr_bits) | (byte_addr & ((1<<baddr_bits) - 1));
+
+ cmd_buf[1] = (addr >> 16) & 0xFF;
+ cmd_buf[2] = (addr >> 8) & 0xFF;
+ cmd_buf[3] = addr & 0xFF;
+}
+
+static df_status_t
+df_read_status(cyg_dataflash_device_t *dev)
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ const cyg_uint8 cmd_buf[2] = { DF_STATUS_READ_CMD, 0 };
+ cyg_uint8 rx_buf[2];
+ df_status_t *status;
+
+ cyg_spi_transaction_transfer(spi_dev, true, 2, cmd_buf, rx_buf, true);
+
+ status = (df_status_t *) &rx_buf[1];
+
+ return *status;
+}
+
+static void
+df_set_busy_buf(cyg_dataflash_device_t *dev, cyg_uint8 buf_num)
+{
+ dev->state = CYG_DATAFLASH_STATE_BUSY;
+ dev->busy_buf = buf_num;
+}
+
+static void
+df_set_busy(cyg_dataflash_device_t *dev)
+{
+ df_set_busy_buf(dev, DATA_BUF_ALL);
+}
+
+static int
+df_wait_ready_buf(cyg_dataflash_device_t *dev, cyg_uint8 buf_num)
+{
+ df_status_t status;
+
+ if (CYG_DATAFLASH_STATE_IDLE == dev->state)
+ return CYG_DATAFLASH_ERR_OK;
+
+ if (DATA_BUF_ALL == buf_num ||
+ DATA_BUF_ALL == dev->busy_buf ||
+ dev->busy_buf == buf_num)
+ {
+ // REMIND: this loop should have an timeout
+ // in case of device malfunction
+
+ do
+ {
+ status = df_read_status(dev);
+ } while (0 == status.ready);
+
+ dev->state = CYG_DATAFLASH_STATE_IDLE;
+ dev->busy_buf = DATA_BUF_NONE;
+ }
+
+ return CYG_DATAFLASH_ERR_OK;
+
+}
+
+static int
+df_wait_ready(cyg_dataflash_device_t *dev)
+{
+ return df_wait_ready_buf(dev, DATA_BUF_ALL);
+}
+
+static void
+df_detect_device(cyg_dataflash_device_t *dev)
+{
+ const cyg_dataflash_dev_info_t *dev_info;
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ df_status_t status;
+
+ cyg_spi_transaction_begin(spi_dev);
+ status = df_read_status(dev);
+ cyg_spi_transaction_end(spi_dev);
+
+ dev_info = df_dev_info;
+
+ while (dev_info->device_id != 0)
+ {
+ if (status.device_id == dev_info->device_id)
+ {
+ dev->info = dev_info;
+ return;
+ }
+ dev_info++;
+ }
+ dev->info = NULL;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_init()
+
+int
+cyg_dataflash_init(cyg_bool polled,
+ cyg_dataflash_device_t *dev)
+{
+ dev->polled = polled;
+ dev->blocking = false;
+ dev->state = CYG_DATAFLASH_STATE_IDLE;
+ dev->busy_buf = DATA_BUF_NONE;
+
+ cyg_drv_mutex_init(&dev->lock);
+
+ df_detect_device(dev);
+
+ if (NULL == dev->info)
+ return CYG_DATAFLASH_ERR_WRONG_PART;
+ else
+ return CYG_DATAFLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_aquire()
+
+int
+cyg_dataflash_aquire(cyg_dataflash_device_t *dev)
+{
+ while (!cyg_drv_mutex_lock(&dev->lock));
+ return CYG_DATAFLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_release()
+
+int
+cyg_dataflash_release(cyg_dataflash_device_t *dev)
+{
+ int err;
+
+ err = df_wait_ready(dev);
+
+ cyg_drv_mutex_unlock(&dev->lock);
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_get_sector_start()
+
+cyg_uint16
+cyg_dataflash_get_sector_start(cyg_dataflash_device_t *dev,
+ cyg_uint16 sector_num)
+{
+ cyg_uint16 res, i;
+
+ if (sector_num >= dev->info->sector_count)
+ return 0;
+
+ res = 0;
+ for (i = 0; i < sector_num; i++)
+ res += dev->info->sector_sizes[i];
+
+ return res;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_wait_ready()
+
+int
+cyg_dataflash_wait_ready(cyg_dataflash_device_t *dev)
+{
+ return df_wait_ready(dev);
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_read_buf()
+
+int
+cyg_dataflash_read_buf(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ cyg_uint8 *buf,
+ cyg_uint32 len,
+ cyg_uint32 pos)
+
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ int err = CYG_DATAFLASH_ERR_OK;
+ cyg_uint8 cmd_buf[5];
+
+ // Check if the position is inside the page
+ if (pos >= dev->info->page_size)
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ // Compose DataFlash command
+
+ if (1 == buf_num) cmd_buf[0] = DF_BUF1_READ_CMD;
+ else if (2 == buf_num) cmd_buf[0] = DF_BUF2_READ_CMD;
+ else
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ df_compose_addr(dev, cmd_buf, 0, pos);
+
+ cyg_spi_transaction_begin(spi_dev);
+
+ // Wait for the target buffer to become ready
+ err = df_wait_ready_buf(dev, buf_num);
+
+ if (CYG_DATAFLASH_ERR_OK == err)
+ {
+ // Send command and read data
+
+ cyg_spi_transaction_transfer(spi_dev, true, 5, cmd_buf, NULL, false);
+ cyg_spi_transaction_transfer(spi_dev, dev->polled, len, buf, buf, true);
+ }
+
+ cyg_spi_transaction_end(spi_dev);
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_write_buf()
+
+int
+cyg_dataflash_write_buf(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ const cyg_uint8 *buf,
+ cyg_uint32 len,
+ cyg_uint32 pos)
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ int err = CYG_DATAFLASH_ERR_OK;
+ cyg_uint8 cmd_buf[4];
+
+ // Check if the position is inside the page
+ if (pos >= dev->info->page_size)
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ // Compose DataFlash command
+
+ if (1 == buf_num) cmd_buf[0] = DF_BUF1_WRITE_CMD;
+ else if (2 == buf_num) cmd_buf[0] = DF_BUF2_WRITE_CMD;
+ else
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ df_compose_addr(dev, cmd_buf, 0, pos);
+
+ cyg_spi_transaction_begin(spi_dev);
+
+ // Wait for the target buffer to become ready
+ err = df_wait_ready_buf(dev, buf_num);
+
+ if (CYG_DATAFLASH_ERR_OK == err)
+ {
+ // Send command and data
+
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, false);
+ cyg_spi_transaction_transfer(spi_dev, dev->polled,
+ len, buf, NULL, true);
+ }
+
+ cyg_spi_transaction_end(spi_dev);
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_mem_to_buf()
+
+int
+cyg_dataflash_mem_to_buf(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ cyg_uint32 page_num)
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ int err = CYG_DATAFLASH_ERR_OK;
+ cyg_uint8 cmd_buf[4];
+
+ // Check if the page number is inside the flash
+ if (page_num >= dev->info->page_count)
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ // Compose DataFlash command
+
+ if (1 == buf_num) cmd_buf[0] = DF_TRANSFER_TO_BUF1_CMD;
+ else if (2 == buf_num) cmd_buf[0] = DF_TRANSFER_TO_BUF2_CMD;
+ else
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ df_compose_addr(dev, cmd_buf, page_num, 0);
+
+ cyg_spi_transaction_begin(spi_dev);
+
+ // Wait for the device to become ready
+ err = df_wait_ready(dev);
+
+ if (CYG_DATAFLASH_ERR_OK == err)
+ {
+ // Send the command
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+ // Mark the target buffer as busy
+ df_set_busy_buf(dev, buf_num);
+
+ // Wait if in blocking mode
+ if (dev->blocking)
+ err = df_wait_ready(dev);
+ }
+
+ cyg_spi_transaction_end(spi_dev);
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_program_buf()
+
+int
+cyg_dataflash_program_buf(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ cyg_uint32 page_num,
+ cyg_bool erase)
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ int err = CYG_DATAFLASH_ERR_OK;
+ cyg_uint8 cmd_buf[4];
+
+ // Check if the page number is inside the flash
+ if (page_num >= dev->info->page_count)
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ // Compose DataFlash command
+
+ if (erase)
+ {
+ if (1 == buf_num) cmd_buf[0] = DF_BUF1_PROG_W_ERASE_CMD;
+ else if (2 == buf_num) cmd_buf[0] = DF_BUF2_PROG_W_ERASE_CMD;
+ else
+ return CYG_DATAFLASH_ERR_INVALID;
+ }
+ else
+ {
+ if (1 == buf_num) cmd_buf[0] = DF_BUF1_PROG_WO_ERASE_CMD;
+ else if (2 == buf_num) cmd_buf[0] = DF_BUF2_PROG_WO_ERASE_CMD;
+ else
+ return CYG_DATAFLASH_ERR_INVALID;
+ }
+
+ df_compose_addr(dev, cmd_buf, page_num, 0);
+
+ cyg_spi_transaction_begin(spi_dev);
+
+ // Wait for the device to become ready
+ err = df_wait_ready(dev);
+
+ if (CYG_DATAFLASH_ERR_OK == err)
+ {
+ // Send the command
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+ // Mark the target buffer as busy
+ df_set_busy_buf(dev, buf_num);
+
+ // Wait if in blocking mode
+ if (dev->blocking)
+ err = df_wait_ready(dev);
+ }
+
+ cyg_spi_transaction_end(spi_dev);
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_compare_buf()
+
+int
+cyg_dataflash_compare_buf(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ cyg_uint32 page_num)
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ int err = CYG_DATAFLASH_ERR_OK;
+ cyg_uint8 cmd_buf[4];
+ df_status_t status;
+
+ // Check if the page number is inside the flash
+ if (page_num >= dev->info->page_count)
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ // Compose DataFlash command
+
+ if (1 == buf_num) cmd_buf[0] = DF_BUF1_COMPARE_CMD;
+ else if (2 == buf_num) cmd_buf[0] = DF_BUF2_COMPARE_CMD;
+ else
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ df_compose_addr(dev, cmd_buf, page_num, 0);
+
+ cyg_spi_transaction_begin(spi_dev);
+
+ // Wait for the device to become ready
+ err = df_wait_ready(dev);
+
+ if (CYG_DATAFLASH_ERR_OK == err)
+ {
+ // Send the command
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+ // Wait for the device to become ready
+ df_set_busy(dev);
+ err = df_wait_ready(dev);
+
+ // Read the result of memory compare
+
+ if (CYG_DATAFLASH_ERR_OK == err)
+ {
+ status = df_read_status(dev);
+ if (status.compare_err)
+ err = CYG_DATAFLASH_ERR_COMPARE;
+ }
+ }
+
+ cyg_spi_transaction_end(spi_dev);
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_erase()
+
+int
+cyg_dataflash_erase(cyg_dataflash_device_t *dev,
+ cyg_uint32 page_num)
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ int err = CYG_DATAFLASH_ERR_OK;
+ cyg_uint8 cmd_buf[4];
+
+ // Check if the page number is inside the flash
+ if (page_num >= dev->info->page_count)
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ // Compose DataFlash command
+
+ cmd_buf[0] = DF_PAGE_ERASE_CMD;
+ df_compose_addr(dev, cmd_buf, page_num, 0);
+
+ cyg_spi_transaction_begin(spi_dev);
+
+ // Wait for the device to become ready
+ err = df_wait_ready(dev);
+
+ if (CYG_DATAFLASH_ERR_OK == err)
+ {
+ // Send the command
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+ // Set device state to busy
+ df_set_busy_buf(dev, DATA_BUF_NONE);
+
+ // Wait if in blocking mode
+ if (dev->blocking)
+ err = df_wait_ready(dev);
+ }
+
+ cyg_spi_transaction_end(spi_dev);
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_erase_block()
+
+int
+cyg_dataflash_erase_block(cyg_dataflash_device_t *dev,
+ cyg_uint32 block_num)
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ int err = CYG_DATAFLASH_ERR_OK;
+ cyg_uint8 cmd_buf[4];
+
+ // Check if the block number is inside the flash
+ if (block_num >= (dev->info->page_count >> 3))
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ // Compose DataFlash command
+
+ cmd_buf[0] = DF_BLOCK_ERASE_CMD;
+ df_compose_addr(dev, cmd_buf, block_num << 3, 0);
+
+ cyg_spi_transaction_begin(spi_dev);
+
+ // Wait for the device to become ready
+ err = df_wait_ready(dev);
+
+ if (CYG_DATAFLASH_ERR_OK == err)
+ {
+ // Send the command
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+ // Set device state to busy
+ df_set_busy_buf(dev, DATA_BUF_NONE);
+
+ // Wait if in blocking mode
+ if (dev->blocking)
+ err = df_wait_ready(dev);
+ }
+
+ cyg_spi_transaction_end(spi_dev);
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_auto_rewrite()
+
+int
+cyg_dataflash_auto_rewrite(cyg_dataflash_device_t *dev,
+ cyg_uint8 buf_num,
+ cyg_uint32 page_num)
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ int err = CYG_DATAFLASH_ERR_OK;
+ cyg_uint8 cmd_buf[4];
+
+ // Check if the page number is inside the flash
+ if (page_num >= dev->info->page_count)
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ // Compose DataFlash command
+
+ if (1 == buf_num) cmd_buf[0] = DF_AUTO_REWRITE_THROUGH_BUF1_CMD;
+ else if (2 == buf_num) cmd_buf[0] = DF_AUTO_REWRITE_THROUGH_BUF2_CMD;
+ else
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ df_compose_addr(dev, cmd_buf, page_num, 0);
+
+ cyg_spi_transaction_begin(spi_dev);
+
+ // Wait for the device to become ready
+ err = df_wait_ready(dev);
+
+ if (CYG_DATAFLASH_ERR_OK == err)
+ {
+ // Send the command
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+ // Mark the target buffer as busy
+ df_set_busy_buf(dev, buf_num);
+
+ // Wait if in blocking mode
+ if (dev->blocking)
+ err = df_wait_ready(dev);
+ }
+
+ cyg_spi_transaction_end(spi_dev);
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_read()
+
+int
+cyg_dataflash_read(cyg_dataflash_device_t *dev,
+ cyg_uint8 *buf,
+ cyg_uint32 len,
+ cyg_uint32 pos)
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ int err = CYG_DATAFLASH_ERR_OK;
+ cyg_uint8 cmd_buf[8];
+ cyg_uint32 page_num, page_pos;
+
+ // Calculate page number and position from given absolute position
+
+ page_num = pos / dev->info->page_size;
+ page_pos = pos % dev->info->page_size;
+
+ // Check if the page number is inside the flash
+ if (page_num >= dev->info->page_count)
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ // Compose DataFlash command
+
+ cmd_buf[0] = DF_CONT_ARRAY_READ_CMD;
+ df_compose_addr(dev, cmd_buf, page_num, page_pos);
+
+ cyg_spi_transaction_begin(spi_dev);
+
+ // Wait for the device to become ready
+ err = df_wait_ready(dev);
+
+ if (CYG_DATAFLASH_ERR_OK == err)
+ {
+ // Send the command and read data from DataFlash main memory
+
+ cyg_spi_transaction_transfer(spi_dev, true, 8, cmd_buf, NULL, false);
+ cyg_spi_transaction_transfer(spi_dev, dev->polled, len, buf, buf, true);
+ }
+
+ cyg_spi_transaction_end(spi_dev);
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_program()
+
+int
+cyg_dataflash_program(cyg_dataflash_device_t *dev,
+ const cyg_uint8 *buf,
+ cyg_uint32 *len,
+ cyg_uint32 pos,
+ cyg_bool erase,
+ cyg_bool verify)
+{
+ cyg_spi_device *spi_dev = dev->spi_dev;
+ int err = CYG_DATAFLASH_ERR_OK;
+ cyg_uint8 cmd_buf[4];
+ cyg_uint32 count, page_num, page_pos;
+
+ // Calculate page number and position from given absolute position
+
+ page_num = pos / dev->info->page_size;
+ page_pos = pos % dev->info->page_size;
+ count = *len;
+
+ cyg_spi_transaction_begin(spi_dev);
+
+ // Wait for device to become ready
+ err = df_wait_ready(dev);
+ if (CYG_DATAFLASH_ERR_OK != err)
+ goto out;
+
+ // Loop until count bytes written
+
+ while (count > 0)
+ {
+ df_status_t status;
+ cyg_uint32 size;
+
+ // Check if the current page number is inside the flash
+ if (page_num >= dev->info->page_count)
+ {
+ err = CYG_DATAFLASH_ERR_INVALID;
+ goto out;
+ }
+
+ // Calculate the number of bytes to write to the current page
+ if ((page_pos + count) > dev->info->page_size)
+ size = dev->info->page_size - page_pos;
+ else
+ size = count;
+
+ // Compose DataFlash command address
+ df_compose_addr(dev, cmd_buf, page_num, page_pos);
+
+ // If we are not rewritting the whole page, then first
+ // read the old data from main memory to the target buffer
+
+ if (page_pos > 0 || size < dev->info->page_size)
+ {
+ cmd_buf[0] = DF_TRANSFER_TO_BUF1_CMD;
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+ df_set_busy(dev);
+ err = df_wait_ready(dev);
+ if (CYG_DATAFLASH_ERR_OK != err)
+ goto out;
+ }
+
+ // Write data to the target buffer
+
+ cmd_buf[0] = DF_BUF1_WRITE_CMD;
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, false);
+ cyg_spi_transaction_transfer(spi_dev, dev->polled,
+ size, buf, NULL, true);
+ df_set_busy(dev);
+ err = df_wait_ready(dev);
+ if (CYG_DATAFLASH_ERR_OK != err)
+ goto out;
+
+ // Program data from the target buffer to main memory
+ // and perform an erase before if requested
+
+ if (erase)
+ cmd_buf[0] = DF_BUF1_PROG_W_ERASE_CMD;
+ else
+ cmd_buf[0] = DF_BUF1_PROG_WO_ERASE_CMD;
+
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+ df_set_busy(dev);
+ err = df_wait_ready(dev);
+ if (CYG_DATAFLASH_ERR_OK != err)
+ goto out;
+
+ // Compare the target buffer contents with the freshly
+ // written main memory page (if requested)
+
+ if (verify)
+ {
+ cmd_buf[0] = DF_BUF1_COMPARE_CMD;
+ cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+ df_set_busy(dev);
+ err = df_wait_ready(dev);
+ if (CYG_DATAFLASH_ERR_OK != err)
+ goto out;
+
+ status = df_read_status(dev);
+
+ if (status.compare_err)
+ {
+ err = CYG_DATAFLASH_ERR_COMPARE;
+ goto out;
+ }
+ }
+
+ // Adjust running values
+
+ page_pos = 0;
+ page_num += 1;
+ count -= size;
+ buf += size;
+ }
+
+out:
+ cyg_spi_transaction_end(spi_dev);
+
+ *len -= count;
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+// End of devs_flash_atmel_dataflash.c
diff --git a/ecos/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c b/ecos/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c
new file mode 100644
index 0000000..b5632a9
--- /dev/null
+++ b/ecos/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c
@@ -0,0 +1,223 @@
+//==========================================================================
+//
+// devs_flash_atmel_dataflash_flash_dev_funs.c
+//
+// DataFlash flash device funs
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Savin Zlobec <savin@elatec.si>
+// Date: 2004-09-06
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_atmel_dataflash.h>
+#include <pkgconf/io_flash.h>
+
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/dataflash.h>
+
+// --------------------------------------------------------------------------
+
+#define RETURN_ON_ERROR(_op_) \
+ if (CYG_DATAFLASH_ERR_OK != (err = _op_)) return df_flash_hwr_map_error(dev, err)
+
+#define GOTO_ON_ERROR(_op_) \
+ if (CYG_DATAFLASH_ERR_OK != (err = _op_)) goto on_error
+
+static int
+df_flash_hwr_map_error(struct cyg_flash_dev *dev, int err)
+{
+ switch (err)
+ {
+ case CYG_DATAFLASH_ERR_OK: return CYG_FLASH_ERR_OK;
+ case CYG_DATAFLASH_ERR_INVALID: return CYG_FLASH_ERR_INVALID;
+ case CYG_DATAFLASH_ERR_WRONG_PART: return CYG_FLASH_ERR_DRV_WRONG_PART;
+ case CYG_DATAFLASH_ERR_TIMEOUT: return CYG_FLASH_ERR_DRV_TIMEOUT;
+ case CYG_DATAFLASH_ERR_COMPARE: return CYG_FLASH_ERR_DRV_VERIFY;
+ default: return CYG_FLASH_ERR_INVALID;
+ }
+}
+
+// --------------------------------------------------------------------------
+
+static int
+df_flash_init(struct cyg_flash_dev *dev)
+{
+ cyg_dataflash_flash_dev_priv_t *priv;
+ cyg_dataflash_device_t *df_dev;
+ int sector_cnt;
+
+ priv = (cyg_dataflash_flash_dev_priv_t *) dev->priv;
+ df_dev = &priv->dev;
+
+#ifdef CYGPKG_REDBOOT
+ if (cyg_dataflash_init(true, df_dev))
+#else
+ if (cyg_dataflash_init(false, df_dev))
+#endif
+ return CYG_DATAFLASH_ERR_WRONG_PART;
+
+ cyg_dataflash_set_blocking_operation(df_dev, true);
+
+ sector_cnt = cyg_dataflash_get_sector_count(df_dev);
+
+ if (priv->end_sector < 0)
+ priv->end_sector = sector_cnt - 1;
+
+ if (priv->start_sector >= sector_cnt ||
+ priv->end_sector >= sector_cnt ||
+ priv->end_sector < priv->start_sector)
+ return CYG_DATAFLASH_ERR_INVALID;
+
+ priv->start_page = cyg_dataflash_get_block_size(df_dev) *
+ cyg_dataflash_get_sector_start(df_dev, priv->start_sector);
+
+ priv->end_page = cyg_dataflash_get_block_size(df_dev) *
+ (cyg_dataflash_get_sector_start(df_dev, priv->end_sector) +
+ cyg_dataflash_get_sector_size(df_dev, priv->end_sector));
+
+ dev->end = (cyg_flashaddr_t)(dev->start +
+ ((priv->end_page - priv->start_page) *
+ cyg_dataflash_get_page_size(df_dev)) - 1);
+ priv->block_info[0].block_size = cyg_dataflash_get_page_size(df_dev);
+ priv->block_info[0].blocks = priv->end_page - priv->start_page;
+
+ return CYG_DATAFLASH_ERR_OK;
+}
+
+static int
+df_flash_erase_block(struct cyg_flash_dev *dev,
+ cyg_flashaddr_t base)
+{
+ cyg_dataflash_flash_dev_priv_t *priv;
+ cyg_uint32 page;
+ int err;
+
+ priv = (cyg_dataflash_flash_dev_priv_t *) dev->priv;
+
+ page = priv->start_page + ((base - dev->start) /
+ cyg_dataflash_get_page_size(&priv->dev));
+
+ RETURN_ON_ERROR( cyg_dataflash_aquire(&priv->dev) );
+ GOTO_ON_ERROR( cyg_dataflash_erase(&priv->dev, page) );
+ RETURN_ON_ERROR( cyg_dataflash_release(&priv->dev) );
+
+ return CYG_DATAFLASH_ERR_OK;
+
+on_error:
+ cyg_dataflash_release(&priv->dev);
+ return df_flash_hwr_map_error(dev, err);
+}
+
+static int
+df_flash_program(struct cyg_flash_dev *dev,
+ cyg_flashaddr_t base,
+ const void *data,
+ size_t len)
+{
+ cyg_dataflash_flash_dev_priv_t *priv;
+ cyg_uint32 page, pos;
+ int err;
+
+ priv = (cyg_dataflash_flash_dev_priv_t *) dev->priv;
+
+ page = priv->start_page + ((base - dev->start) /
+ cyg_dataflash_get_page_size(&priv->dev));
+ pos = (base - dev->start) % cyg_dataflash_get_page_size(&priv->dev);
+
+ RETURN_ON_ERROR( cyg_dataflash_aquire(&priv->dev) );
+ GOTO_ON_ERROR( cyg_dataflash_mem_to_buf(&priv->dev, 1, page) );
+ GOTO_ON_ERROR( cyg_dataflash_write_buf(&priv->dev, 1, data, len, pos) );
+ GOTO_ON_ERROR( cyg_dataflash_program_buf(&priv->dev, 1, page, true) );
+ RETURN_ON_ERROR( cyg_dataflash_release(&priv->dev) );
+
+ return CYG_DATAFLASH_ERR_OK;
+
+on_error:
+ cyg_dataflash_release(&priv->dev);
+ return df_flash_hwr_map_error(dev, err);
+}
+
+static int
+df_flash_read(struct cyg_flash_dev *dev,
+ const cyg_flashaddr_t base,
+ void *data,
+ size_t len)
+{
+ cyg_dataflash_flash_dev_priv_t *priv;
+ cyg_uint32 page, pos;
+ int err;
+
+ priv = (cyg_dataflash_flash_dev_priv_t *) dev->priv;
+
+ page = priv->start_page + ((base - dev->start) /
+ cyg_dataflash_get_page_size(&priv->dev));
+ pos = (base - dev->start) % cyg_dataflash_get_page_size(&priv->dev);
+
+ RETURN_ON_ERROR( cyg_dataflash_aquire(&priv->dev) );
+ GOTO_ON_ERROR( cyg_dataflash_mem_to_buf(&priv->dev, 1, page) );
+ GOTO_ON_ERROR( cyg_dataflash_read_buf(&priv->dev, 1, data, len, pos) );
+ RETURN_ON_ERROR( cyg_dataflash_release(&priv->dev) );
+
+ return CYG_DATAFLASH_ERR_OK;
+
+on_error:
+ cyg_dataflash_release(&priv->dev);
+ return df_flash_hwr_map_error(dev, err);
+}
+
+// --------------------------------------------------------------------------
+
+CYG_FLASH_FUNS(cyg_dataflash_flash_dev_funs,
+ df_flash_init,
+ cyg_flash_devfn_query_nop,
+ df_flash_erase_block,
+ df_flash_program,
+ df_flash_read,
+ cyg_flash_devfn_lock_nop,
+ cyg_flash_devfn_unlock_nop
+);
+
+//----------------------------------------------------------------------------
+// End of devs_flash_atmel_dataflash_flash_dev_funs.c
diff --git a/ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/ChangeLog b/ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/ChangeLog
new file mode 100644
index 0000000..7d736a1
--- /dev/null
+++ b/ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/ChangeLog
@@ -0,0 +1,31 @@
+
+2011-04-13 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * cdl/flash_a2f200_eval.cdl:
+ * src/flash_a2f200_eval.c:
+ New package - Flash support for Actel Smartfusion evaluation board.
+ [Bugzilla 1001291]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/cdl/flash_a2f200_eval.cdl b/ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/cdl/flash_a2f200_eval.cdl
new file mode 100644
index 0000000..caab978
--- /dev/null
+++ b/ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/cdl/flash_a2f200_eval.cdl
@@ -0,0 +1,62 @@
+# ====================================================================
+#
+# flash_a2f200_eval.cdl
+#
+# Flash programming for Atmel device on Actel SmartFusion Board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ccoutand
+# Date: 2011-05-05
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_CORTEXM_A2F200_EVAL {
+ display "Actel SmartFusion board FLASH memory support"
+ description "FLASH memory device support for Actel SmartFusion board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_CORTEXM_A2FXXX
+ requires CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS1
+ implements CYGHWR_DEVS_FLASH_SPI_AT25DFXXX_DEVICE
+
+ compile -library=libextras.a flash_a2f200_eval.c
+}
+
+# EOF flash_a2f200_eval.cdl
diff --git a/ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/src/flash_a2f200_eval.c b/ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/src/flash_a2f200_eval.c
new file mode 100644
index 0000000..986ad32
--- /dev/null
+++ b/ecos/packages/devs/flash/cortexm/a2fxxx/a2f200_eval/current/src/flash_a2f200_eval.c
@@ -0,0 +1,78 @@
+//==========================================================================
+//
+// flash_a2f200_eval.c
+//
+// Flash programming for Atmel device on Actel SmartFusion Board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Date: 2011-05-05
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// ------------------------------------------------------------------------
+// There is an AT25DF161 DataFlash on the SPI bus
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_flash_cortexm_a2f200_eval.h>
+
+#if defined(CYGPKG_IO_SPI) && defined(CYGPKG_DEVS_FLASH_SPI_AT25DFXXX)
+
+#include <cyg/io/spi.h>
+#include <cyg/io/at25dfxxx.h>
+#include <cyg/io/spi_a2fxxx.h>
+
+// Declare Device on SPI bus 1, Use GPIO 19 for chip select, Motorola protocol (mode 0)
+CYG_DEVS_SPI_CORTEXM_A2FXXX_DEVICE (
+ at25dfxxx_spi_device, 1, 19, true, A2FXXX_SPI_MOTOROLA, 0, 0, 5000000, 1, 1, 1
+);
+
+//-----------------------------------------------------------------------------
+// Instantiate the AT25DFxxx device driver.
+
+CYG_DEVS_FLASH_SPI_AT25DFXXX_DRIVER (
+ at25dfxxx_flash_device, CYGNUM_DEVS_FLASH_SPI_AT25XXX_DEV0_MAP_ADDR, &at25dfxxx_spi_device
+);
+
+#endif
+
+// ------------------------------------------------------------------------
+// EOF flash_a2f200_eval.c
diff --git a/ecos/packages/devs/flash/cortexm/stm32/current/ChangeLog b/ecos/packages/devs/flash/cortexm/stm32/current/ChangeLog
new file mode 100644
index 0000000..d38f06b
--- /dev/null
+++ b/ecos/packages/devs/flash/cortexm/stm32/current/ChangeLog
@@ -0,0 +1,78 @@
+2012-03-15 James Smith <jsmith@ecoscentric.com>
+
+ * src/stm32_flash.c: Add support for F4 family devices, and
+ explicit flash size support for specific F4xxx[EG] devices.
+
+ * include/stm32_flash.h:
+ * cdl/flash_stm32.cdl (CYGNUM_DEVS_FLASH_STM32_PARALLELISM):
+ Support for F4 devices.
+
+2012-02-29 James Smith <jsmith@ecoscentric.com>
+
+ * src/stm32_flash.c (stm32_flash_hw_program): Compilation fixes to
+ use renamed WAIT_FOR_FLASH_NOT_BUSY macro and to add missing
+ semi-colon
+
+2011-12-15 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_stm32.cdl (CYGNUM_DEVS_FLASH_STM32_PARALLELISM): New
+ option. Configures program/erase width on F2 processors.
+ * include/stm32_flash.h: Make private device driver data const - it
+ doesn't change so shouldn't be in RAM. Support multiple flash regions
+ for F2.
+ * src/stm32_flash.c: Substantial changes to support F2 processors.
+ Also improve error checking, timeout detection and general robustness.
+
+2009-07-03 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/stm32_flash.c (stm32_flash_init): Add tests for connectivity
+ line devices.
+
+2009-04-06 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/stm32_flash.c:
+ stm32_flash_get_block_info() now computes correct block base
+ address. HSI is enabled for flash erase/program as stated in the
+ manual. Some cleanup.
+
+2008-12-19 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/stm32_flash.c:
+ Hardcoded flash and block sizes as the debug registers are not
+ readable by user software.
+
+2008-11-04 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/stm32_flash.c:
+ Fixed detection on early silicon.
+
+2008-10-07 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/flash_stm32.cdl:
+ * include/stm32_flash.h:
+ * src/stm32_flash.c:
+ New package -- support for STM32 on-chip flash.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/cortexm/stm32/current/cdl/flash_stm32.cdl b/ecos/packages/devs/flash/cortexm/stm32/current/cdl/flash_stm32.cdl
new file mode 100644
index 0000000..8ea6719
--- /dev/null
+++ b/ecos/packages/devs/flash/cortexm/stm32/current/cdl/flash_stm32.cdl
@@ -0,0 +1,132 @@
+## ====================================================================
+##
+## flash_stm32.cdl
+##
+## FLASH memory - Hardware support for STM32 on-chip flash
+##
+## ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008, 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+## ====================================================================
+######DESCRIPTIONBEGIN####
+##
+## Author(s): nickg
+## Date: 2008-09-22
+##
+#####DESCRIPTIONEND####
+##
+## ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_STM32 {
+ display "STM32 FLASH memory support"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ implements CYGHWR_IO_FLASH_DEVICE
+
+ include_dir cyg/io
+
+ compile stm32_flash.c
+
+ description "
+ Flash memory support for on-chip flash on STM32 devices and compatibles.
+ This driver implements the V2 flash driver API."
+
+ cdl_option CYGNUM_DEVS_FLASH_STM32_V2_PROGRAM_BURST_SIZE {
+ display "Number of words to write per burst"
+ flavor data
+ default_value 256
+ legal_values 4 to 4096
+ description "
+ On typical hardware programming the flash requires disabling
+ interrupts for an extended period of time.
+ Some or all of the flash hardware will be unusable while each word
+ is programmed, and disabling interrupts is the only reliable
+ way of ensuring that no interrupt handler or other thread will
+ try to access the flash in the middle of an operation. This
+ can have a major impact on the real-time responsiveness of
+ typical applications. To ameliorate this the driver will
+ perform writes in small bursts, briefly re-enabling the cache
+ and interrupts between each burst. The number of write operations
+ per burst is determined by this option: reducing the number of
+ writes per burst will improve real-time response, but will add
+ overhead so the actual flash program operation will take
+ longer; conversely more writes per burst will worsen response
+ times but reduce overhead."
+ }
+
+ cdl_option CYGNUM_DEVS_FLASH_STM32_PARALLELISM {
+ display "Program/erase parallelism"
+ flavor data
+ legal_values { 8 16 32 64 }
+ active_if { ((CYGHWR_HAL_CORTEXM_STM32_FAMILY == "F2") || (CYGHWR_HAL_CORTEXM_STM32_FAMILY == "F4")) }
+ default_value 32
+ description "
+ The Flash interface of the STM32 F2 and F4 families can program or erase
+ multiple bits in one step. The maximum possible parallelism depends
+ on the supply voltage. The default value of this option (32)
+ corresponds to supply voltage of 2.7 - 3.6V, but another value
+ may be chosen if a different voltage is used."
+ }
+
+ cdl_component CYGPKG_DEVS_FLASH_STM32_OPTIONS {
+ display "STM32 driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building the STM32
+ flash driver, and details of which tests are built."
+
+ cdl_option CYGPKG_DEVS_FLASH_STM32_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the STM32 flash driver. These flags
+ are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_STM32_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the STM32 flash driver. These flags
+ are removed from the set of global flags if present."
+ }
+ }
+}
+
+# End of flash_stm32.cdl
diff --git a/ecos/packages/devs/flash/cortexm/stm32/current/include/stm32_flash.h b/ecos/packages/devs/flash/cortexm/stm32/current/include/stm32_flash.h
new file mode 100644
index 0000000..32df774
--- /dev/null
+++ b/ecos/packages/devs/flash/cortexm/stm32/current/include/stm32_flash.h
@@ -0,0 +1,81 @@
+#ifndef CYGONCE_DEVS_FLASH_STM32_H
+#define CYGONCE_DEVS_FLASH_STM32_H
+//==========================================================================
+//
+// stm32_flash.h
+//
+// STM32 internal flash driver definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2011, 2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Date: 2008-09-22
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal_cortexm_stm32.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#if defined(CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1)
+# define STM32_FLASH_MAXBLOCKINFOS 1
+#elif defined(CYGHWR_HAL_CORTEXM_STM32_FAMILY_HIPERFORMANCE)
+# define STM32_FLASH_MAXBLOCKINFOS 3
+#endif
+
+// The driver-specific data, pointed at by the priv field in a
+// a cyg_flash_dev structure.
+
+typedef struct cyg_stm32_dev
+{
+ cyg_flash_block_info_t block_info[STM32_FLASH_MAXBLOCKINFOS];
+} cyg_stm32_flash_dev;
+
+// The instantiation of that data.
+__externC const cyg_stm32_flash_dev hal_stm32_flash_priv;
+
+//========================================================================*/
+// Exported function pointers.
+
+__externC const struct cyg_flash_dev_funs cyg_stm32_flash_funs;
+
+
+//========================================================================*/
+#endif // CYGONCE_DEVS_FLASH_STM32_H
+// End of stm32_flash.h
diff --git a/ecos/packages/devs/flash/cortexm/stm32/current/src/stm32_flash.c b/ecos/packages/devs/flash/cortexm/stm32/current/src/stm32_flash.c
new file mode 100644
index 0000000..2427947
--- /dev/null
+++ b/ecos/packages/devs/flash/cortexm/stm32/current/src/stm32_flash.c
@@ -0,0 +1,738 @@
+//==========================================================================
+//
+// stm32_flash.c
+//
+// STM32 internal flash driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Date: 2008-09-22
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal_cortexm_stm32.h>
+#include <pkgconf/devs_flash_stm32.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+
+#include <string.h>
+
+#include <cyg/io/stm32_flash.h>
+
+#include CYGHWR_MEMORY_LAYOUT_H
+
+// Does this look like an F1 or F2/F4 device? It makes a difference to sizing and operation.
+#if defined(CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1)
+# define F1STYLE 1
+#elif defined(CYGHWR_HAL_CORTEXM_STM32_FAMILY_HIPERFORMANCE)
+# define F2STYLE 1
+#endif
+
+// ----------------------------------------------------------------------------
+
+#if defined(F1STYLE)
+typedef cyg_uint16 STM32_TYPE;
+#elif defined(F2STYLE)
+// F2/F4's alignment requirements depend on parallelism config, so we treat as
+// bytes for now.
+typedef cyg_uint8 STM32_TYPE;
+#endif
+
+// ----------------------------------------------------------------------------
+
+// How many loops before we consider this a timeout.
+#define STM32_FLASH_TIMEOUT 1000000
+
+// A quick helper macro to avoid repetition.
+#define WAIT_FOR_FLASH_NOT_BUSY(_timeout_) \
+ CYG_MACRO_START \
+ (_timeout_) = STM32_FLASH_TIMEOUT; \
+ do { \
+ HAL_READ_UINT32( base+CYGHWR_HAL_STM32_FLASH_SR, sr ); \
+ } while( (sr & CYGHWR_HAL_STM32_FLASH_SR_BSY) && (_timeout_)-- > 0 ); \
+ CYG_MACRO_END
+
+// ----------------------------------------------------------------------------
+
+// Note that although the F2/F4 parts need special treatment for the Flash's
+// built-in icache and dcache, that doesn't matter for suspend/resume
+// because no-one should expect any part of the Flash in the area being
+// erased/programmed to be any particular value.
+
+# define STM32_INTSCACHE_STATE int _saved_ints_
+# define STM32_INTSCACHE_BEGIN() HAL_DISABLE_INTERRUPTS(_saved_ints_)
+# define STM32_INTSCACHE_SUSPEND() HAL_RESTORE_INTERRUPTS(_saved_ints_)
+# define STM32_INTSCACHE_RESUME() HAL_DISABLE_INTERRUPTS(_saved_ints_)
+# define STM32_INTSCACHE_END() HAL_RESTORE_INTERRUPTS(_saved_ints_)
+
+#define STM32_UNCACHED_ADDRESS(__x) ((STM32_TYPE *)(__x))
+
+// ----------------------------------------------------------------------------
+// Forward declarations for functions that need to be placed in RAM:
+
+static int stm32_enable_hsi(void);
+static void stm32_disable_hsi(void);
+static int stm32_flash_hw_erase(cyg_flashaddr_t addr, cyg_uint16 block_num) __attribute__((section (".2ram.stm32_flash_hw_erase")));
+static int stm32_flash_hw_program( volatile STM32_TYPE* addr, const STM32_TYPE *buf, cyg_uint32 count) __attribute__((section (".2ram.stm32_flash_hw_program")));
+
+// ----------------------------------------------------------------------------
+// Diagnostic routines.
+
+#if 0
+#define stf_diag( __fmt, ... ) diag_printf("STF: %20s[%3d]: " __fmt, __FUNCTION__, __LINE__, ## __VA_ARGS__ );
+#define stf_dump_buf( __addr, __size ) diag_dump_buf( __addr, __size )
+#else
+#define stf_diag( __fmt, ... )
+#define stf_dump_buf( __addr, __size )
+#endif
+
+// ----------------------------------------------------------------------------
+// Select Flash geometry
+
+#if defined(CYGHWR_HAL_CORTEXM_STM32_F103RC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F103VC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F103ZC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F105RC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F105RC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F105VC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F107VC)
+
+ // High-density device with 256K flash (2K blocks)
+#define STM32_FLASH_SIZE 0x40000
+
+#elif defined(CYGHWR_HAL_CORTEXM_STM32_F103RD) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F103VD) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F103ZD)
+
+ // High-density device with 384K flash (2K blocks)
+#define STM32_FLASH_SIZE 0x60000
+
+#elif defined(CYGHWR_HAL_CORTEXM_STM32_F103RE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F103VE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F103ZE)
+
+ // High-density device with 512K flash (2K blocks)
+#define STM32_FLASH_SIZE 0x80000
+
+#elif defined(CYGHWR_HAL_CORTEXM_STM32_F205RB) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F205VB) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F205ZB) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207VB) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207ZB) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207IB)
+// 128K
+#define STM32_FLASH_SIZE (128*1024)
+#define xxxSTM32_FLASH_BLOCK_INFO { { { 16*1024, 4 } , { 64*1024, 1 } } } // guesswork at present - documentation is elusive
+#define STM32_FLASH_NUM_BLOCK_INFOS 2
+
+#elif defined(CYGHWR_HAL_CORTEXM_STM32_F205RC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F205VC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F205ZC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207VC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207ZC) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207IC)
+// 256K
+#define STM32_FLASH_SIZE (256*1024)
+#define xxxSTM32_FLASH_BLOCK_INFO { { { 16*1024, 4 } , { 64*1024, 1 }, { 128*1024, 1 } } } // guesswork at present - documentation is elusive
+#define STM32_FLASH_NUM_BLOCK_INFOS 3
+
+#elif defined(CYGHWR_HAL_CORTEXM_STM32_F205RE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F205VE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F205ZE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207VE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207ZE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207IE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F407IE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F407VE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F407ZE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F417IE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F417VE) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F417ZE)
+// 512K
+#define STM32_FLASH_SIZE (512*1024)
+#define xxxSTM32_FLASH_BLOCK_INFO { { { 16*1024, 4 } , { 64*1024, 1 }, { 128*1024, 3 } } } // guesswork at present - documentation is elusive
+#define STM32_FLASH_NUM_BLOCK_INFOS 3
+
+#elif defined(CYGHWR_HAL_CORTEXM_STM32_F205RF) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F205VF) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F205ZF) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207VF) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207ZF) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207IF)
+// 768K
+#define STM32_FLASH_SIZE (768*1024)
+#define xxxSTM32_FLASH_BLOCK_INFO { { { 16*1024, 4 } , { 64*1024, 1 }, { 128*1024, 5 } } } // guesswork at present - documentation is elusive
+#define STM32_FLASH_NUM_BLOCK_INFOS 3
+
+#elif defined(CYGHWR_HAL_CORTEXM_STM32_F205RG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F205VG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F205ZG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207VG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207ZG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F207IG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F405RG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F405VG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F405ZG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F407IG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F407VG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F407ZG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F417IG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F417VG) || \
+ defined(CYGHWR_HAL_CORTEXM_STM32_F417ZG)
+
+// 1024K
+#define STM32_FLASH_SIZE (1024*1024)
+#define STM32_FLASH_BLOCK_INFO { { { 16*1024, 4 } , { 64*1024, 1 }, { 128*1024, 7 } } }
+#define STM32_FLASH_NUM_BLOCK_INFOS 3
+
+#else
+#error Unknown STM32 microprocessor variant.
+#endif
+
+#ifdef F1STYLE
+// Always 2K blocks
+#define STM32_FLASH_BLOCK_SIZE 0x800
+#endif
+
+// If there's just one block size, it's straightforward.
+#if defined(STM32_FLASH_BLOCK_SIZE)
+const cyg_stm32_flash_dev hal_stm32_flash_priv = { { STM32_FLASH_BLOCK_SIZE, STM32_FLASH_SIZE / STM32_FLASH_BLOCK_SIZE } };
+#elif defined(STM32_FLASH_BLOCK_INFO)
+const cyg_stm32_flash_dev hal_stm32_flash_priv = STM32_FLASH_BLOCK_INFO;
+#else
+# error Incomplete STM32 variant details. It needs filling in.
+#endif
+
+// ----------------------------------------------------------------------------
+
+#ifdef CYGNUM_DEVS_FLASH_STM32_PARALLELISM
+# define CR_PSIZE_MAX CYGHWR_HAL_STM32_FLASH_CR_PSIZE(CYGNUM_DEVS_FLASH_STM32_PARALLELISM)
+# define PARALLEL_BYTES (CYGNUM_DEVS_FLASH_STM32_PARALLELISM/8)
+# define PARALLEL_ALIGN_MASK (PARALLEL_BYTES - 1)
+#endif
+
+// ----------------------------------------------------------------------------
+// Translate our error values into eCos flash driver error values
+
+// Some little helper macros for this function to make it shorter/simpler
+#define _SRBIT(_x_) CYGHWR_HAL_STM32_FLASH_SR_##_x_
+#define _FERR(_x_) CYG_FLASH_ERR_##_x_
+#define DECODE_SR_ERROR(_srbit_, _code_) if ( sr & _SRBIT(_srbit_) ) result = _FERR(_code_)
+
+static int
+stm32_flash_decode_error( int sr )
+{
+ int result = CYG_FLASH_ERR_OK;
+
+ // -1 can never be a valid sr value so we use it to indicate a timeout
+ if ( -1 == sr )
+ return CYG_FLASH_ERR_DRV_TIMEOUT;
+
+#if defined(F1STYLE)
+ DECODE_SR_ERROR( PGERR, PROGRAM );
+ DECODE_SR_ERROR( WRPRTERR, PROTECT );
+#elif defined(F2STYLE)
+ // OPERR is probably unnecessary really, but just in case.
+ // Do it before others though so they can override with a better value.
+ DECODE_SR_ERROR( OPERR, HWR );
+ DECODE_SR_ERROR( WRPERR, PROTECT );
+ DECODE_SR_ERROR( PGAERR, INVALID );
+ DECODE_SR_ERROR( PGPERR, PROTOCOL );
+ DECODE_SR_ERROR( PGSERR, PROTOCOL );
+#endif
+ return result;
+}
+
+static void stm32_flash_clear_sr_err(void)
+{
+ cyg_uint32 sr;
+#if defined(F1STYLE)
+ sr = CYGHWR_HAL_STM32_FLASH_SR_PGERR | CYGHWR_HAL_STM32_FLASH_SR_WRPRTERR;
+#elif defined(F2STYLE)
+ sr = CYGHWR_HAL_STM32_FLASH_SR_OPERR |
+ CYGHWR_HAL_STM32_FLASH_SR_WRPERR |
+ CYGHWR_HAL_STM32_FLASH_SR_PGAERR |
+ CYGHWR_HAL_STM32_FLASH_SR_PGPERR |
+ CYGHWR_HAL_STM32_FLASH_SR_PGSERR;
+#endif
+ HAL_WRITE_UINT32( CYGHWR_HAL_STM32_FLASH + CYGHWR_HAL_STM32_FLASH_SR, sr );
+}
+
+// ----------------------------------------------------------------------------
+// Initialize the flash.
+
+
+static int
+stm32_flash_init(struct cyg_flash_dev* dev)
+{
+ // Set up the block info entries.
+
+ dev->block_info = &hal_stm32_flash_priv.block_info[0];
+#if defined(STM32_FLASH_NUM_BLOCK_INFOS)
+ dev->num_block_infos = STM32_FLASH_NUM_BLOCK_INFOS;
+#else
+ dev->num_block_infos = sizeof(hal_stm32_flash_priv.block_info) / sizeof(hal_stm32_flash_priv.block_info[0]);
+#endif
+
+ // As stated in the errata sheet, the debug register can only be read in
+ // debug mode and is therefore not accessible by user software.
+
+ // Set end address
+ dev->end = dev->start + STM32_FLASH_SIZE - 1;
+
+ stf_diag("block_size %d size %08x end %08x\n", dev->block_info[0].block_size, STM32_FLASH_SIZE, dev->end );
+
+ // Ensure there's nothing hanging over from before us.
+ stm32_flash_clear_sr_err();
+
+ return CYG_FLASH_ERR_OK;
+}
+
+// ----------------------------------------------------------------------------
+
+static size_t
+stm32_flash_query(struct cyg_flash_dev* dev, void* data, size_t len)
+{
+ static char query[] = "STM32 Internal Flash";
+ memcpy( data, query, sizeof(query));
+ return sizeof(query);
+}
+
+// ----------------------------------------------------------------------------
+// Get info about the current block, i.e. base and size.
+
+static void
+stm32_flash_get_block_info(struct cyg_flash_dev* dev, const cyg_flashaddr_t addr, cyg_flashaddr_t* block_start,
+ size_t* block_size, cyg_uint16 *block_num)
+{
+ size_t offset = addr - dev->start;
+ cyg_ucount8 i;
+ cyg_uint32 bi_size_passed = 0;
+ cyg_uint16 blocks_passed = 0;
+
+ // This loop has the termination condition commented out to silence a
+ // warning. It should never be reached anyway, so that's fine, although
+ // that is checked with an assert.
+
+ for ( i=0; /* i < dev->num_block_info */ ; i++ )
+{
+ const cyg_flash_block_info_t *bi = &dev->block_info[i];
+ cyg_uint32 bi_size = bi->blocks * bi->block_size;
+
+ CYG_ASSERTC( i < dev->num_block_infos );
+
+ if ( offset < bi_size)
+ {
+ *block_start = dev->start + bi_size_passed + (offset & ~(bi->block_size-1));
+ *block_size = bi->block_size;
+ while (offset >= bi->block_size)
+ {
+ offset -= bi->block_size;
+ blocks_passed++;
+}
+ *block_num = blocks_passed;
+ break;
+ }
+ bi_size_passed += bi_size;
+ offset -= bi_size;
+ blocks_passed += bi->blocks;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+static int
+stm32_enable_hsi(void)
+{
+ CYG_ADDRESS rcc = CYGHWR_HAL_STM32_RCC;
+ cyg_uint32 cr;
+
+ HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CR, cr );
+ if( cr & CYGHWR_HAL_STM32_RCC_CR_HSIRDY )
+ return 0;
+
+ cr |= CYGHWR_HAL_STM32_RCC_CR_HSION;
+ HAL_WRITE_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CR, cr );
+ while( cr & CYGHWR_HAL_STM32_RCC_CR_HSIRDY )
+ HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CR, cr );
+
+ return 1;
+}
+
+static void
+stm32_disable_hsi(void)
+{
+ CYG_ADDRESS rcc = CYGHWR_HAL_STM32_RCC;
+ cyg_uint32 cr;
+
+ HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CR, cr );
+ cr &= ~(CYGHWR_HAL_STM32_RCC_CR_HSION | CYGHWR_HAL_STM32_RCC_CR_HSIRDY);
+ HAL_WRITE_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CR, cr );
+}
+
+// ----------------------------------------------------------------------------
+// Erase a single sector. There is no API support for chip-erase. The
+// generic code operates one sector at a time, invoking the driver for
+// each sector, so there is no opportunity inside the driver for
+// erasing multiple sectors in a single call. The address argument
+// points at the start of the sector.
+
+static int
+stm32_flash_hw_erase(cyg_flashaddr_t addr, cyg_uint16 block_num)
+{
+ cyg_uint32 base = CYGHWR_HAL_STM32_FLASH;
+ cyg_uint32 sr, cr;
+ cyg_uint32 timeout;
+
+#ifdef CYGDBG_USE_ASSERTS
+ HAL_READ_UINT32( base+CYGHWR_HAL_STM32_FLASH_SR, sr );
+ CYG_ASSERT( 0 == (sr & CYGHWR_HAL_STM32_FLASH_SR_BSY),
+ "Flash busy at start of erase, but it shouldn't be" );
+#endif
+
+ // Unlock the flash control registers
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_KEYR, CYGHWR_HAL_STM32_FLASH_KEYR_KEY1 );
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_KEYR, CYGHWR_HAL_STM32_FLASH_KEYR_KEY2 );
+
+#if defined(F1STYLE)
+ cr = CYGHWR_HAL_STM32_FLASH_CR_PER;
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_CR, cr );
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_AR, addr );
+ cr |= CYGHWR_HAL_STM32_FLASH_CR_STRT;
+#elif defined(F2STYLE)
+ cr = CYGHWR_HAL_STM32_FLASH_CR_SER |
+ CR_PSIZE_MAX |
+ CYGHWR_HAL_STM32_FLASH_CR_SNB(block_num) |
+ CYGHWR_HAL_STM32_FLASH_CR_STRT;
+#endif
+
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_CR, cr );
+
+ WAIT_FOR_FLASH_NOT_BUSY( timeout );
+
+ // Lock CR again (and clear other bits)
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_CR, CYGHWR_HAL_STM32_FLASH_CR_LOCK );
+
+#ifdef F2STYLE
+ // For F2 parts, we need to disable and reset the icache and dcache in the ACR.
+ {
+ cyg_uint32 acr;
+
+ HAL_READ_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr );
+ // disable
+ acr &= ~(CYGHWR_HAL_STM32_FLASH_ACR_DCEN|CYGHWR_HAL_STM32_FLASH_ACR_ICEN);
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr );
+ // reset
+ acr |= CYGHWR_HAL_STM32_FLASH_ACR_DCRST|CYGHWR_HAL_STM32_FLASH_ACR_ICRST;
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr );
+ // re-enable
+ acr &= ~(CYGHWR_HAL_STM32_FLASH_ACR_DCRST|CYGHWR_HAL_STM32_FLASH_ACR_ICRST);
+ acr |= CYGHWR_HAL_STM32_FLASH_ACR_DCEN|CYGHWR_HAL_STM32_FLASH_ACR_ICEN;
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr );
+ }
+#endif
+
+ if (0 == timeout)
+ return -1;
+
+ return sr;
+}
+
+// ----------------------------------------------------------------------------
+// Write data to flash, using individual word writes on F1, or something more
+// complicated on F2. On F1, the destination address will be aligned in a way suitable
+// for the bus. The source address need not be aligned. The count is in STM32_TYPE's on
+// F1, bytes on F2.
+
+static int
+stm32_flash_hw_program( volatile STM32_TYPE* addr, const STM32_TYPE* buf, cyg_uint32 count)
+{
+ cyg_uint32 base = CYGHWR_HAL_STM32_FLASH;
+ cyg_uint32 sr = 0, cr = 0;
+ cyg_uint32 timeout = 1; // Have to set timeout to non-zero to avoid confusing tests later.
+
+#ifdef CYGDBG_USE_ASSERTS
+ HAL_READ_UINT32( base+CYGHWR_HAL_STM32_FLASH_SR, sr );
+ CYG_ASSERT( 0 == (sr & CYGHWR_HAL_STM32_FLASH_SR_BSY),
+ "Flash busy at start of program, but it shouldn't be" );
+#endif
+
+ // Unlock the flash control registers
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_KEYR, CYGHWR_HAL_STM32_FLASH_KEYR_KEY1 );
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_KEYR, CYGHWR_HAL_STM32_FLASH_KEYR_KEY2 );
+
+#if defined(F1STYLE)
+ cr |= CYGHWR_HAL_STM32_FLASH_CR_PG;
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_CR, cr );
+
+ while( count-- )
+ {
+ HAL_WRITE_UINT16( addr, *buf );
+ addr++;
+ buf++;
+
+ WAIT_FOR_FLASH_NOT_BUSY(timeout);
+ if ( 0 == timeout )
+ break;
+ }
+
+
+#elif defined(F2STYLE)
+ // F2 is more complicated because the alignment depends on the parallelism.
+ // So we "simplify" by writing bytes until we've reached the desired alignment.
+
+ {
+ CYG_ADDRESS addr_max = (CYG_ADDRESS)addr + PARALLEL_ALIGN_MASK;
+ addr_max &= ~PARALLEL_ALIGN_MASK;
+
+ byte_write:
+ cr = CYGHWR_HAL_STM32_FLASH_CR_PG | CYGHWR_HAL_STM32_FLASH_CR_PSIZE_8;
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_CR, cr );
+
+ while (count && ((CYG_ADDRESS)addr < addr_max))
+ {
+ HAL_WRITE_UINT8( addr, *buf );
+ addr++;
+ buf++;
+ count--;
+ WAIT_FOR_FLASH_NOT_BUSY(timeout);
+ if (0 == timeout)
+ break;
+ }
+
+ if ( count && timeout )
+ {
+ // Now we should be aligned to the required parallelism boundary
+ // But we have to make sure we stop at an aligned addr too.
+ addr_max += count;
+ addr_max &= ~PARALLEL_ALIGN_MASK;
+
+ cr = CYGHWR_HAL_STM32_FLASH_CR_PG | CR_PSIZE_MAX;
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_CR, cr );
+ while ((CYG_ADDRESS)addr < addr_max)
+ {
+#if (CYGNUM_DEVS_FLASH_STM32_PARALLELISM == 8)
+ HAL_WRITE_UINT8( addr, *buf );
+#elif (CYGNUM_DEVS_FLASH_STM32_PARALLELISM == 16)
+ cyg_uint16 wbuf = *(cyg_uint16*)buf;
+ HAL_WRITE_UINT16( addr, wbuf );
+#elif (CYGNUM_DEVS_FLASH_STM32_PARALLELISM == 32)
+ cyg_uint32 wbuf = *(cyg_uint32*)buf;
+ HAL_WRITE_UINT32( addr, wbuf );
+#elif (CYGNUM_DEVS_FLASH_STM32_PARALLELISM == 64)
+ cyg_uint64 wbuf = *(cyg_uint64*)buf;
+ HAL_WRITE_UINT64( addr, wbuf );
+#endif
+ addr += PARALLEL_BYTES;
+ buf += PARALLEL_BYTES;
+ count -= PARALLEL_BYTES;
+ WAIT_FOR_FLASH_NOT_BUSY(timeout);
+ if (0 == timeout)
+ break;
+ } // while
+ } // if
+
+ if ( count && timeout )
+ {
+ // Still have some bytes left to write. Take a shortcut with goto, to save code.
+ addr_max = (CYG_ADDRESS)addr+count;
+ goto byte_write;
+ } // if
+ }
+
+ // For F2 parts, we need to disable and reset the icache and dcache in the ACR.
+ {
+ cyg_uint32 acr;
+
+ HAL_READ_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr );
+ // disable
+ acr &= ~(CYGHWR_HAL_STM32_FLASH_ACR_DCEN|CYGHWR_HAL_STM32_FLASH_ACR_ICEN);
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr );
+ // reset
+ acr |= CYGHWR_HAL_STM32_FLASH_ACR_DCRST|CYGHWR_HAL_STM32_FLASH_ACR_ICRST;
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr );
+ // re-enable
+ acr &= ~(CYGHWR_HAL_STM32_FLASH_ACR_DCRST|CYGHWR_HAL_STM32_FLASH_ACR_ICRST);
+ acr |= CYGHWR_HAL_STM32_FLASH_ACR_DCEN|CYGHWR_HAL_STM32_FLASH_ACR_ICEN;
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr );
+ }
+#endif // elif defined(F2STYLE)
+
+ // Lock CR again (and clear other bits)
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_CR, CYGHWR_HAL_STM32_FLASH_CR_LOCK );
+
+ if (0 == timeout)
+ return -1;
+
+ return sr;
+}
+
+// ----------------------------------------------------------------------------
+// Erase a single block. The calling code will have supplied a pointer
+// aligned to a block boundary.
+
+static int
+stm32_flash_erase(struct cyg_flash_dev* dev, cyg_flashaddr_t dest)
+{
+ int (*erase_fn)(cyg_uint32, cyg_uint16);
+ cyg_flashaddr_t block_start;
+ size_t block_size;
+ cyg_uint16 block_num;
+ int result;
+ int hsi;
+ STM32_INTSCACHE_STATE;
+
+ stf_diag("dest %p\n", (void *) dest);
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= dev->start) && (dest <= dev->end), "flash address out of device range");
+
+ stm32_flash_get_block_info(dev, dest, &block_start, &block_size, &block_num);
+ stf_diag("block_start %p block_size %d\n", (void *) block_start, block_size);
+ CYG_ASSERT(dest == block_start, "erase address should be the start of a flash block");
+
+ erase_fn = (int (*)(cyg_uint32, cyg_uint16)) cyg_flash_anonymizer( & stm32_flash_hw_erase );
+
+ hsi = stm32_enable_hsi();
+
+ STM32_INTSCACHE_BEGIN();
+
+ result = (*erase_fn)(block_start, block_num);
+ result = stm32_flash_decode_error( result );
+ stm32_flash_clear_sr_err();
+
+ STM32_INTSCACHE_END();
+
+ if (hsi)
+ stm32_disable_hsi();
+
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// Write some data to the flash. The destination must be aligned to a
+// 16 bit boundary. Higher level code guarantees that the data will
+// not straddle a block boundary.
+
+int
+stm32_flash_program(struct cyg_flash_dev* dev, cyg_flashaddr_t dest, const void* src, size_t len)
+{
+ int (*program_fn)(volatile STM32_TYPE*, const STM32_TYPE*, cyg_uint32);
+ volatile STM32_TYPE* uncached;
+ const STM32_TYPE* data;
+ size_t to_write;
+ int result = CYG_FLASH_ERR_OK;
+ int hsi;
+
+ STM32_INTSCACHE_STATE;
+
+ stf_diag("dest %p src %p len %p(%d)\n", (void *) dest, src, (void *) len, len);
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= dev->start) && ((CYG_ADDRESS)dest <= dev->end), "flash address out of device range");
+
+#ifdef F1STYLE
+ // Source and destination must be 16-bit aligned.
+ if( (0 != ((CYG_ADDRESS)dest & 1)) ||
+ (0 != ((CYG_ADDRESS)src & 1)) )
+ return CYG_FLASH_ERR_INVALID;
+#endif
+
+ uncached = STM32_UNCACHED_ADDRESS(dest);
+ data = (const STM32_TYPE*) src;
+ to_write = len / sizeof(STM32_TYPE); // For F1: Number of words, not bytes. For F2: STM32_TYPE is a byte.
+ program_fn = (int (*)(volatile STM32_TYPE*, const STM32_TYPE*, cyg_uint32)) cyg_flash_anonymizer( & stm32_flash_hw_program );
+
+ hsi = stm32_enable_hsi();
+
+ STM32_INTSCACHE_BEGIN();
+ while (to_write > 0)
+ {
+ size_t this_write = (to_write < CYGNUM_DEVS_FLASH_STM32_V2_PROGRAM_BURST_SIZE) ?
+ to_write : CYGNUM_DEVS_FLASH_STM32_V2_PROGRAM_BURST_SIZE;
+
+
+ result = (*program_fn)(uncached, data, this_write);
+ result = stm32_flash_decode_error( result );
+ if (result != CYG_FLASH_ERR_OK)
+ {
+ break;
+ }
+ to_write -= this_write;
+ if (to_write > 0)
+ {
+ // There is still more to be written. The last write must have been a burst size
+ uncached += this_write;
+ data += this_write;
+ STM32_INTSCACHE_SUSPEND();
+ STM32_INTSCACHE_RESUME();
+ }
+ }
+ stm32_flash_clear_sr_err();
+ STM32_INTSCACHE_END();
+
+ if (hsi)
+ stm32_disable_hsi();
+
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// Function table
+
+const CYG_FLASH_FUNS(cyg_stm32_flash_funs,
+ &stm32_flash_init,
+ &stm32_flash_query,
+ &stm32_flash_erase,
+ &stm32_flash_program,
+ (int (*)(struct cyg_flash_dev*, const cyg_flashaddr_t, void*, size_t))0,
+ cyg_flash_devfn_lock_nop,
+ cyg_flash_devfn_unlock_nop);
+
+// ----------------------------------------------------------------------------
+// End of stm32_flash.c
diff --git a/ecos/packages/devs/flash/fr30/skmb91302/current/ChangeLog b/ecos/packages/devs/flash/fr30/skmb91302/current/ChangeLog
new file mode 100644
index 0000000..9f51f30
--- /dev/null
+++ b/ecos/packages/devs/flash/fr30/skmb91302/current/ChangeLog
@@ -0,0 +1,39 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_skmb91302.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2008-07-01 Lars Poeschel <larsi@wh2.tu-dresden.de>
+
+ * src/skmb91302_flash.c: Changed CYGNUM_FLASH_BASE to 0x1000000
+ for real flash support
+
+2007-07-09 Lars Poeschel <larsi@wh2.tu-dresden.de>
+
+ * src/skmb91302_flash.c:
+ * cdl/flash_skmb91302.cdl: New package - platform specifics.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/fr30/skmb91302/current/cdl/flash_skmb91302.cdl b/ecos/packages/devs/flash/fr30/skmb91302/current/cdl/flash_skmb91302.cdl
new file mode 100644
index 0000000..105d7e1
--- /dev/null
+++ b/ecos/packages/devs/flash/fr30/skmb91302/current/cdl/flash_skmb91302.cdl
@@ -0,0 +1,70 @@
+# ====================================================================
+#
+# flash_skmb91302.cdl
+#
+# FLASH memory - Hardware support on Fujitsu Starterkit MB91302
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2002-09-03
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_FR30_SKMB91302 {
+ display "Fujitsu Starterkit MB91302 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_FR30_MB91301_SKMB91302
+
+ compile skmb91302_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL640D
+
+}
+
diff --git a/ecos/packages/devs/flash/fr30/skmb91302/current/src/skmb91302_flash.c b/ecos/packages/devs/flash/fr30/skmb91302/current/src/skmb91302_flash.c
new file mode 100644
index 0000000..7638d10
--- /dev/null
+++ b/ecos/packages/devs/flash/fr30/skmb91302/current/src/skmb91302_flash.c
@@ -0,0 +1,71 @@
+//==========================================================================
+//
+// skmb91302_flash.c
+//
+// Flash programming support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-10-20
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x1000000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT // This feature fails :-(
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF skmb91302_flash.c
diff --git a/ecos/packages/devs/flash/freescale/dspi/sst25xx/current/ChangeLog b/ecos/packages/devs/flash/freescale/dspi/sst25xx/current/ChangeLog
new file mode 100644
index 0000000..db80de4
--- /dev/null
+++ b/ecos/packages/devs/flash/freescale/dspi/sst25xx/current/ChangeLog
@@ -0,0 +1,35 @@
+2013-06-01 Ilija Kocho <ilijak@siva.com.mk>
+
+ * src/sst25_freescale_dspi.c:
+ Fix double-baud rate define. Bug spotted and patch provided by Mike Jones.
+ [ Bugzilla 1001855 ]
+
+2012-01-06 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/flash_sst25xx_freescale_dspi.cdl
+ * src/sst25_freescale_dspi.c:
+ New package -- Disk driver for Freescale DSPI [Bugzilla 1001450]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2012, 2013 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/freescale/dspi/sst25xx/current/cdl/flash_sst25xx_freescale_dspi.cdl b/ecos/packages/devs/flash/freescale/dspi/sst25xx/current/cdl/flash_sst25xx_freescale_dspi.cdl
new file mode 100644
index 0000000..baa4c9d
--- /dev/null
+++ b/ecos/packages/devs/flash/freescale/dspi/sst25xx/current/cdl/flash_sst25xx_freescale_dspi.cdl
@@ -0,0 +1,100 @@
+##==========================================================================
+##
+## flash_sst25xx_freescale_dspi.cdl
+##
+## SST25XX FLASH instatntiation for Freescale DSPI
+##
+##==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+##==========================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): Ilija Kocho <ilijak@siva.com.mk>
+## Date: 2011-12-27
+##
+######DESCRIPTIONEND####
+##
+##==========================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SST25XX_FREESCALE_DSPI {
+ display "Driver for SST25XX flash over Freescale DSPI"
+ parent CYGPKG_DEVS_FLASH_SPI_SST25XX
+
+ cdl_component CYGHWR_DEVS_FLASH_SPI_SST25XX_DEV0 {
+ display "Use SST25XX flash device 0"
+ flavor bool
+ default_value 0
+ no_define
+
+ requires CYGPKG_DEVS_FLASH_SPI_SST25XX
+ requires CYGPKG_DEVS_SPI_FREESCALE_DSPI
+ implements CYGHWR_DEVS_FLASH_SPI_SST25XX_DEVICE
+
+ requires CYGHWR_DEVS_FLASH_SST25XX_DEV0_SPI_BUS
+ requires CYGHWR_DEVS_FLASH_SST25XX_DEV0_SPI_CS
+ requires CYGNUM_DEVS_FLASH_SPI_SST25XX_DEV0_MAP_ADDR
+
+ compile -library=libextras.a sst25xx_freescale_dspi.c
+
+ cdl_component CYGHWR_DEVS_FLASH_SST25XX_DEV0_SPEED {
+ display "Nominal clock speed Hz"
+ flavor data
+ default_value 25000000
+
+ cdl_option CYGHWR_DEVS_FLASH_SST25XX_DEV0_SPI_USE_DBR {
+ display "Use double baud rate"
+ flavor bool
+ default_value 0
+ description "
+ Double baud rate is a feature of Freescale DSPI
+ that may provide higher baud rates but duty the cycle may be
+ different than 50/50 depdent on scaler/prescaler setting
+ for achieved baud rate."
+ }
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_SST25XX_DEV0_CS_DLY {
+ display "Nominal chip select delays (units)"
+ flavor data
+ legal_values { 1 10 }
+ default_value 1
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_SST25XX_DEV0_CS_DLY_UN {
+ display "Chip select delay unit (ns)"
+ flavor data
+ default_value 100
+ legal_values { 100 1000 }
+ }
+ }
+}
diff --git a/ecos/packages/devs/flash/freescale/dspi/sst25xx/current/src/sst25xx_freescale_dspi.c b/ecos/packages/devs/flash/freescale/dspi/sst25xx/current/src/sst25xx_freescale_dspi.c
new file mode 100644
index 0000000..0287224
--- /dev/null
+++ b/ecos/packages/devs/flash/freescale/dspi/sst25xx/current/src/sst25xx_freescale_dspi.c
@@ -0,0 +1,99 @@
+//==========================================================================
+//
+// sst25xx_freescale_dspi.c
+//
+// SST25XX FLASH device over Freescale DSPI
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ilijak
+// Contributor(s):
+// Date: 2011-12-14
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <pkgconf/system.h>
+#if defined(CYGPKG_IO_SPI) && defined(CYGPKG_DEVS_FLASH_SPI_SST25XX)
+// ------------------------------------------------------------------------
+// There is an SST25XX serial flash on the SPI bus
+//#include <cyg/infra/cyg_type.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/sst25xx.h>
+#include <cyg/io/spi_freescale_dspi.h>
+#include <pkgconf/devs_flash_sst25xx_freescale_dspi.h>
+
+// SPI bus device configuration
+#define SST25XX_SPI_FRAME_SIZE 8
+#define SST25XX_SPI_CLOCK_POL 0
+#define SST25XX_SPI_CLOCK_PHASE 0
+
+#ifdef CYGHWR_DEVS_FLASH_SST25XX_DEV0_SPI_USE_DBR
+# define SST25XX_SPI_DBR_DEV0 1
+#else
+# define SST25XX_SPI_DBR_DEV0 0
+#endif
+
+// Underlaying Freescale DSPI device
+CYG_DEVS_SPI_FREESCALE_DSPI_DEVICE(
+ sst25xx_spi_dev0, // Device name
+ CYGHWR_DEVS_FLASH_SST25XX_DEV0_SPI_BUS, // SPI bus
+ CYGHWR_DEVS_FLASH_SST25XX_DEV0_SPI_CS, // Dev num (CS)
+ SST25XX_SPI_FRAME_SIZE, // Frame size
+ SST25XX_SPI_CLOCK_POL, // Clock pol
+ SST25XX_SPI_CLOCK_PHASE, // Clock phase
+ CYGHWR_DEVS_FLASH_SST25XX_DEV0_SPEED, // Clock speed (Hz)
+ CYGHWR_DEVS_FLASH_SST25XX_DEV0_CS_DLY, // CS assert delay
+ CYGHWR_DEVS_FLASH_SST25XX_DEV0_CS_DLY, // CS negate delay
+ CYGHWR_DEVS_FLASH_SST25XX_DEV0_CS_DLY, // Delay between transfers
+ CYGHWR_DEVS_FLASH_SST25XX_DEV0_CS_DLY_UN,// Delay unit (100 or 1000 ns)
+ SST25XX_SPI_DBR_DEV0 // Use double baud rate
+);
+
+//-----------------------------------------------------------------------------
+// Instantiate the SST25xx device driver.
+
+CYG_DEVS_FLASH_SPI_SST25XX_DRIVER(sst25xx_flash_dev0,
+ CYGNUM_DEVS_FLASH_SPI_SST25XX_DEV0_MAP_ADDR,
+ &sst25xx_spi_dev0);
+
+#endif // defined(CYGPKG_IO_SPI) && defined(CYGPKG_DEVS_FLASH_SPI_SST25XX)
+
+//==========================================================================
+// EOF sst25xx_freescale_dspi.c
diff --git a/ecos/packages/devs/flash/freescale/kinetis/current/ChangeLog b/ecos/packages/devs/flash/freescale/kinetis/current/ChangeLog
new file mode 100644
index 0000000..65e7e40
--- /dev/null
+++ b/ecos/packages/devs/flash/freescale/kinetis/current/ChangeLog
@@ -0,0 +1,30 @@
+2012-04-26 Nicolas Aujoux <nau@csm-instruments.com>
+
+ * cdl/kinetis_flash.cdl
+ * include/kinetis_flash.h
+ * src/kinetis_flash.c
+ New package : Freescale Kinetis flash driver. [Bugzilla 1001561]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/freescale/kinetis/current/cdl/kinetis_flash.cdl b/ecos/packages/devs/flash/freescale/kinetis/current/cdl/kinetis_flash.cdl
new file mode 100644
index 0000000..8565c04
--- /dev/null
+++ b/ecos/packages/devs/flash/freescale/kinetis/current/cdl/kinetis_flash.cdl
@@ -0,0 +1,104 @@
+## ====================================================================
+##
+## kinetis_flash.cdl
+##
+## FLASH memory - Hardware support for kinetis on-chip flash
+##
+## ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2012 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+## ====================================================================
+######DESCRIPTIONBEGIN####
+##
+## Author(s): Nicolas Aujoux
+## Date: 2012-03-19
+##
+#####DESCRIPTIONEND####
+##
+## ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_KINETIS {
+ display "Kinetis FLASH memory support"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ implements CYGHWR_IO_FLASH_DEVICE
+
+ include_dir cyg/io
+
+ description "
+ Flash memory support for kinetis"
+
+ cdl_component CYGHWR_HAL_CORTEXM_KINETIS_FLASH {
+ display "Use Kinetis Flash driver"
+ flavor bool
+ default_value 1
+
+ compile -library=libextras.a kinetis_flash.c
+
+ cdl_option CYGNUM_DEVS_KINETIS_FLASH_LOGIC_ERROR_BUG {
+ display "Disable cache aliasing and speculation logic"
+ flavor bool
+ default_value { 1 }
+ description "
+ There is a logical error which prevent from accessing flash
+ properly if cache or prefetch options are enable in the Flash
+ Memory Controler register.
+ The prefetch option is not supported on program flash only or
+ program flash only with swap feature devices.
+ The cache aliasing is not supported on 512 KB and 384 KB
+ program flash. This option disables this two features."
+ }
+
+ cdl_option CYGNUM_DEVS_KINETIS_FLASH_BLOCK_SIZE {
+ display "Block size"
+ flavor data
+ legal_values { 0 0x800 0x1000 }
+ default_value 0x800
+ description "
+ Size of a flash block (called sector in freescale datasheets) :
+ 0x800 (2KB for k60 with 100M clock and ?)
+ 0x1000 (4KB for k60 with 120M and 150M clock and ?)"
+ }
+
+ cdl_option CYGNUM_DEVS_KINETIS_FLASH_LONGWORD_SIZE {
+ display "Longword/phrase size"
+ flavor data
+ legal_values { 4 8 }
+ default_value 4
+ description "
+ Size of a flash writing word, called LONGWORD (4 bytes)
+ or PHRASE (8 bytes) freescale datasheets."
+ }
+ }
+}
+
+# End of kinetis_flash.cdl
diff --git a/ecos/packages/devs/flash/freescale/kinetis/current/include/kinetis_flash.h b/ecos/packages/devs/flash/freescale/kinetis/current/include/kinetis_flash.h
new file mode 100644
index 0000000..7d7a9d8
--- /dev/null
+++ b/ecos/packages/devs/flash/freescale/kinetis/current/include/kinetis_flash.h
@@ -0,0 +1,63 @@
+#ifndef CYGONCE_DEVS_FLASH_KINETIS_H
+#define CYGONCE_DEVS_FLASH_KINETIS_H
+
+//==========================================================================
+//
+// kinetis_flash.h
+//
+// kinetis internal flash driver definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Nicolas Aujoux
+// Date: 2012-03-19
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+// Required data structures.
+#include <cyg/io/flash_dev.h>
+
+
+// The driver-specific data, pointed at by the priv field in a
+// a cyg_flash_dev structure.
+
+typedef struct cyg_kinetis_dev
+{
+} cyg_kinetis_flash_dev;
+
+#endif //CYGONCE_DEVS_FLASH_KINETIS_H
diff --git a/ecos/packages/devs/flash/freescale/kinetis/current/src/kinetis_flash.c b/ecos/packages/devs/flash/freescale/kinetis/current/src/kinetis_flash.c
new file mode 100644
index 0000000..3d622f6
--- /dev/null
+++ b/ecos/packages/devs/flash/freescale/kinetis/current/src/kinetis_flash.c
@@ -0,0 +1,395 @@
+//=================================================================
+//
+// kinetis_flash.c
+//
+// kinetis internal flash driver
+//
+//=================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Nicolas Aujoux
+// Date: 2012-03-19
+//
+//####DESCRIPTIONEND####
+
+
+#include <pkgconf/devs_flash_kinetis.h>
+#include <pkgconf/hal_cortexm_kinetis.h>
+
+#include <cyg/io/kinetis_flash.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+// Include memory access routines
+#include <cyg/hal/hal_io.h>
+
+// For tests
+#include <cyg/infra/testcase.h>
+
+#include <string.h>
+
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#define LONGWORD_SIZE (CYGNUM_DEVS_KINETIS_FLASH_LONGWORD_SIZE)
+
+// Flash command parameters
+#define FLASH_ERASE_BLOCK 0x08
+#define FLASH_ERASE_ALL_BLOCKS 0X44
+#define FLASH_ERASE_SECTOR 0x09
+#define FLASH_PROGRAM_LONGWORD 0x06
+#define FLASH_PROGRAM_PHRASE 0x07
+
+cyg_uint32 defaultRegisterPFB0CR, defaultRegisterPFB1CR;
+
+static int __attribute__((__long_call__)) flash_command_sequence(void)
+ __attribute__((section(".2ram.flashing")));
+
+static void __attribute__((__long_call__)) enable_flash_acceleration (void)
+ __attribute__((section(".2ram.flashing")));
+static void __attribute__((__long_call__)) disable_flash_acceleration (void)
+ __attribute__((section(".2ram.flashing")));
+
+static void __attribute__((__long_call__)) cache_on(cyg_uint32 *cachestate) __attribute__((section(".2ram.flashing")));
+static void __attribute__((__long_call__)) cache_off(cyg_uint32 *cachestate) __attribute__((section(".2ram.flashing")));
+
+// ===================================================================
+// Flash API functions
+// ===================================================================
+
+static int kinetis_flash_init (struct cyg_flash_dev* dev)
+{
+ HAL_READ_UINT32(CYGHWR_HAL_KINETIS_FMC_PFB0CR, defaultRegisterPFB0CR);
+ HAL_READ_UINT32(CYGHWR_HAL_KINETIS_FMC_PFB1CR, defaultRegisterPFB1CR);
+
+ // SIM_SCGC6: FTFL=1
+ CYGHWR_HAL_KINETIS_SIM_P->scgc6 |= CYGHWR_HAL_KINETIS_SIM_SCGC6_FTFL_M;
+
+ return CYG_FLASH_ERR_OK;
+}
+
+static size_t kinetis_flash_query (struct cyg_flash_dev* dev,
+ void* data, size_t len)
+{
+ static const char query[] = "Kinetis Flash";
+ if (sizeof(query) < len)
+ len = sizeof(query);
+ memcpy( data, query, len);
+ return sizeof(query);
+}
+
+static int kinetis_flash_erase_sector (struct cyg_flash_dev* dev,
+ cyg_flashaddr_t block_base)
+{
+ cyg_uint32 cachestate;
+ cyghwr_hal_kinetis_flash_t* flashRegister = CYGHWR_HAL_KINETIS_FLASH_P;
+ int returnValue = CYG_FLASH_ERR_OK;
+
+ // Check if the block_base is sector aligned
+ if((block_base % CYGNUM_DEVS_KINETIS_FLASH_BLOCK_SIZE) != 0)
+ return CYG_FLASH_ERR_INVALID;
+
+ // Check for valid range of the address
+ if(block_base < dev->start || (block_base +
+ CYGNUM_DEVS_KINETIS_FLASH_BLOCK_SIZE - 1) > dev->end)
+ return CYG_FLASH_ERR_INVALID;
+
+ cache_off(&cachestate);
+
+ // Create parameters to erase a flash sector
+ flashRegister->fccob0 = FLASH_ERASE_SECTOR;
+ flashRegister->fccob1 = (cyg_uint8)(block_base >> 16);
+ flashRegister->fccob2 = (cyg_uint8)((block_base >> 8) & 0xFF);
+ flashRegister->fccob3 = (cyg_uint8)(block_base & 0xFF);
+ returnValue = flash_command_sequence();
+
+ cache_on(&cachestate);
+
+ return returnValue;
+}
+
+static int kinetis_flash_program (struct cyg_flash_dev* dev,
+ cyg_flashaddr_t _base,
+ const void* _data,
+ size_t _len)
+{
+ cyghwr_hal_kinetis_flash_t* flashRegister = CYGHWR_HAL_KINETIS_FLASH_P;
+ cyg_uint32 endAddress;
+ int returnValue = CYG_FLASH_ERR_OK;
+ cyg_flashaddr_t base = _base;
+ const cyg_uint32* data = _data;
+ size_t len = _len;
+ cyg_uint32 currentData;
+ cyg_uint8 fccob0;
+ cyg_uint32 cachestate;
+
+ endAddress = base + len;
+
+ // Base and data have to be 16-bit aligned
+ if( (((CYG_ADDRESS)base & 1) != 0) || (((CYG_ADDRESS)data & 1) != 0))
+ return CYG_FLASH_ERR_INVALID;
+
+ // Check for valid range of the addresse
+ if((base < dev->start) || ((endAddress - 1) > dev->end))
+ return CYG_FLASH_ERR_INVALID;
+
+ cache_off(&cachestate);
+
+ while(len > 0)
+ {
+ flashRegister->fccob0 = fccob0 = (4 == LONGWORD_SIZE) ?
+ FLASH_PROGRAM_LONGWORD :
+ FLASH_PROGRAM_PHRASE;
+ flashRegister->fccob1 = (cyg_uint8)((base >> 16) & 0xFF);
+ flashRegister->fccob2 = (cyg_uint8)((base >> 8) & 0xFF);
+ flashRegister->fccob3 = (cyg_uint8)(base & 0xFF);
+
+ currentData = *data++;
+ flashRegister->fccob4 = (cyg_uint8)((currentData >> 24) & 0xFF);
+ flashRegister->fccob5 = (cyg_uint8)((currentData >> 16) & 0xFF);
+ flashRegister->fccob6 = (cyg_uint8)((currentData >> 8) & 0xFF);
+ flashRegister->fccob7 = (cyg_uint8)((currentData) & 0xFF);
+
+ if(FLASH_PROGRAM_PHRASE == fccob0)
+ {
+ currentData = *data++;
+ flashRegister->fccob8 = (cyg_uint8)((currentData >> 24) & 0xFF);
+ flashRegister->fccob9 = (cyg_uint8)((currentData >> 16) & 0xFF);
+ flashRegister->fccobA = (cyg_uint8)((currentData >> 8) & 0xFF);
+ flashRegister->fccobB = (cyg_uint8)((currentData) & 0xFF);
+ }
+
+ returnValue = flash_command_sequence();
+ if(returnValue != CYG_FLASH_ERR_OK)
+ {
+ break;
+ }
+ else
+ {
+ // Compute the next destination address
+ base += LONGWORD_SIZE;
+
+ // Compute size for the next command
+ len -= LONGWORD_SIZE;
+ }
+ }
+
+ cache_on(&cachestate);
+
+ return returnValue;
+}
+
+static int __attribute__((__long_call__)) flash_command_sequence(void)
+{
+ cyghwr_hal_kinetis_flash_t* flashRegister = CYGHWR_HAL_KINETIS_FLASH_P;
+ cyg_uint8 registerValue;
+ int returnValue;
+
+ while((flashRegister->fstat & CYGHWR_HAL_KINETIS_FLASH_FSTAT_CCIF_M)
+ == false)
+ {
+ // We wait for the end of the previous command ->CCIF bit=0 when finished
+ }
+
+ // clear RDCOLERR & ACCERR & FPVIOL flag in flash status register
+ flashRegister->fstat = (CYGHWR_HAL_KINETIS_FLASH_FSTAT_RDCOLERR_M |
+ CYGHWR_HAL_KINETIS_FLASH_FSTAT_ACCERR_M |
+ CYGHWR_HAL_KINETIS_FLASH_FSTAT_FPVIOL_M);
+
+ // Load FFCOB registers with command and paramaters for flash operations
+ // We clear the CCIF bit to start the command
+ HAL_REORDER_BARRIER();
+ flashRegister->fstat = CYGHWR_HAL_KINETIS_FLASH_FSTAT_CCIF_M;
+
+ // We wait the end of the process
+ while((flashRegister->fstat & CYGHWR_HAL_KINETIS_FLASH_FSTAT_CCIF_M)
+ == false){}
+
+ // Check if any error happened
+ // First we read the flash status register
+ registerValue = flashRegister->fstat;
+
+ // Access error
+ if((registerValue & CYGHWR_HAL_KINETIS_FLASH_FSTAT_ACCERR_M) != 0)
+ returnValue = CYG_FLASH_ERR_PROGRAM;
+ // Protection error
+ else if((registerValue & CYGHWR_HAL_KINETIS_FLASH_FSTAT_FPVIOL_M) != 0)
+ returnValue = CYG_FLASH_ERR_PROTECT;
+ // MGSTAT0 non-correctable error
+ else if ((registerValue & CYGHWR_HAL_KINETIS_FLASH_FSTAT_MGSTAT0_M) != 0)
+ returnValue = CYG_FLASH_ERR_PROTOCOL;
+ // No error detected
+ else
+ returnValue = CYG_FLASH_ERR_OK;
+
+ return returnValue;
+}
+
+#if 0
+
+static void kinetis_flash_read(struct cyg_flash_dev *dev,
+ const cyg_flashaddr_t base,
+ void *data,
+ size_t len)
+{
+ memcpy(data, (void*)base, len);
+}
+
+# define KINETIS_FLASH_READ
+
+#endif
+
+// ===================================================================
+// Flash accelerator and cache control functions
+// ===================================================================
+
+
+static void __attribute__((__long_call__)) enable_flash_acceleration ()
+{
+ HAL_WRITE_UINT32(CYGHWR_HAL_KINETIS_FMC_PFB0CR, defaultRegisterPFB0CR);
+ HAL_WRITE_UINT32(CYGHWR_HAL_KINETIS_FMC_PFB1CR, defaultRegisterPFB1CR);
+ __asm__ volatile( "dsb" );
+ __asm__ volatile( "isb" );
+}
+
+static void __attribute__((__long_call__)) disable_flash_acceleration ()
+{
+ cyg_uint32 registerValue;
+
+ // Flash Bank 0 register
+ HAL_READ_UINT32(CYGHWR_HAL_KINETIS_FMC_PFB0CR, registerValue);
+ // We disable data and instruction prefetch
+ registerValue &= ~CYGHWR_HAL_KINETIS_FMC_PFBCR_BIPE;
+ registerValue &= ~CYGHWR_HAL_KINETIS_FMC_PFBCR_BDPE;
+ // We disable data and instruction cache and single entry buffer
+ registerValue &= ~CYGHWR_HAL_KINETIS_FMC_PFBCR_BSEBE;
+ registerValue &= ~CYGHWR_HAL_KINETIS_FMC_PFBCR_BICE;
+ registerValue &= ~CYGHWR_HAL_KINETIS_FMC_PFBCR_BDCE;
+ HAL_WRITE_UINT32(CYGHWR_HAL_KINETIS_FMC_PFB0CR, registerValue);
+ __asm__ volatile( "dsb" );
+ __asm__ volatile( "isb" );
+
+ // Flash Bank 1 register
+ HAL_READ_UINT32(CYGHWR_HAL_KINETIS_FMC_PFB1CR, registerValue);
+ // We disable data and instruction prefetch
+ registerValue &= ~CYGHWR_HAL_KINETIS_FMC_PFBCR_BIPE;
+ registerValue &= ~CYGHWR_HAL_KINETIS_FMC_PFBCR_BDPE;
+ // We disable data and instruction cache and single entry buffer
+ registerValue &= ~CYGHWR_HAL_KINETIS_FMC_PFBCR_BSEBE;
+ registerValue &= ~CYGHWR_HAL_KINETIS_FMC_PFBCR_BICE;
+ registerValue &= ~CYGHWR_HAL_KINETIS_FMC_PFBCR_BDCE;
+ HAL_WRITE_UINT32(CYGHWR_HAL_KINETIS_FMC_PFB1CR, registerValue);
+ __asm__ volatile( "dsb" );
+ __asm__ volatile( "isb" );
+}
+
+static void __attribute__((__long_call__))
+cache_off( cyg_uint32 *cachestate ) {
+ cyg_uint32 intstate, dcachestate, icachestate;
+
+ HAL_DISABLE_INTERRUPTS(intstate);
+ HAL_DCACHE_IS_ENABLED(dcachestate);
+ HAL_ICACHE_IS_ENABLED(icachestate);
+ *cachestate = (dcachestate ? 1 : 0) | (icachestate ? 2 : 0);
+ if (dcachestate) {
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+ }
+ if (icachestate) {
+ HAL_ICACHE_DISABLE();
+ }
+#ifdef CYGNUM_DEVS_KINETIS_FLASH_LOGIC_ERROR_BUG
+ disable_flash_acceleration();
+#endif
+ HAL_RESTORE_INTERRUPTS(intstate);
+}
+
+static void __attribute__((__long_call__))
+cache_on( cyg_uint32 *cachestate ) {
+#ifdef CYGNUM_DEVS_KINETIS_FLASH_LOGIC_ERROR_BUG
+ enable_flash_acceleration();
+#endif
+ if (*cachestate & 1)
+ HAL_DCACHE_ENABLE();
+ if (*cachestate & 2)
+ HAL_ICACHE_ENABLE();
+}
+
+// ===================================================================
+// Function table
+// ===================================================================
+
+const CYG_FLASH_FUNS (
+ cyg_kinetis_flash_funs,
+ &kinetis_flash_init,
+ &kinetis_flash_query,
+ &kinetis_flash_erase_sector,
+ &kinetis_flash_program,
+#ifdef KINETIS_FLASH_READ
+ &kinetis_flash_read,
+#else
+ NULL,
+#endif
+ cyg_flash_devfn_lock_nop,
+ cyg_flash_devfn_unlock_nop);
+
+// Add the flash driver to the HAL TABLE cyg_flashdev
+
+cyg_kinetis_flash_dev hal_kinetis_flash_priv;
+static const cyg_flash_block_info_t cyg_flash_kinetis_block_info[1] = {{
+ CYGNUM_DEVS_KINETIS_FLASH_BLOCK_SIZE,
+ (CYGMEM_REGION_flash_SIZE) / CYGNUM_DEVS_KINETIS_FLASH_BLOCK_SIZE }};
+
+CYG_FLASH_DRIVER(hal_kinetis_flash,
+ &cyg_kinetis_flash_funs,
+ 0,
+ CYGMEM_REGION_flash,
+ (CYGMEM_REGION_flash + CYGMEM_REGION_flash_SIZE - 1),
+ 1, //number of block info
+ cyg_flash_kinetis_block_info,
+ &hal_kinetis_flash_priv);
+
+// ----------------------------------------------------------------------------
+// End of kinetis_flash.c
diff --git a/ecos/packages/devs/flash/frv/frv400/current/ChangeLog b/ecos/packages/devs/flash/frv/frv400/current/ChangeLog
new file mode 100644
index 0000000..a983fe6
--- /dev/null
+++ b/ecos/packages/devs/flash/frv/frv400/current/ChangeLog
@@ -0,0 +1,34 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_frv_frv400.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2004-09-05 Mark Salter <msalter@redhat.com>
+ David Woodhouse <dwmw2@redhat.com>
+
+ * cdl/flash_frv_frv400.cdl: Build on frvgen too.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/frv/frv400/current/cdl/flash_frv_frv400.cdl b/ecos/packages/devs/flash/frv/frv400/current/cdl/flash_frv_frv400.cdl
new file mode 100644
index 0000000..f439f72
--- /dev/null
+++ b/ecos/packages/devs/flash/frv/frv400/current/cdl/flash_frv_frv400.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_frv_frv400.cdl
+#
+# FLASH memory - Hardware support on Fujitsu FRV400
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov, gthomas
+# Original data: jskov
+# Contributors:
+# Date: 2001-09-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_FRV_FRV400 {
+ display "Fujitsu FRV400 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_FRV_FRV400 || CYGPKG_HAL_FRV_MB93091
+
+ compile frv400_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV160
+}
diff --git a/ecos/packages/devs/flash/frv/frv400/current/src/frv400_flash.c b/ecos/packages/devs/flash/frv/frv400/current/src/frv400_flash.c
new file mode 100644
index 0000000..8899c74
--- /dev/null
+++ b/ecos/packages/devs/flash/frv/frv400/current/src/frv400_flash.c
@@ -0,0 +1,73 @@
+//==========================================================================
+//
+// frv400_flash.c
+//
+// Flash programming for Fujitsu/AMD device on Fujitsu FRV400
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, gthomas
+// Contributors: jskov
+// Date: 2001-09-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0xFF000000)
+
+//static cyg_uint32 plf_flash_base;
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT // This feature fails :-(
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF frv400_flash.c
diff --git a/ecos/packages/devs/flash/frv/pdk403/current/ChangeLog b/ecos/packages/devs/flash/frv/pdk403/current/ChangeLog
new file mode 100644
index 0000000..304d702
--- /dev/null
+++ b/ecos/packages/devs/flash/frv/pdk403/current/ChangeLog
@@ -0,0 +1,33 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_frv_pdk403.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2004-09-05 David Woodhouse <dwmw2@redhat.com>
+
+ * cdl/flash_frv_pdk403.cdl, src/pdk403_flash.c: New port.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/frv/pdk403/current/cdl/flash_frv_pdk403.cdl b/ecos/packages/devs/flash/frv/pdk403/current/cdl/flash_frv_pdk403.cdl
new file mode 100644
index 0000000..da1c07b
--- /dev/null
+++ b/ecos/packages/devs/flash/frv/pdk403/current/cdl/flash_frv_pdk403.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_frv_pdk403.cdl
+#
+# FLASH memory - Hardware support on Fujitsu PDK403
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov, gthomas
+# Original data: jskov
+# Contributors:
+# Date: 2001-09-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_FRV_PDK403 {
+ display "Fujitsu PDK403 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_FRV_MB93093
+
+ compile pdk403_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV640
+}
diff --git a/ecos/packages/devs/flash/frv/pdk403/current/src/pdk403_flash.c b/ecos/packages/devs/flash/frv/pdk403/current/src/pdk403_flash.c
new file mode 100644
index 0000000..e1aef5a
--- /dev/null
+++ b/ecos/packages/devs/flash/frv/pdk403/current/src/pdk403_flash.c
@@ -0,0 +1,73 @@
+//==========================================================================
+//
+// pdk403_flash.c
+//
+// Flash programming for Fujitsu/AMD device on Fujitsu PDK403
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, gthomas
+// Contributors: jskov
+// Date: 2001-09-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (2)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0xFF000000)
+
+//static cyg_uint32 plf_flash_base;
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT // This feature fails :-(
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF pdk403_flash.c
diff --git a/ecos/packages/devs/flash/intel/28fxxx/current/ChangeLog b/ecos/packages/devs/flash/intel/28fxxx/current/ChangeLog
new file mode 100644
index 0000000..3712e17
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/28fxxx/current/ChangeLog
@@ -0,0 +1,141 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_intel_28fxxx.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2008-09-04 Dave Lawrence <dlawrence@ad-holdings.co.uk>
+
+ * include/flash_28fxxx.inl:
+ * include/flash_28fxxx_parts.inl: Support write buffering. Add an
+ entry to the parts table indicating the size of the buffer and
+ copy it into the device table during initialization.
+
+2006-12-14 Yoshinori Sato <ysato@users.sourceforge.jp>
+
+ * cdl/flash_intel_28fxxx.cdl, include/flash_28fxxx_parts.inl: Add
+ Intel 28F320J3 part.
+
+2006-11-28 Sergei Gavrikov <sg@sgs.gomel.by>
+
+ * cdl/flash_intel_28fxxx.cdl, include/flash_28fxxx_parts.inl:
+ Add Intel 28F160C3-B part.
+
+2006-11-21 Alexander Neundorf <alexander.neundorf@jenoptik.com>
+
+ * cdl/flash_intel_28fxxx.cdl, include/flash_28fxxx_parts.inl:
+ Add Intel 28F128K3, 28F128P30 and 28F128J3 parts.
+
+2006-11-17 Alexander Neundorf <alexander.neundorf@jenoptik.com>
+
+ * cdl/flash_intel_28fxxx.cdl, include/flash_28fxxx.inl:
+ Make the timeout configurable by adding a new CDL-option
+ CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT
+
+2006-05-10 Sergei Gavrikov <sg@belvok.com>
+
+ * cdl/flash_intel_28fxxx.cdl, include/flash_28fxxx_parts.inl: Add
+ Intel 28F160B3-T part.
+
+2005-04-22 David Vrabel <dvrabel@arcom.com>
+
+ * cdl/flash_intel_28fxxx.cdl, include/flash_28fxxx_parts.inl: Add
+ Intel 28F800B5-T and 28F800B5-B parts.
+
+2002-12-12 Gary Thomas <gthomas@ecoscentric.com>
+2002-12-12 Patrick Doyle <wpd@delcomsys.com>
+
+ * include/flash_28fxxx_parts.inl:
+ * include/flash_28fxxx.inl:
+ * cdl/flash_intel_28fxxx.cdl: Add SHARP 28F016 parts.
+
+2002-08-05 Gary Thomas <gary@chez-thomas.org>
+2002-08-05 Jani Monoses <jani@iv.ro>
+
+ * include/flash_28fxxx_parts.inl:
+ * cdl/flash_intel_28fxxx.cdl: Add support for 28F320B3.
+
+2002-03-06 Nick Garnett <nickg@redhat.com>
+
+ * include/flash_28fxxx.inl:
+ Added CYGHWR_FLASH_WRITE_ENABLE() and CYGHWR_FLASH_WRITE_DISABLE()
+ macro calls to enable and disable FLASH writing in platform
+ hardware. Some platforms have extra protection for the FLASH
+ beyond that provided for the FLASH itself.
+
+ * include/flash_28fxxx_parts.inl:
+ * cdl/flash_intel_28fxxx.cdl:
+ Added support for the 28f320S3 part. This mainly differs from the
+ C3 in that it does not have any bootblocks.
+
+2001-10-17 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/flash_28fxxx_parts.inl: Fix boot block start address.
+
+2001-08-15 Jesper Skov <jskov@redhat.com>
+ [from branch]
+ * include/flash_28fxxx_parts.inl: Set correct bootblock sub-block
+ sizes.
+
+ * include/flash_28fxxx.inl (nDEBUG): Added some debug code.
+ (flash_unlock_block, flash_lock_block): Iterate properly over
+ bootblock sub-blocks.
+
+2001-08-10 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_intel_28fxxx.cdl: Added options for variants.
+
+ * include/flash_28fxxx.inl: Support bootblock parts. Support
+ locking. Buffered writes are broken though.
+ Which affects the Malta, which uses them.
+
+ * include/flash_28fxxx_parts.inl: Created.
+
+2001-06-29 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_28fxxx.inl: Fix 28F160 block size.
+
+2001-06-20 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_28fxxx.inl (flash_hwr_init): Fix bad size
+ calculations.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_intel_28fxxx.cdl: Links flash functions to RAM. IO
+ driver should not copy them there.
+
+2001-03-23 Jesper Skov <jskov@redhat.com>
+
+ * include/flash_28fxxx.inl (flash_program_buf): Calculate correct
+ wc for buffered writes.
+ (flash_query): Don't return until flash is safely back in data
+ mode.
+
+2001-03-21 Jesper Skov <jskov@redhat.com>
+
+ * Package cloned from at29cxxxx driver. Changed to support Intel
+ FlashFile.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/intel/28fxxx/current/cdl/flash_intel_28fxxx.cdl b/ecos/packages/devs/flash/intel/28fxxx/current/cdl/flash_intel_28fxxx.cdl
new file mode 100644
index 0000000..d94fa19
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/28fxxx/current/cdl/flash_intel_28fxxx.cdl
@@ -0,0 +1,232 @@
+# ====================================================================
+#
+# flash_intel_28fxxx.cdl
+#
+# FLASH memory - Hardware support for Intel flash parts
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov, gthomas
+# Date: 2001-03-21
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_INTEL_28FXXX {
+ display "Intel FlashFile FLASH memory support"
+ description "FLASH memory device support for Intel FlashFile"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+
+ active_if CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ include_dir cyg/io
+
+ requires { CYGINT_DEVS_FLASH_INTEL_VARIANTS != 0 }
+
+ cdl_option CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT {
+ display "Timeout for flash operations (simple counter based)"
+ flavor data
+ legal_values 1000000 to 1000000000
+ default_value 50000000
+ description "
+ Timeout for flash operations. This is just a simple
+ counter. It depends on the speed of the flash, the processor, etc.
+ It has to be adjusted for each hardware configuration. "
+ }
+
+
+ cdl_interface CYGINT_DEVS_FLASH_INTEL_VARIANTS {
+ display "Number of included variants"
+ }
+
+ cdl_interface CYGHWR_DEVS_FLASH_INTEL_BUFFERED_WRITES {
+ flavor booldata
+ display "Must support buffered writes"
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F160S5 {
+ display "Intel 28F160S5 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ implements CYGHWR_DEVS_FLASH_INTEL_BUFFERED_WRITES
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F160S5
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F160B3T {
+ display "Intel 28F160B3T flash memory support"
+ default_value 0
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F160B3T
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F160C3B {
+ display "Intel 28F160C3B flash memory support"
+ default_value 0
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F160C3B
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F320B3 {
+ display "Intel 28F320B3 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F320B3
+ part in the family."
+ }
+
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F320C3 {
+ display "Intel 28F320C3 flash memory support"
+ default_value 0
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F320C3
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F320S3 {
+ display "Intel 28F320S3 flash memory support"
+ default_value 0
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F320S3
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F128K3 {
+ display "Intel 28F128K3 flash memory support"
+ default_value 0
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F128K3
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F128P30 {
+ display "Intel 28F128P30 flash memory support"
+ default_value 0
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ implements CYGHWR_DEVS_FLASH_INTEL_BUFFERED_WRITES
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F128P30
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F128J3 {
+ display "Intel 28F128J3 flash memory support"
+ default_value 0
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F128J3
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F320J3 {
+ display "Intel 28F320J3 flash memory support"
+ default_value 0
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F320J3
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_INTEL_28F800B5 {
+ display "Intel 28F800B5 flash memory support"
+ default_value 0
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the 28F800B5
+ part in the family."
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4 {
+ display "Sharp LH28F016SCT-Z4 flash memory support"
+ default_value 0
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the Sharp LH28F016SCT-Z4
+ part. Although this part is not an Intel part, the driver
+ is implemented using the same command status definitions."
+
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_95 {
+ display "Sharp LH28F016SCT-95 flash memory support"
+ default_value 0
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGINT_DEVS_FLASH_INTEL_VARIANTS
+ description "
+ When this option is enabled, the Intel flash driver will be
+ able to recognize and handle the Sharp LH28F016SCT-95
+ part. Although this part is not an Intel part, the driver
+ is implemented using the same command status definitions."
+
+ }
+}
diff --git a/ecos/packages/devs/flash/intel/28fxxx/current/include/flash_28fxxx.inl b/ecos/packages/devs/flash/intel/28fxxx/current/include/flash_28fxxx.inl
new file mode 100644
index 0000000..a0557af
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/28fxxx/current/include/flash_28fxxx.inl
@@ -0,0 +1,768 @@
+#ifndef CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL
+#define CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL
+//==========================================================================
+//
+// flash_28fxxx.inl
+//
+// Intel 28Fxxx series flash driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-03-21
+// Purpose:
+// Description:
+//
+// Notes: Device table could use unions of flags to save some space
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_flash.h>
+#include <pkgconf/devs_flash_intel_28fxxx.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#include <cyg/hal/hal_io.h>
+
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+#define nDEBUG
+
+#ifdef DEBUG
+typedef void (*call_t)(char* str, ...);
+extern void diag_printf(char* str, ...);
+call_t d_print = &diag_printf;
+#endif
+
+//----------------------------------------------------------------------------
+// Common device details.
+#define FLASH_Read_ID FLASHWORD( 0x90 )
+#define FLASH_Reset FLASHWORD( 0xFF )
+#define FLASH_Program FLASHWORD( 0x40 )
+#define FLASH_Write_Buffer FLASHWORD( 0xe8 )
+#define FLASH_Block_Erase FLASHWORD( 0x20 )
+#define FLASH_Confirm FLASHWORD( 0xD0 )
+#define FLASH_Resume FLASHWORD( 0xD0 )
+
+#define FLASH_Set_Lock FLASHWORD( 0x60 )
+#define FLASH_Set_Lock_Confirm FLASHWORD( 0x01 )
+#define FLASH_Clear_Lock FLASHWORD( 0x60 )
+#define FLASH_Clear_Lock_Confirm FLASHWORD( 0xd0 )
+
+#define FLASH_Read_Status FLASHWORD( 0x70 )
+#define FLASH_Clear_Status FLASHWORD( 0x50 )
+#define FLASH_Status_Ready FLASHWORD( 0x80 )
+
+// Status that we read back:
+#define FLASH_ErrorMask FLASHWORD( 0x7E )
+#define FLASH_ErrorProgram FLASHWORD( 0x10 )
+#define FLASH_ErrorErase FLASHWORD( 0x20 )
+#define FLASH_ErrorLock FLASHWORD( 0x30 )
+#define FLASH_ErrorLowVoltage FLASHWORD( 0x08 )
+#define FLASH_ErrorLocked FLASHWORD( 0x02 )
+
+// Platform code must define the below
+// #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel)
+// #define CYGNUM_FLASH_SERIES : Number of devices in series
+// #define CYGNUM_FLASH_WIDTH : Width of devices on platform
+// #define CYGNUM_FLASH_BASE : Address of first device
+
+#define CYGNUM_FLASH_BLANK (1)
+#define CYGNUM_FLASH_DEVICES (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
+
+
+#ifndef FLASH_P2V
+# define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_)))
+#endif
+#ifndef CYGHWR_FLASH_28FXXX_PLF_INIT
+# define CYGHWR_FLASH_28FXXX_PLF_INIT()
+#endif
+#ifndef CYGHWR_FLASH_WRITE_ENABLE
+#define CYGHWR_FLASH_WRITE_ENABLE()
+#endif
+#ifndef CYGHWR_FLASH_WRITE_DISABLE
+#define CYGHWR_FLASH_WRITE_DISABLE()
+#endif
+
+//----------------------------------------------------------------------------
+// Now that device properties are defined, include magic for defining
+// accessor type and constants.
+#include <cyg/io/flash_dev.h>
+
+//----------------------------------------------------------------------------
+// Information about supported devices
+typedef struct flash_dev_info {
+ flash_data_t device_id;
+ cyg_uint32 block_size;
+ cyg_int32 block_count;
+ cyg_uint32 base_mask;
+ cyg_uint32 device_size;
+ cyg_bool locking; // supports locking
+ cyg_bool buffered_w; // supports buffered writes
+ cyg_uint32 buffer_size;
+ cyg_bool bootblock;
+ cyg_uint32 bootblocks[12]; // 0 is bootblock offset, 1-11 sub-sector sizes (or 0)
+ cyg_bool banked;
+ cyg_uint32 banks[2]; // bank offets, highest to lowest (lowest should be 0)
+ // (only one entry for now, increase to support devices
+ // with more banks).
+} flash_dev_info_t;
+
+static const flash_dev_info_t* flash_dev_info;
+static const flash_dev_info_t supported_devices[] = {
+#include <cyg/io/flash_28fxxx_parts.inl>
+};
+#define NUM_DEVICES (sizeof(supported_devices)/sizeof(flash_dev_info_t))
+
+//----------------------------------------------------------------------------
+// Functions that put the flash device into non-read mode must reside
+// in RAM.
+void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
+int flash_erase_block(void* block, unsigned int size)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int flash_program_buf(void* addr, void* data, int len,
+ unsigned long block_mask, int buffer_size)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+int flash_lock_block(void* addr)
+ __attribute__ ((section (".2ram.flash_lock_block")));
+int flash_unlock_block(void* block, int block_size, int blocks)
+ __attribute__ ((section (".2ram.flash_unlock_block")));
+
+//----------------------------------------------------------------------------
+// Initialize driver details
+int
+flash_hwr_init(void)
+{
+ int i;
+ flash_data_t id[2];
+
+ CYGHWR_FLASH_28FXXX_PLF_INIT();
+
+ flash_dev_query(id);
+
+ // Look through table for device data
+ flash_dev_info = supported_devices;
+ for (i = 0; i < NUM_DEVICES; i++) {
+ if (flash_dev_info->device_id == id[1])
+ break;
+ flash_dev_info++;
+ }
+
+ // Did we find the device? If not, return error.
+ if (NUM_DEVICES == i)
+ return FLASH_ERR_DRV_WRONG_PART;
+
+ // Hard wired for now
+ flash_info.block_size = flash_dev_info->block_size;
+ flash_info.blocks = flash_dev_info->block_count * CYGNUM_FLASH_SERIES;
+ flash_info.start = (void *)CYGNUM_FLASH_BASE;
+ flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (flash_dev_info->device_size * CYGNUM_FLASH_SERIES));
+ flash_info.buffer_size = flash_dev_info->buffer_size;
+
+ return FLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int e)
+{
+ return e;
+}
+
+
+//----------------------------------------------------------------------------
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern unsigned char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
+
+//----------------------------------------------------------------------------
+// Flash Query
+//
+// Only reads the manufacturer and part number codes for the first
+// device(s) in series. It is assumed that any devices in series
+// will be of the same type.
+
+void
+flash_query(void* data)
+{
+ volatile flash_data_t *ROM;
+ flash_data_t* id = (flash_data_t*) data;
+ flash_data_t w;
+
+ ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
+
+ w = ROM[0];
+
+ CYGHWR_FLASH_WRITE_ENABLE();
+
+ ROM[0] = FLASH_Read_ID;
+
+ // Manufacturers' code
+ id[0] = ROM[0];
+ // Part number
+ id[1] = ROM[1];
+
+ ROM[0] = FLASH_Reset;
+
+ CYGHWR_FLASH_WRITE_DISABLE();
+
+ // Stall, waiting for flash to return to read mode.
+ while (w != ROM[0]);
+}
+
+//----------------------------------------------------------------------------
+// Erase Block
+int
+flash_erase_block(void* block, unsigned int block_size)
+{
+ int res = FLASH_ERR_OK;
+ int timeout;
+ unsigned long len;
+ int len_ix = 1;
+ flash_data_t stat;
+ volatile flash_data_t *ROM;
+ volatile flash_data_t *b_p = (flash_data_t*) block;
+ volatile flash_data_t *b_v;
+ cyg_bool bootblock;
+
+ ROM = FLASH_P2V((unsigned long)block & flash_dev_info->base_mask);
+
+ // Is this the boot sector?
+ bootblock = (flash_dev_info->bootblock &&
+ (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM)));
+ if (bootblock) {
+ len = flash_dev_info->bootblocks[len_ix++];
+ } else {
+ len = flash_dev_info->block_size;
+ }
+
+ CYGHWR_FLASH_WRITE_ENABLE();
+
+ while (len > 0) {
+ b_v = FLASH_P2V(b_p);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Erase block
+ ROM[0] = FLASH_Block_Erase;
+ *b_v = FLASH_Confirm;
+
+ timeout = CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT ;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ if (stat & FLASH_ErrorMask) {
+ if (!(stat & FLASH_ErrorErase)) {
+ res = FLASH_ERR_HWR; // Unknown error
+ } else {
+ if (stat & FLASH_ErrorLowVoltage)
+ res = FLASH_ERR_LOW_VOLTAGE;
+ else if (stat & FLASH_ErrorLocked)
+ res = FLASH_ERR_PROTECT;
+ else
+ res = FLASH_ERR_ERASE;
+ }
+ }
+
+ // Check if block got erased
+ while (len > 0) {
+ b_v = FLASH_P2V(b_p++);
+ if (*b_v != FLASH_BlankValue ) {
+ // Only update return value if erase operation was OK
+ if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
+ return res;
+ }
+ len -= sizeof(*b_p);
+ }
+
+ if (bootblock)
+ len = flash_dev_info->bootblocks[len_ix++];
+ }
+
+ CYGHWR_FLASH_WRITE_DISABLE();
+
+ return res;
+}
+
+//----------------------------------------------------------------------------
+// Program Buffer
+int
+flash_program_buf(void* addr, void* data, int len,
+ unsigned long block_mask, int buffer_size)
+{
+ flash_data_t stat = 0;
+ int timeout;
+
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* BA;
+ volatile flash_data_t* addr_v;
+ volatile flash_data_t* addr_p = (flash_data_t*) addr;
+ volatile flash_data_t* data_p = (flash_data_t*) data;
+
+ int res = FLASH_ERR_OK;
+
+ // Base address of device(s) being programmed.
+ ROM = FLASH_P2V((unsigned long)addr & flash_dev_info->base_mask);
+ BA = FLASH_P2V((unsigned long)addr & ~(flash_dev_info->block_size - 1));
+
+ CYGHWR_FLASH_WRITE_ENABLE();
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_BUFFERED_WRITES
+ // FIXME: This code has not been adjusted to handle bootblock
+ // parts yet.
+ // If the buffer size has not been initialised, buffered write will
+ // be skipped.
+
+ if (flash_dev_info->buffered_w && buffer_size) {
+ int i, wc;
+ // Write any big chunks first
+ while (len >= buffer_size) {
+ wc = buffer_size;
+ if (wc > len) wc = len;
+ len -= wc;
+ wc = wc / ((CYGNUM_FLASH_WIDTH/8)*CYGNUM_FLASH_INTERLEAVE); // Word count
+ timeout = CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT;
+
+ *BA = FLASH_Write_Buffer;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ goto bad;
+ }
+ *BA = FLASH_Write_Buffer;
+ }
+ *BA = FLASHWORD(wc-1); // Count is 0..N-1
+ for (i = 0; i < wc; i++) {
+ addr_v = FLASH_P2V(addr_p++);
+ *addr_v = *data_p++;
+ }
+ *BA = FLASH_Confirm;
+
+ ROM[0] = FLASH_Read_Status;
+ timeout = CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ goto bad;
+ }
+ }
+ }
+ }
+#endif // CYGHWR_DEVS_FLASH_INTEL_BUFFERED_WRITES
+
+ while (len > 0) {
+ addr_v = FLASH_P2V(addr_p++);
+ ROM[0] = FLASH_Program;
+ *addr_v = *data_p;
+ timeout = CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ goto bad;
+ }
+ }
+ if (stat & FLASH_ErrorMask) {
+ if (!(stat & FLASH_ErrorProgram))
+ res = FLASH_ERR_HWR; // Unknown error
+ else {
+ if (stat & FLASH_ErrorLowVoltage)
+ res = FLASH_ERR_LOW_VOLTAGE;
+ else if (stat & FLASH_ErrorLocked)
+ res = FLASH_ERR_PROTECT;
+ else
+ res = FLASH_ERR_PROGRAM;
+ }
+ break;
+ }
+ ROM[0] = FLASH_Clear_Status;
+ ROM[0] = FLASH_Reset;
+ if (*addr_v != *data_p++) {
+ res = FLASH_ERR_DRV_VERIFY;
+ break;
+ }
+ len -= sizeof( flash_data_t );
+ }
+
+ // Restore ROM to "normal" mode
+ bad:
+ ROM[0] = FLASH_Reset;
+
+ CYGHWR_FLASH_WRITE_DISABLE();
+
+ // Ideally, we'd want to return not only the failure code, but also
+ // the address/device that reported the error.
+ return res;
+}
+
+#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
+//----------------------------------------------------------------------------
+// Lock block
+int
+flash_lock_block(void* block)
+{
+ volatile flash_data_t *ROM;
+ int res = FLASH_ERR_OK;
+ flash_data_t state;
+ int timeout = CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT;
+ volatile flash_data_t* b_p = (flash_data_t*) block;
+ volatile flash_data_t *b_v;
+ cyg_bool bootblock;
+ int len, len_ix = 1;
+
+ if (!flash_dev_info->locking)
+ return res;
+
+#ifdef DEBUG
+ d_print("flash_lock_block %08x\n", block);
+#endif
+
+ ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask);
+
+ // Is this the boot sector?
+ bootblock = (flash_dev_info->bootblock &&
+ (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM)));
+ if (bootblock) {
+ len = flash_dev_info->bootblocks[len_ix++];
+ } else {
+ len = flash_dev_info->block_size;
+ }
+
+ CYGHWR_FLASH_WRITE_ENABLE();
+
+ while (len > 0) {
+ b_v = FLASH_P2V(b_p);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Set lock bit
+ *b_v = FLASH_Set_Lock;
+ *b_v = FLASH_Set_Lock_Confirm; // Confirmation
+ while(((state = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ // Go to next block
+ b_p += len / sizeof( flash_data_t );
+ len = 0;
+
+ if (FLASH_ErrorLock == (state & FLASH_ErrorLock))
+ res = FLASH_ERR_LOCK;
+
+ if (res != FLASH_ERR_OK)
+ break;
+
+ if (bootblock)
+ len = flash_dev_info->bootblocks[len_ix++];
+ }
+
+ CYGHWR_FLASH_WRITE_DISABLE();
+
+ return res;
+}
+
+//----------------------------------------------------------------------------
+// Unlock block
+
+int
+flash_unlock_block(void* block, int block_size, int blocks)
+{
+ volatile flash_data_t *ROM;
+ int res = FLASH_ERR_OK;
+ flash_data_t state;
+ int timeout = CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT;
+ volatile flash_data_t* b_p = (flash_data_t*) block;
+ volatile flash_data_t *b_v;
+
+#if (defined(CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4) || defined(CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_95) )
+ // The Sharp device follows all the same rules as the Intel 28x part,
+ // except that the unlocking mechanism unlocks all blocks at once. This
+ // is the way the Strata part seems to work. I will replace the
+ // flash_unlock_block function with one similar to the Strata function.
+ // As the Sharp part does not have the bootlock characteristics, I
+ // will ignore them.
+//
+// The difficulty with this operation is that the hardware does not support
+// unlocking single blocks. However, the logical layer would like this to
+// be the case, so this routine emulates it. The hardware can clear all of
+// the locks in the device at once. This routine will use that approach and
+// then reset the regions which are known to be locked.
+//
+
+#define MAX_FLASH_BLOCKS (flash_dev_info->block_count * CYGNUM_FLASH_SERIES)
+
+ unsigned char is_locked[MAX_FLASH_BLOCKS];
+ int i;
+
+ // Get base address and map addresses to virtual addresses
+#ifdef DEBUG
+ d_print("\nNow inside low level driver\n");
+#endif
+ ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
+ block = FLASH_P2V(block);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Get current block lock state. This needs to access each block on
+ // the device so currently locked blocks can be re-locked.
+ b_p = ROM;
+ for (i = 0; i < blocks; i++) {
+ b_v = FLASH_P2V( b_p );
+ *b_v = FLASH_Read_ID;
+ if (b_v == block) {
+ is_locked[i] = 0;
+ } else {
+ if(b_v[2]){ /* it is possible that one of the interleaved devices
+ * is locked, but others are not. Coming out of this
+ * function, if one was locked, all will be locked.
+ */
+ is_locked[i] = 1;
+ }else{
+ is_locked[i] = 0;
+ }
+ }
+#ifdef DEBUG
+#endif
+ b_p += block_size / sizeof(*b_p);
+ }
+ ROM[0] = FLASH_Reset;
+#ifdef DEBUG
+ for (i = 0; i < blocks; i++) {
+ d_print("\nblock %d %s", i,
+ is_locked[i] ? "LOCKED" : "UNLOCKED");
+ }
+ d_print("\n");
+#endif
+
+ // Clears all lock bits
+ ROM[0] = FLASH_Clear_Lock;
+ ROM[0] = FLASH_Clear_Lock_Confirm; // Confirmation
+ timeout = CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT;
+ while(((state = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore the lock state
+ b_p = ROM;
+ for (i = 0; i < blocks; i++) {
+ b_v = FLASH_P2V( b_p );
+ if (is_locked[i]) {
+ *b_v = FLASH_Set_Lock;
+ *b_v = FLASH_Set_Lock_Confirm; // Confirmation
+ timeout = CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT;
+ while(((state = ROM[0]) & FLASH_Status_Ready)
+ != FLASH_Status_Ready) {
+ if (--timeout == 0){
+ res = FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ }
+ if (FLASH_ErrorLock == (state & FLASH_ErrorLock))
+ res = FLASH_ERR_LOCK;
+
+ if (res != FLASH_ERR_OK)
+ break;
+
+ }
+ b_p += block_size / sizeof(*b_p);
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ return res;
+
+#else // not CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4
+
+ cyg_bool bootblock;
+ int len, len_ix = 1;
+
+ if (!flash_dev_info->locking)
+ return res;
+
+ ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask);
+
+#ifdef DEBUG
+ d_print("flash_unlock_block dev %08x block %08x size %08x count %08x\n", ROM, block, block_size, blocks);
+#endif
+
+ // Is this the boot sector?
+ bootblock = (flash_dev_info->bootblock &&
+ (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM)));
+ if (bootblock) {
+ len = flash_dev_info->bootblocks[len_ix++];
+ } else {
+ len = flash_dev_info->block_size;
+ }
+
+ CYGHWR_FLASH_WRITE_ENABLE();
+
+ while (len > 0) {
+
+ b_v = FLASH_P2V(b_p);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Clear lock bit
+ *b_v = FLASH_Clear_Lock;
+ *b_v = FLASH_Clear_Lock_Confirm; // Confirmation
+ while(((state = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ res = FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ // Go to next block
+ b_p += len / sizeof( flash_data_t );
+ len = 0;
+
+ if (FLASH_ErrorLock == (state & FLASH_ErrorLock))
+ res = FLASH_ERR_LOCK;
+
+ if (res != FLASH_ERR_OK)
+ break;
+
+ if (bootblock)
+ len = flash_dev_info->bootblocks[len_ix++];
+ }
+
+ CYGHWR_FLASH_WRITE_DISABLE();
+
+ return res;
+
+ // FIXME: Unlocking need to support some other parts in the future
+ // as well which take a little more diddling.
+#if 0
+//
+// The difficulty with this operation is that the hardware does not support
+// unlocking single blocks. However, the logical layer would like this to
+// be the case, so this routine emulates it. The hardware can clear all of
+// the locks in the device at once. This routine will use that approach and
+// then reset the regions which are known to be locked.
+//
+
+#define MAX_FLASH_BLOCKS (flash_dev_info->block_count * CYGNUM_FLASH_SERIES)
+
+ unsigned char is_locked[MAX_FLASH_BLOCKS];
+
+ // Get base address and map addresses to virtual addresses
+ ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)block );
+ block = FLASH_P2V(block);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Get current block lock state. This needs to access each block on
+ // the device so currently locked blocks can be re-locked.
+ bp = ROM;
+ for (i = 0; i < blocks; i++) {
+ bpv = FLASH_P2V( bp );
+ *bpv = FLASH_Read_Query;
+ if (bpv == block) {
+ is_locked[i] = 0;
+ } else {
+ is_locked[i] = bpv[2];
+ }
+ bp += block_size / sizeof(*bp);
+ }
+
+ // Clears all lock bits
+ ROM[0] = FLASH_Clear_Locks;
+ ROM[0] = FLASH_Clear_Locks_Confirm; // Confirmation
+ timeout = CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore the lock state
+ bp = ROM;
+ for (i = 0; i < blocks; i++) {
+ bpv = FLASH_P2V( bp );
+ if (is_locked[i]) {
+ *bpv = FLASH_Set_Lock;
+ *bpv = FLASH_Set_Lock_Confirm; // Confirmation
+ timeout = CYGNUM_DEVS_FLASH_INTEL_28FXXX_TIMEOUT;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+ }
+ bp += block_size / sizeof(*bp);
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+#endif
+#endif // #CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4
+}
+#endif // CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+#endif // CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL
diff --git a/ecos/packages/devs/flash/intel/28fxxx/current/include/flash_28fxxx_parts.inl b/ecos/packages/devs/flash/intel/28fxxx/current/include/flash_28fxxx_parts.inl
new file mode 100644
index 0000000..1fdf22c
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/28fxxx/current/include/flash_28fxxx_parts.inl
@@ -0,0 +1,359 @@
+#ifndef CYGONCE_DEVS_FLASH_INTEL_28FXXX_PARTS_INL
+#define CYGONCE_DEVS_FLASH_INTEL_28FXXX_PARTS_INL
+//==========================================================================
+//
+// flash_28fxxx_parts.inl
+//
+// Intel 28Fxxx part descriptors
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov, gthomas
+// Date: 2001-08-07
+// Purpose:
+// Description: Intel 28Fxxx part descriptors
+// Usage: Should be included from the flash_28fxxx.inl file only.
+//
+// FIXME: Add configury for selecting bottom/top bootblocks
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#if CYGNUM_FLASH_WIDTH == 8
+#ifdef CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4
+ { // LH28F016SCT_Z4
+ device_id : FLASHWORD(0xA0),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ buffered_w : false,
+ locking : true,
+ bootblock : false,
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_95
+ { // LH28F016SCT_95
+ device_id : FLASHWORD(0xAA),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ buffered_w : false,
+ locking : true,
+ bootblock : false,
+ banked : false
+ },
+#endif
+
+#else // 16 bit devices
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F320C3
+ { // 28F320C3-T
+ device_id : FLASHWORD(0x88c4),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : true,
+ buffered_w : false,
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ banked : false
+ },
+ { // 28F320C3-B
+ device_id : FLASHWORD(0x88c5),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : true,
+ buffered_w : false,
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F320B3
+ { // 28F320B3-T
+ device_id : FLASHWORD(0x8896),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : false,
+ buffered_w : false,
+ bootblock : true,
+ bootblocks : { 0x3f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ banked : false
+ },
+ { // 28F320B3-B
+ device_id : FLASHWORD(0x8897),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : false,
+ buffered_w : false,
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F320S3
+ { // 28F320S3
+ device_id : FLASHWORD(0x00d4),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 64,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : true,
+ buffered_w : false,
+ bootblock : false,
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F320J3
+ { // 28F320J3
+ device_id : FLASHWORD(0x0016),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x400000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x400000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : false,
+ buffered_w : false,
+ bootblock : false,
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F128K3
+ {
+ device_id : FLASHWORD(0x8802),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : true,
+ buffered_w : true,
+// buffer_size: TODO!!!
+ bootblock : false,
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F128P30
+ {
+ device_id : FLASHWORD(0x8818),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : true,
+ buffered_w : true,
+// buffer_size: TODO!!!
+ bootblock : false,
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F128J3
+ {
+ device_id : FLASHWORD(0x18),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 128,
+ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : true,
+ buffered_w : true,
+ buffer_size: 32,
+ bootblock : false,
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F160S5
+ { // 28F160S5
+ device_id : FLASHWORD(0x00d0),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ buffered_w : true,
+// buffer_size: TODO
+ locking : false,
+ bootblock : false,
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F160B3T
+ { // 28F160B3-T
+ device_id : FLASHWORD(0x8890),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ buffered_w : false,
+ locking : true,
+ bootblock : true,
+ bootblocks : { 0x1f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F160C3B
+ { // 28F160C3-B
+ device_id : FLASHWORD(0x88C3),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ buffered_w : false,
+ locking : true,
+ bootblock : true,
+ bootblocks : { 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x1f0000 * CYGNUM_FLASH_INTERLEAVE,
+ 0
+ },
+ banked : false
+ },
+#endif
+
+#ifdef CYGHWR_DEVS_FLASH_INTEL_28F800B5
+ { // 28F800B5-T
+ device_id : FLASHWORD(0x889c),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 8,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : false,
+ buffered_w : false,
+ bootblock : true,
+ bootblocks : { 0xE0000,
+ 0x18000,
+ 0x2000,
+ 0x2000,
+ 0x4000
+ },
+ banked : false
+ },
+ { // 28F800B5-B
+ device_id : FLASHWORD(0x889d),
+ block_size : 0x20000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 8,
+ device_size: 0x100000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x100000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ locking : false,
+ buffered_w : false,
+ bootblock : true,
+ bootblocks : { 0x00000,
+ 0x4000,
+ 0x2000,
+ 0x2000,
+ 0x18000
+ },
+ banked : false
+ },
+#endif
+
+#endif // 16 bit devices
+
+
+#endif // CYGONCE_DEVS_FLASH_INTEL_28FXXX_PARTS_INL
diff --git a/ecos/packages/devs/flash/intel/strata/current/ChangeLog b/ecos/packages/devs/flash/intel/strata/current/ChangeLog
new file mode 100644
index 0000000..9272453
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/strata/current/ChangeLog
@@ -0,0 +1,320 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/strata.c: leave _FLASH_PRIVATE_ to the private strata.h
+ (Change from bartv 2004-12-02, merged from flash_v2 branch).
+ * cdl/flash_strata.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2005-01-14 Thomas Koeller <thomas.koeller@baslerweb.com>
+
+ * src/flash_query.c (flash_query): Fix switching the flash back to
+ array mode, which was broken on MIPS platforms. Always write
+ control codes to offset 0.
+
+2004-09-02 Mark Salter <msalter@redhat.com>
+
+ * src/flash_query.c (CYGHWR_FLASH_READ_QUERY): Add platform hook
+ to handle access to query info.
+ * src/flash_program_buf.c (CYGHWR_FLASH_WRITE_BUF): Add platform
+ hook handle access to write buffer.
+
+2004-08-21 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * cdl/flash_strata.cdl: CDL to control the maximum number of
+ blocks the driver supports. Some of the newer strata device has more
+ than the default maximum of 128. Problem pointed out by Kevin Zhang.
+
+2005-01-26 Scott Wilkinson <scott@alliantnetworks.com>
+ * src/strata.h:
+ * src/strata.c:
+ Flash from STMicro is compatible with the Intel strata chips,
+ so detect them as well. Check for manuf id 0x20.
+
+2003-10-29 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash_unlock_block.c (flash_unlock_block): test lock bit
+ explicitly - newer flash parts use the reserved bits in the
+ returned data.
+
+2003-09-11 Jani Monoses <jani@iv.ro>
+
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_program_buf.c (flash_program_buf): Fix bootblock handling
+ in erase. Fix erase and word-program for Synchronous Strata and later
+ chips where block address and word address are required in the first
+ cycle of the operation while for earlier parts any address was good.
+
+2003-09-10 Jani Monoses <jani@iv.ro>
+
+ * cdl/flash_strata.cdl:
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf): Use .2ram sections
+ for putting flash functions to RAM instead of the old method.
+
+2003-05-02 Jani Monoses <jani@iv.ro>
+
+ * src/strata.c: Switch to using generic flash_query_dev.
+ The previous cache related changes broke flash_query for
+ Strata because in the query case the generic flash driver was not
+ called to handle the caches but the internal handling was removed
+ nevertheless.
+
+2003-04-04 Jani Monoses <jani@iv.ro>
+
+ * src/strata.h:
+ Use generic flash_dev.h for providing the FLASHWORD macro for
+ different widths and device numbers.No reason to duplicate that
+ here.This implicitely fixes the case when CYGNUM_FLASH_WIDTH is 16
+ and CYGNUM_FLASH_DEVICES is 4.
+
+2003-04-03 Jani Monoses <jani@iv.ro>
+
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf):
+ Cache enabling and disabling are already handled by generic flash
+
+2002-08-12 Mark Salter <msalter@redhat.com>
+
+ * src/flash_unlock_block.c: Add synchronous strataflash support.
+ * src/strata.h: Add comments regarding synchronous strataflash.
+
+2002-04-30 Christoph Csebits <christoph.csebits@frequentis.com>
+
+ * src/flash_unlock_block.c: Getting the current block lock
+ state for flashes in 8-Bit mode is now working correctly.
+
+2002-04-16 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/flash_strata.cdl: Invoke $(CC) with $(CFLAGS) to ensure the
+ correct flags are passed.
+
+2002-04-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/strata.c: Clean up warnings.
+
+2002-01-22 Mark Salter <msalter@redhat.com>
+
+ * cdl/flash_strata.cdl: Add ".text" before "_end" markers in .s files.
+
+2001-10-23 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/flash_strata.cdl: Provide an option so that RedBoot .ecm
+ files can turn off the functionality of copying flash driver code
+ to separate RAM for execution; it's not needed for RAM and ROMRAM
+ startup, and for some platforms it is required to *not* copy thus.
+
+2001-08-25 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_program_buf.c (flash_program_buf): Allow configuration
+ specific code sequence for actual writing of data. Define by the
+ macro CYGHWR_FLASH_WRITE_ELEM. Note: this is required on some
+ hardware, like the Intel SA185, which handles flash writes in
+ strange/obscure fashion.
+
+2001-07-17 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+
+ * src/flash_query.c (flash_query): Query needs to be done on even
+ addresses for byte-enabled strata flash
+
+ * src/flash_program_buf.c (flash_program_buf): Fix of conversion of
+ write buffer length (in bytes) to the length in 'flash_t' words.
+
+2001-06-22 Hugo Tyson <hmt@redhat.com>
+
+ * src/strata.c (flash_hwr_init): Need to refer to the query code
+ as extern char flash_query[], flash_query_end[]; (with the []) or
+ MIPS code gen assumes these are short offsets and linking fails.
+ The generic flash code in io/flash already uses this idiom.
+
+2001-06-22 Hugo Tyson <hmt@redhat.com>
+
+ * src/strata.c (flash_hwr_init): Warnings reduced. No arithmetic
+ on void *.
+
+2001-06-21 Hugo Tyson <hmt@redhat.com>
+
+ * src/flash_program_buf.c (flash_program_buf): The buffered write
+ code didn't jump out if there was a write error, nor verify the
+ data by reading back. This isn't consistent with the slow case,
+ and made it take an age if the device is unhappy, and then report
+ a bizarre error code. Both issues fixed.
+
+2001-06-21 Hugo Tyson <hmt@redhat.com>
+
+ * src/strata.c (flash_hwr_init): If shrinking to fit, must also
+ adjust the flash_info.blocks field, else unlock crashes trying to
+ get status of all those extra blocks that we cannot actually see.
+
+2001-06-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/strata.c: Remove dependency on printf() via user functions.
+
+2001-06-07 Hugo Tyson <hmt@redhat.com>
+
+ * src/strata.c (flash_hwr_init): If we find a flash device that is
+ larger than is possible given the memory map, shrink to fit.
+ We know about the memory map from CYGNUM_FLASH_BASE_MASK (if
+ defined); it tells us the stride from one device to another.
+
+ This is to cope with installing, say, a 28F640 in a slot designed
+ for a 28F320 because of supply issues - it all works fine so long
+ as A22 is grounded.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_strata.cdl: Needs IO driver to copy functions to RAM.
+
+2001-04-26 Gary Thomas <gthomas@redhat.com>
+
+ * src/strata.c: Be more careful when enable/flush/disable caches.
+
+ * src/flash_erase_block.c (flash_erase_block): Boot block devices
+ may require additional erase commands to erase entire 'block'.
+
+2001-03-21 Hugo Tyson <hmt@redhat.com>
+
+ * src/strata.h (FLASH_Write_Buffer): Do not define this if
+ CYGOPT_FLASH_IS_NOT_ADVANCED is defined; Advanced (xxxJ3) flash is
+ usual these days. Also added documentation of the options that
+ can be used to control this module.
+
+ * src/flash_program_buf.c (flash_program_buf): Reduce warnings
+ about unused variables if no FLASH_Write_Buffer command available.
+
+2001-03-21 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_program_buf.c (flash_program_buf): Buffered write code
+ fixups, only on platforms with it defined.
+
+2001-03-17 Gary Thomas <gthomas@redhat.com>
+
+ * src/strata.h:
+ * src/strata.c: Support buffered writes.
+
+ * src/flash_program_buf.c: Use buffered writes if possible. This
+ mode allows the chip to do parallelized writes which is much faster.
+ It does require additional information, now provided by upper layer.
+
+2001-02-15 Hugo Tyson <hmt@redhat.com>
+
+ * src/flash_query.c (flash_query): Depending on whether
+ CYGOPT_FLASH_IS_BOOTBLOCK (just a #define from the instantiator,
+ not really a cdl_option) is set, do the full Read_Query or just
+ acquire two codes for manufacturer and device type using Read_ID.
+
+ * src/strata.c (flash_hwr_init): Again depending on whether
+ CYGOPT_FLASH_IS_BOOTBLOCK, decode the device type into a size and
+ so on, or use the full Read_Query data as before.
+
+ * src/strata.h (FLASH_Read_ID): Undefine those commands which we
+ do not use. Conditionally define those that we use depending on
+ CYGOPT_FLASH_IS_BOOTBLOCK. Thus we should be able to deal with
+ StrataFlash and BootBlock flash with the same code.
+
+ * cdl/flash_strata.cdl: Do not implement (in the CDL sense)
+ CYGHWR_IO_FLASH_BLOCK_LOCKING leave it up to the instantiating
+ package instead. Also move the build of the two objects that do
+ locking and unlocking into a compenent which is only active if
+ CYGHWR_IO_FLASH_BLOCK_LOCKING is indeed (requested to be)
+ implemented somewhere.
+
+2001-02-14 Hugo Tyson <hmt@redhat.com>
+
+ * devs/flash/intel/strata/...: New package, generic strataFlash
+ driver based on several others; a portion of its history
+ follows...
+
+ flash.h -> strata.h
+ flash<platform>.c -> strata.c
+
+2001-02-06 Hugo Tyson <hmt@redhat.com>
+
+ * src/flash.h: Much more generic again. Not yet separated into
+ generic component and invocation header, but the structure is
+ there. Also included support for a mapping from the physical
+ flash address we're thinking of to the virtual address we use to
+ access it. More documentation. Generalization to 8,16,32 and
+ 64-bit access, made up from 8,16 or 32-bit devices. Command and
+ status macros modified to accommodate these options.
+
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf):
+ All now acquire when possible the ROM address from the block
+ address, and use the physical to virtual macro as needed.
+
+ * src/flash_unlock_block.c (flash_unlock_block):
+ The same changes, but a little more complex because of the need to
+ clear-all then re-lock some semantics. Shadow pointer to virtual
+ address is used each time round the loop.
+
+ * cdl/flash_strata.cdl: Add explicit dependencies on flash.h, for
+ there were none - or they were ignored - for the specially built
+ compilation units that get copied to RAM for execution.
+
+2001-02-01 Hugo Tyson <hmt@redhat.com>
+
+ * all: copied from the assabet flash driver.
+
+2000-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/assabet_flash.c (flash_code_overlaps): Define stext/etext
+ as array types so no assumptions can be made by the compiler about
+ location.
+
+2000-10-24 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_program_buf.c (flash_program_buf):
+ * src/flash_erase_block.c (flash_erase_block): Support up to 32M FLASH.
+
+2000-09-10 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_unlock_block.c:
+ * src/flash_lock_block.c: New file(s).
+
+ * src/flash.h:
+ * cdl/flash_assabet.cdl: Add region locking functions.
+
+2000-08-29 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_flash.c: Improve error decoding.
+
+2000-08-24 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_query.c:
+ * src/flash_erase_block.c:
+ * src/flash.h: FLASH support for Intel SA1110 Assabet.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/intel/strata/current/cdl/flash_strata.cdl b/ecos/packages/devs/flash/intel/strata/current/cdl/flash_strata.cdl
new file mode 100644
index 0000000..2519595
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/strata/current/cdl/flash_strata.cdl
@@ -0,0 +1,92 @@
+# ====================================================================
+#
+# flash_strata.cdl
+#
+# FLASH memory - Hardware support for Intel Strata Flash
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_STRATA {
+ display "Intel StrataFLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ active_if CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "FLASH memory device support for Intel StrataFlash"
+ compile strata.c flash_erase_block.c flash_program_buf.c flash_query.c
+
+ define_proc {
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_DEVS_FLASH_STRATA_CFG";
+ }
+
+ cdl_component CYGPKG_DEVS_FLASH_STRATA_LOCKING {
+ display "Flash device implements locking"
+ active_if 0 < CYGHWR_IO_FLASH_BLOCK_LOCKING
+ calculated 1
+ compile flash_lock_block.c flash_unlock_block.c
+
+ cdl_option CYGNUM_DEVS_FLASH_STRATA_MAX_BLOCKS {
+ display "Maximum number of blocks the driver supports"
+ flavor data
+ default_value 128
+ description "
+ The strata devices do not support unlocking an
+ individual block. Instead it is necassary to unlock
+ all the blocks in one operation and then lock all those
+ blocks that should be blocked. To do this we need an array
+ containing the current status of the blocks. This controls the
+ size of that array."
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/flash/intel/strata/current/src/flash_erase_block.c b/ecos/packages/devs/flash/intel/strata/current/src/flash_erase_block.c
new file mode 100644
index 0000000..c5414fc
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/strata/current/src/flash_erase_block.c
@@ -0,0 +1,115 @@
+//==========================================================================
+//
+// flash_erase_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "strata.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+int flash_erase_block(volatile flash_t *block, unsigned int block_size)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int flash_erase_block(volatile flash_t *block, unsigned int block_size)
+{
+ volatile flash_t *ROM;
+ flash_t stat = 0;
+ int timeout = 50000;
+ int len, block_len, erase_block_size;
+ volatile flash_t *eb;
+
+ // Get base address and map addresses to virtual addresses
+ ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block);
+ eb = block = FLASH_P2V(block);
+ block_len = block_size;
+
+#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
+#define BLOCKSIZE (0x10000*CYGNUM_FLASH_DEVICES)
+#define ERASE_BLOCKSIZE (0x2000*CYGNUM_FLASH_DEVICES)
+ if ((eb - ROM) < BLOCKSIZE/(sizeof eb[0])) {
+ erase_block_size = ERASE_BLOCKSIZE;
+ } else {
+ erase_block_size = block_size;
+ }
+#else
+ erase_block_size = block_size;
+#endif
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Erase block
+ while (block_len > 0) {
+ eb[0] = FLASH_Block_Erase;
+ eb[0] = FLASH_Confirm;
+
+ timeout = 5000000;
+ while(((stat = eb[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ block_len -= erase_block_size;
+ eb = FLASH_P2V((unsigned int)eb + erase_block_size);
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ // If an error was reported, see if the block erased anyway
+ if (stat & FLASH_ErrorMask ) {
+ len = block_size;
+ while (len > 0) {
+ if (*block++ != FLASH_BlankValue ) break;
+ len -= sizeof(*block);
+ }
+ if (len == 0) stat = 0;
+ }
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/intel/strata/current/src/flash_lock_block.c b/ecos/packages/devs/flash/intel/strata/current/src/flash_lock_block.c
new file mode 100644
index 0000000..d39ebba
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/strata/current/src/flash_lock_block.c
@@ -0,0 +1,83 @@
+//==========================================================================
+//
+// flash_lock_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "strata.h"
+
+
+int
+flash_lock_block(volatile flash_t *block)
+ __attribute__ ((section (".2ram.flash_lock_block")));
+int
+flash_lock_block(volatile flash_t *block)
+{
+ volatile flash_t *ROM;
+ flash_t stat;
+ int timeout = 5000000;
+
+ // Get base address and map addresses to virtual addresses
+ ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block);
+ block = FLASH_P2V(block);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Set lock bit
+ block[0] = FLASH_Set_Lock;
+ block[0] = FLASH_Set_Lock_Confirm; // Confirmation
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/intel/strata/current/src/flash_program_buf.c b/ecos/packages/devs/flash/intel/strata/current/src/flash_program_buf.c
new file mode 100644
index 0000000..b0645b2
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/strata/current/src/flash_program_buf.c
@@ -0,0 +1,162 @@
+//==========================================================================
+//
+// flash_program_buf.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "strata.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+// Platforms may define this for special handling when accessing the write buffer.
+#ifndef CYGHWR_FLASH_WRITE_BUF
+#define CYGHWR_FLASH_WRITE_BUF(a,b) (*(a) = *(b))
+#endif
+
+int
+flash_program_buf(volatile flash_t *addr, flash_t *data, int len,
+ unsigned long block_mask, int buffer_size)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+int
+flash_program_buf(volatile flash_t *addr, flash_t *data, int len,
+ unsigned long block_mask, int buffer_size)
+{
+ volatile flash_t *ROM;
+ volatile flash_t *BA;
+ flash_t stat = 0;
+ int timeout = 50000;
+#ifdef FLASH_Write_Buffer
+ int i, wc;
+#endif
+
+ // Get base address and map addresses to virtual addresses
+ ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)addr );
+ BA = addr = FLASH_P2V(addr);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+#ifdef FLASH_Write_Buffer
+ // Write any big chunks first
+ while (len >= buffer_size) {
+ wc = buffer_size;
+ if (wc > len) wc = len;
+ len -= wc;
+ // convert 'wc' in bytes to 'wc' in 'flash_t'
+ wc = wc / sizeof(flash_t); // Word count
+ *BA = FLASH_Write_Buffer;
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ goto bad;
+ }
+ *BA = FLASH_Write_Buffer;
+ }
+ *BA = FLASHWORD(wc-1); // Count is 0..N-1
+ for (i = 0; i < wc; i++) {
+#ifdef CYGHWR_FLASH_WRITE_ELEM
+ CYGHWR_FLASH_WRITE_ELEM(addr+i, data+i);
+#else
+ CYGHWR_FLASH_WRITE_BUF(addr+i, data+i);
+#endif
+ }
+ *BA = FLASH_Confirm;
+
+ ROM[0] = FLASH_Read_Status;
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ goto bad;
+ }
+ }
+ // Jump out if there was an error
+ if (stat & FLASH_ErrorMask) {
+ goto bad;
+ }
+ // And verify the data - also increments the pointers.
+ *BA = FLASH_Reset;
+ for (i = 0; i < wc; i++) {
+ if ( *addr++ != *data++ ) {
+ stat = FLASH_ErrorNotVerified;
+ goto bad;
+ }
+ }
+ }
+#endif
+
+ while (len > 0) {
+ BA[0] = FLASH_Program;
+#ifdef CYGHWR_FLASH_WRITE_ELEM
+ CYGHWR_FLASH_WRITE_ELEM(addr, data);
+#else
+ *addr = *data;
+#endif
+ timeout = 5000000;
+ while(((stat = BA[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ goto bad;
+ }
+ }
+ if (stat & FLASH_ErrorMask) {
+ break;
+ }
+ BA[0] = FLASH_Reset;
+ if (*addr++ != *data++) {
+ stat = FLASH_ErrorNotVerified;
+ break;
+ }
+ len -= sizeof( flash_t );
+ }
+
+ // Restore ROM to "normal" mode
+ bad:
+ BA[0] = FLASH_Reset;
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/intel/strata/current/src/flash_query.c b/ecos/packages/devs/flash/intel/strata/current/src/flash_query.c
new file mode 100644
index 0000000..8c3aef5
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/strata/current/src/flash_query.c
@@ -0,0 +1,107 @@
+//==========================================================================
+//
+// flash_query.c
+//
+// Flash programming - query device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "strata.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+// Platforms may define this for special handling when accessing the query data.
+#ifndef CYGHWR_FLASH_READ_QUERY
+#define CYGHWR_FLASH_READ_QUERY(a) (*(a))
+#endif
+
+#define CNT 20*1000*10 // Approx 20ms
+
+int
+flash_query(unsigned char *data) __attribute__ ((section (".2ram.flash_query")));
+int
+flash_query(unsigned char *data)
+{
+ volatile flash_t *ROM, *p, dummy;
+ int i, cnt;
+
+ // Get base address and map addresses to virtual addresses
+ ROM = FLASH_P2V( CYGNUM_FLASH_BASE );
+#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
+ // BootBlock flash does not support full Read_Query - we have do a
+ // table oriented thing above, after getting just two bytes of results:
+ ROM[0] = FLASH_Read_ID;
+ i = 2;
+#else
+ // StrataFlash supports the full Read_Query op:
+ ROM[0] = FLASH_Read_Query;
+ i = sizeof(struct FLASH_query);
+#endif // Not CYGOPT_FLASH_IS_BOOTBLOCK
+
+ for (cnt = CNT; cnt > 0; cnt--) ;
+ p = ROM;
+ while ( i--) {
+ // It is very deliberate that data is chars NOT flash_t:
+ // The info comes out in bytes regardless of device.
+ *data++ = (unsigned char) CYGHWR_FLASH_READ_QUERY(p++);
+#ifndef CYGOPT_FLASH_IS_BOOTBLOCK
+# if 8 == CYGNUM_FLASH_WIDTH
+ // strata flash with 'byte-enable' contains the configuration data
+ // at even addresses
+ ++p;
+# endif
+#endif
+ }
+ // Reset the flash to array mode. The dummy read is required on MIPS
+ // platforms (don't know about others) to force the write out. Should
+ // there be direct HAL support for this kind of operation?
+ ROM[0] = FLASH_Reset;
+ dummy = ROM[0];
+
+ return 0;
+}
diff --git a/ecos/packages/devs/flash/intel/strata/current/src/flash_unlock_block.c b/ecos/packages/devs/flash/intel/strata/current/src/flash_unlock_block.c
new file mode 100644
index 0000000..4d8cd4a
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/strata/current/src/flash_unlock_block.c
@@ -0,0 +1,141 @@
+//==========================================================================
+//
+// flash_unlock_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "strata.h"
+
+
+//
+// The difficulty with this operation is that the hardware does not support
+// unlocking single blocks. However, the logical layer would like this to
+// be the case, so this routine emulates it. The hardware can clear all of
+// the locks in the device at once. This routine will use that approach and
+// then reset the regions which are known to be locked.
+//
+
+#define FLASH_LOCK_MASK 0x1 // which bit of the read query has the lock bit
+
+int
+flash_unlock_block(volatile flash_t *block, int block_size, int blocks)
+ __attribute__ ((section (".2ram.flash_unlock_block")));
+int
+flash_unlock_block(volatile flash_t *block, int block_size, int blocks)
+{
+ volatile flash_t *ROM;
+ flash_t stat;
+ int timeout = 5000000;
+#ifndef CYGOPT_FLASH_IS_SYNCHRONOUS
+ int i;
+ volatile flash_t *bp, *bpv;
+ unsigned char is_locked[CYGNUM_DEVS_FLASH_STRATA_MAX_BLOCKS];
+#endif
+
+ // Get base address and map addresses to virtual addresses
+ ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)block );
+ block = FLASH_P2V(block);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+#ifdef CYGOPT_FLASH_IS_SYNCHRONOUS
+ // Clear lock bit
+ block[0] = FLASH_Clear_Locks;
+ block[0] = FLASH_Clear_Locks_Confirm; // Confirmation
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+#else
+ // Get current block lock state. This needs to access each block on
+ // the device so currently locked blocks can be re-locked.
+ bp = ROM;
+ for (i = 0; i < blocks; i++) {
+ bpv = FLASH_P2V( bp );
+ *bpv = FLASH_Read_Query;
+ if (bpv == block) {
+ is_locked[i] = 0;
+ } else {
+#if 8 == CYGNUM_FLASH_WIDTH
+ is_locked[i] = bpv[4] & FLASH_LOCK_MASK;
+#else
+ is_locked[i] = bpv[2] & FLASH_LOCK_MASK;
+# endif
+ }
+ bp += block_size / sizeof(*bp);
+ }
+
+ // Clears all lock bits
+ ROM[0] = FLASH_Clear_Locks;
+ ROM[0] = FLASH_Clear_Locks_Confirm; // Confirmation
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore the lock state
+ bp = ROM;
+ for (i = 0; i < blocks; i++) {
+ bpv = FLASH_P2V( bp );
+ if (is_locked[i]) {
+ *bpv = FLASH_Set_Lock;
+ *bpv = FLASH_Set_Lock_Confirm; // Confirmation
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+ }
+ bp += block_size / sizeof(*bp);
+ }
+#endif // CYGOPT_FLASH_IS_SYNCHRONOUS
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/intel/strata/current/src/strata.c b/ecos/packages/devs/flash/intel/strata/current/src/strata.c
new file mode 100644
index 0000000..53f4a87
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/strata/current/src/strata.c
@@ -0,0 +1,185 @@
+//==========================================================================
+//
+// strata.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/io/flash.h>
+
+#include "strata.h"
+
+#define _si(p) ((p[1]<<8)|p[0])
+
+extern void diag_dump_buf(void *buf, CYG_ADDRWORD len);
+
+extern int strncmp(const char *s1, const char *s2, size_t len);
+extern void *memcpy( void *, const void *, size_t );
+
+int
+flash_hwr_init(void)
+{
+ struct FLASH_query data, *qp;
+ int num_regions, region_size, buffer_size;
+
+ flash_dev_query(&data);
+ qp = &data;
+ if ( ((qp->manuf_code == FLASH_Intel_code) ||
+ (qp->manuf_code == FLASH_STMicro_code))
+#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
+ // device types go as follows: 0x90 for 16-bits, 0xD0 for 8-bits,
+ // plus 0 or 1 for -T (Top Boot) or -B (Bottom Boot)
+ // [FIXME: whatever that means :FIXME]
+ // [I think it means the boot blocks are top/bottom of addr space]
+ // plus the following size codes:
+ // 0: 16Mbit 2: 8Mbit 4: 4Mbit
+ // 6: 32Mbit 8: 64Mbit
+#if 16 == CYGNUM_FLASH_WIDTH
+ && (0x90 == (0xF0 & qp->device_code)) // 16-bit devices
+#elif 8 == CYGNUM_FLASH_WIDTH
+ && (0xD0 == (0xF0 & qp->device_code)) // 8-bit devices
+#else
+ && 0
+#error Only understand 16 and 8-bit bootblock flash types
+#endif
+ ) {
+ int lookup[] = { 16, 8, 4, 32, 64 };
+#define BLOCKSIZE (0x10000)
+ region_size = BLOCKSIZE;
+ num_regions = qp->device_code & 0x0F;
+ num_regions >>= 1;
+ if ( num_regions > 4 )
+ goto flash_type_unknown;
+ num_regions = lookup[num_regions];
+ num_regions *= 1024 * 1024; // to bits
+ num_regions /= 8; // to bytes
+ num_regions /= BLOCKSIZE; // to blocks
+ buffer_size = 0;
+#else // CYGOPT_FLASH_IS_BOOTBLOCK
+ && (strncmp(qp->id, "QRY", 3) == 0)) {
+ num_regions = _si(qp->num_regions)+1;
+ region_size = _si(qp->region_size)*256;
+ if (_si(qp->buffer_size)) {
+ buffer_size = CYGNUM_FLASH_DEVICES << _si(qp->buffer_size);
+ } else {
+ buffer_size = 0;
+ }
+#endif // Not CYGOPT_FLASH_IS_BOOTBLOCK
+
+ flash_info.block_size = region_size*CYGNUM_FLASH_DEVICES;
+ flash_info.buffer_size = buffer_size;
+ flash_info.blocks = num_regions;
+ flash_info.start = (void *)CYGNUM_FLASH_BASE;
+ flash_info.end = (void *)(CYGNUM_FLASH_BASE +
+ (num_regions*region_size*CYGNUM_FLASH_DEVICES));
+#ifdef CYGNUM_FLASH_BASE_MASK
+ // Then this gives us a maximum size for the (visible) device.
+ // This is to cope with oversize devices fitted, with some high
+ // address lines ignored.
+ if ( ((unsigned int)flash_info.start & CYGNUM_FLASH_BASE_MASK) !=
+ (((unsigned int)flash_info.end - 1) & CYGNUM_FLASH_BASE_MASK ) ) {
+ // then the size of the device appears to span >1 device-worth!
+ unsigned int x;
+ x = (~(CYGNUM_FLASH_BASE_MASK)) + 1; // expected device size
+ x += (unsigned int)flash_info.start;
+ if ( x < (unsigned int)flash_info.end ) { // 2nd sanity check
+ (*flash_info.pf)("\nFLASH: Oversized device! End addr %p changed to %p\n",
+ flash_info.end, (void *)x );
+ flash_info.end = (void *)x;
+ // Also adjust the block count else unlock crashes!
+ x = ((cyg_uint8 *)flash_info.end - (cyg_uint8 *)flash_info.start)
+ / flash_info.block_size;
+ flash_info.blocks = x;
+ }
+ }
+#endif // CYGNUM_FLASH_BASE_MASK
+
+ return FLASH_ERR_OK;
+ }
+#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
+ flash_type_unknown:
+#endif
+ (*flash_info.pf)("Can't identify FLASH, sorry, man %x, dev %x, id [%4s] \n",
+ qp->manuf_code, qp->device_code, qp->id );
+ diag_dump_buf(qp, sizeof(data));
+ return FLASH_ERR_HWR;
+}
+
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int err)
+{
+ if (err & FLASH_ErrorMask) {
+ (*flash_info.pf)("Err = %x\n", err);
+ if (err & FLASH_ErrorProgram)
+ return FLASH_ERR_PROGRAM;
+ else if (err & FLASH_ErrorErase)
+ return FLASH_ERR_ERASE;
+ else
+ return FLASH_ERR_HWR; // FIXME
+ } else {
+ return FLASH_ERR_OK;
+ }
+}
+
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
+
+// EOF strata.c
diff --git a/ecos/packages/devs/flash/intel/strata/current/src/strata.h b/ecos/packages/devs/flash/intel/strata/current/src/strata.h
new file mode 100644
index 0000000..e1fbdc4
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/strata/current/src/strata.h
@@ -0,0 +1,177 @@
+#ifndef CYGONCE_DEVS_FLASH_INTEL_STRATA_FLASH_H
+#define CYGONCE_DEVS_FLASH_INTEL_STRATA_FLASH_H
+//==========================================================================
+//
+// strata.h
+//
+// strataFlash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2001-02-14
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_flash_strata.h>
+#include CYGDAT_DEVS_FLASH_STRATA_INL
+
+// ------------------------------------------------------------------------
+//
+// It is expected that the above include defined all the properties of the
+// device we want to drive: the choices this module supports include:
+//
+// Buffered Read Block
+// write query locking
+// 28FxxxB3 - Bootblock - no no no
+// 28FxxxC3 - StrataFlash - no yes yes
+// 28FxxxJ3 - Advanced StrataFlash - yes yes yes
+// 28FxxxK3 - Synchronous StrataFlash - yes yes yes
+//
+// These options are controlled by defining or not, in that include file,
+// these symbols (not CDL options, just symbols - though they could be CDL
+// in future)
+// CYGOPT_FLASH_IS_BOOTBLOCK - for xxxB3 devices.
+// CYGOPT_FLASH_IS_NOT_ADVANCED - for xxxC3 devices.
+// CYGOPT_FLASH_IS_SYNCHRONOUS - for xxxK3 devices.
+// none of the above - for xxxJ3 devices.
+// (Advanced seems to be usual these days hence the sense of that opt)
+//
+// Other properties are controlled by these symbols:
+// CYGNUM_FLASH_DEVICES number of devices across the databus
+// CYGNUM_FLASH_WIDTH number of bits in each device
+// CYGNUM_FLASH_BLANK 1 if blank is allones, 0 if 0
+// CYGNUM_FLASH_BASE base address
+// CYGNUM_FLASH_BASE_MASK a mask to get base address from any
+//
+// for example, a 32-bit memory could be made from 1x32bit, 2x16bit or
+// 4x8bit devices; usually 16bit ones are chosen in practice, so we would
+// have CYGNUM_FLASH_DEVICES = 2, and CYGNUM_FLASH_WIDTH = 16. Both
+// devices would be handled simulataneously, via 32bit bus operations.
+// Some CPUs can handle a single 16bit device as 32bit memory "by magic".
+// In that case, CYGNUM_FLASH_DEVICES = 1 and CYGNUM_FLASH_WIDTH = 16, and
+// the device is managed using only 16bit bus operations.
+
+#define CYGNUM_FLASH_INTERLEAVE CYGNUM_FLASH_DEVICES
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash_dev.h>
+
+#define flash_t flash_data_t
+// ------------------------------------------------------------------------
+//
+// This generic code is intended to deal with all shapes and orientations
+// of Intel StrataFlash. Trademarks &c belong to their respective owners.
+//
+// It therefore needs some trickery to define the constants and accessor
+// types that we use to interact with the device or devices.
+//
+// The assumptions are that
+// o Parallel devices, we write to, with the "opcode" replicated per
+// device
+// o The "opcode" and status returns exist only in the low byte of the
+// device's interface regardless of its width.
+// o Hence opcodes and status are only one byte.
+// An exception is the test for succesfully erased data.
+//
+// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
+
+#define FLASH_Read_ID FLASHWORD( 0x90 )
+#ifndef CYGOPT_FLASH_IS_BOOTBLOCK
+#define FLASH_Read_Query FLASHWORD( 0x98 ) // Strata only
+#endif
+#define FLASH_Read_Status FLASHWORD( 0x70 )
+#define FLASH_Clear_Status FLASHWORD( 0x50 )
+#define FLASH_Status_Ready FLASHWORD( 0x80 )
+#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
+#define FLASH_Program FLASHWORD( 0x40 ) // BootBlock only
+#else
+#define FLASH_Program FLASHWORD( 0x10 )
+#endif
+#define FLASH_Block_Erase FLASHWORD( 0x20 )
+#ifndef CYGOPT_FLASH_IS_BOOTBLOCK
+#ifndef CYGOPT_FLASH_IS_NOT_ADVANCED
+#define FLASH_Write_Buffer FLASHWORD( 0xE8 ) // *Advanced* Strata only
+#endif // flash is advanced ie. has Write Buffer command
+#define FLASH_Set_Lock FLASHWORD( 0x60 ) // Strata only
+#define FLASH_Set_Lock_Confirm FLASHWORD( 0x01 ) // Strata only
+#define FLASH_Clear_Locks FLASHWORD( 0x60 ) // Strata only
+#define FLASH_Clear_Locks_Confirm FLASHWORD( 0xD0 ) // Strata only
+#endif
+#define FLASH_Confirm FLASHWORD( 0xD0 )
+//#define FLASH_Configure FLASHWORD( 0xB8 )
+//#define FLASH_Configure_ReadyWait FLASHWORD( 0x00 )
+//#define FLASH_Configure_PulseOnErase FLASHWORD( 0x01 )
+//#define FLASH_Configure_PulseOnProgram FLASHWORD( 0x02 )
+//#define FLASH_Configure_PulseOnBoth FLASHWORD( 0x03 )
+#define FLASH_Reset FLASHWORD( 0xFF )
+
+// Status that we read back:
+#define FLASH_ErrorMask FLASHWORD( 0x7E )
+#define FLASH_ErrorProgram FLASHWORD( 0x10 )
+#define FLASH_ErrorErase FLASHWORD( 0x20 )
+
+#define FLASH_ErrorNotVerified FLASHWORD( 0x9910 ) // made-up number
+
+// ------------------------------------------------------------------------
+
+#define FLASH_Intel_code 0x89 // NOT mapped to 16+16
+#define FLASH_STMicro_code 0x20 // NOT mapped to 16+16
+
+// Extended query information
+struct FLASH_query {
+ unsigned char manuf_code; // FLASH_Intel_code
+ unsigned char device_code;
+ unsigned char _unused0[14];
+ unsigned char id[3]; // Q R Y
+ unsigned char _unused1[20];
+ unsigned char device_size;
+ unsigned char device_interface[2];
+ unsigned char buffer_size[2];
+ unsigned char is_block_oriented;
+ unsigned char num_regions[2];
+ unsigned char region_size[2];
+};
+
+#endif // CYGONCE_DEVS_FLASH_INTEL_STRATA_FLASH_H
+// ------------------------------------------------------------------------
+// EOF strata.h
diff --git a/ecos/packages/devs/flash/intel/stratav2/current/ChangeLog b/ecos/packages/devs/flash/intel/stratav2/current/ChangeLog
new file mode 100644
index 0000000..ea1bda2
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/stratav2/current/ChangeLog
@@ -0,0 +1,507 @@
+2012-03-21 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+ Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/strata_aux.c (strata_hw_cfi): Fix compiler warnings that
+ variable is set but not used. [ Bugzilla 1001541 ]
+
+2009-04-21 Bart Veer <bartv@ecoscentric.com>
+
+ * src/strata.c: Added set of parentheses around macro parameters
+ used in multiplications. Fixes 16as8 bug.
+
+2008-12-19 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_strata_v2.cdl: Doh, fix doc link properly.
+
+2008-11-23 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * doc/strata.sgml: Fix cut'n'paste typo in example: amd->strata.
+
+2008-11-20 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_strata_v2.cdl: Fix doc link.
+
+2008-11-13 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * include/flash_strata_v2.inl:
+ * include/strata_v2_priv.h:
+ Remove these as they are now unused and don't match the CDL.
+
+2006-08-08 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/strata.c: Provide a default HAL_MEMORY_BARRIER()
+ define if the HAL hasn't provided one.
+ * src/strata_aux.c: Use HAL_MEMORY_BARRIER() any time the
+ flash is switched back to read array mode. Some processors need
+ to have their write buffers flushed.
+
+2006-08-02 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * include/strata_dev.h: Replace use of flash_priv.h by flash_dev.h
+ as per io/flash changes.
+ * src/strata.c: Ditto.
+
+2006-07-31 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/strata.c: Remove strata-specific nop devfn functions now
+ provided by io/flash. Also strata_anonymizer.
+ * src/strata_aux.c: Change strata_anonymizer to cyg_flash_anonymizer.
+
+ * doc/strata.sgml: Update to reflect generic nop devfn functions
+ now provided by io/flash.
+
+2006-05-15 John Dallaway <jld@ecoscentric.com>
+
+ * cdl/flash_strata_v2.cdl: Add reference to package documentation.
+
+2006-04-09 Bart Veer <bartv@ecoscentric.com>
+
+ * src/strata_aux.c (strata_hw_bufprogram): re-read status after
+ the loop, the bits may not all change at the same time.
+
+2006-03-31 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/strata_aux.c (strata_hw_erase): Workaround for
+ ST M58XXXX doesn't work for parallel flash. Another
+ hack put in place instead so it works not just for
+ parallel flash in general, but also parallel ST M58XXXX
+ should that ever be used in future.
+ (strata_hw_bufprogram): count of bytes to write has to
+ be STRATA_PARALLELed to affect all parallel devices.
+
+2006-03-29 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/strata_aux.c (cyg_strata_program): Fixed bug in
+ increments/decrements during main loop to match those in
+ bufprogram.
+ Modified diagnostic output a little.
+
+2006-01-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/strata.c (STRATA_OFFSET_CFI_WRITE_BUFFER_LSB): Add definition
+ of CFI offset. Ditto _MSB.
+
+ * src/strata_aux.c (strata_hw_cfi): Detect writebuffer size.
+
+2005-11-28 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/strata_aux.c: Added support for byte swapping the command
+ and status reads and writes. Fixed some pointer increment bugs.
+ Added some diagnostic macros.
+
+ * src/strata.c: Added byte swapping support.
+
+2005-08-03 Jonathan Larmour <jifl@eCosCentric.com>
+2005-08-03 Bart Veer <bartv@eCosCentric.com>
+
+ * src/strata.c (STRATA_INTSCACHE_DEFAULT_END): In the
+ case of !defined(CYGHWR_DEVS_FLASH_STRATA_V2_CACHED_ONLY) and
+ !defined(CYGIMP_DEVS_FLASH_STRATA_V2_LEAVE_INTERRUPTS_ENABLED)
+ briefly blip the interrupt enable on to allow pending interrupts
+ to run, thus reducing max interrupt latency.
+
+2005-08-02 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/strata.c (STRATA_INTSCACHE_DEFAULT_END): Even when
+ !defined(CYGHWR_DEVS_FLASH_STRATA_V2_CACHED_ONLY) we need to
+ remove stale dcache entries for the Flash before finishing
+ the whole operation. So invalidate (and therefore also sync)
+ the dcache.
+
+ * src/strata_aux.c (cyg_strata_lock_j3): Allow building with
+ assertions enabled (CYGPKG_INFRA_DEBUG).
+ (cyg_strata_unlock_all_j3): Ditto.
+ (cyg_strata_lock_k3): Ditto.
+ (cyg_strata_unlock_k3): Ditto.
+
+2005-07-25 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_strata_v2.cdl: add configury for finer control of the
+ cache and interrupts.
+ * src/strata.c: STRATA_P2V() renamed to STRATA_UNCACHED_ADDRESS(),
+ a more appropriate name. Provide three versions of the INTSCACHE()
+ macros for different configurations.
+ * src/strata_aux.c: use STRATA_UNCACHED_ADDRESS() throughout.
+ Sort out the assertions properly. Reorganize status bit checks
+ and add comment re. discrepancy with datasheets.
+ * include/strata_dev.h, src_strata_aux.c: unlock_all_j3 now takes
+ a cyg_flashaddr_t instead of a device pointer, for compatibility
+ with the main flash API.
+
+2005-06-16 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/strata_aux.c (strata_hw_erase): Order detection of errors
+ correctly, so most appropriate error codes get returned first.
+ (strata_hw_program): Ditto.
+ (strata_hw_bufprogram): Ditto.
+ (strata_hw_lock_j3): Ditto. Also remove duplicate resetting to
+ read array.
+ (strata_hw_unlock_all_j3): Ditto.
+ (cyg_strata_program): Place assertion check correctly.
+ (cyg_strata_bufprogram): Ditto.
+ (cyg_strata_lock_j3): Ditto.
+ (cyg_strata_lock_k3): Ditto.
+ (cyg_strata_unlock_k3): Ditto.
+
+2005-06-16 Bart Veer <bartv@eCosCentric.com>
+
+ * src/strata_aux.c (strata_hw_bufprogram): Write the correct
+ number of bytes. Confirm write at correct address.
+ (cyg_strata_bufprogram): update "written" correctly.
+
+2005-06-11 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_strata_v2.cdl, include/strata_dev.h, src/strata.c,
+ src/strata_aux.c, doc/strata.sgml: new version of the V2 strata
+ driver based on the am29xxxxxv2 driver, interrupt and cache safe.
+
+2004-11-29 Bart Veer <bartv@ecoscentric.com>
+
+ * include/flash_strata_v2.inl: hwr_map_error() is now internal to
+ the driver, not exported to the generic flash code.
+
+ * include/flash_strata_v2.inl: use the dummy lock/unlock functions
+ provided by the generic flash code.
+
+2004-11-25 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/flash_strata_v2.inl: Correct the usage of const
+ parameters. strata_init() needs to be able to modify priv.
+ strata_program_buf() does not need to modify priv.
+
+2004-11-25 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_strata_v2.cdl: this V2 driver relies on the generic
+ flash code to handle the cache
+
+2004-11-22 Bart Veer <bartv@ecoscentric.com>
+
+ * include/flash_strata_v2.inl: adjust const parameters as per
+ change to generic flash package
+ * include/flash_strata_v2.inl: rename cyg_block_info to
+ cyg_flash_block_info
+
+2004-11-21 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_strata_v2.cdl: CYGHWR_IO_FLASH_DEVICE_V2 is now
+ implicit
+
+2004-09-14 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/flash_strata_v2.inl: Return the end address which is the
+ last valid address, not the first invalid address.
+ Also import Mark Salters changes from the trunk.
+
+2004-08-21 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/flash_strata_v2.inl (flash_unlock_block):
+ * cdl/flash_strata_v2.cdl: CDL to control the maximum number of
+ blocks the driver supports. Some of the newer strata device has more
+ than the default maximum of 128. Problem pointed out by Kevin Zhang.
+
+2004-08-13 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/flash_strata_v2.cdl: Indicate we implement
+ CYGHWR_IO_FLASH_BLOCK_LOCKING when
+ CYGOPT_DEVS_FLASH_STRATA_V2_LOCKING is enabled.
+ * include/flash_strata_v2.inl: Make block unlock and
+ lock compile.
+
+2004-08-05 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * New version of the strata driver based on the old version. This
+ version uses the new flash device API.
+
+2005-01-26 Scott Wilkinson <scott@alliantnetworks.com>
+ * src/strata.h:
+ * src/strata.c:
+ Flash from STMicro is compatible with the Intel strata chips,
+ so detect them as well. Check for manuf id 0x20.
+
+2003-10-29 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/flash_unlock_block.c (flash_unlock_block): test lock bit
+ explicitly - newer flash parts use the reserved bits in the
+ returned data.
+
+2003-09-11 Jani Monoses <jani@iv.ro>
+
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_program_buf.c (flash_program_buf): Fix bootblock handling
+ in erase. Fix erase and word-program for Synchronous Strata and later
+ chips where block address and word address are required in the first
+ cycle of the operation while for earlier parts any address was good.
+
+2003-09-10 Jani Monoses <jani@iv.ro>
+
+ * cdl/flash_strata.cdl:
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf): Use .2ram sections
+ for putting flash functions to RAM instead of the old method.
+
+2003-05-02 Jani Monoses <jani@iv.ro>
+
+ * src/strata.c: Switch to using generic flash_query_dev.
+ The previous cache related changes broke flash_query for
+ Strata because in the query case the generic flash driver was not
+ called to handle the caches but the internal handling was removed
+ nevertheless.
+
+2003-04-04 Jani Monoses <jani@iv.ro>
+
+ * src/strata.h:
+ Use generic flash_dev.h for providing the FLASHWORD macro for
+ different widths and device numbers.No reason to duplicate that
+ here.This implicitely fixes the case when CYGNUM_FLASH_WIDTH is 16
+ and CYGNUM_FLASH_DEVICES is 4.
+
+2003-04-03 Jani Monoses <jani@iv.ro>
+
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf):
+ Cache enabling and disabling are already handled by generic flash
+
+2002-08-12 Mark Salter <msalter@redhat.com>
+
+ * src/flash_unlock_block.c: Add synchronous strataflash support.
+ * src/strata.h: Add comments regarding synchronous strataflash.
+
+2002-04-30 Christoph Csebits <christoph.csebits@frequentis.com>
+
+ * src/flash_unlock_block.c: Getting the current block lock
+ state for flashes in 8-Bit mode is now working correctly.
+
+2002-04-16 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/flash_strata.cdl: Invoke $(CC) with $(CFLAGS) to ensure the
+ correct flags are passed.
+
+2002-04-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/strata.c: Clean up warnings.
+
+2002-01-22 Mark Salter <msalter@redhat.com>
+
+ * cdl/flash_strata.cdl: Add ".text" before "_end" markers in .s files.
+
+2001-10-23 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/flash_strata.cdl: Provide an option so that RedBoot .ecm
+ files can turn off the functionality of copying flash driver code
+ to separate RAM for execution; it's not needed for RAM and ROMRAM
+ startup, and for some platforms it is required to *not* copy thus.
+
+2001-08-25 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_program_buf.c (flash_program_buf): Allow configuration
+ specific code sequence for actual writing of data. Define by the
+ macro CYGHWR_FLASH_WRITE_ELEM. Note: this is required on some
+ hardware, like the Intel SA185, which handles flash writes in
+ strange/obscure fashion.
+
+2001-07-17 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+
+ * src/flash_query.c (flash_query): Query needs to be done on even
+ addresses for byte-enabled strata flash
+
+ * src/flash_program_buf.c (flash_program_buf): Fix of conversion of
+ write buffer length (in bytes) to the length in 'flash_t' words.
+
+2001-06-22 Hugo Tyson <hmt@redhat.com>
+
+ * src/strata.c (flash_hwr_init): Need to refer to the query code
+ as extern char flash_query[], flash_query_end[]; (with the []) or
+ MIPS code gen assumes these are short offsets and linking fails.
+ The generic flash code in io/flash already uses this idiom.
+
+2001-06-22 Hugo Tyson <hmt@redhat.com>
+
+ * src/strata.c (flash_hwr_init): Warnings reduced. No arithmetic
+ on void *.
+
+2001-06-21 Hugo Tyson <hmt@redhat.com>
+
+ * src/flash_program_buf.c (flash_program_buf): The buffered write
+ code didn't jump out if there was a write error, nor verify the
+ data by reading back. This isn't consistent with the slow case,
+ and made it take an age if the device is unhappy, and then report
+ a bizarre error code. Both issues fixed.
+
+2001-06-21 Hugo Tyson <hmt@redhat.com>
+
+ * src/strata.c (flash_hwr_init): If shrinking to fit, must also
+ adjust the flash_info.blocks field, else unlock crashes trying to
+ get status of all those extra blocks that we cannot actually see.
+
+2001-06-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/strata.c: Remove dependency on printf() via user functions.
+
+2001-06-07 Hugo Tyson <hmt@redhat.com>
+
+ * src/strata.c (flash_hwr_init): If we find a flash device that is
+ larger than is possible given the memory map, shrink to fit.
+ We know about the memory map from CYGNUM_FLASH_BASE_MASK (if
+ defined); it tells us the stride from one device to another.
+
+ This is to cope with installing, say, a 28F640 in a slot designed
+ for a 28F320 because of supply issues - it all works fine so long
+ as A22 is grounded.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_strata.cdl: Needs IO driver to copy functions to RAM.
+
+2001-04-26 Gary Thomas <gthomas@redhat.com>
+
+ * src/strata.c: Be more careful when enable/flush/disable caches.
+
+ * src/flash_erase_block.c (flash_erase_block): Boot block devices
+ may require additional erase commands to erase entire 'block'.
+
+2001-03-21 Hugo Tyson <hmt@redhat.com>
+
+ * src/strata.h (FLASH_Write_Buffer): Do not define this if
+ CYGOPT_FLASH_IS_NOT_ADVANCED is defined; Advanced (xxxJ3) flash is
+ usual these days. Also added documentation of the options that
+ can be used to control this module.
+
+ * src/flash_program_buf.c (flash_program_buf): Reduce warnings
+ about unused variables if no FLASH_Write_Buffer command available.
+
+2001-03-21 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_program_buf.c (flash_program_buf): Buffered write code
+ fixups, only on platforms with it defined.
+
+2001-03-17 Gary Thomas <gthomas@redhat.com>
+
+ * src/strata.h:
+ * src/strata.c: Support buffered writes.
+
+ * src/flash_program_buf.c: Use buffered writes if possible. This
+ mode allows the chip to do parallelized writes which is much faster.
+ It does require additional information, now provided by upper layer.
+
+2001-02-15 Hugo Tyson <hmt@redhat.com>
+
+ * src/flash_query.c (flash_query): Depending on whether
+ CYGOPT_FLASH_IS_BOOTBLOCK (just a #define from the instantiator,
+ not really a cdl_option) is set, do the full Read_Query or just
+ acquire two codes for manufacturer and device type using Read_ID.
+
+ * src/strata.c (flash_hwr_init): Again depending on whether
+ CYGOPT_FLASH_IS_BOOTBLOCK, decode the device type into a size and
+ so on, or use the full Read_Query data as before.
+
+ * src/strata.h (FLASH_Read_ID): Undefine those commands which we
+ do not use. Conditionally define those that we use depending on
+ CYGOPT_FLASH_IS_BOOTBLOCK. Thus we should be able to deal with
+ StrataFlash and BootBlock flash with the same code.
+
+ * cdl/flash_strata.cdl: Do not implement (in the CDL sense)
+ CYGHWR_IO_FLASH_BLOCK_LOCKING leave it up to the instantiating
+ package instead. Also move the build of the two objects that do
+ locking and unlocking into a compenent which is only active if
+ CYGHWR_IO_FLASH_BLOCK_LOCKING is indeed (requested to be)
+ implemented somewhere.
+
+2001-02-14 Hugo Tyson <hmt@redhat.com>
+
+ * devs/flash/intel/strata/...: New package, generic strataFlash
+ driver based on several others; a portion of its history
+ follows...
+
+ flash.h -> strata.h
+ flash<platform>.c -> strata.c
+
+2001-02-06 Hugo Tyson <hmt@redhat.com>
+
+ * src/flash.h: Much more generic again. Not yet separated into
+ generic component and invocation header, but the structure is
+ there. Also included support for a mapping from the physical
+ flash address we're thinking of to the virtual address we use to
+ access it. More documentation. Generalization to 8,16,32 and
+ 64-bit access, made up from 8,16 or 32-bit devices. Command and
+ status macros modified to accommodate these options.
+
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf):
+ All now acquire when possible the ROM address from the block
+ address, and use the physical to virtual macro as needed.
+
+ * src/flash_unlock_block.c (flash_unlock_block):
+ The same changes, but a little more complex because of the need to
+ clear-all then re-lock some semantics. Shadow pointer to virtual
+ address is used each time round the loop.
+
+ * cdl/flash_strata.cdl: Add explicit dependencies on flash.h, for
+ there were none - or they were ignored - for the specially built
+ compilation units that get copied to RAM for execution.
+
+2001-02-01 Hugo Tyson <hmt@redhat.com>
+
+ * all: copied from the assabet flash driver.
+
+2000-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/assabet_flash.c (flash_code_overlaps): Define stext/etext
+ as array types so no assumptions can be made by the compiler about
+ location.
+
+2000-10-24 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_program_buf.c (flash_program_buf):
+ * src/flash_erase_block.c (flash_erase_block): Support up to 32M FLASH.
+
+2000-09-10 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_unlock_block.c:
+ * src/flash_lock_block.c: New file(s).
+
+ * src/flash.h:
+ * cdl/flash_assabet.cdl: Add region locking functions.
+
+2000-08-29 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_flash.c: Improve error decoding.
+
+2000-08-24 Gary Thomas <gthomas@redhat.com>
+
+ * src/flash_query.c:
+ * src/flash_erase_block.c:
+ * src/flash.h: FLASH support for Intel SA1110 Assabet.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/intel/stratav2/current/cdl/flash_strata_v2.cdl b/ecos/packages/devs/flash/intel/stratav2/current/cdl/flash_strata_v2.cdl
new file mode 100644
index 0000000..5773a06
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/stratav2/current/cdl/flash_strata_v2.cdl
@@ -0,0 +1,208 @@
+# ====================================================================
+#
+# flash_strata_v2.cdl
+#
+# FLASH memory - Hardware support for Intel Strata Flash
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Contributors:
+# Date: 2005-06-11
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_STRATA_V2 {
+ display "Intel StrataFLASH memory support"
+ doc ref/devs-flash-strata.html
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ implements CYGHWR_IO_FLASH_DEVICE
+ include_dir cyg/io
+ compile strata.c
+
+ description "
+ Flash memory support for Intel StrataFlash devices and compatibles.
+ This driver implements the V2 flash driver API"
+
+ cdl_option CYGNUM_DEVS_FLASH_STRATA_V2_PROGRAM_TIMEOUT {
+ display "Maximum number of iterations during a write"
+ flavor data
+ default_value 100000000
+ legal_values 1024 to 0x7fffffff
+ description "
+ Flash program operations may take a long time, and the driver
+ needs to poll the device to detect when the operation has
+ completed. This option controls the maximum number of iterations
+ of the polling loop, before the driver will give up. The timeout
+ should never actually trigger, as long as the hardware is
+ functioning correctly. If a timeout does occur the flash device
+ may be left in an inconsistent state. If very slow flash devices
+ are used then the platform HAL may require a larger timeout."
+ }
+
+ cdl_option CYGNUM_DEVS_FLASH_STRATA_V2_ERASE_TIMEOUT {
+ display "Maximum number of iterations during a block erase"
+ flavor data
+ default_value 100000000
+ legal_values 1024 to 0x7fffffff
+ description "
+ The driver needs to poll the flash device during a block erase
+ to detect when the operation has completed. This option controls
+ the maximum number of iterations of the polling loop, before the
+ driver will give up. The timeout should never actually trigger,
+ as long as the hardware is functioning correctly. If a timeout
+ does occur the flash device may be left in an inconsistent state.
+ If very slow flash devices are used then the platform HAL may
+ require a larger timeout."
+ }
+
+ cdl_option CYGIMP_DEVS_FLASH_STRATA_V2_LEAVE_INTERRUPTS_ENABLED {
+ display "Leave interrupts enabled during flash operations"
+ active_if { ! CYGHWR_DEVS_FLASH_STRATA_V2_CACHED_ONLY }
+ default_value 0
+ description "
+ On typical hardware erasing or programming a flash block requires
+ disabling interrupts and possibly the cache. During these operations
+ some or all of the flash hardware will be unusable, and disabling
+ interrupts is the only reliable way of ensuring that no interrupt
+ handler or other thread will try to access the flash in the middle
+ of the operation. This can have a major impact on the real-time
+ responsiveness of typical applications.
+
+ In some circumstances it is possible to leave interrupts enabled.
+ The application must run in RAM, not in flash. There must be some
+ way of accessing the flash which bypasses the cache. The application
+ must only access the flash using the proper API, for example
+ cyg_flash_read(), which ensures that only one thread at a time can
+ access a flash device. Finally there must be no possibility of
+ entering a ROM monitor running in flash. This can happen if RedBoot
+ is used as the ROM monitor and virtual vectors are enabled. It can
+ also happen when debugging the application via RedBoot or gdb stubs.
+
+ If the application can absolutely guarantee that the flash will not be
+ accessed during a flash operation then it is possible to enable this option,
+ improving interrupt latency. Any unexpected flash accesses are likely
+ to cause a system crash. If in doubt leave this option disabled."
+ }
+
+ cdl_interface CYGHWR_DEVS_FLASH_STRATA_V2_CACHED_ONLY {
+ display "Flash memory accesses are always cached"
+ flavor bool
+ description "
+ Flash memory devices are usually accessed via the cache to achieve
+ acceptable performance. However erase and program operations need
+ to access the flash directly, bypassing the cache. On some targets
+ it is possible to access the flash in an uncached part of the
+ address space, for example by suitable MMU settings. On other
+ targets it is necessary to disable the cache while erasing or
+ programming blocks of flash. In the latter case the platform HAL
+ will implement this interface."
+ }
+
+ cdl_option CYGNUM_DEVS_FLASH_STRATA_V2_ERASE_REGIONS {
+ display "Number of different erase regions"
+ flavor data
+ default_value 2
+ legal_values 1 to 64
+ description "
+ Flash devices vary widely in the way the various flash blocks are
+ laid out. In uniform devices all flash blocks are the same size,
+ for example 64 blocks of 64K each. Other devices have a boot block,
+ where one of the big blocks is subdivided into a number of smaller
+ ones. For example there could be eight 8K blocks, followed by 63 64K
+ blocks. Each sequence of blocks of a given size is known as an erase
+ region, so a uniform device has a single erase region and the above
+ boot block device has two erase regions. The driver needs to know the
+ maximum number of erase regions that may be present, especially if
+ CFI is used to determine the block details at run-time. Typically
+ this option is controlled by a requires property in the platform HAL,
+ so users do not need to edit it."
+ }
+
+ cdl_option CYGNUM_DEVS_FLASH_STRATA_V2_BLOCKS {
+ display "Maximum number of blocks per device"
+ flavor data
+ default_value 256
+ legal_values 1 to 65536
+ description "
+ The unlock operation on some members of the Strata family of flash chips,
+ for example the j3 series, is complicated. There is no individual block
+ unlock command, only a global unlock. Hence to unlock a single block it
+ is necessary to read the current locked state of all blocks, unlock all
+ blocks, then restore the locked state where appropriate. This requires
+ one bit on the stack for every block, so the maximum number of blocks
+ must be known at compile-time. The default value of 256 should suffice
+ for most flash devices and results in additional stack usage of 32 bytes,
+ small enough that it should not cause stack overflow problems. The
+ platform HAL may require a larger value if the board's flash chips
+ require it."
+ }
+
+ cdl_component CYGPKG_DEVS_FLASH_STRATA_V2_OPTIONS {
+ display "Strata driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building the Strata
+ flash driver, and details of which tests are built."
+
+ cdl_option CYGPKG_DEVS_FLASH_STRATA_V2_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Strata flash driver. These flags
+ are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_STRATA_V2_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Strata flash driver. These flags
+ are removed from the set of global flags if present."
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/flash/intel/stratav2/current/doc/strata.sgml b/ecos/packages/devs/flash/intel/stratav2/current/doc/strata.sgml
new file mode 100644
index 0000000..99779e2
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/stratav2/current/doc/strata.sgml
@@ -0,0 +1,914 @@
+<!-- DOCTYPE part PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- strata.sgml -->
+<!-- -->
+<!-- Documentation for the V2 strata flash device driver. -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Date: 2005/06/11 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-flash-strata"><title>Intel Strata Flash Device Driver</title>
+
+<refentry id="strata">
+ <refmeta>
+ <refentrytitle>Overview</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Overview</refname>
+ <refpurpose>eCos Support for Intel Strata Flash Devices and Compatibles</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="strata-description"><title>Description</title>
+ <para>
+The <varname>CYGPKG_DEVS_FLASH_STRATA_V2</varname>
+flash driver package implements support for the Intel Strata
+family of flash devices and compatibles. The driver is not normally
+accessed directly. Instead application code will use the API provided
+by the generic flash driver package
+<varname>CYGPKG_IO_FLASH</varname>, for example by calling functions
+like <function>cyg_flash_program</function>. There are a small number
+of <link linkend="strata-api-other">additional functions</link>
+specific to Strata devices.
+ </para>
+ <para>
+The driver imposes one restriction on application code which
+developers should be aware of: when programming the flash the
+destination addresses must be aligned to a bus boundary. For example
+if the target hardware has a single flash device attached to a 16-bit
+bus then program operations must involve a multiple of 16-bit values
+aligned to a 16-bit boundary. Note that it is the bus width that
+matters, not the device width. If the target hardware has two 16-bit
+devices attached to a 32-bit bus then program operations must still be
+aligned to a 32-bit boundary, even though in theory a 16-bit boundary
+would suffice. In practice this is rarely an issue, and requiring the
+larger boundary greatly simplifies the code and improves performance.
+ </para>
+ <note><para>
+Many eCos targets with Strata or compatible flash devices will
+still use the older driver package
+<varname>CYGPKG_DEVS_FLASH_STRATA</varname>. Only newer ports
+and some older ports that have been converted will use the V2 driver.
+This documentation only applies to the V2 driver.
+ </para></note>
+ </refsect1>
+
+ <refsect1 id="strata-config"><title>Configuration Options</title>
+ <para>
+The Strata flash driver package will be loaded automatically when
+configuring eCos for a target with suitable hardware. However the
+driver will be inactive unless the generic flash package
+<varname>CYGPKG_IO_FLASH</varname> is loaded. It may be necessary to
+add this generic package to the configuration explicitly before the
+driver functionality becomes available. There should never be any need
+to load or unload the Strata driver package.
+ </para>
+ <para>
+There are a number of configuration options, relating mostly to hardware
+characteristics. It is very rare that application developers need to
+change any of these. For example the option
+<varname>CYGNUM_DEVS_FLASH_STRATA_V2_ERASE_REGIONS</varname> may need
+a non-default value if the flash devices used on the target have an
+unusual boot block layout. If so the platform HAL will impose a
+requires constraint on this option and the configuration system will
+resolve the constraint. The only time it might be necessary to change
+the value manually is if the actual board being used is a variant of
+the one supported by the platform HAL and uses a different flash chip.
+ </para>
+ </refsect1>
+</refentry>
+
+<refentry id="strata-instance">
+ <refmeta>
+ <refentrytitle>Instantiating a Strata Device</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Instantiating</refname>
+ <refpurpose>including the driver in an eCos target</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>
+#include &lt;cyg/io/strata_dev.h&gt;
+ </funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_init_nop</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_init_check_devid_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_init_cfi_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_erase_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_program_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ <paramdef>const void* <parameter>data</parameter></paramdef>
+ <paramdef>size_t <parameter>len</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_bufprogram_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ <paramdef>const void* <parameter>data</parameter></paramdef>
+ <paramdef>size_t <parameter>len</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_lock_j3_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>const cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_unlock_j3_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>const cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_lock_k3_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>const cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_unlock_k3_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>const cyg_flashaddr_t <parameter>addr</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="strata-instance-description"><title>Description</title>
+ <para>
+The Strata family contains a number of different devices, all
+supporting the same basic set of operations but with various common or
+uncommon extensions. The range includes:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>28FxxxB3 Boot Block</term>
+ <listitem><para>
+These support 8 8K boot blocks as well as the usual 64K blocks. There
+is no buffered write capability. The only locking mechanism available
+involves manipulating voltages on certain pins.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>28FxxxC3</term>
+ <listitem><para>
+These also have boot blocks. There is no buffered write capability.
+Individual blocks can be locked and unlocked in software.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>28FxxxJ3</term>
+ <listitem><para>
+These are uniform devices where all blocks are 128K. Buffered writes
+are supported. Blocks can be locked individually, but the only unlock
+operation is a global unlock-all.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>28FxxxK3</term>
+ <listitem><para>
+These are also uniform devices with 128K blocks. Buffered writes are
+supported. Individual blocks can be locked and unlocked in software.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+Each of these comes in a range of sizes and bus widths. There are also
+platform-specific issues such as how many devices are actually present
+on the board and where they are mapped in the address space. The
+Strata driver package cannot know all this information. Instead it
+is the responsibility of another package, usually the platform HAL, to
+instantiate some flash device structures. Two pieces of information
+are especially important: the bus configuration and the boot block
+layout.
+ </para>
+ <para>
+Flash devices are typically 8-bits, 16-bits, or 32-bits wide (64-bit
+devices are not yet in common use). Most 16-bit devices will also
+support 8-bit accesses, but not all. Similarly 32-bit devices can be
+accessed 16-bits at a time or 8-bits at a time. A board will have one
+or more of these devices on the bus. For example there may be a single
+16-bit device on a 16-bit bus, or two 16-bit devices on a 32-bit bus.
+The processor's bus logic determines which combinations are possible,
+and usually there will be a trade off between cost and performance.
+For example two 16-bit devices in parallel can provide twice the
+memory bandwidth of a single device. The driver supports the following
+combinations:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>8</term>
+ <listitem><para>
+A single 8-bit flash device on an 8-bit bus.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>16</term>
+ <listitem><para>
+A single 16-bit flash device on a 16-bit bus.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>32</term>
+ <listitem><para>
+A single 32-bit flash device on an 32-bit bus.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>88</term>
+ <listitem><para>
+Two parallel 8-bit devices on an 16-bit bus.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>8888</term>
+ <listitem><para>
+Four parallel 8-bit devices on a 32-bit bus.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>1616</term>
+ <listitem><para>
+Two parallel 16-bit devices on a 32-bit bus, with one device providing
+the bottom two bytes of each 32-bit datum and the other device
+providing the upper two bytes.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>16as8</term>
+ <listitem><para>
+A single 16-bit flash device connected to an 8-bit bus.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+These configuration all require slightly different code to manipulate
+the hardware. The Strata driver package provides separate functions
+for each configuration, for example
+<function>cyg_strata_erase_16</function> and
+<function>cyg_strata_program_1616</function>.
+ </para>
+ <caution><para>
+At the time of writing not all the configurations have been tested.
+ </para></caution>
+ <para>
+The second piece of information is the boot block layout. Flash
+devices are subdivided into blocks (also known as sectors, both terms
+are in common use). Some operations such as erase work on a whole
+block at a time, and for most applications a block is the smallest
+unit that gets updated. A typical block size is 64K. It is inefficient
+to use an entire 64K block for small bits of configuration data and
+similar information, so some flash devices also support a number of
+smaller boot blocks. A typical 2MB flash device could have eight 8K
+blocks and 31 full-size 64K blocks. The boot blocks may appear at the
+bottom or the top of the device. So-called uniform devices do not have
+boot blocks, just full-size ones. The driver needs to know the boot
+block layout. With modern devices it can work this out at run-time,
+but often it is better to provide the information statically.
+ </para>
+ </refsect1>
+
+ <refsect1 id="strata-instance-example"><title>Example</title>
+ <para>
+Flash support is usually specific to each platform. Even if two
+platforms happen to use the same flash device there are likely to be
+differences such as the location in the address map. Hence there is
+little possibility of re-using the platform-specific code, and this
+code is generally placed in the platform HAL rather than in a separate
+package. Typically this involves a separate file and a corresponding
+compile property in the platform HAL's CDL:
+ </para>
+ <programlisting width=72>
+cdl_package CYGPKG_HAL_M68K_KIKOO {
+ &hellip;
+ compile -library=libextras.a kikoo_flash.c
+ &hellip;
+}
+ </programlisting>
+ <para>
+The contents of this file will not be accessed directly, only
+indirectly via the generic flash API, so normally it would be removed
+by link-time garbage collection. To avoid this the object file has to
+go into <filename>libextras.a</filename>.
+ </para>
+ <para>
+The actual file <filename>kikoo_flash.c</filename> will look something like:
+ </para>
+ <programlisting>
+#include &lt;pkgconf/system.h&gt;
+#ifdef CYGPKG_DEVS_FLASH_STRATA_V2
+
+#include &lt;cyg/io/flash.h&gt;
+#include &lt;cyg/io/strata_dev.h&gt;
+
+static const CYG_FLASH_FUNS(hal_kikoo_flash_strata_funs,
+ &amp;cyg_strata_init_check_devid_16,
+ &amp;cyg_flash_devfn_query_nop,
+ &amp;cyg_strata_erase_16,
+ &amp;cyg_strata_bufprogram_16,
+ (int (*)(struct cyg_flash_dev*, const cyg_flashaddr_t, void*, size_t))0,
+ &amp;cyg_strata_lock_j3_16,
+ &amp;cyg_strata_unlock_j3_16);
+
+static const cyg_strata_dev hal_kikoo_flash_priv = {
+ .manufacturer_code = CYG_FLASH_STRATA_MANUFACTURER_INTEL,
+ .device_code = 0x0017,
+ .bufsize = 16,
+ .block_info = {
+ { 0x00020000, 64 } // 64 * 128K blocks
+ }
+};
+
+CYG_FLASH_DRIVER(hal_kikoo_flash,
+ &amp;hal_kikoo_flash_strata_funs,
+ 0,
+ 0x60000000,
+ 0x601FFFFF,
+ 1,
+ hal_kikoo_flash_priv.block_info,
+ &amp;hal_kikoo_flash_priv
+);
+#endif
+ </programlisting>
+ <para>
+The bulk of the file is protected by an ifdef for the Strata flash
+driver. That driver will only be active if the generic flash support
+is enabled. Without that support there will be no way of accessing
+the device so there is no point in instantiating the device. The rest
+of the file is split into three definitions. The first supplies the
+functions which will be used to perform the actual flash accesses,
+using a macro provided by the generic flash code in <filename
+class="headerfile">cyg/io/flash_dev.h</filename>. The
+relevant ones have an <literal>_16</literal> suffix, indicating that
+on this board there is a single 16-bit flash device on a 16-bit
+bus. The second definition provides information specific to Strata
+flash devices. The third provides the
+<structname>cyg_flash_dev</structname> structure needed by the generic
+flash code, which contains pointers to the previous two.
+ </para>
+ </refsect1>
+
+ <refsect1 id="strata-instance-functions"><title>Functions</title>
+ <para>
+All eCos flash device drivers must implement a standard interface,
+defined by the generic flash code <varname>CYGPKG_IO_FLASH</varname>.
+This interface includes a table of 7 function pointers for various
+operations: initialization, query, erase, program, read,
+locking and unlocking. The query operation is optional and
+the generic flash support provides a dummy implementation
+<function>cyg_flash_devfn_query_nop</function>. Strata flash devices
+are always directly accessible so there is no need for a separate read
+function. The remaining functions are more complicated.
+ </para>
+ <para>
+Usually the table can be declared <literal>const</literal>. In a ROM
+startup application this avoids both ROM and RAM copies of the table,
+saving a small amount of memory. <literal>const</literal> should not
+be used if the table may be modified by a platform-specific
+initialization routine.
+ </para>
+
+ <refsect2 id="strata-instance-functions-init"><title>Initialization</title>
+ <para>
+There is a choice of three main initialization functions. The simplest
+is <function>cyg_flash_devfn_init_nop</function>, which does nothing. It
+can be used if the <structname>cyg_strata_dev</structname> and
+<structname>cyg_flash_dev</structname> structures are fully
+initialized statically and the flash will just work without special
+effort. This is useful if it is guaranteed that the board will always
+be manufactured using the same flash chip, since the nop function
+involves the smallest code size and run-time overheads.
+ </para>
+ <para>
+The next step up is
+<function>cyg_strata_init_check_devid_XX</function>, where
+<literal>XX</literal> will be replaced by the suffix appropriate for
+the bus configuration. It is still necessary to provide all the device
+information statically, including the <structfield>devid</structfield>
+field in the <structname>cyg_strata_dev</structname> structure.
+However this initialization function will attempt to query the flash
+device and check that the provided manufacturer and device codes
+matches the actual hardware. If there is a mismatch the device will be
+marked uninitialized and subsequent attempts to manipulate the flash
+will fail.
+ </para>
+ <para>
+If the board may end up being manufactured with any of a number of
+different flash chips then the driver can perform run-time
+initialization, using a <function>cyg_strata_init_cfi_XX</function>
+function. This queries the flash device as per the Common Flash Memory
+Interface Specification, supported by all current devices (although
+not necessarily by older devices). The
+<structfield>block_info</structfield> field in the
+<structname>cyg_strata_dev</structname> structure and the
+<structfield>end</structfield> and
+<structfield>num_block_infos</structfield> fields in the
+<structname>cyg_flash_dev</structname> structure will be filled in.
+It is still necessary to supply the <structfield>start</structfield>
+field statically since otherwise the driver will not know how to
+access the flash device. The main disadvantage of using CFI is that it
+will increase the code size.
+ </para>
+ <para>
+A final option is to use a platform-specific initialization function.
+This may be useful if the board may be manufactured with one of a
+small number of different flash devices and the platform HAL needs to
+adapt to this. The Strata driver provides a utility function to
+read the device id, <link
+linkend="strata-api-other"><function>cyg_strata_read_devid_XX</function></link>:
+ </para>
+ <programlisting width=72>
+static int
+kikoo_flash_init(struct cyg_flash_dev* dev)
+{
+ int manufacturer_code, device_code;
+ cyg_strata_read_devid_1616(dev, &amp;manufacturer_code, &amp;device_code);
+ if (manufacturer_code != CYG_FLASH_STRATA_MANUFACTURER_STMICRO) {
+ return CYG_FLASH_ERR_DRV_WRONG_PART;
+ }
+ switch(device_code) {
+ case 0x0042 :
+ &hellip;
+ case 0x0084 :
+ &hellip;
+ default:
+ return CYG_FLASH_ERR_DRV_WRONG_PART;
+ }
+}
+ </programlisting>
+ <para>
+There are many other possible uses for a platform-specific
+initialization function. For example initial prototype boards might
+have only supported 8-bit access to a 16-bit flash device rather than
+16-bit access, but this was fixed in the next revision. The
+platform-specific initialization function could figure out which model
+board it is running on and replace the default
+<literal>16as8</literal> functions with <literal>16</literal> ones.
+ </para>
+ </refsect2>
+
+ <refsect2 id="strata-instance-functions-erase-program"><title>Erase and Program</title>
+ <para>
+The Strata driver provides erase and program functions appropriate
+for the various bus configurations. On most targets these can be used
+directly. On some targets it may be necessary to do some extra work
+before and after the erase and program operations. For example if the
+hardware has an MMU then the part of the address map containing the
+flash may have been set to read-only, in an attempt to catch spurious
+memory accesses. Erasing or programming the flash requires
+write-access, so the MMU settings have to be changed temporarily. For
+another example some flash device may require a higher voltage to be
+applied during an erase or program operation. or a higher voltage may
+be desirable to make the operation proceed faster. A typical
+platform-specific erase function would look like this:
+ </para>
+ <programlisting width=72>
+static int
+kikoo_flash_erase(struct cyg_flash_dev* dev, cyg_flashaddr_t addr)
+{
+ int result;
+ &hellip; // Set up the hardware for an erase
+ result = cyg_strata_erase_32(dev, addr);
+ &hellip; // Revert the hardware change
+ return result;
+}
+ </programlisting>
+ <para>
+There are two versions of the program function.
+<function>cyg_strata_bufprogram_xx</function> uses the buffered write
+capability of some strata chips. This allows the flash chip to perform
+the writes in parallel, thus greatly improving performance. It
+requires that the <structfield>bufsize</structfield> field of the
+<structname>cyg_strata_dev</structname> structure is set correctly to
+the number of words in the write buffer. The usual value for this is
+16, corresponding to a 32-byte write buffer. The alternative
+<function>cyg_strata_program_xx</function> writes the data one word at
+a time so is significantly slower. It should be used only with strata
+chips that do not support buffered writes, for example the b3 and c3
+series.
+ </para>
+ <para>
+There are two configuration options which affect the erase and program
+functions, and which a platform HAL may wish to change:
+<varname>CYGNUM_DEVS_FLASH_STRATA_V2_ERASE_TIMEOUT</varname> and
+<varname>CYGNUM_DEVS_FLASH_STRATA_V2_PROGRAM_TIMEOUT</varname>. The
+erase and program operations both involve polling for completion, and
+these timeout impose an upper bound on the polling loop. Normally
+these operations should never take anywhere close to the timeout
+period, and hence a timeout probably indicates a catastrophic failure
+that should really be handled by a watchdog reset. A reset is
+particularly appropriate because there will be no clean way of
+aborting the flash operation. The main reason for the timeouts is to
+help with debugging when porting to new hardware. If there is a valid
+reason why a particular platform needs different timeouts then the
+platform HAL's CDL can require appropriate values for these options.
+ </para>
+ </refsect2>
+
+ <refsect2 id="strata-instance-functions-locking"><title>Locking</title>
+ <para>
+Current Strata devices implement locking in three different ways,
+requiring different sets of functions:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>28FxxxB3</term>
+ <listitem><para>
+There is no software locking support. The
+<function>cyg_flash_devfn_lock_nop</function> and
+<function>cyg_flash_devfn_unlock_nop</function> functions should be used.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>28FxxxC3</term>
+ <term>28FxxxK3</term>
+ <listitem><para>
+These support locking and unlocking individual blocks. The
+<function>cyg_strata_lock_k3_XX</function> and
+<function>cyg_strata_unlock_k3_XX</function> functions should be used.
+All blocks are locked following power-up or reset, so the unlock
+function must be used before any erase or program operation.
+Theoretically the lock function is optional and
+<function>cyg_flash_devfn_lock_nop</function> can be used instead, saving a
+small amount of code space.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>28FxxxJ3</term>
+ <listitem><para>
+Individual blocks can be locked using
+<function>cyg_strata_lock_j3_XX</function>, albeit using a slightly
+different algorithm from the C3 and K3 series. However the only unlock
+support is a global unlock of all blocks. Hence the only way to unlock
+a single block is to check the locked status of every block, unlock
+them all, and relock the ones that should still be locked. This
+time-consuming operation is implemented by
+<function>cyg_strata_unlock_j3_XX</function>. Worse, unlocking all
+blocks can take approximately a second. During this time the flash is
+unusable so normally interrupts have to be disabled, affecting
+real-time responsiveness. There is no way of suspending this
+operation.
+ </para>
+ <para>
+Unlike the C3 and K3 chips, on a J3 blocks are not automatically
+locked following power-up or reset. Hence lock and unlock support is
+optional, and <function>cyg_flash_devfn_lock_nop</function> and
+<function>cyg_flash_devfn_unlock_nop</function> can be used.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+If real locking functions are used then the platform HAL's CDL script
+should implement the CDL interface
+<varname>CYGHWR_IO_FLASH_BLOCK_LOCKING</varname>. Otherwise the
+generic flash package may believe that none of the flash drivers in
+the system provide locking functionality and disable the interface
+functions.
+ </para>
+ </refsect2>
+ </refsect1>
+
+ <refsect1 id="strata-instance-devpriv"><title>Device-Specific Structure</title>
+ <para>
+The <structname>cyg_strata_dev</structname> structure provides
+information specific to Strata flash devices, as opposed to the
+more generic flash information which goes into the
+<structname>cyg_flash_dev</structname> structure. There are only two
+fields: <structfield>devid</structfield> and
+<structfield>block_info</structfield>.
+ </para>
+ <para>
+<structfield>manufacturer_code</structfield> and
+<structfield>device_code</structfield> are needed only if the driver's
+initialization function is set to
+<function>cyg_strata_init_check_devid_XX</function>. That function
+will extract the actual device info from the flash chip and compare it
+with these fields. If there is a mismatch then subsequent operations
+on the device will fail. Definitions of
+<varname>CYG_FLASH_STRATA_MANUFACTURER_INTEL</varname> and
+<varname>CYG_FLASH_STRATA_MANUFACTURER_STMICRO</varname> are provided
+for convenience.
+ </para>
+ <para>
+The <structfield>bufsize</structfield> field is needed only if a
+buffered program function
+<function>cyg_strata_bufprogram_XX</function> is used. It should give
+the size of the buffer in words. Typically Strata devices have a
+32-byte buffer, so when attached to an 8-bit bus
+<structfield>bufsize</structfield> should be 32 and when attached to a
+16-bit bus it should be 16.
+ </para>
+ <para>
+The <structfield>block_info</structfield> field consists of one or
+more pairs of the block size in bytes and the number of blocks of that
+size. The order must match the actual hardware device since the flash
+code will use the table to determine the start and end locations of
+each block. The table can be initialized in one of three ways:
+ </para>
+ <orderedlist>
+ <listitem><para>
+If the driver initialization function is set to
+<function>cyg_strata_init_nop</function> or
+<function>cyg_strata_init_check_devid_XX</function> then the block
+information should be provided statically. This is appropriate if the
+board will also be manufactured using the same flash chip.
+ </para></listitem>
+ <listitem><para>
+If <function>cyg_strata_init_cfi_XX</function> is used then this
+will fill in the block info table. Hence there is no need for static
+initialization.
+ </para></listitem>
+ <listitem><para>
+If a platform-specific initialization function is used then either
+this should fill in the block info table, or the info should be
+provided statically.
+ </para></listitem>
+ </orderedlist>
+ <para>
+The size of the <structfield>block_info</structfield> table is
+determined by the configuration option
+<varname>CYGNUM_DEVS_FLASH_STRATA_V2_ERASE_REGIONS</varname>.
+This has a default value of 2, which should suffice for nearly all
+Strata flash devices. If more entries are needed then the platform
+HAL's CDL script should require a larger value.
+ </para>
+ <para>
+If the <structname>cyg_strata_dev</structname> structure is
+statically initialized then it can be <literal>const</literal>. This
+saves a small amount of memory in ROM startup applications. If the
+structure may be updated at run-time, either by
+<function>cyg_strata_init_cfi_XX</function> or by a
+platform-specific initialization routine, then it cannot be
+<literal>const</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="strata-instance-flash"><title>Flash Structure</title>
+ <para>
+Internally the flash code works in terms of
+<structname>cyg_flash_dev</structname> structures, and the platform
+HAL should define one of these. The structure should be placed in the
+<literal>cyg_flashdev</literal> table. The following fields need to be
+provided:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><structfield>funs</structfield></term>
+ <listitem><para>
+This should point at the table of functions.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>start</structfield></term>
+ <listitem><para>
+The base address of the flash in the address map. On
+some board the flash may be mapped into memory several times, for
+example it may appear in both cached and uncached parts of the address
+space. The <structfield>start</structfield> field should correspond to
+the cached address.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>end</structfield></term>
+ <listitem><para>
+The address of the last byte in the flash. It can
+either be statically initialized, or
+<function>cyg_strata_init_cfi_XX</function> will calculate
+its value at run-time.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>num_block_infos</structfield></term>
+ <listitem><para>
+This should be the number of entries in the
+<structfield>block_info</structfield> table. It can either be
+statically initialized or it will be filled in by
+<function>cyg_strata_init_cfi_XX</function>.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>block_info</structfield></term>
+ <listitem><para>
+The table with the block information is held in the
+<structname>cyg_strata_dev</structname> structure, so this field
+should just point into that structure.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><structfield>priv</structfield></term>
+ <listitem><para>
+This field is reserved for use by the device driver. For the Strata
+driver it should point at the appropriate
+<structname>cyg_strata_dev</structname> structure.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+The <structname>cyg_flash_dev</structname> structure contains a number
+of other fields which are manipulated only by the generic flash code.
+Some of these fields will be updated at run-time so the structure
+cannot be declared <literal>const</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="strata-instance-serial"><title>Multiple Devices</title>
+ <para>
+A board may have several flash devices in parallel, for example two
+16-bit devices on a 32-bit bus. It may also have several such banks
+to increase the total amount of flash. If each device provides 2MB,
+there could be one bank of 2 parallel flash devices at 0xFF800000 and
+another bank at 0xFFC00000, giving a total of 8MB. This setup can be
+described in several ways. One approach is to define two
+<structname>cyg_flash_dev</structname> structures. The table of
+function pointers can usually be shared, as can the
+<structname>cyg_strata_dev</structname> structure. Another approach
+is to define a single <structname>cyg_flash_dev</structname>
+structure but with a larger <structfield>block_info</structfield>
+table, covering the blocks in both banks of devices. The second
+approach makes more efficient use of memory.
+ </para>
+ <para>
+Many variations are possible, for example a small slow flash device
+may be used for initial bootstrap and holding the configuration data,
+while there is also a much larger and faster device to hold a file
+system. Such variations are usually best described by separate
+<structname>cyg_flash_dev</structname> structures.
+ </para>
+ <para>
+If more than one <structname>cyg_flash_dev</structname> structure is
+instantiated then the platform HAL's CDL script should implement the
+CDL interface <varname>CYGHWR_IO_FLASH_DEVICE</varname> once for every
+device past the first. Otherwise the generic code may default to the
+case of a single flash device and optimize for that.
+ </para>
+ </refsect1>
+
+ <refsect1 id="strata-instance-platform"><title>Platform-Specific Macros</title>
+ <para>
+The Strata driver source code includes the header files
+<filename class="headerfile">cyg/hal/hal_arch.h</filename> and
+<filename class="headerfile">cyg/hal/hal_io.h</filename>, and hence
+indirectly the corresponding platform header files (if defined).
+Optionally these headers can define macros which are used inside the
+driver, thus giving the HAL limited control over how the driver works.
+ </para>
+ </refsect1>
+
+ <refsect1 id="strata-instance-cache"><title>Cache Management</title>
+ <para>
+By default the strata driver assumes that the flash can be accessed
+uncached, and it will use the HAL
+<function>CYGARC_UNCACHED_ADDRESS</function> macro to map the cached
+address in the <structfield>start</structfield> field of the
+<structname>cyg_flash_dev</structname> structure into an uncached
+address. If for any reason this HAL macro is inappropriate for the
+flash then an alternative macro
+<function>HAL_STRATA_UNCACHED_ADDRESS</function> can be defined
+instead. However fixing the
+<function>CYGARC_UNCACHED_ADDRESS</function> macro is normally the
+better solution.
+ </para>
+ <para>
+If there is no way of bypassing the cache then the platform HAL should
+implement the CDL interface
+<varname>CYGHWR_DEVS_FLASH_STRATA_V2_CACHED_ONLY</varname>. The flash
+driver will now disable and re-enable the cache as required. For
+example a program operation will involve the following:
+ </para>
+ <programlisting width=72>
+ STRATA_INTSCACHE_STATE;
+ STRATA_INTSCACHE_BEGIN();
+ while ( ! finished ) {
+ program data
+ }
+ STRATA_INTSCACHE_END();
+ </programlisting>
+ <para>
+The default implementations of these INTSCACHE macros are as follows:
+<varname>STATE</varname> defines any local variables that may be
+needed, e.g. to save the current interrupt state;
+<function>BEGIN</function> disables interrupts, synchronizes the data
+caches, disables it, and invalidates the current contents;
+<function>END</function> re-enables the cache and then
+interrupts. The cache is only disabled when interrupts are disabled,
+so there is no possibility of an interrupt handler running or a
+context switch occurring while the cache is disabled, potentially
+leaving the system running very slowly. The data cache synchronization
+ensures that there are no dirty cache lines, so when the cache is
+disabled the low-level flash write code will not see stale data in
+memory. The invalidate ensures that at the end of the operation
+higher-level code will not pick up stale cache contents instead of the
+newly written flash data.
+ </para>
+ <para>
+Some implementations of the HAL cache macros may not provide the exact
+semantics required by the flash driver. For example
+<function>HAL_DCACHE_DISABLE</function> may have an unwanted side
+effect, or it may do more work than is needed here. The driver will
+check for alternative macros
+<function>HAL_STRATA_INTSCACHE_STATE</function>,
+<function>HAL_STRATA_INTSCACHE_BEGIN</function> and
+<function>HAL_STRATA_INTSCACHE_END</function>, using these instead of
+the defaults.
+ </para>
+ </refsect1>
+
+</refentry>
+
+<refentry id="strata-api-other">
+ <refmeta>
+ <refentrytitle>Strata-Specific Functions</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Strata</refname>
+ <refpurpose>driver-specific functions</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>
+#include &lt;cyg/io/strata_dev.h&gt;
+ </funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>void <function>cyg_strata_read_devid_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ <paramdef>cyg_uint32* <parameter>manufacturer</parameter></paramdef>
+ <paramdef>cyg_uint32* <parameter>device</parameter></paramdef>
+ </funcprototype>
+ <funcprototype>
+ <funcdef>int <function>cyg_strata_unlock_all_j3_XX</function></funcdef>
+ <paramdef>struct cyg_flash_dev* <parameter>device</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="strata-api-other-description">
+ <title>Description</title>
+ <para>
+The driver provides two sets of functions specific to Strata devices
+and not accessible via the standard eCos flash API. Both may be used
+safely before the flash subsystem is initialized using
+<function>cyg_flash_init</function>.
+ </para>
+ <para>
+<function>cyg_strata_read_devid_XX</function> can be used to get the
+manufacturer and device codes. Typically it is called from a
+platform-specific driver initialization routine, allowing the platform
+HAL to adapt to the actual device present on the board. This may be
+useful if a board may get manufactured with several different and
+somewhat incompatible chips, although usually
+<function>cyg_strata_init_cfi</function> is the better approach. It
+may also be used during testing and porting to check that the chip is
+working correctly.
+ </para>
+ <para>
+<function>cyg_strata_unlock_all_j3_XX</function> is only useful with
+28FxxxJ3 chips and compatibles. These do not allow individual blocks
+to be unlocked. Hence the standard block unlock functionality is
+expensive: it requires checking the locked state of every block,
+unlocking every block, and then relocking all the blocks that should
+still be blocked. Worse, unlocking every block is a time-consuming
+operation, taking approximately a second, that needs to run with
+interrupts disabled. For many applications it is better to just ignore
+the chip's locking capabilities and run with all blocks permanently
+unlocked. Invoking <function>cyg_strata_unlock_all_j3_XX</function>
+during manufacture or when the board is commissioned achieves this.
+ </para>
+ </refsect1>
+</refentry>
+
+</part>
diff --git a/ecos/packages/devs/flash/intel/stratav2/current/include/strata_dev.h b/ecos/packages/devs/flash/intel/stratav2/current/include/strata_dev.h
new file mode 100644
index 0000000..fafb0c7
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/stratav2/current/include/strata_dev.h
@@ -0,0 +1,164 @@
+#ifndef CYGONCE_DEVS_FLASH_STRATA_DEV_V2_H
+# define CYGONCE_DEVS_FLASH_STRATA_DEV_V2_H
+//==========================================================================
+//
+// strata_dev.h
+//
+// Flash driver for the Intel Strata family - driver details
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors:
+// Date: 2005-06-11
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_flash_strata_v2.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+externC int cyg_strata_init_nop(struct cyg_flash_dev*);
+externC size_t cyg_strata_query_nop(struct cyg_flash_dev*, void*, const size_t);
+externC int cyg_strata_hwr_map_error_nop(struct cyg_flash_dev*, int);
+externC int cyg_strata_lock_nop(struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_nop(struct cyg_flash_dev*, const cyg_flashaddr_t);
+
+externC void cyg_strata_read_devid_8( struct cyg_flash_dev*, cyg_uint32*, cyg_uint32*);
+externC void cyg_strata_read_devid_16( struct cyg_flash_dev*, cyg_uint32*, cyg_uint32*);
+externC void cyg_strata_read_devid_32( struct cyg_flash_dev*, cyg_uint32*, cyg_uint32*);
+externC void cyg_strata_read_devid_88( struct cyg_flash_dev*, cyg_uint32*, cyg_uint32*);
+externC void cyg_strata_read_devid_8888( struct cyg_flash_dev*, cyg_uint32*, cyg_uint32*);
+externC void cyg_strata_read_devid_1616( struct cyg_flash_dev*, cyg_uint32*, cyg_uint32*);
+externC void cyg_strata_read_devid_16as8( struct cyg_flash_dev*, cyg_uint32*, cyg_uint32*);
+
+externC int cyg_strata_init_check_devid_8( struct cyg_flash_dev*);
+externC int cyg_strata_init_check_devid_16( struct cyg_flash_dev*);
+externC int cyg_strata_init_check_devid_32( struct cyg_flash_dev*);
+externC int cyg_strata_init_check_devid_88( struct cyg_flash_dev*);
+externC int cyg_strata_init_check_devid_8888( struct cyg_flash_dev*);
+externC int cyg_strata_init_check_devid_1616( struct cyg_flash_dev*);
+externC int cyg_strata_init_check_devid_16as8( struct cyg_flash_dev*);
+
+externC int cyg_strata_init_cfi_8( struct cyg_flash_dev*);
+externC int cyg_strata_init_cfi_16( struct cyg_flash_dev*);
+externC int cyg_strata_init_cfi_32( struct cyg_flash_dev*);
+externC int cyg_strata_init_cfi_88( struct cyg_flash_dev*);
+externC int cyg_strata_init_cfi_8888( struct cyg_flash_dev*);
+externC int cyg_strata_init_cfi_1616( struct cyg_flash_dev*);
+externC int cyg_strata_init_cfi_16as8( struct cyg_flash_dev*);
+
+externC int cyg_strata_erase_8( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_strata_erase_16( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_strata_erase_32( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_strata_erase_88( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_strata_erase_8888( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_strata_erase_1616( struct cyg_flash_dev*, cyg_flashaddr_t);
+externC int cyg_strata_erase_16as8( struct cyg_flash_dev*, cyg_flashaddr_t);
+
+externC int cyg_strata_program_8( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_program_16( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_program_32( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_program_88( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_program_8888( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_program_1616( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_program_16as8( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+
+externC int cyg_strata_bufprogram_8( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_bufprogram_16( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_bufprogram_32( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_bufprogram_88( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_bufprogram_8888( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_bufprogram_1616( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+externC int cyg_strata_bufprogram_16as8( struct cyg_flash_dev*, cyg_flashaddr_t, const void*, size_t);
+
+externC int cyg_strata_lock_j3_8( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_lock_j3_16( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_lock_j3_32( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_lock_j3_88( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_lock_j3_1616( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_lock_j3_16as8( struct cyg_flash_dev*, const cyg_flashaddr_t);
+
+externC int cyg_strata_lock_k3_8( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_lock_k3_16( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_lock_k3_32( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_lock_k3_88( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_lock_k3_1616( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_lock_k3_16as8( struct cyg_flash_dev*, const cyg_flashaddr_t);
+
+externC int cyg_strata_unlock_j3_8( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_j3_16( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_j3_32( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_j3_88( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_j3_1616( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_j3_16as8( struct cyg_flash_dev*, const cyg_flashaddr_t);
+
+externC int cyg_strata_unlock_k3_8( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_k3_16( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_k3_32( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_k3_88( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_k3_1616( struct cyg_flash_dev*, const cyg_flashaddr_t);
+externC int cyg_strata_unlock_k3_16as8( struct cyg_flash_dev*, const cyg_flashaddr_t);
+
+// An additional exported interface for application developers.
+externC int cyg_strata_unlock_all_j3_8( const cyg_flashaddr_t);
+externC int cyg_strata_unlock_all_j3_16( const cyg_flashaddr_t);
+externC int cyg_strata_unlock_all_j3_32( const cyg_flashaddr_t);
+externC int cyg_strata_unlock_all_j3_88( const cyg_flashaddr_t);
+externC int cyg_strata_unlock_all_j3_1616( const cyg_flashaddr_t);
+externC int cyg_strata_unlock_all_j3_16as8( const cyg_flashaddr_t);
+
+// The driver-specific data, pointed at by the priv field in a
+// a cyg_flash_dev structure.
+typedef struct cyg_strata_dev {
+ // The device id, mainly for use by the init_check_devid() routines
+ cyg_uint32 manufacturer_code;
+ cyg_uint32 device_code;
+ // The buffer size for buffered writes in words, usually 16
+ cyg_uint32 bufsize;
+ // Space for the block_info fields needed for the cyg_flash_dev.
+ // These can be statically initialized, or dynamically via
+ // init_cfi().
+ cyg_flash_block_info_t block_info[CYGNUM_DEVS_FLASH_STRATA_V2_ERASE_REGIONS];
+} cyg_strata_dev;
+
+#define CYG_FLASH_STRATA_MANUFACTURER_INTEL 0x0089
+#define CYG_FLASH_STRATA_MANUFACTURER_STMICRO 0x0020
+
+#endif // CYGONCE_DEVS_FLASH_STRATA_DEV_V2_H
diff --git a/ecos/packages/devs/flash/intel/stratav2/current/src/strata.c b/ecos/packages/devs/flash/intel/stratav2/current/src/strata.c
new file mode 100644
index 0000000..1cbdc40
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/stratav2/current/src/strata.c
@@ -0,0 +1,476 @@
+//==========================================================================
+//
+// strata.c
+//
+// Flash driver for the Intel Strata family
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors:
+// Date: 2005-06-11
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_flash_strata_v2.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+#include <cyg/io/strata_dev.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_io.h>
+#include <string.h>
+
+// This driver supports multiple banks of Intel Strata flash devices
+// or compatibles. These are NOR-flash devices, requiring explicit
+// erase operations with an erase value of 0xff.
+//
+// The devices may be 8-bit, 16-bit, or 32-bit (64-bit devices are not
+// yet supported). Most but not all 16-bit devices can also be
+// accessed as 8-bit, in which case the chip may be hooked up to an
+// 8-bit bus. A bank of flash may involve just a single chip, or there
+// may be several chips in parallel. Typical combinations are 88 to
+// get 16-bit, 8888 for 32-bit, and 1616 for 32-bit. It is assumed
+// that all chips within a bank are the same device. There may also be
+// several banks of flash, and different banks may use different
+// devices.
+//
+// This driver instantiates support for the various bus
+// configurations: 8, 16, 16AS8, 32, 88, 8888, and 1616. On any given
+// platform only one or two of these combinations will be of interest,
+// but the remainder will be eliminated via linker garbage collection.
+// To avoid excessive duplication an auxiliary file contains the
+// actual implementations. Compiler optimization should eliminate any
+// unnecessary code.
+
+// A flash driver is supposed to provide the following functions:
+// int (*init)(...)
+// size_t (*query)(...)
+// int (*erase)(...)
+// int (*program)(...)
+// int (*hwr_map_error)(...)
+// int (*block_lock)(...)
+// int (*block_unlock)(...)
+//
+// The devices do not need any special initialization. However a given
+// board may be manufactured with any one of several devices, which
+// complicates things. The main complication is that there may be
+// different bootsector layouts. The primary job of the init function
+// is to check the device id, possibly fill in the bootsector info,
+// or even to use the CFI support to get the bootsector info from the
+// device itself. There may be other complications, e.g. minor variations
+// of a given board design. These can be handled by h/w specific init
+// functions in the platform HAL.
+//
+// The query function need not do anything useful, it is
+// driver-defined.
+//
+// No read function need be supplied because the flash memory is
+// always directly accessible to the cpu.
+//
+// The hwr_map_error is a no-op.
+//
+// Erase, program, and the locking functions need real
+// implementations.
+
+// ----------------------------------------------------------------------------
+// The protocol understood by Strata flash chips and compatibles. The
+// STRATA_PARALLEL() macro is used in bus configurations with multiple
+// devices in parallel, to issue commands to all the devices in a
+// single write. For CFI only one of the chips is queried. For READ_ID
+// when getting the manufacturer and device id only a single device
+// has to be queried, but when checking lock status all devices have
+// to be checked.
+#define STRATA_COMMAND_READ_ARRAY STRATA_SWAP(STRATA_PARALLEL(0x00FF))
+#define STRATA_COMMAND_READ_ID STRATA_SWAP(STRATA_PARALLEL(0x0090))
+#define STRATA_COMMAND_READ_STATUS STRATA_SWAP(STRATA_PARALLEL(0x0070))
+#define STRATA_COMMAND_CLEAR_STATUS STRATA_SWAP(STRATA_PARALLEL(0x0050))
+#define STRATA_COMMAND_PROGRAM_WORD STRATA_SWAP(STRATA_PARALLEL(0x0040))
+#define STRATA_COMMAND_WRITE_BUFFER STRATA_SWAP(STRATA_PARALLEL(0x00E8))
+#define STRATA_COMMAND_WRITE_CONFIRM STRATA_SWAP(STRATA_PARALLEL(0x00D0))
+#define STRATA_COMMAND_ERASE STRATA_SWAP(STRATA_PARALLEL(0x0020))
+#define STRATA_COMMAND_ERASE_CONFIRM STRATA_SWAP(STRATA_PARALLEL(0x00D0))
+#define STRATA_COMMAND_CFI STRATA_SWAP((0x0098))
+#define STRATA_COMMAND_CONFIGURATION STRATA_SWAP(STRATA_PARALLEL(0x00B8))
+#define STRATA_COMMAND_LOCK_BLOCK_0 STRATA_SWAP(STRATA_PARALLEL(0x0060))
+#define STRATA_COMMAND_LOCK_BLOCK_1 STRATA_SWAP(STRATA_PARALLEL(0x0001))
+#define STRATA_COMMAND_UNLOCK_BLOCK_0 STRATA_SWAP(STRATA_PARALLEL(0x0060))
+#define STRATA_COMMAND_UNLOCK_BLOCK_1 STRATA_SWAP(STRATA_PARALLEL(0x00D0))
+#define STRATA_COMMAND_UNLOCK_ALL_0 STRATA_SWAP(STRATA_PARALLEL(0x0060))
+#define STRATA_COMMAND_UNLOCK_ALL_1 STRATA_SWAP(STRATA_PARALLEL(0x00D0))
+
+// CFI offsets of interest. This assumes that the standard query table
+// has not been replaced by the extended query table, although the
+// CFI standard allows that behaviour.
+#define STRATA_OFFSET_CFI_Q STRATA_OFFSET_CFI_DATA(0x0010)
+#define STRATA_OFFSET_CFI_SIZE STRATA_OFFSET_CFI_DATA(0x0027)
+#define STRATA_OFFSET_CFI_WRITE_BUFFER_LSB STRATA_OFFSET_CFI_DATA(0x002A)
+#define STRATA_OFFSET_CFI_WRITE_BUFFER_MSB STRATA_OFFSET_CFI_DATA(0x002B)
+#define STRATA_OFFSET_CFI_BLOCK_REGIONS STRATA_OFFSET_CFI_DATA(0x002C)
+#define STRATA_OFFSET_CFI_BLOCK_COUNT_LSB(_i_) STRATA_OFFSET_CFI_DATA(0x002D + (4 * (_i_)))
+#define STRATA_OFFSET_CFI_BLOCK_COUNT_MSB(_i_) STRATA_OFFSET_CFI_DATA(0x002E + (4 * (_i_)))
+#define STRATA_OFFSET_CFI_BLOCK_SIZE_LSB(_i_) STRATA_OFFSET_CFI_DATA(0x002F + (4 * (_i_)))
+#define STRATA_OFFSET_CFI_BLOCK_SIZE_MSB(_i_) STRATA_OFFSET_CFI_DATA(0x0030 + (4 * (_i_)))
+
+#define STRATA_STATUS_SR7 STRATA_SWAP(STRATA_PARALLEL(0x0080))
+#define STRATA_STATUS_SR6 STRATA_SWAP(STRATA_PARALLEL(0x0040))
+#define STRATA_STATUS_SR5 STRATA_SWAP(STRATA_PARALLEL(0x0020))
+#define STRATA_STATUS_SR4 STRATA_SWAP(STRATA_PARALLEL(0x0010))
+#define STRATA_STATUS_SR3 STRATA_SWAP(STRATA_PARALLEL(0x0008))
+#define STRATA_STATUS_SR2 STRATA_SWAP(STRATA_PARALLEL(0x0004))
+#define STRATA_STATUS_SR1 STRATA_SWAP(STRATA_PARALLEL(0x0002))
+#define STRATA_STATUS_SR0 STRATA_SWAP(STRATA_PARALLEL(0x0001))
+#define STRATA_ID_LOCKED STRATA_SWAP(STRATA_PARALLEL(0x01))
+
+// When programming the flash the source data may not be aligned
+// correctly (although usually it will be). Hence it is necessary to
+// construct the 16-bit or 32-bit numbers to be written to the flash
+// from individual bytes, allowing for endianness.
+#define STRATA_NEXT_DATUM_8(_ptr_) (*_ptr_++)
+#if CYG_BYTEORDER == CYG_LSBFIRST
+# define STRATA_NEXT_DATUM_16(_ptr_) \
+ ({ \
+ cyg_uint16 _result_; \
+ _result_ = (_ptr_[1] << 8) | _ptr_[0]; \
+ _ptr_ += 2; \
+ _result_; })
+
+# define STRATA_NEXT_DATUM_32(_ptr_) \
+ ({ \
+ cyg_uint32 _result_; \
+ _result_ = (_ptr_[3] << 24) | (_ptr_[2] << 16) | (_ptr_[1] << 8) | _ptr_[0]; \
+ _ptr_ += 4; \
+ _result_; })
+#else
+# define STRATA_NEXT_DATUM_16(_ptr_) \
+ ({ \
+ cyg_uint16 _result_; \
+ _result_ = (_ptr_[0] << 8) | _ptr_[1]; \
+ _ptr_ += 2; \
+ _result_; })
+
+# define STRATA_NEXT_DATUM_32(_ptr_) \
+ ({ \
+ cyg_uint32 _result_; \
+ _result_ = (_ptr_[0] << 24) | (_ptr_[1] << 16) | (_ptr_[2] << 8) | _ptr_[3]; \
+ _ptr_ += 4; \
+ _result_; })
+
+#endif
+
+// The addresses used for programming the flash may be different from
+// the ones used to read the flash. The macro
+// HAL_STRATA_UNCACHED_ADDRESS() can be supplied by one of the HAL
+// packages. Otherwise if CYGHWR_DEVS_FLASH_STRATA_V2_CACHED_ONLY
+// is not implemented then the macro CYGARC_UNCACHED_ADDRESS()
+// will be used. If there is no way of bypassing the cache then
+// the addresses will remain unchanged and instead the INTSCACHE
+// macros will disable the cache.
+#if defined(HAL_STRATA_UNCACHED_ADDRESS)
+# define STRATA_UNCACHED_ADDRESS(_addr_) (volatile STRATA_TYPE*)HAL_STRATA_UNCACHED_ADDRESS(_addr_)
+#elif !defined(CYGHWR_DEVS_FLASH_STRATA_V2_CACHED_ONLY)
+# ifndef CYGARC_UNCACHED_ADDRESS
+# error Cache should be bypassed but CYGARC_UNCACHED_ADDRESS is not defined.
+# endif
+# define STRATA_UNCACHED_ADDRESS(_addr_) (volatile STRATA_TYPE*)CYGARC_UNCACHED_ADDRESS(_addr_)
+#else
+# define STRATA_UNCACHED_ADDRESS(_addr_) (volatile STRATA_TYPE*)(_addr_)
+#endif
+
+// The bits on the data bus may need swapping, either because of
+// endianness issues or because some lines are just wired wrong.
+// SWAP is for commands going to the flash chip. UNSWAP is for
+// data coming back from the flash chip. The swapping takes
+// effect after allowing for STRATA_PARALLEL(). Data is never
+// swapped, it does not matter if bit 5 of a datum is actually
+// stored in bit 3 of the flash as long as the data reads back
+// right.
+#if defined(HAL_STRATA_SWAP)
+# define STRATA_SWAP(_data_) HAL_STRATA_SWAP(_data_)
+#else
+# define STRATA_SWAP(_data_) (_data_)
+#endif
+#if defined(HAL_STRATA_UNSWAP)
+# define STRATA_UNSWAP(_data_) HAL_STRATA_UNSWAP(_data_)
+#else
+# define STRATA_UNSWAP(_data_) (_data_)
+#endif
+
+// Cache and interrupt manipulation. This driver supports fine-grained
+// control over interrupts and the cache, using three macros. These may
+// be provided by the platform HAL, or by defaults here. There are
+// three variants:
+//
+// 1) control both interrupts and cache, needed if
+// CYGHWR_DEVS_FLASH_STRATA_V2_CACHED_ONLY is implemented i.e. if it
+// is necessary to disable the cache to get direct access to the flash.
+// 2) control interrupts only, the default if the cache can be bypassed
+// when accessing the flash.
+// 3) do nothing, if the cache can be bypassed and the application
+// guarantees that the flash will not be accessed by any interrupt
+// handlers or other threads.
+
+#if defined(CYGHWR_DEVS_FLASH_STRATA_V2_CACHED_ONLY)
+
+// First, the amount of state that should be preserved. By default
+// this means the interrupt state and the data cache state.
+# define STRATA_INTSCACHE_DEFAULT_STATE int _saved_ints_, _saved_dcache_
+
+// Start an operation on the flash. Make sure that interrupts are
+// disabled and then save the current state of the data cache. The
+// actual flash manipulation should happen with the cache disabled.
+// There may still be data in the cache that has not yet been flushed
+// to memory, so take care of that first. Then invalidate the cache
+// lines so that when the cache is re-enabled later on the processor
+// gets everything from memory, rather than reusing old data in the
+// cache.
+# define STRATA_INTSCACHE_DEFAULT_BEGIN() \
+ CYG_MACRO_START \
+ HAL_DISABLE_INTERRUPTS(_saved_ints_); \
+ HAL_DCACHE_IS_ENABLED(_saved_dcache_); \
+ HAL_DCACHE_SYNC(); \
+ if (_saved_dcache_) { \
+ HAL_DCACHE_DISABLE(); \
+ } \
+ HAL_DCACHE_INVALIDATE_ALL(); \
+ CYG_MACRO_END
+
+// A flash operation has completed. Restore the situation to what it
+// was before. Because of suspend/resume support interrupt handlers
+// and other threads may have run, filling various cache lines with
+// useful data. However it is assumed that none of those cache
+// lines contain any of the data that has been manipulated by this
+// flash operation (the stack and the flash block), so there is
+// no need for another sync or invalidate. It is also assumed that
+// we have not been executing any code out of the block of flash
+// that has just been erased or programmed, so no need to worry
+// about the icache.
+#define STRATA_INTSCACHE_DEFAULT_END() \
+ CYG_MACRO_START \
+ if (_saved_dcache_) { \
+ HAL_DCACHE_ENABLE(); \
+ } \
+ HAL_RESTORE_INTERRUPTS(_saved_ints_); \
+ CYG_MACRO_END
+
+#elif !defined(CYGIMP_DEVS_FLASH_STRATA_V2_LEAVE_INTERRUPTS_ENABLED)
+
+# define STRATA_INTSCACHE_DEFAULT_STATE int _saved_ints_
+# define STRATA_INTSCACHE_DEFAULT_BEGIN() HAL_DISABLE_INTERRUPTS(_saved_ints_)
+// The following blips the interrupt enable to allow pending interrupts
+// to run, which will reduce interrupt latency given the dcache sync/invalidate
+// may be relatively lengthy.
+# define STRATA_INTSCACHE_DEFAULT_END() \
+ CYG_MACRO_START \
+ HAL_RESTORE_INTERRUPTS(_saved_ints_); \
+ HAL_DISABLE_INTERRUPTS(_saved_ints_); \
+ HAL_DCACHE_SYNC(); \
+ HAL_DCACHE_INVALIDATE_ALL(); \
+ HAL_RESTORE_INTERRUPTS(_saved_ints_); \
+ CYG_MACRO_END
+
+#else
+
+# define STRATA_INTSCACHE_DEFAULT_STATE CYG_EMPTY_STATEMENT
+# define STRATA_INTSCACHE_DEFAULT_BEGIN() CYG_EMPTY_STATEMENT
+# define STRATA_INTSCACHE_DEFAULT_END() \
+ CYG_MACRO_START \
+ int _saved_ints_; \
+ HAL_DISABLE_INTERRUPTS(_saved_ints_); \
+ HAL_DCACHE_SYNC(); \
+ HAL_DCACHE_INVALIDATE_ALL(); \
+ HAL_RESTORE_INTERRUPTS(_saved_ints_); \
+ CYG_MACRO_END
+
+#endif
+
+#ifdef HAL_STRATA_INTSCACHE_STATE
+# define STRATA_INTSCACHE_STATE HAL_STRATA_INTSCACHE_STATE
+#else
+# define STRATA_INTSCACHE_STATE STRATA_INTSCACHE_DEFAULT_STATE
+#endif
+#ifdef HAL_STRATA_INTSCACHE_BEGIN
+# define STRATA_INTSCACHE_BEGIN HAL_STRATA_INTSCACHE_BEGIN
+#else
+# define STRATA_INTSCACHE_BEGIN STRATA_INTSCACHE_DEFAULT_BEGIN
+#endif
+#ifdef HAL_STRATA_INTSCACHE_END
+# define STRATA_INTSCACHE_END HAL_STRATA_INTSCACHE_END
+#else
+# define STRATA_INTSCACHE_END STRATA_INTSCACHE_DEFAULT_END
+#endif
+
+// Some HALs require a special instruction to flush write buffers.
+// Not all HALs do though, so we define it empty if it isn't already present.
+#ifndef HAL_MEMORY_BARRIER
+# define HAL_MEMORY_BARRIER() CYG_EMPTY_STATEMENT
+#endif
+
+// ----------------------------------------------------------------------------
+// Generic code.
+
+// Get info about the current block, i.e. base and size.
+static void
+strata_get_block_info(struct cyg_flash_dev* dev, const cyg_flashaddr_t addr, cyg_flashaddr_t* block_start, size_t* block_size)
+{
+ cyg_uint32 i;
+ size_t offset = addr - dev->start;
+ cyg_flashaddr_t result;
+
+ result = dev->start;
+
+ for (i = 0; i < dev->num_block_infos; i++) {
+ if (offset < (dev->block_info[i].blocks * dev->block_info[i].block_size)) {
+ offset -= (offset % dev->block_info[i].block_size);
+ *block_start = result + offset;
+ *block_size = dev->block_info[i].block_size;
+ return;
+ }
+ result += (dev->block_info[i].blocks * dev->block_info[i].block_size);
+ offset -= (dev->block_info[i].blocks * dev->block_info[i].block_size);
+ }
+ CYG_FAIL("Address out of range of selected flash device");
+}
+
+// ----------------------------------------------------------------------------
+// Instantiate all of the h/w functions appropriate for the various
+// configurations.
+// The suffix is used to construct the function names.
+// Types for the width of the bus, controlling the granularity of access.
+// devcount specifies the number of devices in parallel, and is used for looping
+// The NEXT_DATUM() macro allows for misaligned source data.
+// The PARALLEL macro, if defined, is used for sending commands and reading
+// status bits from all devices in the bank in one operation.
+
+// A single 8-bit device on an 8-bit bus.
+#define STRATA_SUFFIX 8
+#define STRATA_TYPE cyg_uint8
+#define STRATA_DEVCOUNT 1
+#define STRATA_NEXT_DATUM(_ptr_) STRATA_NEXT_DATUM_8(_ptr_)
+
+#include "strata_aux.c"
+
+#undef STRATA_SUFFIX
+#undef STRATA_TYPE
+#undef STRATA_DEVCOUNT
+#undef STRATA_NEXT_DATUM
+
+// A single 16-bit device.
+#define STRATA_SUFFIX 16
+#define STRATA_TYPE cyg_uint16
+#define STRATA_DEVCOUNT 1
+#define STRATA_NEXT_DATUM(_ptr_) STRATA_NEXT_DATUM_16(_ptr_)
+
+#include "strata_aux.c"
+
+#undef STRATA_SUFFIX
+#undef STRATA_TYPE
+#undef STRATA_DEVCOUNT
+#undef STRATA_NEXT_DATUM
+
+// A single 32-bit device.
+#define STRATA_SUFFIX 32
+#define STRATA_TYPE cyg_uint32
+#define STRATA_DEVCOUNT 1
+#define STRATA_NEXT_DATUM(_ptr_) STRATA_NEXT_DATUM_32(_ptr_)
+
+#include "strata_aux.c"
+
+#undef STRATA_SUFFIX
+#undef STRATA_TYPE
+#undef STRATA_DEVCOUNT
+#undef STRATA_NEXT_DATUM
+
+// Two 8-bit devices, giving a 16-bit bus.
+#define STRATA_SUFFIX 88
+#define STRATA_TYPE cyg_uint16
+#define STRATA_DEVCOUNT 2
+#define STRATA_NEXT_DATUM(_ptr_) STRATA_NEXT_DATUM_16(_ptr_)
+#define STRATA_PARALLEL(_cmd_) ((_cmd_ << 8) | _cmd_)
+
+#include "strata_aux.c"
+
+#undef STRATA_SUFFIX
+#undef STRATA_TYPE
+#undef STRATA_DEVCOUNT
+#undef STRATA_NEXT_DATUM
+
+// Four 8-bit devices, giving a 32-bit bus.
+#define STRATA_SUFFIX 8888
+#define STRATA_TYPE cyg_uint32
+#define STRATA_DEVCOUNT 4
+#define STRATA_NEXT_DATUM(_ptr_) STRATA_NEXT_DATUM_32(_ptr_)
+#define STRATA_PARALLEL(_cmd_) ((_cmd_ << 24) | (_cmd_ << 16) | (_cmd_ << 8) | _cmd_)
+
+#include "strata_aux.c"
+
+#undef STRATA_SUFFIX
+#undef STRATA_TYPE
+#undef STRATA_DEVCOUNT
+#undef STRATA_NEXT_DATUM
+
+// Two 16-bit devices, giving a 32-bit bus.
+#define STRATA_SUFFIX 1616
+#define STRATA_TYPE cyg_uint32
+#define STRATA_DEVCOUNT 2
+#define STRATA_NEXT_DATUM(_ptr_) STRATA_NEXT_DATUM_32(_ptr_)
+#define STRATA_PARALLEL(_cmd_) ((_cmd_ << 16) | _cmd_)
+
+#include "strata_aux.c"
+
+#undef STRATA_SUFFIX
+#undef STRATA_TYPE
+#undef STRATA_DEVCOUNT
+#undef STRATA_NEXT_DATUM
+
+// 16AS8. A 16-bit device hooked up so that only byte accesses are
+// allowed. This requires unusual offsets for the CFI and query data.
+#define STRATA_SUFFIX 16as8
+#define STRATA_TYPE cyg_uint8
+#define STRATA_DEVCOUNT 1
+#define STRATA_NEXT_DATUM(_ptr_) STRATA_NEXT_DATUM_8(_ptr_)
+#define STRATA_OFFSET_MANUFACTURER_ID 00
+#define STRATA_OFFSET_DEVICE_ID 02
+#define STRATA_OFFSET_LOCK_STATUS 04
+#define STRATA_OFFSET_CFI_DATA(_idx_) (2 * (_idx_))
+
+#include "strata_aux.c"
diff --git a/ecos/packages/devs/flash/intel/stratav2/current/src/strata_aux.c b/ecos/packages/devs/flash/intel/stratav2/current/src/strata_aux.c
new file mode 100644
index 0000000..71d1144
--- /dev/null
+++ b/ecos/packages/devs/flash/intel/stratav2/current/src/strata_aux.c
@@ -0,0 +1,873 @@
+//==========================================================================
+//
+// strata_aux.c
+//
+// Flash driver for the Intel Strata family - implementation.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors:
+// Date: 2005-06-11
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// This file is #include'd multiple times from the main strata.c file,
+// It serves to instantiate the various hardware operations in ways
+// appropriate for all the bus configurations.
+
+// The following macros are used to construct suitable function names
+// for the current bus configuration. STRATA_SUFFIX is #define'd before
+// each #include of strata_aux.c
+
+#ifndef STRATA_STR
+# define STRATA_STR1(_a_) # _a_
+# define STRATA_STR(_a_) STRATA_STR1(_a_)
+# define STRATA_CONCAT3_AUX(_a_, _b_, _c_) _a_##_b_##_c_
+# define STRATA_CONCAT3(_a_, _b_, _c_) STRATA_CONCAT3_AUX(_a_, _b_, _c_)
+#endif
+
+#define STRATA_FNNAME(_base_) STRATA_CONCAT3(_base_, _, STRATA_SUFFIX)
+
+// Similarly construct a forward declaration, placing the function in
+// the .2ram section. Each function must still be in a separate section
+// for linker garbage collection.
+
+# define STRATA_RAMFNDECL(_base_, _args_) \
+ STRATA_FNNAME(_base_) _args_ __attribute__((section (".2ram." STRATA_STR(_base_) "_" STRATA_STR(STRATA_SUFFIX))))
+
+// Calculate the CFI and ID offsets based on the device count. The
+// main code may override this for specific configurations, e.g. 16as8
+#ifndef STRATA_OFFSET_CFI_DATA
+# define STRATA_OFFSET_CFI_DATA(_idx_) _idx_
+#endif
+#ifndef STRATA_OFFSET_MANUFACTURER_ID
+# define STRATA_OFFSET_MANUFACTURER_ID 0x00
+#endif
+#ifndef STRATA_OFFSET_DEVICE_ID
+# define STRATA_OFFSET_DEVICE_ID 0x01
+#endif
+#ifndef STRATA_OFFSET_LOCK_STATUS
+# define STRATA_OFFSET_LOCK_STATUS 0x02
+#endif
+
+
+// For parallel operation commands are issued in parallel and status
+// bits are checked in parallel.
+#ifndef STRATA_PARALLEL
+# define STRATA_PARALLEL(_cmd_) (_cmd_)
+#endif
+
+// ----------------------------------------------------------------------------
+// Diagnostic routines.
+
+#if 0
+#define sf_diag( __fmt, ... ) diag_printf("SF: %s[%d]: " __fmt, __FUNCTION__, __LINE__, __VA_ARGS__ );
+#define sf_dump_buf( __addr, __size ) diag_dump_buf( __addr, __size )
+#else
+#define sf_diag( __fmt, ... )
+#define sf_dump_buf( __addr, __size )
+#endif
+
+
+// ----------------------------------------------------------------------------
+// When performing the various low-level operations like erase the flash
+// chip can no longer support ordinary data reads. Obviously this is a
+// problem if the current code is executing out of flash. The solution is
+// to store the key functions in RAM rather than flash, via a special
+// linker section .2ram which usually gets placed in the same area as
+// .data.
+//
+// In a ROM startup application anything in .2ram will consume space
+// in both the flash and RAM. Hence it is desirable to keep the .2ram
+// functions as small as possible, responsible only for the actual
+// hardware manipulation.
+//
+// All these .2ram functions should be invoked with interrupts
+// disabled. Depending on the hardware it may also be necessary to
+// have the data cache disabled. The .2ram functions must be
+// self-contained, even macro invocations like HAL_DELAY_US() are
+// banned because on some platforms those could be implemented as
+// function calls.
+
+// gcc requires forward declarations with the attributes, then the actual
+// definitions.
+static void STRATA_RAMFNDECL(strata_hw_query, (volatile STRATA_TYPE*, cyg_uint32*, cyg_uint32*));
+static int STRATA_RAMFNDECL(strata_hw_cfi, (struct cyg_flash_dev*, cyg_strata_dev*, volatile STRATA_TYPE*));
+static int STRATA_RAMFNDECL(strata_hw_erase, (volatile STRATA_TYPE*));
+static int STRATA_RAMFNDECL(strata_hw_program, (volatile STRATA_TYPE*, const cyg_uint8*, cyg_uint32 count));
+static int STRATA_RAMFNDECL(strata_hw_bufprogram, (volatile STRATA_TYPE*, const cyg_uint8*, cyg_uint32 count));
+static int STRATA_RAMFNDECL(strata_hw_is_locked, (volatile STRATA_TYPE*));
+static int STRATA_RAMFNDECL(strata_hw_lock_j3, (volatile STRATA_TYPE*));
+static int STRATA_RAMFNDECL(strata_hw_unlock_all_j3, (volatile STRATA_TYPE*));
+static int STRATA_RAMFNDECL(strata_hw_lock_k3, (volatile STRATA_TYPE*));
+static int STRATA_RAMFNDECL(strata_hw_unlock_k3, (volatile STRATA_TYPE*));
+
+// Read the device id. This involves a straightforward command
+// sequence, followed by a reset to get back into array mode.
+// All chips are accessed in parallel, but only the response
+// from the least significant is used.
+static void
+STRATA_FNNAME(strata_hw_query)(volatile STRATA_TYPE* addr, cyg_uint32* manufacturer, cyg_uint32* device)
+{
+ sf_diag("addr %08x cmd %08x width %d\n", addr, STRATA_COMMAND_READ_ID, sizeof(addr[0]) );
+ addr[0] = STRATA_COMMAND_READ_ID;
+ *manufacturer = STRATA_UNSWAP(addr[STRATA_OFFSET_MANUFACTURER_ID]);
+ *device = STRATA_UNSWAP(addr[STRATA_OFFSET_DEVICE_ID]);
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+}
+
+// Perform a CFI query. This involves placing the device(s) into CFI
+// mode, checking that this has really happened, and then reading the
+// size and block info. The address corresponds to the start of the
+// flash.
+static int
+STRATA_FNNAME(strata_hw_cfi)(struct cyg_flash_dev* dev, cyg_strata_dev* strata_dev, volatile STRATA_TYPE* addr)
+{
+ int dev_size;
+ int i;
+ int erase_regions;
+ cyg_uint8 writebuffer_lsb;
+ cyg_uint32 writebuffer;
+
+ sf_diag("addr %08x %d cmd %08x\n",addr, sizeof(STRATA_TYPE), STRATA_COMMAND_CFI);
+ // Just a single write is needed to put the device into CFI mode
+ addr[0] = STRATA_COMMAND_CFI;
+ sf_dump_buf( addr, 256 );
+ // Now check that we really are in CFI mode. There should be a 'Q'
+ // at a specific address. This test is not 100% reliable, but should
+ // be good enough.
+ if ('Q' != (STRATA_UNSWAP(addr[STRATA_OFFSET_CFI_Q]) & 0x00FF)) {
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+ return CYG_FLASH_ERR_PROTOCOL;
+ }
+ // Device sizes are always a power of 2, and the shift is encoded
+ // in a single byte
+ dev_size = 0x01 << (STRATA_UNSWAP(addr[STRATA_OFFSET_CFI_SIZE]) & 0x00FF);
+ dev->end = dev->start + dev_size - 1;
+
+ // The number of erase regions is also encoded in a single byte.
+ // Usually this is no more than 2. A value of 0 indicates that
+ // only chip erase is supported, but the driver does not cope
+ // with that.
+ erase_regions = STRATA_UNSWAP(addr[STRATA_OFFSET_CFI_BLOCK_REGIONS]) & 0x00FF;
+ if (erase_regions > CYGNUM_DEVS_FLASH_STRATA_V2_ERASE_REGIONS) {
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+ return CYG_FLASH_ERR_PROTOCOL;
+ }
+ dev->num_block_infos = erase_regions;
+
+ for (i = 0; i < erase_regions; i++) {
+ cyg_uint32 count, size;
+ cyg_uint32 count_lsb = STRATA_UNSWAP(addr[STRATA_OFFSET_CFI_BLOCK_COUNT_LSB(i)]) & 0x00FF;
+ cyg_uint32 count_msb = STRATA_UNSWAP(addr[STRATA_OFFSET_CFI_BLOCK_COUNT_MSB(i)]) & 0x00FF;
+ cyg_uint32 size_lsb = STRATA_UNSWAP(addr[STRATA_OFFSET_CFI_BLOCK_SIZE_LSB(i)]) & 0x00FF;
+ cyg_uint32 size_msb = STRATA_UNSWAP(addr[STRATA_OFFSET_CFI_BLOCK_SIZE_MSB(i)]) & 0x00FF;
+
+ count = ((count_msb << 8) | count_lsb) + 1;
+ size = (size_msb << 16) | (size_lsb << 8);
+ sf_diag("erase_region %d count %d size %d\n", i, count, size);
+ strata_dev->block_info[i].block_size = (size_t) size * STRATA_DEVCOUNT;
+ strata_dev->block_info[i].blocks = count;
+ }
+
+ writebuffer_lsb = STRATA_UNSWAP(addr[STRATA_OFFSET_CFI_WRITE_BUFFER_LSB]) & 0x00FF;
+ /* No need to include MSB, it would never be as large as 2^256 ! */
+ writebuffer = 1 << writebuffer_lsb;
+
+ strata_dev->bufsize = writebuffer / sizeof(STRATA_TYPE);
+
+ // Get out of CFI mode
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+
+ return CYG_FLASH_ERR_OK;
+}
+
+// Erase a single sector. There is no API support for chip-erase. The
+// generic code operates one sector at a time, invoking the driver for
+// each sector, so there is no opportunity inside the driver for
+// erasing multiple sectors in a single call. The address argument
+// points at the start of the sector.
+static int
+STRATA_FNNAME(strata_hw_erase)(volatile STRATA_TYPE* addr)
+{
+ STRATA_TYPE status;
+ int result = CYG_FLASH_ERR_OK;
+ int retries;
+
+ sf_diag("addr %08x fc %d\n",addr, first_call);
+ // Start the erase operation
+ addr[0] = STRATA_COMMAND_CLEAR_STATUS;
+ addr[0] = STRATA_COMMAND_ERASE;
+ addr[0] = STRATA_COMMAND_ERASE_CONFIRM;
+
+ // All chips are now erasing in parallel. Loop until all have
+ // completed. The SR7 bit will be clear while the erase is
+ // proceeding, set when is has completed. For an already erased
+ // block in a parallel configuration we'll read the 0xff erased
+ // value so the test succeeds there as well.
+ for (retries = CYGNUM_DEVS_FLASH_STRATA_V2_ERASE_TIMEOUT;
+ retries > 0;
+ retries--) {
+ status = addr[0];
+ if ((status & STRATA_STATUS_SR7) == STRATA_STATUS_SR7) {
+ break;
+ }
+ }
+
+ if (retries == 0) {
+ // The world is messed up. One or more chips are still
+ // erasing, status bits may be set, etc. This should not
+ // happen, the erase timeout should be big enough. There
+ // is no easy way to get back into a sane state.
+ return CYG_FLASH_ERR_DRV_TIMEOUT;
+ }
+
+ // The erase operation has completed. First get the chip(s) back
+ // into a sane state.
+ addr[0] = STRATA_COMMAND_READ_STATUS;
+ status = addr[0];
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+
+ // According to the data sheet the bits should be checked in order SR5,
+ // SR3, SR2. This does not appear to work, at least on a J3. If the
+ // block is locked then SR5 is set as well as SR1, so the wrong error
+ // code would be returned.
+ if (status & STRATA_STATUS_SR1) {
+ result = CYG_FLASH_ERR_PROTECT;
+ } else if (status & STRATA_STATUS_SR3) {
+ result = CYG_FLASH_ERR_LOW_VOLTAGE;
+ } else if (status & STRATA_STATUS_SR5) {
+ if (status & STRATA_STATUS_SR4) {
+ result = CYG_FLASH_ERR_PROTOCOL;
+ } else {
+ result = CYG_FLASH_ERR_ERASE;
+ }
+ }
+ sf_diag("status %08x result %d\n", status, result);
+ return result;
+}
+
+// Write data to flash, using individual word writes. The destination
+// address will be aligned in a way suitable for the bus. The source
+// address need not be aligned. The count is in STRATA_TYPE's, i.e. as
+// per the bus alignment, not in bytes.
+static int
+STRATA_FNNAME(strata_hw_program)(volatile STRATA_TYPE* addr, const cyg_uint8* buf, cyg_uint32 count)
+{
+ int i;
+ int result = CYG_FLASH_ERR_OK;
+ int retries = CYGNUM_DEVS_FLASH_STRATA_V2_PROGRAM_TIMEOUT;
+ STRATA_TYPE status;
+
+// sf_diag("addr %08x %d\n",addr, count);
+ addr[0] = STRATA_COMMAND_CLEAR_STATUS;
+ for (i = 0; (i < count) && (result == CYG_FLASH_ERR_OK); i++) {
+ addr[i] = STRATA_COMMAND_PROGRAM_WORD;
+ addr[i] = STRATA_NEXT_DATUM(buf);
+
+ // The data is now being written. While the write is in progress
+ // SR7 will be clear.
+ do {
+ status = addr[i];
+ } while ((--retries > 0) && ((status & STRATA_STATUS_SR7) != STRATA_STATUS_SR7));
+
+ // The status bits may not all change at the same time.
+ // Re-read just to be sure
+ status = addr[i];
+
+ // Again the order here is not that in the datasheet. If the block is
+ // locked then SR4 will be set as well as SR2.
+ if (retries == 0) {
+ result = CYG_FLASH_ERR_DRV_TIMEOUT;
+ } else if (status & STRATA_STATUS_SR1) {
+ result = CYG_FLASH_ERR_PROTECT;
+ } else if (status & STRATA_STATUS_SR3) {
+ result = CYG_FLASH_ERR_LOW_VOLTAGE;
+ } else if (status & STRATA_STATUS_SR4) {
+ result = CYG_FLASH_ERR_PROGRAM;
+ }
+ }
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+ return result;
+}
+
+static int
+STRATA_FNNAME(strata_hw_bufprogram)(volatile STRATA_TYPE* addr, const cyg_uint8* buf, cyg_uint32 count)
+{
+ int result = CYG_FLASH_ERR_OK;
+ STRATA_TYPE status;
+ int retries = CYGNUM_DEVS_FLASH_STRATA_V2_PROGRAM_TIMEOUT;
+ int i;
+
+// sf_diag("addr %p buf %p count %d\n",addr, buf, count);
+ addr[0] = STRATA_COMMAND_CLEAR_STATUS;
+ do {
+ // Issue the command and check that the buffer is ready
+ *addr = STRATA_COMMAND_WRITE_BUFFER;
+ status = *addr;
+ } while ((--retries > 0) && ((status & STRATA_STATUS_SR7) != STRATA_STATUS_SR7));
+
+ // Now issue the count, data, and confirm the operation
+ addr[0] = STRATA_SWAP(STRATA_PARALLEL((count - 1)));
+ for( i = 0 ; i < count ; i++ )
+ {
+ STRATA_TYPE val = STRATA_NEXT_DATUM(buf);
+ addr[i] = val;
+ }
+ addr[0] = STRATA_COMMAND_WRITE_CONFIRM;
+
+ // The write is proceeding. Loop for status.
+ do {
+ status = addr[0];
+ } while ((--retries > 0) && ((status & STRATA_STATUS_SR7) != STRATA_STATUS_SR7));
+
+ // Re-read status, in case bit 7 changed before the others
+ status = addr[0];
+
+// sf_diag("status %08x retries %d SR7 %08x\n", status, retries, STRATA_STATUS_SR7);
+ // Again the order here is not that in the datasheet. If the block is
+ // locked then SR4 will be set as well as SR1.
+ if (retries == 0) {
+ result = CYG_FLASH_ERR_DRV_TIMEOUT;
+ } else if (status & STRATA_STATUS_SR1) {
+ result = CYG_FLASH_ERR_PROTECT;
+ } else if (status & STRATA_STATUS_SR3) {
+ result = CYG_FLASH_ERR_LOW_VOLTAGE;
+ } else if (status & STRATA_STATUS_SR4) {
+ result = CYG_FLASH_ERR_PROGRAM;
+ }
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+ if( result != CYG_FLASH_ERR_OK )
+ {
+ sf_diag("status %08x result %d\n", status, result );
+ }
+ return result;
+}
+
+static int
+STRATA_FNNAME(strata_hw_is_locked)(volatile STRATA_TYPE* addr)
+{
+ int result;
+ addr[0] = STRATA_COMMAND_READ_ID;
+ sf_dump_buf(addr, 16 );
+ result = addr[STRATA_OFFSET_LOCK_STATUS];
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+ sf_diag("addr %08x result %08x id_locked %08x\n",addr, result, STRATA_ID_LOCKED);
+ // The bottom bit always holds the block locked status. Other bits
+ // may get used, e.g. on the k3 family bit 1 holds the locked-down
+ // status. This is ignored for now.
+ return (0 != (result & STRATA_ID_LOCKED));
+}
+
+// With the J3 family locking involves checking the status register.
+// There is no individual block unlock, instead code has to unlock
+// all blocks and then selectively relock them.
+static int
+STRATA_FNNAME(strata_hw_lock_j3)(volatile STRATA_TYPE* addr)
+{
+ int result = CYG_FLASH_ERR_OK;
+ STRATA_TYPE status;
+
+ sf_diag("addr %08x\n",addr);
+ addr[0] = STRATA_COMMAND_CLEAR_STATUS;
+ addr[0] = STRATA_COMMAND_LOCK_BLOCK_0;
+ addr[0] = STRATA_COMMAND_LOCK_BLOCK_1;
+ do {
+ status = addr[0];
+ } while ((status & STRATA_STATUS_SR7) != STRATA_STATUS_SR7);
+ status = addr[0];
+ if (status & STRATA_STATUS_SR3) {
+ result = CYG_FLASH_ERR_LOW_VOLTAGE;
+ } else if ((status & STRATA_STATUS_SR5) && (status & STRATA_STATUS_SR4)) {
+ result = CYG_FLASH_ERR_PROTOCOL;
+ } else if (status & STRATA_STATUS_SR4) {
+ result = CYG_FLASH_ERR_LOCK;
+ }
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+ sf_diag("addr %08x status %08x result %d\n",addr, status, result );
+ return result;
+}
+
+static int
+STRATA_FNNAME(strata_hw_unlock_all_j3)(volatile STRATA_TYPE* addr)
+{
+ int result = CYG_FLASH_ERR_OK;
+ STRATA_TYPE status;
+
+ sf_diag("addr %08x\n",addr);
+ addr[0] = STRATA_COMMAND_CLEAR_STATUS;
+ addr[0] = STRATA_COMMAND_UNLOCK_ALL_0;
+ addr[0] = STRATA_COMMAND_UNLOCK_ALL_1;
+ do {
+ status = addr[0];
+ } while ((status & STRATA_STATUS_SR7) != STRATA_STATUS_SR7);
+ status = addr[0];
+ if (status & STRATA_STATUS_SR3) {
+ result = CYG_FLASH_ERR_LOW_VOLTAGE;
+ } else if ((status & STRATA_STATUS_SR5) && (status & STRATA_STATUS_SR4)) {
+ result = CYG_FLASH_ERR_PROTOCOL;
+ } else if (status & STRATA_STATUS_SR4) {
+ result = CYG_FLASH_ERR_LOCK;
+ }
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+ sf_diag("addr %08x status %08x result %d\n",addr, status, result );
+ return result;
+}
+
+// With the K3 family locking involves checking the id rather than the
+// status register, and there is a block unlock command. There is no
+// exported support for manipulating the block low-down bits so it is
+// assumed these bits remain clear.
+static int
+STRATA_FNNAME(strata_hw_lock_k3)(volatile STRATA_TYPE* addr)
+{
+ int result = CYG_FLASH_ERR_OK;
+ STRATA_TYPE status;
+
+ sf_diag("addr %08x\n",addr);
+ do {
+ addr[0] = STRATA_COMMAND_LOCK_BLOCK_0;
+ addr[0] = STRATA_COMMAND_LOCK_BLOCK_1;
+ addr[0] = STRATA_COMMAND_READ_ID;
+ status = addr[STRATA_OFFSET_LOCK_STATUS];
+ } while ((status & STRATA_ID_LOCKED) != STRATA_ID_LOCKED);
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+ return result;
+}
+
+static int
+STRATA_FNNAME(strata_hw_unlock_k3)(volatile STRATA_TYPE* addr)
+{
+ int result = CYG_FLASH_ERR_OK;
+ STRATA_TYPE status;
+
+ do {
+ addr[0] = STRATA_COMMAND_UNLOCK_BLOCK_0;
+ addr[0] = STRATA_COMMAND_UNLOCK_BLOCK_1;
+ addr[0] = STRATA_COMMAND_READ_ID;
+ status = addr[STRATA_OFFSET_LOCK_STATUS];
+ } while ((status & STRATA_ID_LOCKED) != 0);
+ addr[0] = STRATA_COMMAND_READ_ARRAY;
+ HAL_MEMORY_BARRIER();
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// Exported code, mostly for placing in a cyg_flash_dev_funs structure.
+
+// Just read the device id, either for sanity checking that the system
+// has been configured for the right device, or for filling in the
+// block info by a platform-specific init routine if the platform may
+// be manufactured with one of several different chips.
+void
+STRATA_FNNAME(cyg_strata_read_devid) (struct cyg_flash_dev* dev, cyg_uint32* manufacturer, cyg_uint32* device)
+{
+ int (*query_fn)(volatile STRATA_TYPE*, cyg_uint32*, cyg_uint32*);
+ volatile STRATA_TYPE* uncached;
+ STRATA_INTSCACHE_STATE;
+
+ sf_diag("\n", 0);
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+
+ uncached = STRATA_UNCACHED_ADDRESS(dev->start);
+ query_fn = (int (*)(volatile STRATA_TYPE*, cyg_uint32*, cyg_uint32*)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_query) );
+ STRATA_INTSCACHE_BEGIN();
+ (*query_fn)(uncached, manufacturer, device);
+ STRATA_INTSCACHE_END();
+}
+
+// Validate that the device statically configured is the one on the
+// board.
+int
+STRATA_FNNAME(cyg_strata_init_check_devid)(struct cyg_flash_dev* dev)
+{
+ cyg_strata_dev* strata_dev;
+ cyg_uint32 manufacturer, device;
+
+ sf_diag("\n", 0);
+ strata_dev = (cyg_strata_dev*) dev->priv;
+ STRATA_FNNAME(cyg_strata_read_devid)(dev, &manufacturer, &device);
+ if ((manufacturer != strata_dev->manufacturer_code) ||
+ (device != strata_dev->device_code)) {
+ return CYG_FLASH_ERR_DRV_WRONG_PART;
+ }
+ // Successfully queried the device, and the id's match. That
+ // should be a good enough indication that the flash is working.
+ return CYG_FLASH_ERR_OK;
+}
+
+// Initialize via a CFI query, instead of statically specifying the
+// boot block layout.
+int
+STRATA_FNNAME(cyg_strata_init_cfi)(struct cyg_flash_dev* dev)
+{
+ int (*cfi_fn)(struct cyg_flash_dev*, cyg_strata_dev*, volatile STRATA_TYPE*);
+ volatile STRATA_TYPE* uncached;
+ cyg_strata_dev* strata_dev;
+ int result;
+ STRATA_INTSCACHE_STATE;
+
+ sf_diag("\n", 0);
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ strata_dev = (cyg_strata_dev*) dev->priv; // Remove const, only place where this is needed.
+ uncached = STRATA_UNCACHED_ADDRESS(dev->start);
+ cfi_fn = (int (*)(struct cyg_flash_dev*, cyg_strata_dev*, volatile STRATA_TYPE*))
+ cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_cfi));
+
+ STRATA_INTSCACHE_BEGIN();
+ result = (*cfi_fn)(dev, strata_dev, uncached);
+ STRATA_INTSCACHE_END();
+
+ // Now calculate the device size, and hence the end field.
+ if (CYG_FLASH_ERR_OK == result) {
+ int i;
+ int size = 0;
+ for (i = 0; i < dev->num_block_infos; i++) {
+ size += (dev->block_info[i].block_size * dev->block_info[i].blocks);
+ }
+ dev->end = dev->start + size - 1;
+ }
+ return result;
+}
+
+// Erase a single block. The calling code will have supplied a pointer
+// aligned to a block boundary.
+int
+STRATA_FNNAME(cyg_strata_erase)(struct cyg_flash_dev* dev, cyg_flashaddr_t dest)
+{
+ int (*erase_fn)(volatile STRATA_TYPE*);
+ volatile STRATA_TYPE* uncached;
+ cyg_flashaddr_t block_start;
+ size_t block_size;
+ int result;
+ STRATA_INTSCACHE_STATE;
+
+ sf_diag("\n", 0);
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= dev->start) && (dest <= dev->end), "flash address out of device range");
+
+ strata_get_block_info(dev, dest, &block_start, &block_size);
+ CYG_ASSERT(dest == block_start, "erase address should be the start of a flash block");
+
+ uncached = STRATA_UNCACHED_ADDRESS(dest);
+ erase_fn = (int (*)(volatile STRATA_TYPE*)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_erase) );
+
+ STRATA_INTSCACHE_BEGIN();
+ result = (*erase_fn)(uncached);
+ STRATA_INTSCACHE_END();
+ return result;
+}
+
+// Write some data to the flash. The destination must be aligned
+// appropriately for the bus width (not the device width). Higher
+// level code guarantees that the data will not straddle a block
+// boundary.
+int
+STRATA_FNNAME(cyg_strata_program)(struct cyg_flash_dev* dev, cyg_flashaddr_t dest, const void* src, size_t len)
+{
+ int (*program_fn)(volatile STRATA_TYPE*, const cyg_uint8*, cyg_uint32);
+ volatile STRATA_TYPE* uncached;
+ const cyg_uint8* data;
+ int result = CYG_FLASH_ERR_OK;
+ STRATA_INTSCACHE_STATE;
+
+ sf_diag("dest %p src %p len %p(%d) end %p\n", dest, src, len, len, dest+len-1 );
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= dev->start) && ((CYG_ADDRESS)dest <= dev->end), "flash address out of device range");
+
+ // Only support writes that are aligned to the bus boundary. This
+ // may be more restrictive than what the hardware is capable of.
+ // However it ensures that the hw_program routine can write as
+ // much data as possible each iteration, and hence significantly
+ // improves performance. The length had better be a multiple of
+ // the bus width as well
+ if ((0 != ((CYG_ADDRWORD)dest & (sizeof(STRATA_TYPE) - 1))) ||
+ (0 != (len & (sizeof(STRATA_TYPE) - 1)))) {
+ return CYG_FLASH_ERR_INVALID;
+ }
+
+ uncached = STRATA_UNCACHED_ADDRESS(dest);
+ data = (const cyg_uint8*) src;
+ program_fn = (int (*)(volatile STRATA_TYPE*, const cyg_uint8*, cyg_uint32)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_program) );
+
+ STRATA_INTSCACHE_BEGIN();
+ result = (*program_fn)(uncached, data, len / sizeof(STRATA_TYPE));
+ STRATA_INTSCACHE_END();
+ return result;
+}
+
+// Write some data to the flash. The destination must be aligned
+// appropriately for the bus width (not the device width).
+int
+STRATA_FNNAME(cyg_strata_bufprogram)(struct cyg_flash_dev* dev, cyg_flashaddr_t dest, const void* src, size_t len)
+{
+ int (*program_fn)(volatile STRATA_TYPE*, const cyg_uint8*, cyg_uint32);
+ volatile STRATA_TYPE* uncached;
+ const cyg_uint8* data;
+ int bufsize;
+ size_t to_write, first_write, this_write;
+ int result = CYG_FLASH_ERR_OK;
+ STRATA_INTSCACHE_STATE;
+
+ sf_diag("\n", 0);
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= dev->start) && ((CYG_ADDRESS)dest <= dev->end), "flash address out of device range");
+
+ bufsize = ((const cyg_strata_dev*)dev->priv)->bufsize;
+
+ // Only support writes that are aligned to the bus boundary. This
+ // may be more restrictive than what the hardware is capable of.
+ // However it ensures that the hw_program routine can write as
+ // much data as possible each iteration, and hence significantly
+ // improves performance. The length had better be a multiple of
+ // the bus width as well
+ if ((0 != ((CYG_ADDRWORD)dest & (sizeof(STRATA_TYPE) - 1))) ||
+ (0 != (len & (sizeof(STRATA_TYPE) - 1)))) {
+ return CYG_FLASH_ERR_INVALID;
+ }
+
+ uncached = STRATA_UNCACHED_ADDRESS(dest);
+
+ data = (const cyg_uint8*) src;
+ program_fn = (int (*)(volatile STRATA_TYPE*, const cyg_uint8*, cyg_uint32)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_bufprogram) );
+
+ // Buffering works best when the data is aligned to a suitable
+ // boundary, so the first write size may be smaller than the
+ // buffer size to achieve alignment.
+ if ((CYG_ADDRWORD)uncached & ((bufsize * sizeof(STRATA_TYPE)) - 1)) {
+ first_write = (CYG_ADDRWORD)uncached & ((bufsize * sizeof(STRATA_TYPE)) - 1);
+ first_write /= sizeof(STRATA_TYPE);
+ first_write = bufsize - first_write;
+ } else {
+ first_write = 0;
+ }
+
+ STRATA_INTSCACHE_BEGIN();
+ for (to_write = len/sizeof(STRATA_TYPE); to_write > 0; ) {
+
+ if (first_write) {
+ this_write = first_write;
+ first_write = 0;
+ } else {
+ this_write = bufsize;
+ }
+ if (this_write > to_write) {
+ this_write = to_write;
+ }
+ result = (*program_fn)(uncached, data, this_write);
+ if (result != CYG_FLASH_ERR_OK) {
+ break;
+ }
+ to_write -= this_write;
+ if (to_write > 0) {
+ uncached += this_write;
+ data += sizeof(STRATA_TYPE) * this_write;
+ }
+ }
+ STRATA_INTSCACHE_END();
+ return result;
+}
+
+int
+STRATA_FNNAME(cyg_strata_lock_j3)(struct cyg_flash_dev* dev, const cyg_flashaddr_t dest)
+{
+ volatile STRATA_TYPE* uncached;
+ int result;
+ int (*lock_fn)(volatile STRATA_TYPE*);
+ STRATA_INTSCACHE_STATE;
+
+ sf_diag("\n", 0);
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= (cyg_flashaddr_t)dev->start) &&
+ ((CYG_ADDRESS)dest <= dev->end), "flash address out of device range");
+
+ uncached = STRATA_UNCACHED_ADDRESS(dest);
+ lock_fn = (int (*)(volatile STRATA_TYPE*)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_lock_j3) );
+ STRATA_INTSCACHE_BEGIN();
+ result = (*lock_fn)(uncached);
+ STRATA_INTSCACHE_END();
+ return result;
+}
+
+int
+STRATA_FNNAME(cyg_strata_unlock_j3)(struct cyg_flash_dev* dev, const cyg_flashaddr_t dest)
+{
+ int (*locked_fn)(volatile STRATA_TYPE*);
+ int (*lock_fn)(volatile STRATA_TYPE*);
+ int (*unlock_all_fn)(volatile STRATA_TYPE*);
+ cyg_uint8 locked_bits[(CYGNUM_DEVS_FLASH_STRATA_V2_BLOCKS + 7) / 8];
+ int i, j;
+ int current_block;
+ volatile STRATA_TYPE* uncached;
+ volatile STRATA_TYPE* uncached_block;
+ STRATA_INTSCACHE_STATE;
+
+ sf_diag("\n", 0);
+ locked_fn = (int (*)(volatile STRATA_TYPE*)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_is_locked));
+ lock_fn = (int (*)(volatile STRATA_TYPE*)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_lock_j3));
+ unlock_all_fn = (int (*)(volatile STRATA_TYPE*)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_unlock_all_j3));
+
+ memset(locked_bits, 0, sizeof(locked_bits));
+
+ uncached = STRATA_UNCACHED_ADDRESS(dev->start);
+ uncached_block = STRATA_UNCACHED_ADDRESS(dest);
+
+ STRATA_INTSCACHE_BEGIN();
+
+ // The obvious optimization: no point in doing anything if the
+ // block is already unlocked.
+ if (! (*locked_fn)(uncached_block)) {
+ STRATA_INTSCACHE_END();
+ return CYG_FLASH_ERR_OK;
+ }
+
+ for (i = 0, current_block = 0; i < dev->num_block_infos; i++) {
+ sf_diag("block_info[%d] n %d sz %d\n",i, dev->block_info[i].blocks, dev->block_info[i].block_size );
+ for (j = 0; j < dev->block_info[i].blocks; j++, current_block++) {
+ CYG_LOOP_INVARIANT(current_block < CYGNUM_DEVS_FLASH_STRATA_V2_BLOCKS, "Device has too many blocks");
+ if ((uncached != uncached_block) && (*locked_fn)(uncached)) {
+ locked_bits[current_block >> 3] |= (0x01 << (current_block & 0x07));
+ }
+ uncached += dev->block_info[i].block_size/sizeof(STRATA_TYPE);
+ }
+ }
+ sf_diag("locked bits:\n", 0 );
+ sf_dump_buf( locked_bits, sizeof(locked_bits) );
+ uncached = STRATA_UNCACHED_ADDRESS(dev->start);
+ (*unlock_all_fn)(uncached);
+ for (i = 0, current_block = 0; i < dev->num_block_infos; i++) {
+ for (j = 0; j < dev->block_info[i].blocks; j++, current_block++) {
+ if (locked_bits[current_block >> 3] & (0x01 << (current_block & 0x07))) {
+ (*lock_fn)(uncached);
+ }
+ uncached += dev->block_info[i].block_size/sizeof(STRATA_TYPE);
+ }
+ }
+ STRATA_INTSCACHE_END();
+ return CYG_FLASH_ERR_OK;
+}
+
+// An additional exported interface to make life easier for
+// application developers. This code assumes the pointer is for a
+// strata flash device.
+int
+STRATA_FNNAME(cyg_strata_unlock_all_j3)(const cyg_flashaddr_t dest)
+{
+ cyg_flash_info_t info;
+ volatile STRATA_TYPE* uncached;
+ int (*unlock_all_fn)(volatile STRATA_TYPE*);
+ int result;
+ STRATA_INTSCACHE_STATE;
+
+ sf_diag("\n", 0);
+ result = cyg_flash_get_info_addr(dest, &info);
+ if (CYG_FLASH_ERR_OK != result) {
+ return result;
+ }
+
+ uncached = STRATA_UNCACHED_ADDRESS(info.start);
+ unlock_all_fn = (int (*)(volatile STRATA_TYPE*)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_unlock_all_j3));
+ STRATA_INTSCACHE_BEGIN();
+ result = (*unlock_all_fn)(uncached);
+ STRATA_INTSCACHE_END();
+ return result;
+}
+
+int
+STRATA_FNNAME(cyg_strata_lock_k3)(struct cyg_flash_dev* dev, const cyg_flashaddr_t dest)
+{
+ volatile STRATA_TYPE* uncached;
+ int result;
+ int (*lock_fn)(volatile STRATA_TYPE*);
+ STRATA_INTSCACHE_STATE;
+
+ sf_diag("\n", 0);
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= (cyg_flashaddr_t)dev->start) &&
+ ((CYG_ADDRESS)dest <= dev->end), "flash address out of device range");
+
+ uncached = STRATA_UNCACHED_ADDRESS(dest);
+ lock_fn = (int (*)(volatile STRATA_TYPE*)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_lock_k3) );
+ STRATA_INTSCACHE_BEGIN();
+ result = (*lock_fn)(uncached);
+ STRATA_INTSCACHE_END();
+ return result;
+}
+
+int
+STRATA_FNNAME(cyg_strata_unlock_k3)(struct cyg_flash_dev* dev, const cyg_flashaddr_t dest)
+{
+ volatile STRATA_TYPE* uncached;
+ int result;
+ int (*unlock_fn)(volatile STRATA_TYPE*);
+ STRATA_INTSCACHE_STATE;
+
+ sf_diag("\n", 0);
+ CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
+ CYG_ASSERT((dest >= (cyg_flashaddr_t)dev->start) &&
+ ((CYG_ADDRESS)dest <= dev->end), "flash address out of device range");
+
+ uncached = STRATA_UNCACHED_ADDRESS(dest);
+ unlock_fn = (int (*)(volatile STRATA_TYPE*)) cyg_flash_anonymizer( & STRATA_FNNAME(strata_hw_unlock_k3) );
+ STRATA_INTSCACHE_BEGIN();
+ result = (*unlock_fn)(uncached);
+ STRATA_INTSCACHE_END();
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// Clean up the various #define's so this file can be #include'd again
+#undef STRATA_FNNAME
+#undef STRATA_RAMFNDECL
+#undef STRATA_OFFSET_MANUFACTURER_ID
+#undef STRATA_OFFSET_DEVICE_ID
+#undef STRATA_OFFSET_LOCK_STATUS
+#undef STRATA_OFFSET_CFI_DATA
+#undef STRATA_PARALLEL
diff --git a/ecos/packages/devs/flash/mips/atlas/current/ChangeLog b/ecos/packages/devs/flash/mips/atlas/current/ChangeLog
new file mode 100644
index 0000000..73dfcb8
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/atlas/current/ChangeLog
@@ -0,0 +1,56 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/atlas_flash.c:
+ Explicitly include <cyg/io/flash_dev.h> rather than just
+ defining _FLASH_PRIVATE_. (From bartv in flash_v2 branch)
+
+ * cdl/flash_atlas.cdl: Indicate that this driver uses
+ the legacy flash device API.
+
+2003-09-23 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/flash_atlas.cdl: Added requirements for strncmp.
+
+2003-09-16 Jani Monoses <jani@iv.ro>
+
+ * cdl/flash_atlas.cdl:
+ * src/flash_lock_block.c (flash_lock_block):
+ * src/flash_unlock_block.c (flash_unlock_block):
+ * src/flash_erase_block.c (flash_erase_block):
+ * src/flash_query.c (flash_query):
+ * src/flash_program_buf.c (flash_program_buf): Use .2ram sections
+ for putting flash functions to RAM instead of the old method. Use
+ generic flash_dev_query.
+
+2001-06-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/atlas_flash.c: Remove dependency on printf() via user functions.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_atlas.cdl: Needs IO controller to copy functions to
+ RAM.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/mips/atlas/current/cdl/flash_atlas.cdl b/ecos/packages/devs/flash/mips/atlas/current/cdl/flash_atlas.cdl
new file mode 100644
index 0000000..777ad88
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/atlas/current/cdl/flash_atlas.cdl
@@ -0,0 +1,74 @@
+# ====================================================================
+#
+# flash_atlas.cdl
+#
+# FLASH memory - Hardware support on MIPS32 Atlas board.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data: gthomas
+# Contributors: msalter
+# Date: 2000-07-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ATLAS {
+ display "MIPS Atlas FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_MIPS_ATLAS
+ requires CYGINT_ISO_STRING_STRFUNCS
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "FLASH memory device support for MIPS Atlas"
+ compile atlas_flash.c flash_erase_block.c flash_program_buf.c flash_query.c
+
+ cdl_component CYGPKG_DEVS_FLASH_ATLAS_LOCKING {
+ display "Flash device implements locking"
+ active_if 0 < CYGHWR_IO_FLASH_BLOCK_LOCKING
+ calculated 1
+ compile flash_lock_block.c flash_unlock_block.c
+ }
+}
diff --git a/ecos/packages/devs/flash/mips/atlas/current/src/atlas_flash.c b/ecos/packages/devs/flash/mips/atlas/current/src/atlas_flash.c
new file mode 100644
index 0000000..6892954
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/atlas/current/src/atlas_flash.c
@@ -0,0 +1,131 @@
+//==========================================================================
+//
+// atlas_flash.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, msalter
+// Date: 2000-12-06
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include "flash.h"
+
+#include <string.h>
+
+#define _si(p) ((p[1]<<8)|p[0])
+
+int
+flash_hwr_init(void)
+{
+ struct FLASH_query data, *qp;
+ int num_regions, region_size;
+
+ flash_dev_query(&data);
+
+ qp = &data;
+ if (/*(qp->manuf_code == FLASH_Intel_code) && */
+ (strncmp(qp->id, "QRY", 3) == 0)) {
+ num_regions = _si(qp->num_regions)+1;
+ region_size = _si(qp->region_size)*256;
+
+ flash_info.block_size = region_size*2; // Pairs of chips in parallel
+ flash_info.blocks = num_regions*2; // and pairs of chips in serial
+ flash_info.start = (void *)0x9c000000;
+ flash_info.end = (void *)0x9e000000;
+ return FLASH_ERR_OK;
+ } else {
+ (*flash_info.pf)("Can't identify FLASH, sorry\n");
+ diag_dump_buf((void*)&data, sizeof(data));
+ return FLASH_ERR_HWR;
+ }
+}
+
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int err)
+{
+ if (err & 0x007E007E) {
+ (*flash_info.pf)("Err = %x\n", err);
+ if (err & 0x00100010) {
+ return FLASH_ERR_PROGRAM;
+ } else
+ if (err & 0x00200020) {
+ return FLASH_ERR_ERASE;
+ } else
+ return FLASH_ERR_HWR; // FIXME
+ } else {
+ return FLASH_ERR_OK;
+ }
+}
+
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern char _stext[], _etext[];
+ unsigned long p_stext, pstart, p_etext, pend;
+
+ p_stext = CYGARC_PHYSICAL_ADDRESS((unsigned long)&_stext);
+ p_etext = CYGARC_PHYSICAL_ADDRESS((unsigned long)&_etext);
+
+ // if _stext/_etext in boot shadow region, convert to
+ // system flash address
+ if ((p_stext >= 0x1fc00000) && (p_etext <= 0x20000000)) {
+ p_stext -= 0x02000000;
+ p_etext -= 0x02000000;
+ }
+
+ pstart = CYGARC_PHYSICAL_ADDRESS((unsigned long)start);
+ pend = CYGARC_PHYSICAL_ADDRESS((unsigned long)end);
+
+ return (((p_stext >= pstart) && (p_stext < pend)) ||
+ ((p_etext >= pstart) && (p_etext < pend)));
+}
diff --git a/ecos/packages/devs/flash/mips/atlas/current/src/flash.h b/ecos/packages/devs/flash/mips/atlas/current/src/flash.h
new file mode 100644
index 0000000..5cdfb02
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/atlas/current/src/flash.h
@@ -0,0 +1,104 @@
+//==========================================================================
+//
+// flash.h
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef _FLASH_HWR_H_
+#define _FLASH_HWR_H_
+
+#define FLASH_Intel_code 0x89
+
+#define FLASH_Read_ID 0x00900090
+#define FLASH_Read_Query 0x00980098
+#define FLASH_Read_Status 0x00700070
+#define FLASH_Clear_Status 0x00500050
+#define FLASH_Status_Ready 0x00800080
+#define FLASH_Write_Buffer 0x00E800E8
+#define FLASH_Program 0x00100010
+#define FLASH_Block_Erase 0x00200020
+#define FLASH_Set_Lock 0x00600060
+#define FLASH_Set_Lock_Confirm 0x00010001
+#define FLASH_Clear_Locks 0x00600060
+#define FLASH_Clear_Locks_Confirm 0x00D000D0
+#define FLASH_Confirm 0x00D000D0
+#define FLASH_Configure 0x00B800B8
+#define FLASH_Configure_ReadyWait 0x00000000
+#define FLASH_Configure_PulseOnErase 0x00010001
+#define FLASH_Configure_PulseOnProgram 0x00020002
+#define FLASH_Configure_PulseOnBoth 0x00030003
+#define FLASH_Reset 0x00FF00FF
+
+#define FLASH_BLOCK_SIZE 0x40000
+
+#define FLASH_Intel_code 0x89
+
+#define FLASH_BASE_MASK 0xff000000
+
+// Extended query information
+struct FLASH_query {
+ unsigned char manuf_code;
+ unsigned char device_code;
+ unsigned char _unused0[14];
+ unsigned char id[3]; // Q R Y
+ unsigned char _unused1[20];
+ unsigned char device_size;
+ unsigned char device_interface[2];
+ unsigned char buffer_size[2];
+ unsigned char is_block_oriented;
+ unsigned char num_regions[2];
+ unsigned char region_size[2];
+};
+
+#define ATLAS_SFWCTRL *((volatile unsigned *)0xbf000700)
+#define ATLAS_WEN_MAGIC 0xc7
+
+#define FLASH_WRITE_ENABLE() (ATLAS_SFWCTRL = ATLAS_WEN_MAGIC)
+#define FLASH_WRITE_DISABLE() (ATLAS_SFWCTRL = 0)
+
+#endif // _FLASH_HWR_H_
diff --git a/ecos/packages/devs/flash/mips/atlas/current/src/flash_erase_block.c b/ecos/packages/devs/flash/mips/atlas/current/src/flash_erase_block.c
new file mode 100644
index 0000000..a1bb556
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/atlas/current/src/flash_erase_block.c
@@ -0,0 +1,100 @@
+//==========================================================================
+//
+// flash_erase_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, msalter
+// Date: 2000-12-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+
+
+int flash_erase_block(volatile unsigned long *block)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int flash_erase_block(volatile unsigned long *block)
+{
+ volatile unsigned long *ROM;
+ unsigned long stat;
+ int timeout = 50000;
+ int len;
+
+ FLASH_WRITE_ENABLE();
+
+ block = (volatile unsigned long *)CYGARC_UNCACHED_ADDRESS((unsigned long)block);
+ ROM = (volatile unsigned long *)((unsigned long)block & FLASH_BASE_MASK);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Erase block
+ ROM[0] = FLASH_Block_Erase;
+ *block = FLASH_Confirm;
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ // If an error was reported, see if the block erased anyway
+ if (stat & 0x007E007E) {
+ len = FLASH_BLOCK_SIZE;
+ while (len > 0) {
+ if (*block++ != 0xFFFFFFFF) break;
+ len -= sizeof(*block);
+ }
+ if (len == 0) stat = 0;
+ }
+
+ FLASH_WRITE_DISABLE();
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/mips/atlas/current/src/flash_lock_block.c b/ecos/packages/devs/flash/mips/atlas/current/src/flash_lock_block.c
new file mode 100644
index 0000000..5e2fe68
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/atlas/current/src/flash_lock_block.c
@@ -0,0 +1,87 @@
+//==========================================================================
+//
+// flash_lock_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, msalter
+// Date: 2000-12-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+#include <cyg/hal/hal_arch.h>
+
+
+int
+flash_lock_block(volatile unsigned long *block)
+ __attribute__ ((section (".2ram.flash_lock_block")));
+int
+flash_lock_block(volatile unsigned long *block)
+{
+ volatile unsigned long *ROM;
+ unsigned long stat;
+ int timeout = 5000000;
+
+ FLASH_WRITE_ENABLE();
+
+ block = (volatile unsigned long *)CYGARC_UNCACHED_ADDRESS((unsigned long)block);
+ ROM = (volatile unsigned long *)((unsigned long)block & FLASH_BASE_MASK);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Set lock bit
+ block[0] = FLASH_Set_Lock;
+ block[0] = FLASH_Set_Lock_Confirm; // Confirmation
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ FLASH_WRITE_DISABLE();
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/mips/atlas/current/src/flash_program_buf.c b/ecos/packages/devs/flash/mips/atlas/current/src/flash_program_buf.c
new file mode 100644
index 0000000..e17e473
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/atlas/current/src/flash_program_buf.c
@@ -0,0 +1,103 @@
+//==========================================================================
+//
+// flash_program_buf.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, msalter
+// Date: 2000-12-07
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+
+
+int
+flash_program_buf(volatile unsigned long *addr, unsigned long *data, int len)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+int
+flash_program_buf(volatile unsigned long *addr, unsigned long *data, int len)
+{
+ volatile unsigned long *ROM;
+ unsigned long stat = 0;
+ int timeout = 50000;
+
+ FLASH_WRITE_ENABLE();
+
+ addr = (volatile unsigned long *)CYGARC_UNCACHED_ADDRESS((unsigned long)addr);
+ ROM = (volatile unsigned long *)((unsigned long)addr & FLASH_BASE_MASK);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ while (len > 0) {
+ ROM[0] = FLASH_Program;
+ *addr = *data;
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) {
+ goto bad;
+ }
+ }
+ if (stat & 0x007E007E) {
+ break;
+ }
+ ROM[0] = FLASH_Reset;
+ if (*addr++ != *data++) {
+ stat = 0x99109910;
+ break;
+ }
+ len -= 4;
+ }
+
+ // Restore ROM to "normal" mode
+ bad:
+ ROM[0] = FLASH_Reset;
+
+ FLASH_WRITE_DISABLE();
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/mips/atlas/current/src/flash_query.c b/ecos/packages/devs/flash/mips/atlas/current/src/flash_query.c
new file mode 100644
index 0000000..3a2ad9f
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/atlas/current/src/flash_query.c
@@ -0,0 +1,81 @@
+//==========================================================================
+//
+// flash_query.c
+//
+// Flash programming - query device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-26
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+
+#define CNT 20*1000*10 // Approx 20ms
+
+int
+flash_query(unsigned char *data) __attribute__ ((section (".2ram.flash_query")));
+int
+flash_query(unsigned char *data)
+{
+ volatile unsigned long *ROM;
+ int i, cnt;
+
+ ROM = (volatile unsigned long *)0xBC000000; // base of system flash
+
+ ROM[0] = FLASH_Read_Query;
+ for (cnt = CNT; cnt > 0; cnt--) ;
+ for (i = 0; i < sizeof(struct FLASH_query); i++) {
+ *data++ = *ROM++;
+ }
+
+ ROM[0] = FLASH_Reset;
+
+ return 0;
+}
diff --git a/ecos/packages/devs/flash/mips/atlas/current/src/flash_unlock_block.c b/ecos/packages/devs/flash/mips/atlas/current/src/flash_unlock_block.c
new file mode 100644
index 0000000..39394e1
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/atlas/current/src/flash_unlock_block.c
@@ -0,0 +1,128 @@
+//==========================================================================
+//
+// flash_unlock_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-09-10
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "flash.h"
+
+#include <cyg/hal/hal_arch.h>
+
+
+//
+// The difficulty with this operation is that the hardware does not support
+// unlocking single blocks. However, the logical layer would like this to
+// be the case, so this routine emulates it. The hardware can clear all of
+// the locks in the device at once. This routine will use that approach and
+// then reset the regions which are known to be locked.
+//
+
+#define MAX_FLASH_BLOCKS 128
+
+int
+flash_unlock_block(volatile unsigned long *block, int block_size, int blocks)
+ __attribute__ ((section (".2ram.flash_unlock_block")));
+int
+flash_unlock_block(volatile unsigned long *block, int block_size, int blocks)
+{
+ volatile unsigned long *ROM, *bp;
+ unsigned long stat;
+ int timeout = 5000000;
+ unsigned char is_locked[MAX_FLASH_BLOCKS];
+ int i;
+
+ FLASH_WRITE_ENABLE();
+
+ block = (volatile unsigned long *)CYGARC_UNCACHED_ADDRESS((unsigned long)block);
+ ROM = (volatile unsigned long *)((unsigned long)block & FLASH_BASE_MASK);
+
+ // Clear any error conditions
+ ROM[0] = FLASH_Clear_Status;
+
+ // Get current block lock state. This needs to access each block on
+ // the device so currently locked blocks can be re-locked.
+ bp = ROM;
+ for (i = 0; i < (blocks/2); i++) {
+ if (bp == block) {
+ is_locked[i] = 0;
+ } else {
+ *bp = FLASH_Read_Query;
+ is_locked[i] = bp[2];
+ }
+ bp += block_size / sizeof(*bp);
+ }
+
+ // Clears all lock bits
+ block[0] = FLASH_Clear_Locks;
+ block[0] = FLASH_Clear_Locks_Confirm; // Confirmation
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+
+ // Restore the lock state
+ bp = ROM;
+ for (i = 0; i < (blocks/2); i++) {
+ if (is_locked[i]) {
+ *bp = FLASH_Set_Lock;
+ *bp = FLASH_Set_Lock_Confirm; // Confirmation
+ timeout = 5000000;
+ while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
+ if (--timeout == 0) break;
+ }
+ }
+ bp += block_size / sizeof(*bp);
+ }
+
+ // Restore ROM to "normal" mode
+ ROM[0] = FLASH_Reset;
+
+ FLASH_WRITE_DISABLE();
+
+ return stat;
+}
diff --git a/ecos/packages/devs/flash/mips/idt79s334a/current/ChangeLog b/ecos/packages/devs/flash/mips/idt79s334a/current/ChangeLog
new file mode 100644
index 0000000..52adab5
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/idt79s334a/current/ChangeLog
@@ -0,0 +1,34 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_mips_refidt334.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2003-02-13 Tim Michals <t.michals@attbi.com>
+2003-02-13 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * New package - support for MIPS IDT 79s334a board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/mips/idt79s334a/current/cdl/flash_mips_refidt334.cdl b/ecos/packages/devs/flash/mips/idt79s334a/current/cdl/flash_mips_refidt334.cdl
new file mode 100755
index 0000000..0bcf18a
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/idt79s334a/current/cdl/flash_mips_refidt334.cdl
@@ -0,0 +1,69 @@
+# ====================================================================
+#
+# flash_mips_refidt334.cdl
+#
+# FLASH memory - Hardware support for IDT board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): tmichals
+# Contributors: jskov
+# Date: 2003-02-13
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_MIPS_REFIDT334 {
+ display "IDT 79RC32334 reference platform flash support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_MIPS_IDT32334_REFIDT334
+
+ compile mips_idt334a_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "AMD AM29F040B driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29F040B
+}
+
+# flash_mips_refidt334.cdl
diff --git a/ecos/packages/devs/flash/mips/idt79s334a/current/src/mips_idt334a_flash.c b/ecos/packages/devs/flash/mips/idt79s334a/current/src/mips_idt334a_flash.c
new file mode 100755
index 0000000..3074699
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/idt79s334a/current/src/mips_idt334a_flash.c
@@ -0,0 +1,68 @@
+//==========================================================================
+//
+// mips_idt334a_flash.c
+//
+// Flash programming for AMD device on MIPS IDT 79s334a reference board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): tmichals
+// Contributors: jskov
+// Date: 2003-02-13
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_BASE (0xbfc00000u)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF mips_idt334a_flash.c
diff --git a/ecos/packages/devs/flash/mips/malta/current/ChangeLog b/ecos/packages/devs/flash/mips/malta/current/ChangeLog
new file mode 100644
index 0000000..2f0d79e
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/malta/current/ChangeLog
@@ -0,0 +1,49 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_malta.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2001-08-10 Jesper Skov <jskov@redhat.com>
+
+ * src/mips_malta_flash.c: Define width.
+
+ * cdl/flash_malta.cdl: Require 28F160S5 support.
+
+2001-03-23 Jesper Skov <jskov@redhat.com>
+
+ * src/mips_malta_flash.c (CYGNUM_FLASH_BASE): Changed again to
+ non-cached area at 0x1e000000 to avoid problem with board ID
+ word.
+
+2001-03-22 Jesper Skov <jskov@redhat.com>
+
+ * src/mips_malta_flash.c (CYGNUM_FLASH_BASE): Changed.
+
+2001-03-21 Jesper Skov <jskov@redhat.com>
+
+ * Use generic Intel driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/mips/malta/current/cdl/flash_malta.cdl b/ecos/packages/devs/flash/mips/malta/current/cdl/flash_malta.cdl
new file mode 100644
index 0000000..7fb3685
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/malta/current/cdl/flash_malta.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_malta.cdl
+#
+# FLASH memory - Hardware support on MIPS Malta
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors:
+# Date: 2001-03-21
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_MALTA {
+ display "MIPS Malta FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_MIPS_MALTA
+
+ compile mips_malta_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED {
+ display "Generic Intel FlashFile driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED
+
+ requires CYGHWR_DEVS_FLASH_INTEL_28F160S5
+}
diff --git a/ecos/packages/devs/flash/mips/malta/current/src/mips_malta_flash.c b/ecos/packages/devs/flash/mips/malta/current/src/mips_malta_flash.c
new file mode 100644
index 0000000..830a33b
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/malta/current/src/mips_malta_flash.c
@@ -0,0 +1,69 @@
+//==========================================================================
+//
+// mips_malta_flash.c
+//
+// Flash programming for Intel FlashFile devices on MIPS Malta board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-03-21
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+// We use the two Intel FlashFile 28F160 parts on the Malta board.
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0xbe000000u)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_28fxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF mips_malta_flash.c
diff --git a/ecos/packages/devs/flash/mips/ocelot/current/ChangeLog b/ecos/packages/devs/flash/mips/ocelot/current/ChangeLog
new file mode 100644
index 0000000..31e6ff1
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/ocelot/current/ChangeLog
@@ -0,0 +1,47 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_mips_ocelot.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2001-06-08 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_mips_ocelot.cdl: Require AM29F040B support.
+
+2001-05-28 Jesper Skov <jskov@redhat.com>
+
+ * src/mips_ocelot_flash.c: Specify data width now driver
+ autodetects part.
+
+2001-05-22 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_mips_ocelot.cdl: QED renamed to PMC-Sierra.
+ * include/devs_flash_mips_ocelot.inl: Same.
+
+2000-12-05 Jesper Skov <jskov@redhat.com>
+
+ * Created.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/mips/ocelot/current/cdl/flash_mips_ocelot.cdl b/ecos/packages/devs/flash/mips/ocelot/current/cdl/flash_mips_ocelot.cdl
new file mode 100644
index 0000000..0409ae0
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/ocelot/current/cdl/flash_mips_ocelot.cdl
@@ -0,0 +1,67 @@
+# ====================================================================
+#
+# flash_mips_ocelot.cdl
+#
+# FLASH memory - Hardware support for PMC-Sierra Ocelot board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2000-12-05
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_MIPS_OCELOT {
+ display "Flash memory support for PMC-Sierra Ocelot board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_MIPS_RM7000_OCELOT
+
+ compile mips_ocelot_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "AMD AM29F040B driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29F040B
+}
diff --git a/ecos/packages/devs/flash/mips/ocelot/current/src/mips_ocelot_flash.c b/ecos/packages/devs/flash/mips/ocelot/current/src/mips_ocelot_flash.c
new file mode 100644
index 0000000..737c998
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/ocelot/current/src/mips_ocelot_flash.c
@@ -0,0 +1,68 @@
+//==========================================================================
+//
+// mips_ocelot_flash.c
+//
+// Flash programming for AMD device on MIPS Ocelot board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-05-22
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_BASE (0xbfc00000u)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF mips_ocelot_flash.c
diff --git a/ecos/packages/devs/flash/mips/vrc437x/current/ChangeLog b/ecos/packages/devs/flash/mips/vrc437x/current/ChangeLog
new file mode 100644
index 0000000..7ed78b1
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/vrc437x/current/ChangeLog
@@ -0,0 +1,35 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_mips_vrc437x.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2001-09-10 Nick Garnett <nickg@redhat.com>
+
+ * cdl/flash_mips_vrc437x.cdl:
+ * src/mips_vrc437x_flash.c:
+ Created by copying the ocelot package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/mips/vrc437x/current/cdl/flash_mips_vrc437x.cdl b/ecos/packages/devs/flash/mips/vrc437x/current/cdl/flash_mips_vrc437x.cdl
new file mode 100644
index 0000000..b37410a
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/vrc437x/current/cdl/flash_mips_vrc437x.cdl
@@ -0,0 +1,67 @@
+# ====================================================================
+#
+# flash_mips_vrc437x.cdl
+#
+# FLASH memory - Hardware support for VRC437X board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov, nickg
+# Date: 2001-19-10
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_MIPS_VRC437X {
+ display "Flash memory support for VRC437X board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_MIPS_VR4300_VRC437X
+
+ compile mips_vrc437x_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "AMD AM29F040B driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29F040B
+}
diff --git a/ecos/packages/devs/flash/mips/vrc437x/current/src/mips_vrc437x_flash.c b/ecos/packages/devs/flash/mips/vrc437x/current/src/mips_vrc437x_flash.c
new file mode 100644
index 0000000..b89a57f
--- /dev/null
+++ b/ecos/packages/devs/flash/mips/vrc437x/current/src/mips_vrc437x_flash.c
@@ -0,0 +1,68 @@
+//==========================================================================
+//
+// mips_vrc437x_flash.c
+//
+// Flash programming for AMD device on NEC VRC437X board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov, nickg
+// Date: 2001-09-10
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_BASE (0xbfc00000u)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF mips_vrc437x_flash.c
diff --git a/ecos/packages/devs/flash/mn10300/asb2303/current/ChangeLog b/ecos/packages/devs/flash/mn10300/asb2303/current/ChangeLog
new file mode 100644
index 0000000..54b5047
--- /dev/null
+++ b/ecos/packages/devs/flash/mn10300/asb2303/current/ChangeLog
@@ -0,0 +1,38 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_asb2303.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2002-12-05 Mark Salter <msalter@redhat.com>
+
+ * src/mn10300_asb2303_flash.c (CYGNUM_FLASH_16AS8): Define
+ as 1 due to recent change in generic driver.
+
+2002-12-04 Mark Salter <msalter@redhat.com>
+
+ * cdl/flash_asb2303.cdl: Support AM29DL322D.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/mn10300/asb2303/current/cdl/flash_asb2303.cdl b/ecos/packages/devs/flash/mn10300/asb2303/current/cdl/flash_asb2303.cdl
new file mode 100644
index 0000000..4ace23a
--- /dev/null
+++ b/ecos/packages/devs/flash/mn10300/asb2303/current/cdl/flash_asb2303.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_asb2303.cdl
+#
+# FLASH memory - Hardware support on Matsushita ASB2303
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data: dhowells
+# Contributors:
+# Date: 2002-11-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_MN10300_ASB2303 {
+ display "Matsushita MN10300 ASB2303 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_MN10300_AM33_ASB
+
+ compile mn10300_asb2303_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29XXXXX driver required"
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_MN10300_ASB2303_BANK {
+ display "Which flash bank to program"
+ flavor data
+ legal_values { "BootPROM" "SysFlash" }
+ default_value { "SysFlash" }
+ description "
+ This option controls which bank of flash will be programmable."
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL322D
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL324D
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV800
+}
diff --git a/ecos/packages/devs/flash/mn10300/asb2303/current/src/mn10300_asb2303_flash.c b/ecos/packages/devs/flash/mn10300/asb2303/current/src/mn10300_asb2303_flash.c
new file mode 100644
index 0000000..e997dd4
--- /dev/null
+++ b/ecos/packages/devs/flash/mn10300/asb2303/current/src/mn10300_asb2303_flash.c
@@ -0,0 +1,87 @@
+//==========================================================================
+//
+// mn10300_asb2303_flash.c
+//
+// Flash programming for Matsushita ASB2303
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: msalter
+// Date: 2002-11-08
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+#include <pkgconf/devs_flash_mn10300_asb2303.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#if defined(CYGHWR_DEVS_FLASH_MN10300_ASB2303_BANK_SysFlash)
+// We use a four chip parallel AM29DL324BE module plugged into the System Flash socket
+// on the ASB2303 board.
+#define CYGNUM_FLASH_INTERLEAVE (4)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_16AS8 (1)
+#define CYGNUM_FLASH_BASE (0x84000000u) /* cached flash chip address */
+
+#elif defined(CYGHWR_DEVS_FLASH_MN10300_ASB2303_BANK_BootPROM)
+// We have a single AM29LV800TA soldered onto the board as the boot PROM
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x80000000u) /* cached flash chip address */
+
+#else
+#error unknown flash bank selected
+#endif
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+// Offset of uncached shadow region
+#define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_)+0x20000000))
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF mn10300_asb2303_flash.c
diff --git a/ecos/packages/devs/flash/mn10300/asb2305/current/ChangeLog b/ecos/packages/devs/flash/mn10300/asb2305/current/ChangeLog
new file mode 100644
index 0000000..3ab4f1f
--- /dev/null
+++ b/ecos/packages/devs/flash/mn10300/asb2305/current/ChangeLog
@@ -0,0 +1,43 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_asb2305.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2002-12-05 Mark Salter <msalter@redhat.com>
+
+ * src/mn10300_asb2305_flash.c (CYGNUM_FLASH_16AS8): Define
+ as 1 due to recent change in generic driver.
+
+2002-12-04 Mark Salter <msalter@redhat.com>
+
+ * cdl/flash_asb2305.cdl: Support AM29DL322D.
+
+2001-06-08 Jesper Skov <jskov@redhat.com>
+ From dhowells@redhat.com
+ * src/mn10300_asb2305_flash.c: New package/file(s).
+ * cdl/flash_asb2305.cdl: Same.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/mn10300/asb2305/current/cdl/flash_asb2305.cdl b/ecos/packages/devs/flash/mn10300/asb2305/current/cdl/flash_asb2305.cdl
new file mode 100644
index 0000000..96cf742
--- /dev/null
+++ b/ecos/packages/devs/flash/mn10300/asb2305/current/cdl/flash_asb2305.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_asb2305.cdl
+#
+# FLASH memory - Hardware support on Matsushita ASB2305
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): dhowells
+# Original data: dhowells
+# Contributors:
+# Date: 2001-05-15
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_MN10300_ASB2305 {
+ display "Matsushita MN10300 ASB2305 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_MN10300_AM33_ASB2305
+
+ compile mn10300_asb2305_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29XXXXX driver required"
+ }
+
+ cdl_option CYGHWR_DEVS_FLASH_MN10300_ASB2305_BANK {
+ display "Which flash bank to program"
+ flavor data
+ legal_values { "BootPROM" "SysFlash" }
+ default_value { "SysFlash" }
+ description "
+ This option controls which bank of flash will be programmable."
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL322D
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL324D
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV800
+}
diff --git a/ecos/packages/devs/flash/mn10300/asb2305/current/src/mn10300_asb2305_flash.c b/ecos/packages/devs/flash/mn10300/asb2305/current/src/mn10300_asb2305_flash.c
new file mode 100644
index 0000000..a1aa32b
--- /dev/null
+++ b/ecos/packages/devs/flash/mn10300/asb2305/current/src/mn10300_asb2305_flash.c
@@ -0,0 +1,87 @@
+//==========================================================================
+//
+// mn10300_asb2305_flash.c
+//
+// Flash programming for Matsushita ASB2305
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dhowells
+// Contributors: dhowells
+// Date: 2001-06-01
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+#include <pkgconf/devs_flash_mn10300_asb2305.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#if defined(CYGHWR_DEVS_FLASH_MN10300_ASB2305_BANK_SysFlash)
+// We use a four chip parallel AM29DL324BE module plugged into the System Flash socket
+// on the ASB2305 board.
+#define CYGNUM_FLASH_INTERLEAVE (4)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_16AS8 (1)
+#define CYGNUM_FLASH_BASE (0x84000000u) /* cached flash chip address */
+
+#elif defined(CYGHWR_DEVS_FLASH_MN10300_ASB2305_BANK_BootPROM)
+// We have a single AM29LV800TA soldered onto the board as the boot PROM
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x80000000u) /* cached flash chip address */
+
+#else
+#error unknown flash bank selected
+#endif
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+// Offset of uncached shadow region
+#define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_)+0x20000000))
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF mn10300_asb2305_flash.c
diff --git a/ecos/packages/devs/flash/mn10300/stb/current/ChangeLog b/ecos/packages/devs/flash/mn10300/stb/current/ChangeLog
new file mode 100644
index 0000000..415c7cc
--- /dev/null
+++ b/ecos/packages/devs/flash/mn10300/stb/current/ChangeLog
@@ -0,0 +1,43 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_stb.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2002-12-05 Mark Salter <msalter@redhat.com>
+
+ * src/mn10300_stb_flash.c (CYGNUM_FLASH_16AS8): Define
+ as 1 due to recent change in generic driver.
+
+2001-08-03 David Howells <dhowells@redhat.com>
+
+ * src/mn10300_stb_flash.c: updated to latest AMD flash interface.
+
+2001-06-08 Jesper Skov <jskov@redhat.com>
+ From dhowells@redhat.com
+ * cdl/flash_stb.cdl: New package/file(s).
+ * src/mn10300_stb_flash.c: Same.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/mn10300/stb/current/cdl/flash_stb.cdl b/ecos/packages/devs/flash/mn10300/stb/current/cdl/flash_stb.cdl
new file mode 100644
index 0000000..1cf7675
--- /dev/null
+++ b/ecos/packages/devs/flash/mn10300/stb/current/cdl/flash_stb.cdl
@@ -0,0 +1,69 @@
+# ====================================================================
+#
+# flash_stb.cdl
+#
+# FLASH memory - Hardware support on Matsushita MN10300 STB
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): dhowells
+# Original data: dhowells
+# Contributors:
+# Date: 2001-05-15
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_MN10300_STB {
+ display "Matsushita MN10300 STB FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_MN10300_AM33_STB
+
+ compile mn10300_stb_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29XXXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL324D
+ requires CYGHWR_DEVS_FLASH_AMD_AM29F800
+}
diff --git a/ecos/packages/devs/flash/mn10300/stb/current/src/mn10300_stb_flash.c b/ecos/packages/devs/flash/mn10300/stb/current/src/mn10300_stb_flash.c
new file mode 100644
index 0000000..2b9aad7
--- /dev/null
+++ b/ecos/packages/devs/flash/mn10300/stb/current/src/mn10300_stb_flash.c
@@ -0,0 +1,71 @@
+//==========================================================================
+//
+// mn10300_stb_flash.c
+//
+// Flash programming for Matsushita MN10300 STB
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dhowells
+// Contributors: dhowells
+// Date: 2001-05-15
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+// We use a four chip parallel AM29xxxxx module plugged into the SRAM3 socket
+// on the STB board.
+#define CYGNUM_FLASH_INTERLEAVE (4)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_16AS8 (1)
+#define CYGNUM_FLASH_BASE (0x82C00000u) /* uncached shadow region */
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF mn10300_stb_flash.c
diff --git a/ecos/packages/devs/flash/openrisc/orp/current/ChangeLog b/ecos/packages/devs/flash/openrisc/orp/current/ChangeLog
new file mode 100644
index 0000000..5892459
--- /dev/null
+++ b/ecos/packages/devs/flash/openrisc/orp/current/ChangeLog
@@ -0,0 +1,35 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_openrisc_orp.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2003-03-06 Scott Furman <sfurman@rosum.com>
+
+ * src/openrisc_orp_flash.c, cdl/flash_openrisc_orp.cdl
+ New package: Flash programming for AMD AM29LVxxxxx devices
+ used with OpenRISC Reference Platform (ORP).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/openrisc/orp/current/cdl/flash_openrisc_orp.cdl b/ecos/packages/devs/flash/openrisc/orp/current/cdl/flash_openrisc_orp.cdl
new file mode 100644
index 0000000..3b48b56
--- /dev/null
+++ b/ecos/packages/devs/flash/openrisc/orp/current/cdl/flash_openrisc_orp.cdl
@@ -0,0 +1,69 @@
+# ====================================================================
+#
+# flash_openrisc_orp.cdl
+#
+# FLASH memory - Hardware support for OpenRISC Reference Platform
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): sfurman
+# Contributors:
+# Date: 2003-04-24
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_OPENRISC_ORP {
+ display "Flash memory support for OpenRISC ORP"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_OPENRISC_ORP
+
+ compile openrisc_orp_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "AMD AM29LV160 driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV160
+}
+
+# EOF flash_openrisc_orp.cdl
diff --git a/ecos/packages/devs/flash/openrisc/orp/current/src/openrisc_orp_flash.c b/ecos/packages/devs/flash/openrisc/orp/current/src/openrisc_orp_flash.c
new file mode 100644
index 0000000..68f9fad
--- /dev/null
+++ b/ecos/packages/devs/flash/openrisc/orp/current/src/openrisc_orp_flash.c
@@ -0,0 +1,69 @@
+//==========================================================================
+//
+// openrisc_orp_flash.c
+//
+// Flash programming for AMD AM29LVxxxxx devices connected to OpenRISC
+// Reference Platform (ORP).
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): sfurman
+// Contributors:
+// Date: 2003-04-24
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0xF0000000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF openrisc_orp_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/adder/current/ChangeLog b/ecos/packages/devs/flash/powerpc/adder/current/ChangeLog
new file mode 100644
index 0000000..dc03374
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/adder/current/ChangeLog
@@ -0,0 +1,35 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_adder.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2002-11-25 Gary Thomas <gthomas@ecoscentric.com>
+
+ * src/adder_flash.c:
+ * cdl/flash_adder.cdl: New package - platform specific support
+ for Analogue & Micro Adder (PowerPC 850) boards.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/adder/current/cdl/flash_adder.cdl b/ecos/packages/devs/flash/powerpc/adder/current/cdl/flash_adder.cdl
new file mode 100644
index 0000000..c297fc4
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/adder/current/cdl/flash_adder.cdl
@@ -0,0 +1,70 @@
+# ====================================================================
+#
+# flash_adder.cdl
+#
+# FLASH memory - Hardware support on A&M PowerPC/8xx Adder
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2001-01-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_POWERPC_ADDER {
+ display "A&M Adder (PowerPC/860) FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_ADDER
+
+ compile adder_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV320D
+
+}
+
diff --git a/ecos/packages/devs/flash/powerpc/adder/current/src/adder_flash.c b/ecos/packages/devs/flash/powerpc/adder/current/src/adder_flash.c
new file mode 100644
index 0000000..15fdc34
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/adder/current/src/adder_flash.c
@@ -0,0 +1,72 @@
+//==========================================================================
+//
+// adder_flash.c
+//
+// Flash programming support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-10-20
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0xFE000000)
+#define CYGNUM_FLASH_16AS8 (0)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT // This feature fails :-(
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF adder_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/cme555/current/ChangeLog b/ecos/packages/devs/flash/powerpc/cme555/current/ChangeLog
new file mode 100644
index 0000000..506419b
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/cme555/current/ChangeLog
@@ -0,0 +1,33 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_cme555.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2002-04-24 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/cme555/current/cdl/flash_cme555.cdl b/ecos/packages/devs/flash/powerpc/cme555/current/cdl/flash_cme555.cdl
new file mode 100644
index 0000000..40ec593
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/cme555/current/cdl/flash_cme555.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_mbx.cdl
+#
+# FLASH memory - Hardware support on Axiom's CME555
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Bob Koninckx
+# Original data: Bob Koninckx
+# Contributors:
+# Date: 2001-12-18
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_CME555 {
+ display "CME555 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_CME555
+
+ compile powerpc_cme555_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29F040 driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV200
+}
diff --git a/ecos/packages/devs/flash/powerpc/cme555/current/src/powerpc_cme555_flash.c b/ecos/packages/devs/flash/powerpc/cme555/current/src/powerpc_cme555_flash.c
new file mode 100644
index 0000000..6e4d243
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/cme555/current/src/powerpc_cme555_flash.c
@@ -0,0 +1,68 @@
+//==========================================================================
+//
+// powerpc_cme555_flash.c
+//
+// Flash programming for Atmel device on Axiom's CME555 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bob Koninckx
+// Contributors: Bob Koninckx
+// Date: 2001-12-18
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x00800000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF powerpc_mbx_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/csb281/current/ChangeLog b/ecos/packages/devs/flash/powerpc/csb281/current/ChangeLog
new file mode 100644
index 0000000..3177301
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/csb281/current/ChangeLog
@@ -0,0 +1,29 @@
+2002-12-24 Gary Thomas <gary@mlbassoc.com>
+
+ * include/csb281_strataflash.inl:
+ * cdl/flash_csb281.cdl: New package - FLASH support for
+ Cogent CSB281 (PowerPC 8245) board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/csb281/current/cdl/flash_csb281.cdl b/ecos/packages/devs/flash/powerpc/csb281/current/cdl/flash_csb281.cdl
new file mode 100644
index 0000000..825a1cf
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/csb281/current/cdl/flash_csb281.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_csb281.cdl
+#
+# FLASH memory - Hardware support on Cogent CSB281 (PowerPC 8245)
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2002-07-23
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_CSB281 {
+ display "Cogent CSB281 (PowerPC 8245) FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_CSB281
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/csb281_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_csb281.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
+
diff --git a/ecos/packages/devs/flash/powerpc/csb281/current/include/csb281_strataflash.inl b/ecos/packages/devs/flash/powerpc/csb281/current/include/csb281_strataflash.inl
new file mode 100644
index 0000000..6d12c55
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/csb281/current/include/csb281_strataflash.inl
@@ -0,0 +1,66 @@
+#ifndef CYGONCE_DEVS_FLASH_CSB281_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_CSB281_STRATAFLASH_INL
+//==========================================================================
+//
+// csb281_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, hmt
+// Contributors: gthomas
+// Date: 2002-07-23
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// The csb281 has two 16-bit devices.
+// StrataFlash 28F128.
+
+#define CYGNUM_FLASH_DEVICES (2)
+#define CYGNUM_FLASH_BASE_MASK (0xFE000000u) // 32Mb
+
+#define CYGNUM_FLASH_BASE (0x70000000u)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_CSB281_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF csb281_strataflash.inl
diff --git a/ecos/packages/devs/flash/powerpc/ec555/current/ChangeLog b/ecos/packages/devs/flash/powerpc/ec555/current/ChangeLog
new file mode 100644
index 0000000..bde0f79
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/ec555/current/ChangeLog
@@ -0,0 +1,38 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_ec555.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2004-04-08 Bob Koninckx <bob.koninckx@o-3s.com>
+
+ * src/powerpc_ec555_flash.c: Adapted flash start address to new
+ memory map. Up to 16 MB of flash is now supported.
+
+2002-04-24 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/ec555/current/cdl/flash_ec555.cdl b/ecos/packages/devs/flash/powerpc/ec555/current/cdl/flash_ec555.cdl
new file mode 100644
index 0000000..d0c864e
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/ec555/current/cdl/flash_ec555.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_ec555.cdl
+#
+# FLASH memory - Hardware support on ec555 board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Bob Koninckx
+# Original data: Bob Koninckx
+# Contributors:
+# Date: 2002-01-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_EC555 {
+ display "ec555 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_EC555
+
+ compile powerpc_ec555_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29F040 driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV800
+}
diff --git a/ecos/packages/devs/flash/powerpc/ec555/current/src/powerpc_ec555_flash.c b/ecos/packages/devs/flash/powerpc/ec555/current/src/powerpc_ec555_flash.c
new file mode 100644
index 0000000..a976b4b
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/ec555/current/src/powerpc_ec555_flash.c
@@ -0,0 +1,68 @@
+//==========================================================================
+//
+// powerpc_ec555_flash.c
+//
+// Flash programming on ec555 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bob Koninckx
+// Contributors: Bob Koninckx
+// Date: 2002-01-01
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x02000000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF powerpc_ec555_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/mbx/current/ChangeLog b/ecos/packages/devs/flash/powerpc/mbx/current/ChangeLog
new file mode 100644
index 0000000..d0c70fe
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/mbx/current/ChangeLog
@@ -0,0 +1,63 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_mbx.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2001-06-08 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_mbx.cdl: Require handling of the AM29F040.
+
+2001-05-28 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc_mbx_flash.c: Specify data width now driver
+ autodetects part.
+
+2001-02-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_mbx.cdl: Use new generic AMD driver.
+ * src/flash.h: [deleted]
+ * src/flash_erase_block.c: [deleted]
+ * src/flash_program_buf.c: [deleted]
+ * src/flash_query.c: [deleted]
+ * src/mbx_flash.c: [deleted]
+ * src/powerpc_mbx_flash.c: [added]
+
+2000-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/mbx_flash.c (flash_code_overlaps): Define stext/etext
+ as array types so no assumptions can be made by the compiler about
+ location.
+
+2000-10-20 Gary Thomas <gthomas@redhat.com>
+
+ * src/mbx_flash.c:
+ * src/flash_query.c:
+ * src/flash_program_buf.c:
+ * src/flash_erase_block.c:
+ * src/flash.h:
+ * cdl/flash_mbx.cdl: New package/file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/mbx/current/cdl/flash_mbx.cdl b/ecos/packages/devs/flash/powerpc/mbx/current/cdl/flash_mbx.cdl
new file mode 100644
index 0000000..6b646d3
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/mbx/current/cdl/flash_mbx.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_mbx.cdl
+#
+# FLASH memory - Hardware support on Motorola PowerPC/860
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_MBX {
+ display "Motorola PowerPC/860 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_MBX
+
+ compile powerpc_mbx_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29F040 driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29F040B
+}
diff --git a/ecos/packages/devs/flash/powerpc/mbx/current/src/powerpc_mbx_flash.c b/ecos/packages/devs/flash/powerpc/mbx/current/src/powerpc_mbx_flash.c
new file mode 100644
index 0000000..3ca30e3
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/mbx/current/src/powerpc_mbx_flash.c
@@ -0,0 +1,68 @@
+//==========================================================================
+//
+// powerpc_mbx_flash.c
+//
+// Flash programming for Atmel device on POWERPC MBX board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-02-22
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_BASE (0xfe000000u)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF powerpc_mbx_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/moab/current/ChangeLog b/ecos/packages/devs/flash/powerpc/moab/current/ChangeLog
new file mode 100644
index 0000000..e26b685
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/moab/current/ChangeLog
@@ -0,0 +1,23 @@
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/moab/current/cdl/flash_moab.cdl b/ecos/packages/devs/flash/powerpc/moab/current/cdl/flash_moab.cdl
new file mode 100644
index 0000000..59b7e86
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/moab/current/cdl/flash_moab.cdl
@@ -0,0 +1,99 @@
+# ====================================================================
+#
+# flash_moab.cdl
+#
+# FLASH memory - Hardware support for boot FLASH on TAMS MOAB
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov, tdrury, nickg
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_POWERPC_MOAB {
+ display "TAMS MOAB FLASH memory support"
+ description "FLASH memory device(s) support for MOAB board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_MOAB
+ requires { CYGSEM_DEVS_FLASH_POWERPC_MOAB_BOOT || CYGSEM_DEVS_FLASH_POWERPC_MOAB_MAIN }
+
+ cdl_component CYGSEM_DEVS_FLASH_POWERPC_MOAB_BOOT {
+ display "Boot FLASH support"
+ default_value 0
+ no_define
+ description "
+ This option enables the drivers for the bootstrap FLASH
+ device. Note: this device is not suitable for the RedBoot
+ Flash Image System (FIS)."
+
+ compile moab_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED {
+ display "Generic Atmel AM49XXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_ATMEL_AT49XXXX_REQUIRED
+ }
+
+ cdl_component CYGSEM_DEVS_FLASH_POWERPC_MOAB_MAIN {
+ display "Main (NAND) FLASH support"
+ default_value 1
+ no_define
+ description "
+ This option enables the drivers for the main FLASH
+ device. Note: this device can be used for the RedBoot
+ Flash Image System (FIS)."
+
+ compile moab_nand_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_TOSHIBA_TC58XXX_REQUIRED {
+ display "Generic Toshiba TC58XXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_TOSHIBA_TC58XXX_REQUIRED
+ }
+}
diff --git a/ecos/packages/devs/flash/powerpc/moab/current/src/moab_flash.c b/ecos/packages/devs/flash/powerpc/moab/current/src/moab_flash.c
new file mode 100644
index 0000000..f155cca
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/moab/current/src/moab_flash.c
@@ -0,0 +1,65 @@
+//==========================================================================
+//
+// moab_flash.c
+//
+// Flash programming for Atmel boot device on MOAB board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors:
+// Date: 2003-09-19
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// There's a single AT49LV040 on the MOAB board.
+
+#define CYGPKG_DEVS_FLASH_ATMEL_AT49LV040
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0xFFF80000u)
+
+#include <cyg/io/flash_at49xxxx.inl>
+
+
+// ------------------------------------------------------------------------
+// EOF moab_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/moab/current/src/moab_nand_flash.c b/ecos/packages/devs/flash/powerpc/moab/current/src/moab_nand_flash.c
new file mode 100644
index 0000000..cd11518
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/moab/current/src/moab_nand_flash.c
@@ -0,0 +1,146 @@
+//==========================================================================
+//
+// moab_nand_flash.c
+//
+// Flash programming for Toshiba NAND FLASH device on MOAB board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Gary Thomas <gary@mlbassoc.com>
+// Contributors:
+// Date: 2003-09-02
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
+#include <cyg/hal/ppc_regs.h> // Platform registers
+#include <cyg/hal/hal_io.h> // I/O macros
+#include <cyg/hal/hal_if.h> // Virtual vector interfaces
+
+// There's a single TC58256 or TC58DVG02 on the MOAB board.
+
+#define CYGHWR_DEVS_FLASH_TOSHIBA_TC58256
+#define CYGHWR_DEVS_FLASH_TOSHIBA_TC58DVG02
+#define CYGNUM_FLASH_BLANK (1)
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (_MOAB_NAND)
+
+#define CYGHWR_FLASH_TC58XXX_CE moab_CE
+#define CYGHWR_FLASH_TC58XXX_CLE moab_CLE
+#define CYGHWR_FLASH_TC58XXX_ALE moab_ALE
+#define CYGHWR_FLASH_TC58XXX_RDY moab_RDY
+
+//
+// Select the NAND device - this will be held until the
+// entire command/data sequence has completed (which is
+// necessary for read sequential)
+//
+static void __inline__
+moab_CE(int state)
+{
+ cyg_uint32 gpio_or;
+ HAL_READ_UINT32(GPIO_OR, gpio_or);
+ if (state) {
+ // Assert CE
+ gpio_or &= ~_MOAB_CE;
+ } else {
+ // De-assert CE
+ gpio_or |= _MOAB_CE;
+ }
+ HAL_WRITE_UINT32(GPIO_OR, gpio_or);
+}
+
+//
+// Prepare to send a command byte to the NAND interface
+//
+static void __inline__
+moab_CLE(int state)
+{
+ cyg_uint32 gpio_or;
+ HAL_READ_UINT32(GPIO_OR, gpio_or);
+ if (state) {
+ // Assert CLE
+ gpio_or |= _MOAB_CLE;
+ } else {
+ // De-assert CLE
+ gpio_or &= ~_MOAB_CLE;
+ }
+ HAL_WRITE_UINT32(GPIO_OR, gpio_or);
+}
+
+//
+// Prepare to send address byte(s) to the NAND interface
+//
+static void __inline__
+moab_ALE(int state)
+{
+ cyg_uint32 gpio_or;
+
+ HAL_READ_UINT32(GPIO_OR, gpio_or);
+ if (state) {
+ // Assert ALE
+ gpio_or |= _MOAB_ALE;
+ } else {
+ // De-assert ALE
+ gpio_or &= ~_MOAB_ALE;
+ }
+ HAL_WRITE_UINT32(GPIO_OR, gpio_or);
+}
+
+//
+// Wait until the NAND device is ready (after a long operation)
+//
+static bool __inline__
+moab_RDY(void)
+{
+ cyg_uint32 gpio_ir;
+
+ HAL_READ_UINT32(GPIO_IR, gpio_ir);
+ return ((gpio_ir & _MOAB_RDY) != 0);
+}
+
+#include <cyg/io/flash_tc58xxx.inl>
+
+
+// ------------------------------------------------------------------------
+// EOF moab_nand_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/pati/current/ChangeLog b/ecos/packages/devs/flash/powerpc/pati/current/ChangeLog
new file mode 100644
index 0000000..0315577
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/pati/current/ChangeLog
@@ -0,0 +1,35 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_pati.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2008-06-18 Steven Clugston <steven.clugston@ncl.ac.uk>
+
+ * src/powerpc_pati_flash.c:
+ * cdl/flash_pati.cdl: New package - FLASH support on MPL PATI
+ (MPC555) system.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/pati/current/cdl/flash_pati.cdl b/ecos/packages/devs/flash/powerpc/pati/current/cdl/flash_pati.cdl
new file mode 100644
index 0000000..c1da53b
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/pati/current/cdl/flash_pati.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_pati.cdl
+#
+# FLASH memory - Hardware support on MPC555 MPL PATI Board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Steven Clugston
+# Original data: pfine, gthomas
+# Contributors:
+# Date: 2008-05-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_PATI {
+ display "MPL PATI flash memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_PATI
+
+ compile powerpc_pati_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED {
+ display "Generic INTEL 28FXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_INTEL_28F320C3
+}
diff --git a/ecos/packages/devs/flash/powerpc/pati/current/src/powerpc_pati_flash.c b/ecos/packages/devs/flash/powerpc/pati/current/src/powerpc_pati_flash.c
new file mode 100644
index 0000000..d57e628
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/pati/current/src/powerpc_pati_flash.c
@@ -0,0 +1,94 @@
+//==========================================================================
+//
+// powerpc_pati_flash.c
+//
+// Flash programming for INTEL device on PowerPC MPC555 MPL PATI
+// board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Steven Clugston
+// Original: jskov
+// Contributors:
+// Date: 2008-06-18
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/plf_misc.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+// One 28F320C3T part used on the board
+/// 32Mbit top boot block
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (CYGMEM_REGION_eflash)
+
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+// The programming voltage is switched on/off by setting a register bit in
+// the on board EPLD.
+#define CYGHWR_FLASH_WRITE_ENABLE() \
+{cyg_uint32 epld_misc; \
+HAL_READ_UINT32(CYGPLF_REG_PLD_MISC_CONFIG, epld_misc); \
+epld_misc |= CYGPLF_REG_PLD_MISC_EXT_VPP; \
+HAL_WRITE_UINT32(CYGPLF_REG_PLD_MISC_CONFIG, epld_misc);}\
+
+#define CYGHWR_FLASH_WRITE_DISABLE() \
+{cyg_uint32 epld_misc; \
+HAL_READ_UINT32(CYGPLF_REG_PLD_MISC_CONFIG, epld_misc); \
+epld_misc &= ~(CYGPLF_REG_PLD_MISC_EXT_VPP); \
+HAL_WRITE_UINT32(CYGPLF_REG_PLD_MISC_CONFIG, epld_misc);}\
+
+// Force a reset of the flash to keep driver happy
+# define CYGHWR_FLASH_28FXXX_PLF_INIT() \
+HAL_WRITE_UINT16(CYGNUM_FLASH_BASE,0xFF); \
+HAL_DELAY_US(10); \
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_28fxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF powerpc_pati_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/rattler/current/ChangeLog b/ecos/packages/devs/flash/powerpc/rattler/current/ChangeLog
new file mode 100644
index 0000000..8ad6d3d
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/rattler/current/ChangeLog
@@ -0,0 +1,35 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_rattler.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2003-08-19 Gary Thomas <gary@mlbassoc.com>
+
+ * src/rattler_flash.c:
+ * cdl/flash_rattler.cdl: New file(s) - platform support for
+ FLASH on Analogue & Micro Rattler (MPC8250) boards.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/rattler/current/cdl/flash_rattler.cdl b/ecos/packages/devs/flash/powerpc/rattler/current/cdl/flash_rattler.cdl
new file mode 100644
index 0000000..d6affd8
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/rattler/current/cdl/flash_rattler.cdl
@@ -0,0 +1,71 @@
+# ====================================================================
+#
+# flash_rattler.cdl
+#
+# FLASH memory - Hardware support on A&M Rattler (MPC8250)
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2003-08-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_POWERPC_RATTLER {
+ display "A&M Rattler (MPC8250) FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_RATTLER
+
+ compile rattler_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV320D
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV640
+
+}
+
diff --git a/ecos/packages/devs/flash/powerpc/rattler/current/src/rattler_flash.c b/ecos/packages/devs/flash/powerpc/rattler/current/src/rattler_flash.c
new file mode 100644
index 0000000..a24b929
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/rattler/current/src/rattler_flash.c
@@ -0,0 +1,72 @@
+//==========================================================================
+//
+// rattler_flash.c
+//
+// Flash programming support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2003-08-19
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0xFE000000)
+#define CYGNUM_FLASH_16AS8 (0)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT // This feature fails :-(
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF rattler_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/ts1000/current/ChangeLog b/ecos/packages/devs/flash/powerpc/ts1000/current/ChangeLog
new file mode 100644
index 0000000..8f268ab
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/ts1000/current/ChangeLog
@@ -0,0 +1,42 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_ts1000.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2002-10-18 Gary Thomas <gthomas@ecoscentric.com>
+
+ * cdl/flash_ts1000.cdl: Package renamed for consistency.
+
+2002-09-19 Gary Thomas <gary@mlbassoc.com>
+
+ * cdl/flash_ts1000.cdl: Part is AM29DL640D (not LV640D).
+
+2002-09-03 Gary Thomas <gary@mlbassoc.com>
+
+ * src/ts1000_flash.c:
+ * cdl/flash_ts1000.cdl: New package - platform specifics.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/ts1000/current/cdl/flash_ts1000.cdl b/ecos/packages/devs/flash/powerpc/ts1000/current/cdl/flash_ts1000.cdl
new file mode 100644
index 0000000..ec6bb98
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/ts1000/current/cdl/flash_ts1000.cdl
@@ -0,0 +1,70 @@
+# ====================================================================
+#
+# flash_ts1000.cdl
+#
+# FLASH memory - Hardware support on Allied Telesyn TS1000 (PPC855)
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2002-09-03
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_POWERPC_TS1000 {
+ display "Allied Telesyn TS1000 (PPC855) FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_TS1000
+
+ compile ts1000_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29DL640D
+
+}
+
diff --git a/ecos/packages/devs/flash/powerpc/ts1000/current/src/ts1000_flash.c b/ecos/packages/devs/flash/powerpc/ts1000/current/src/ts1000_flash.c
new file mode 100644
index 0000000..fb9d700
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/ts1000/current/src/ts1000_flash.c
@@ -0,0 +1,71 @@
+//==========================================================================
+//
+// ts1000_flash.c
+//
+// Flash programming support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-10-20
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0xFE000000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT // This feature fails :-(
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF ts1000_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/ts6/current/ChangeLog b/ecos/packages/devs/flash/powerpc/ts6/current/ChangeLog
new file mode 100644
index 0000000..48a7457
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/ts6/current/ChangeLog
@@ -0,0 +1,36 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_ts6.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2002-12-12 Gary Thomas <gthomas@ecoscentric.com>
+2002-12-12 Patrick Doyle <wpd@delcomsys.com>
+
+ * src/powerpc_ts6_flash.c:
+ * cdl/flash_ts6.cdl: New package - FLASH support on Delphi
+ Communications TS6 board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/ts6/current/cdl/flash_ts6.cdl b/ecos/packages/devs/flash/powerpc/ts6/current/cdl/flash_ts6.cdl
new file mode 100644
index 0000000..c377753
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/ts6/current/cdl/flash_ts6.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_ts6.cdl
+#
+# FLASH memory - Hardware support on Delphi MPC8260 TS6 Board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): pfine
+# Original data: gthomas
+# Contributors:
+# Date: 2002-02-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_TS6 {
+ display "Delphi TS6 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_TS6
+
+ compile powerpc_ts6_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED {
+ display "Generic INTEL 28FXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED
+ requires (CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_95 || CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4)
+}
diff --git a/ecos/packages/devs/flash/powerpc/ts6/current/src/powerpc_ts6_flash.c b/ecos/packages/devs/flash/powerpc/ts6/current/src/powerpc_ts6_flash.c
new file mode 100644
index 0000000..86beaa3
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/ts6/current/src/powerpc_ts6_flash.c
@@ -0,0 +1,69 @@
+//==========================================================================
+//
+// powerpc_ts6_flash.c
+//
+// Flash programming for SHARP device on DELPHI TS6 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): pfine
+// Original: jskov
+// Contributors:
+// Date: 2002-02-27
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (4)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_BASE (0xff800000u)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_28fxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF powerpc_ts6_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/vads/current/ChangeLog b/ecos/packages/devs/flash/powerpc/vads/current/ChangeLog
new file mode 100644
index 0000000..b0af970
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/vads/current/ChangeLog
@@ -0,0 +1,40 @@
+2009-02-13 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_vads.cdl: eliminate CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM.
+
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_vads.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2002-12-12 Gary Thomas <gthomas@ecoscentric.com>
+2002-12-12 Patrick Doyle <wpd@delcomsys.com>
+
+ * src/powerpc_vads_flash.c:
+ * cdl/flash_vads.cdl: New package - FLASH support on Motorola
+ VADS (MPC8260) system.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/vads/current/cdl/flash_vads.cdl b/ecos/packages/devs/flash/powerpc/vads/current/cdl/flash_vads.cdl
new file mode 100644
index 0000000..dd037aa
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/vads/current/cdl/flash_vads.cdl
@@ -0,0 +1,67 @@
+# ====================================================================
+#
+# flash_vads.cdl
+#
+# FLASH memory - Hardware support on Motorola MPC8260 Voyager Board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): pfine
+# Original data: gthomas
+# Contributors:
+# Date: 2002-01-11
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_VADS {
+ display "Motorola MPC8260 Voyager ADS FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_VADS
+ compile powerpc_vads_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED {
+ display "Generic INTEL 28FXXX driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_INTEL_28FXXX_REQUIRED
+ requires (CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4 || CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_95)
+}
diff --git a/ecos/packages/devs/flash/powerpc/vads/current/src/powerpc_vads_flash.c b/ecos/packages/devs/flash/powerpc/vads/current/src/powerpc_vads_flash.c
new file mode 100644
index 0000000..d7adc6a
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/vads/current/src/powerpc_vads_flash.c
@@ -0,0 +1,75 @@
+//==========================================================================
+//
+// powerpc_vads_flash.c
+//
+// Flash programming for SHARP device on POWERPC MPC8260 Voyager
+// ADS board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): pfine
+// Original: jskov
+// Contributors:
+// Date: 2002-01-11
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (4)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (8)
+#define nPF_HACK
+#ifdef PF_HACK
+#define CYGNUM_FLASH_BASE (0xfe000000u)
+#else
+#define CYGNUM_FLASH_BASE (0xff800000u)
+#endif
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_28fxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF powerpc_vads_flash.c
diff --git a/ecos/packages/devs/flash/powerpc/viper/current/ChangeLog b/ecos/packages/devs/flash/powerpc/viper/current/ChangeLog
new file mode 100644
index 0000000..adeea60
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/viper/current/ChangeLog
@@ -0,0 +1,72 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_viper.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2003-09-05 Gary Thomas <gary@mlbassoc.com>
+
+ * src/viper_flash.c: Need <pkgconf.h> to make platform decisions!
+
+2003-08-19 Gary Thomas <gary@mlbassoc.com>
+
+ * src/viper_flash.c: Support new board layout which has 16bit
+ wide FLASH devices.
+
+ * cdl/flash_viper.cdl: Add new 8MB device AM29LV640.
+
+2002-06-24 Gary Thomas <gary@chez-thomas.org>
+
+ * cdl/flash_viper.cdl: Old devices use AM29LV800 chip.
+
+2002-06-20 Gary Thomas <gary@chez-thomas.org>
+
+ * src/flash_query.c:
+ * src/flash_program_buf.c:
+ * src/flash_erase_block.c:
+ * src/flash.h: Removed file(s).
+
+ * src/viper_flash.c:
+ * cdl/flash_viper.cdl: Update to use generic AMD FLASH drivers.
+
+2001-06-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/viper_flash.c: Remove dependency on printf() via user functions.
+
+2001-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_viper.cdl: Needs IO controller to copy functions to
+ RAM.
+
+2001-01-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/viper_flash.c:
+ * src/flash_query.c:
+ * src/flash_program_buf.c:
+ * src/flash_erase_block.c:
+ * src/flash.h:
+ * cdl/flash_viper.cdl: New package/file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/powerpc/viper/current/cdl/flash_viper.cdl b/ecos/packages/devs/flash/powerpc/viper/current/cdl/flash_viper.cdl
new file mode 100644
index 0000000..953e5a0
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/viper/current/cdl/flash_viper.cdl
@@ -0,0 +1,72 @@
+# ====================================================================
+#
+# flash_viper.cdl
+#
+# FLASH memory - Hardware support on A&M PowerPC/8xx Viper
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2001-01-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_VIPER {
+ display "A&M Viper (PowerPC/860) FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_POWERPC_VIPER
+
+ compile viper_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV320D
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV640
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV800
+
+}
+
diff --git a/ecos/packages/devs/flash/powerpc/viper/current/src/viper_flash.c b/ecos/packages/devs/flash/powerpc/viper/current/src/viper_flash.c
new file mode 100644
index 0000000..eaeefed
--- /dev/null
+++ b/ecos/packages/devs/flash/powerpc/viper/current/src/viper_flash.c
@@ -0,0 +1,78 @@
+//==========================================================================
+//
+// viper_flash.c
+//
+// Flash programming support
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-10-20
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#ifdef CYGHWR_HAL_POWERPC_VIPER_I // Old board layout
+#define CYGNUM_FLASH_WIDTH (8)
+#define CYGNUM_FLASH_16AS8 (1)
+#else // New board layout
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_16AS8 (0)
+#endif
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0xFE000000)
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+#define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT // This feature fails :-(
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+// ------------------------------------------------------------------------
+// EOF viper_flash.c
diff --git a/ecos/packages/devs/flash/sh/cq7750/current/ChangeLog b/ecos/packages/devs/flash/sh/cq7750/current/ChangeLog
new file mode 100644
index 0000000..b18c4f5
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/cq7750/current/ChangeLog
@@ -0,0 +1,27 @@
+2001-12-20 Koichi Nagashima <naga@r-lab.co.jp>
+
+ * Cloned from EDK7708 flash package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/sh/cq7750/current/cdl/flash_cq7750.cdl b/ecos/packages/devs/flash/sh/cq7750/current/cdl/flash_cq7750.cdl
new file mode 100644
index 0000000..f1ddb99
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/cq7750/current/cdl/flash_cq7750.cdl
@@ -0,0 +1,71 @@
+# ====================================================================
+#
+# flash_cq7750.cdl
+#
+# FLASH memory - Hardware support on CqREEK SH7750 board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Koichi Nagashima
+# Contributors: Koichi Nagashima
+# Date: 2001-12-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_CQ7750 {
+ display "CqREEK SH7750 board FLASH memory support"
+ description "FLASH memory device support for CqREEK SH7750 board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_SH_SH7750_CQ7750
+
+ compile cq7750_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD AM29LV800B driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_TC58FVB800
+ # requires CYGHWR_DEVS_FLASH_AMD_AM29LV800
+}
+
+# EOF flash_cq7750.cdl
diff --git a/ecos/packages/devs/flash/sh/cq7750/current/src/cq7750_flash.c b/ecos/packages/devs/flash/sh/cq7750/current/src/cq7750_flash.c
new file mode 100644
index 0000000..25eafae
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/cq7750/current/src/cq7750_flash.c
@@ -0,0 +1,65 @@
+//==========================================================================
+//
+// cq7750_flash.c
+//
+// Flash programming for Atmel device on Hitachi CQ7750 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Koichi Nagashima
+// Contributors: Koichi Nagashima
+// Date: 2001-12-20
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// A Toshiba TC58FVB800FT-85 is equipped with the CQ7750 platform.
+
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (0x80000000u)
+// #define CYGHWR_FLASH_AM29XXXXX_NO_WRITE_PROTECT
+
+#include "cyg/io/flash_am29xxxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF cq7750_flash.c
diff --git a/ecos/packages/devs/flash/sh/edk7708/current/ChangeLog b/ecos/packages/devs/flash/sh/edk7708/current/ChangeLog
new file mode 100644
index 0000000..5f11a31
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/edk7708/current/ChangeLog
@@ -0,0 +1,27 @@
+2001-09-13 Jesper Skov <jskov@redhat.com>
+
+ * Cloned from ARM PID driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/sh/edk7708/current/cdl/flash_sh_edk7708.cdl b/ecos/packages/devs/flash/sh/edk7708/current/cdl/flash_sh_edk7708.cdl
new file mode 100644
index 0000000..b2007a7
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/edk7708/current/cdl/flash_sh_edk7708.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_edk7708.cdl
+#
+# FLASH memory - Hardware support on Hitachi EDK7708 board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas, hmt, jskov
+# Original data: gthomas
+# Contributors: gthomas
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SH_EDK7708 {
+ display "Hitachi EDK7708 board FLASH memory support"
+ description "FLASH memory device support for Hitachi EDK7708 board"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_SH_EDK7708
+
+ compile sh_edk7708_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED {
+ display "Generic AMD AM29F040 driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED
+}
diff --git a/ecos/packages/devs/flash/sh/edk7708/current/src/sh_edk7708_flash.c b/ecos/packages/devs/flash/sh/edk7708/current/src/sh_edk7708_flash.c
new file mode 100644
index 0000000..13cf5e0
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/edk7708/current/src/sh_edk7708_flash.c
@@ -0,0 +1,64 @@
+//==========================================================================
+//
+// sh_edk7708_flash.c
+//
+// Flash programming for Atmel device on Hitachi EDK7708 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-09-13
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+// There's a single AT29C1024 on the EDK7708 board.
+
+#define CYGPKG_DEVS_FLASH_ATMEL_AT29LV1024
+#define CYGNUM_FLASH_INTERLEAVE (1)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_BASE (0x80000000u)
+
+#include "cyg/io/flash_at29cxxxx.inl"
+
+
+// ------------------------------------------------------------------------
+// EOF sh_edk7708_flash.c
diff --git a/ecos/packages/devs/flash/sh/hs7729pci/current/ChangeLog b/ecos/packages/devs/flash/sh/hs7729pci/current/ChangeLog
new file mode 100644
index 0000000..ade1cd6
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/hs7729pci/current/ChangeLog
@@ -0,0 +1,45 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_sh_hs7729pci.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2001-06-08 Jesper Skov <jskov@redhat.com>
+
+ * cdl/flash_sh_hs7729pci.cdl: Require AM29LV160 support.
+
+2001-05-29 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_hs7729pci_flash.c (plf_flash_init): Automatically
+ determine location of flash.
+
+2001-05-28 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_hs7729pci_flash.c (CYGNUM_FLASH_BASE): Hack address for
+ EPROM boot config for now.
+
+ * Added flash support for HS7729PCI.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/sh/hs7729pci/current/cdl/flash_sh_hs7729pci.cdl b/ecos/packages/devs/flash/sh/hs7729pci/current/cdl/flash_sh_hs7729pci.cdl
new file mode 100644
index 0000000..7bea784
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/hs7729pci/current/cdl/flash_sh_hs7729pci.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_sh_hs7729pci.cdl
+#
+# FLASH memory - Hardware support on Hitachi SH/HS7729PCI
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: jskov
+# Contributors:
+# Date: 2001-05-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SH_HS7729PCI {
+ display "Hitachi SH/HS7729PCI FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_SH_SH7729_HS7729PCI
+
+ compile sh_hs7729pci_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV160
+}
diff --git a/ecos/packages/devs/flash/sh/hs7729pci/current/src/sh_hs7729pci_flash.c b/ecos/packages/devs/flash/sh/hs7729pci/current/src/sh_hs7729pci_flash.c
new file mode 100644
index 0000000..057cb5d
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/hs7729pci/current/src/sh_hs7729pci_flash.c
@@ -0,0 +1,101 @@
+//==========================================================================
+//
+// sh_hs7729pci_flash.c
+//
+// Flash programming for Fujitsu/AMD device on SH HS7729PCI board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-05-28
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (plf_flash_base)
+
+static cyg_uint32 plf_flash_base;
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+static void plf_flash_init(void);
+#define CYGHWR_FLASH_AM29XXXXX_PLF_INIT() plf_flash_init()
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+//--------------------------------------------------------------------------
+// Magic to determine location of flash
+// This works by querying at the location where we expect the EPROM to
+// be. Then the returned data is compared with the data at that location.
+// If there's a match, assume that to be the location of the EPROM.
+// Otherwise it's at the other location.
+//
+// This is done to avoid having separate configurations for the two board
+// configurations. This is simple, has negligible overhead, and Just Works.
+void
+plf_flash_init(void)
+{
+ flash_data_t id[2];
+ flash_data_t* p;
+
+ plf_flash_base = 0xa0400000;
+ flash_dev_query(id);
+
+ p = (flash_data_t*)0xa0400000;
+ if (id[0] == *p++ && id[1] == *p)
+ plf_flash_base = 0xa0000000;
+
+ // Make that the cached region.
+ plf_flash_base &= ~0x20000000;
+}
+
+// ------------------------------------------------------------------------
+// EOF sh_hs7729pci_flash.c
diff --git a/ecos/packages/devs/flash/sh/microdev/current/ChangeLog b/ecos/packages/devs/flash/sh/microdev/current/ChangeLog
new file mode 100644
index 0000000..a71c4fa
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/microdev/current/ChangeLog
@@ -0,0 +1,31 @@
+2003-09-05 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/flash_microdev.cdl:
+ * include/microdev_strataflash.inl:
+ New package -- support for StrataFlash on SuperH SH4-202 MicroDev
+ CPU board.
+
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/sh/microdev/current/cdl/flash_microdev.cdl b/ecos/packages/devs/flash/sh/microdev/current/cdl/flash_microdev.cdl
new file mode 100644
index 0000000..00ad9fc
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/microdev/current/cdl/flash_microdev.cdl
@@ -0,0 +1,79 @@
+# ====================================================================
+#
+# flash_microdev.cdl
+#
+# FLASH memory - Hardware support on SuperH SH4-202 CPU Board
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): nickg
+# Original data: gthomas
+# Contributors:
+# Date: 2003-08-22
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SH_MICRODEV {
+ display "SuperH SH4-202 CPU Board FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_SH_SH4_202_MD
+
+ requires CYGPKG_DEVS_FLASH_STRATA
+
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_STRATA_REQUIRED {
+ display "Generic StrataFLASH driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_STRATA_REQUIRED
+
+ define_proc {
+ puts $::cdl_system_header "/***** strataflash driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_INL <cyg/io/microdev_strataflash.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_FLASH_STRATA_CFG <pkgconf/devs_flash_sh_microdev.h>"
+ puts $::cdl_system_header "/***** strataflash driver proc output end *****/"
+ }
+}
+
diff --git a/ecos/packages/devs/flash/sh/microdev/current/include/microdev_strataflash.inl b/ecos/packages/devs/flash/sh/microdev/current/include/microdev_strataflash.inl
new file mode 100644
index 0000000..2ba69ae
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/microdev/current/include/microdev_strataflash.inl
@@ -0,0 +1,64 @@
+#ifndef CYGONCE_DEVS_FLASH_MICRODEV_STRATAFLASH_INL
+#define CYGONCE_DEVS_FLASH_MICRODEV_STRATAFLASH_INL
+//==========================================================================
+//
+// microdev_strataflash.inl
+//
+// Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: gthomas
+// Date: 2003-08-22
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// The microdev system has two 16-bit devices.
+
+#define CYGNUM_FLASH_DEVICES (2)
+#define CYGNUM_FLASH_BASE (0xA0000000)
+#define CYGNUM_FLASH_BASE_MASK (0xFC000000u) // 32Mb devices
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BLANK (1)
+
+#endif // CYGONCE_DEVS_FLASH_MICRODEV_STRATAFLASH_INL
+// ------------------------------------------------------------------------
+// EOF microdev_strataflash.inl
diff --git a/ecos/packages/devs/flash/sh/se7751/current/ChangeLog b/ecos/packages/devs/flash/sh/se7751/current/ChangeLog
new file mode 100644
index 0000000..072a40a
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/se7751/current/ChangeLog
@@ -0,0 +1,33 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_sh_se7751.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2001-07-09 Jesper Skov <jskov@redhat.com>
+
+ * Added flash support for SE7751.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/sh/se7751/current/cdl/flash_sh_se7751.cdl b/ecos/packages/devs/flash/sh/se7751/current/cdl/flash_sh_se7751.cdl
new file mode 100644
index 0000000..f70a66d
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/se7751/current/cdl/flash_sh_se7751.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_sh_se7751.cdl
+#
+# FLASH memory - Hardware support on Hitachi SH/SE7751
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: jskov
+# Contributors:
+# Date: 2001-07-09
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SH_SE7751 {
+ display "Hitachi SH/SE7751 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_SH_SH7751_SE7751
+
+ compile sh_se7751_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV160
+}
diff --git a/ecos/packages/devs/flash/sh/se7751/current/src/sh_se7751_flash.c b/ecos/packages/devs/flash/sh/se7751/current/src/sh_se7751_flash.c
new file mode 100644
index 0000000..ab04be3
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/se7751/current/src/sh_se7751_flash.c
@@ -0,0 +1,101 @@
+//==========================================================================
+//
+// sh_se7751_flash.c
+//
+// Flash programming for Fujitsu/AMD device on SH SE7751 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-07-09
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (plf_flash_base)
+
+static cyg_uint32 plf_flash_base;
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+static void plf_flash_init(void);
+#define CYGHWR_FLASH_AM29XXXXX_PLF_INIT() plf_flash_init()
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+//--------------------------------------------------------------------------
+// Magic to determine location of flash
+// This works by querying at the location where we expect the EPROM to
+// be. Then the returned data is compared with the data at that location.
+// If there's a match, assume that to be the location of the EPROM.
+// Otherwise it's at the other location.
+//
+// This is done to avoid having separate configurations for the two board
+// configurations. This is simple, has negligible overhead, and Just Works.
+void
+plf_flash_init(void)
+{
+ flash_data_t id[2];
+ flash_data_t* p;
+
+ plf_flash_base = 0xa1000000;
+ flash_dev_query(id);
+
+ p = (flash_data_t*)0xa1000000;
+ if (id[0] == *p++ && id[1] == *p)
+ plf_flash_base = 0xa0000000;
+
+ // Make that the cached region.
+ plf_flash_base &= ~0x20000000;
+}
+
+// ------------------------------------------------------------------------
+// EOF sh_se7751_flash.c
diff --git a/ecos/packages/devs/flash/sh/se77x9/current/ChangeLog b/ecos/packages/devs/flash/sh/se77x9/current/ChangeLog
new file mode 100644
index 0000000..dde0e5b
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/se77x9/current/ChangeLog
@@ -0,0 +1,33 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_sh_se77x9.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2001-06-12 Jesper Skov <jskov@redhat.com>
+
+ * Added flash support for SE77x9.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/sh/se77x9/current/cdl/flash_sh_se77x9.cdl b/ecos/packages/devs/flash/sh/se77x9/current/cdl/flash_sh_se77x9.cdl
new file mode 100644
index 0000000..43ce2cd
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/se77x9/current/cdl/flash_sh_se77x9.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_sh_se77x9.cdl
+#
+# FLASH memory - Hardware support on Hitachi SH/SE77X9
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: jskov
+# Contributors:
+# Date: 2001-05-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SH_SE77X9 {
+ display "Hitachi SH/SE77X9 FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGPKG_HAL_SH_SH77X9_SE77X9
+
+ compile sh_se77x9_flash.c
+
+ # Arguably this should do in the generic package
+ # but then there is a logic loop so you can never enable it.
+ cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
+ display "Generic AMD flash driver required"
+ }
+
+ implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
+ requires CYGHWR_DEVS_FLASH_AMD_AM29LV160
+}
diff --git a/ecos/packages/devs/flash/sh/se77x9/current/src/sh_se77x9_flash.c b/ecos/packages/devs/flash/sh/se77x9/current/src/sh_se77x9_flash.c
new file mode 100644
index 0000000..a02f684
--- /dev/null
+++ b/ecos/packages/devs/flash/sh/se77x9/current/src/sh_se77x9_flash.c
@@ -0,0 +1,101 @@
+//==========================================================================
+//
+// sh_se77x9_flash.c
+//
+// Flash programming for Fujitsu/AMD device on SH SE77X9 board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-05-28
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+//--------------------------------------------------------------------------
+// Device properties
+
+#define CYGNUM_FLASH_INTERLEAVE (2)
+#define CYGNUM_FLASH_SERIES (1)
+#define CYGNUM_FLASH_WIDTH (16)
+#define CYGNUM_FLASH_BASE (plf_flash_base)
+
+static cyg_uint32 plf_flash_base;
+
+//--------------------------------------------------------------------------
+// Platform specific extras
+
+static void plf_flash_init(void);
+#define CYGHWR_FLASH_AM29XXXXX_PLF_INIT() plf_flash_init()
+
+//--------------------------------------------------------------------------
+// Now include the driver code.
+#include "cyg/io/flash_am29xxxxx.inl"
+
+//--------------------------------------------------------------------------
+// Magic to determine location of flash
+// This works by querying at the location where we expect the EPROM to
+// be. Then the returned data is compared with the data at that location.
+// If there's a match, assume that to be the location of the EPROM.
+// Otherwise it's at the other location.
+//
+// This is done to avoid having separate configurations for the two board
+// configurations. This is simple, has negligible overhead, and Just Works.
+void
+plf_flash_init(void)
+{
+ flash_data_t id[2];
+ flash_data_t* p;
+
+ plf_flash_base = 0xa1000000;
+ flash_dev_query(id);
+
+ p = (flash_data_t*)0xa1000000;
+ if (id[0] == *p++ && id[1] == *p)
+ plf_flash_base = 0xa0000000;
+
+ // Make that the cached region.
+ plf_flash_base &= ~0x20000000;
+}
+
+// ------------------------------------------------------------------------
+// EOF sh_se77x9_flash.c
diff --git a/ecos/packages/devs/flash/spi/at25dfxxx/current/ChangeLog b/ecos/packages/devs/flash/spi/at25dfxxx/current/ChangeLog
new file mode 100644
index 0000000..bbcb93c
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/at25dfxxx/current/ChangeLog
@@ -0,0 +1,37 @@
+
+2012-01-05 Christophe Coutand <ecos@hotmail.co.uk>
+ * cdl/at25dfxxx.cdl:
+ * tests/at25dfxxx_test.c:
+ Added Atmel AT25DFxxx driver test application.
+ [Bugzilla 1001449]
+
+2011-04-13 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * cdl/at25dfxxx.cdl:
+ * include/at25dfxxx.h:
+ * src/at25dfxxx.c:
+ New package - SPI flash driver for Atmel AT25DFxxx devices.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/spi/at25dfxxx/current/cdl/flash_at25dfxxx.cdl b/ecos/packages/devs/flash/spi/at25dfxxx/current/cdl/flash_at25dfxxx.cdl
new file mode 100644
index 0000000..23ab137
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/at25dfxxx/current/cdl/flash_at25dfxxx.cdl
@@ -0,0 +1,133 @@
+##=============================================================================
+##
+## flash_at25dfxxx..cdl
+##
+## AT25DFxxx SPI flash driver configuration options.
+##
+##=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+##
+## Author(s): ccoutand, updated for Atmel AT95DFxxx flash
+## Original(s): Chris Holgate
+## Date: 2011-04-25
+## Purpose: Configure AT95DFxxx SPI flash driver.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SPI_AT25DFXXX {
+ display "Atmel AT25DFxxx flash memory support"
+ parent CYGPKG_IO_FLASH
+
+ active_if { CYGPKG_IO_FLASH && CYGPKG_IO_SPI }
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_INDIRECT_READS
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+
+ include_dir cyg/io
+ compile at25dfxxx.c
+
+ description "
+ Flash memory support for Atmel AT95DFxxx SPI flash devices
+ and compatibles. This driver implements the V2 flash driver API."
+
+ cdl_interface CYGHWR_DEVS_FLASH_SPI_AT25DFXXX_DEVICE {
+ display "Hardware AT25DFxxx FLASH device drivers"
+ description "
+ This calculated option gives the number of AT25DFxxx flash
+ devices on the current platform."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_BLOCK_SIZE {
+ display "Flash block size in bytes"
+ legal_values { 4096 32768 65536 }
+ flavor data
+ default_value { 4096 }
+
+ description "
+ Most Atmel AT95DFxxx SPI flash devices can use block size of
+ 4KB, 32K or 64KB. This option allow users to select the flash
+ geometry to use. For device such as AT25F512 not supporting
+ 64K, selecting a wrong geometry will force the driver to
+ abort the initialization process."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_READ_MODE {
+ display "Flash read transaction"
+ legal_values { "FAST" "SLOW" "RAPIDS"}
+ flavor data
+ default_value { "FAST" }
+
+ description "
+ Atmel AT95DFxxx SPI flash devices differentiate read access
+ according to the throughput required for this operation. The
+ driver allows fast and slow reading operation. Some parts
+ also supports the Atmel RapidS protocol."
+ }
+
+ cdl_option CYGNUM_DEVS_FLASH_SPI_AT25DFXXX_READ_BLOCK_SIZE {
+ display "Maximum read block size"
+ flavor data
+ default_value 0
+
+ description "
+ In theory it is possible to read back the entire flash
+ contents using a single SPI transaction. However, some SPI
+ bus drivers have a maximum transaction size - for example
+ transactions may be limited to the length of a DMA bounce
+ buffer. Setting this option to a non-zero value specifies
+ the maximum SPI bus transfer size which will be used when
+ reading back data. Read requests for areas larger than
+ this block size will automatically be split into a series
+ of smaller SPI bus transactions."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_TESTS {
+ display "SPI flash driver tests for Atmel AT95DFxxx flash"
+ active_if CYGPKG_KERNEL
+ active_if CYGPKG_IO_SPI
+ requires { CYGHWR_DEVS_FLASH_SPI_AT25DFXXX_DEVICE >= 1 }
+ flavor data
+ no_define
+ calculated { "tests/at25dfxxx_test.c" }
+ description "
+ This option specifies the set of tests for the Atmel AT95DFxxx
+ SPI flash."
+ }
+}
+
+# EOF flash_at25dfxxx.cdl
diff --git a/ecos/packages/devs/flash/spi/at25dfxxx/current/include/at25dfxxx.h b/ecos/packages/devs/flash/spi/at25dfxxx/current/include/at25dfxxx.h
new file mode 100644
index 0000000..3b7a7be
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/at25dfxxx/current/include/at25dfxxx.h
@@ -0,0 +1,78 @@
+#ifndef CYGONCE_DEVS_FLASH_SPI_AT25DFXXX_H
+#define CYGONCE_DEVS_FLASH_SPI_AT25DFXXX_H
+
+//=============================================================================
+//
+// at25dfxxx.h
+//
+// SPI flash driver for Atmel AT95DFxxx devices and compatibles.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand, updated for Atmel AT95DFxxx flash
+// Original(s): Chris Holgate
+// Purpose: Atmel AT95DFxxx SPI flash driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// Required data structures.
+#include <cyg/io/flash_dev.h>
+
+// Exported handle on the driver function table.
+externC struct cyg_flash_dev_funs cyg_devs_flash_spi_at25dfxxx_funs;
+
+//-----------------------------------------------------------------------------
+// Macro used to generate a flash device object with the default AT25DFXXX
+// settings. Even though the block info data structure is declared here, the
+// details are not filled in until the device type is inferred during
+// initialization. This also applies to the 'end' field which is calculated
+// using the _start_ address and the inferred size of the device.
+// _name_ is the root name of the instantiated data structures.
+// _start_ is the base address of the device - for SPI based devices this can
+// have an arbitrary value, since the device is not memory mapped.
+// _spidev_ is a pointer to a SPI device object of type cyg_spi_device. This
+// is not typechecked during compilation so be careful!
+
+#define CYG_DEVS_FLASH_SPI_AT25DFXXX_DRIVER(_name_, _start_, _spidev_) \
+struct cyg_flash_block_info _name_ ##_block_info; \
+CYG_FLASH_DRIVER(_name_, &cyg_devs_flash_spi_at25dfxxx_funs, 0, \
+ _start_, _start_, 1, & _name_ ##_block_info, (void*) _spidev_)
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_DEVS_FLASH_SPI_AT25DFXXX_H
+// EOF atd25dfxxx.h
diff --git a/ecos/packages/devs/flash/spi/at25dfxxx/current/src/at25dfxxx.c b/ecos/packages/devs/flash/spi/at25dfxxx/current/src/at25dfxxx.c
new file mode 100644
index 0000000..e658ac1
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/at25dfxxx/current/src/at25dfxxx.c
@@ -0,0 +1,648 @@
+//=============================================================================
+//
+// at25dfxxx.c
+//
+// SPI flash driver for Atmel AT25DFxxx devices and compatibles.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand, updated for Atmel AT95DFxxx flash
+// Original(s): Chris Holgate
+// Date: 2011-04-25
+// Purpose: Atmel AT95DFxxx SPI flash driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/io/spi.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <pkgconf/devs_flash_spi_at25dfxxx.h>
+
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// Enable polled SPI operation for non-kernel builds.
+
+#ifdef CYGPKG_KERNEL
+# define AT25DFXXX_POLLED false
+#else
+# define AT25DFXXX_POLLED true
+#endif
+
+//-----------------------------------------------------------------------------
+// Implement delay functions for kernel and non-kernel builds. The kernel
+// build assumes that the API calls are made in the thread context.
+
+#ifdef CYGPKG_KERNEL
+# define AT25DFXXX_DELAY_MS(_msdelay_) cyg_thread_delay \
+ (1 + ((1000 * _msdelay_ * CYGNUM_HAL_RTC_DENOMINATOR) / (CYGNUM_HAL_RTC_NUMERATOR / 1000)))
+
+#else
+# define AT25DFXXX_DELAY_MS(_msdelay_) CYGACC_CALL_IF_DELAY_US (_msdelay_ * 1000)
+#endif
+
+//-----------------------------------------------------------------------------
+// Maintenance and debug macros.
+
+#define ASSERT_AT25DFXXX(_test_, _msg_) CYG_ASSERT(_test_, "FAIL (AT25DFXXX) : " _msg_)
+#define TRACE_AT25DFXXX(_msg_, _args_...) if (dev->pf) dev->pf ("AT25DFXXX : " _msg_, ##_args_)
+
+//=============================================================================
+// Define AT25DFxxx SPI protocol.
+//=============================================================================
+
+typedef enum at25dfxxx_cmd {
+ AT25DFXXX_CMD_WREN = 0x06, // Write enable.
+ AT25DFXXX_CMD_WDRI = 0x04, // Write disable.
+ AT25DFXXX_CMD_RDID = 0x9F, // Read identification.
+ AT25DFXXX_CMD_RDSR1 = 0x05, // Read status register.
+ AT25DFXXX_CMD_RDSR2 = 0x31, // Read status register.
+ AT25DFXXX_CMD_WRSR = 0x01, // Write status register.
+ AT25DFXXX_CMD_SREAD = 0x03, // Read data (slow transaction).
+ AT25DFXXX_CMD_READ = 0x0B, // Read data.
+ AT25DFXXX_CMD_FREAD = 0x1B, // Read data (fast transaction).
+ AT25DFXXX_CMD_PP = 0x02, // Page program.
+ AT25DFXXX_CMD_SE_4K = 0x20, // 4K sector erase.
+ AT25DFXXX_CMD_SE_32K = 0x52, // 32K sector erase.
+ AT25DFXXX_CMD_SE_64K = 0xD8, // 64K sector erase.
+ AT25DFXXX_CMD_BE = 0xC7, // Chip erase.
+ AT25DFXXX_CMD_LOCK = 0x36, // Protect sector
+ AT25DFXXX_CMD_UNLOCK = 0x39, // Unprotect sector
+} at25dfxxx_cmd;
+
+// Status register bitfields.
+#define AT25DFXXX_STATUS_BSY 0x01 /* Operation in progress. */
+#define AT25DFXXX_STATUS_WEL 0x02 /* Write enable latch. */
+#define AT25DFXXX_STATUS_BP0 0x04 /* Global protect 0. */
+#define AT25DFXXX_STATUS_BP1 0x08 /* Global protect 1. */
+#define AT25DFXXX_STATUS_BP2 0x10 /* Global protect 2. */
+#define AT25DFXXX_STATUS_SPRL 0x80 /* Sector Protect Register Lock. */
+
+// Page size of 256 bytes appears to be common for all devices.
+#define AT25DFXXX_PAGE_SIZE 256
+
+// A few helper constants
+#ifndef SZ_1K
+# define SZ_1K 0x00000400
+# define SZ_2K 0x00000800
+# define SZ_4K 0x00001000
+# define SZ_8K 0x00002000
+# define SZ_16K 0x00004000
+# define SZ_32K 0x00008000
+# define SZ_64K 0x00010000
+#endif
+
+// Select read OPCODE
+#if defined(CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_READ_MODE_SLOW)
+# define AT25DFXXX_CMD_READ_LEN 4
+# define AT25DFXXX_CMD_READ_OPCODE AT25DFXXX_CMD_SREAD
+#elif defined(CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_READ_MODE_FAST)
+# define AT25DFXXX_CMD_READ_LEN 5
+# define AT25DFXXX_CMD_READ_OPCODE AT25DFXXX_CMD_READ
+#elif defined(CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_READ_MODE_RAPIDS)
+# define AT25DFXXX_CMD_READ_LEN 6
+# define AT25DFXXX_CMD_READ_OPCODE AT25DFXXX_CMD_FREAD
+#endif
+
+// Select sector size
+#if CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_BLOCK_SIZE == SZ_64K
+# define AT25DFXXX_CMD_SE AT25DFXXX_CMD_SE_64K
+#elif CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_BLOCK_SIZE == SZ_32K
+# define AT25DFXXX_CMD_SE AT25DFXXX_CMD_SE_32K
+#elif CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_BLOCK_SIZE == SZ_4K
+# define AT25DFXXX_CMD_SE AT25DFXXX_CMD_SE_4K
+#endif
+
+//=============================================================================
+// Array containing a list of supported devices. This allows the device
+// parameters to be dynamically detected on initialization.
+//=============================================================================
+
+typedef struct at25dfxxx_params {
+ // Atmel AT25DFxxx SPI flash can be used with 4K, 32K or 64K sector size.
+ // sector_size, sector_count are defined as array, allowing
+ // to describe the geometry of the device for all supported sector size.
+ cyg_uint32 sector_size[4]; // Supported sector size(s) in Byte
+ cyg_uint16 sector_count[4]; // Number of sectors on device.
+ cyg_bool support_rapids; // Atmel RapidS protocol support
+ cyg_uint32 jedec_id; // 3 byte JEDEC identifier
+} at25dfxxx_params;
+
+
+static const at25dfxxx_params at25dfxxx_supported_devices [] = {
+ // Some Atmel AT25DFxxx part (Atmel JEDEC code: 0x1f)
+ // Consider removing the revision number from the Manufacturer /
+ // Device ID for larger chip coverage.
+
+ { // Support for Atmel 64 MBit devices (AT25DF641).
+ sector_count : {2048, 256, 128, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ support_rapids : true,
+ jedec_id : 0x001f4800
+ },
+ { // Support for Atmel 32 MBit devices (AT25DF321A).
+ sector_count : {1024, 128, 64, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ support_rapids : true,
+ jedec_id : 0x001f4701
+ },
+ { // Support for Atmel 16 MBit devices (AT25DF161).
+ sector_count : {512, 64, 32, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ support_rapids : true,
+ jedec_id : 0x001f4602
+ },
+ { // Support for Atmel 8 MBit devices (AT25DF081A).
+ sector_count : {256, 32, 16, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ support_rapids : true,
+ jedec_id : 0x001f4501
+ },
+ { // Support for Atmel 4 MBit devices (AT25DF041A).
+ sector_count : {128, 16, 8, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ support_rapids : false,
+ jedec_id : 0x001f4400
+ },
+ { // Support for Atmel 2 MBit devices (AT25DF021).
+ sector_count : {64, 8, 4, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ support_rapids : false,
+ jedec_id : 0x001f4300
+ },
+ { // Support for Atmel 512 KBit devices (AT25F512B).
+ sector_count : {8, 1, 0},
+ sector_size : {SZ_4K, SZ_32K, 0},
+ support_rapids : false,
+ jedec_id : 0x001f6500
+ },
+ { // Null terminating entry.
+ sector_count : {0},
+ sector_size : {0},
+ support_rapids : false,
+ jedec_id : 0
+ }
+};
+//=============================================================================
+// Utility functions for address calculations.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Strips out any device address offset to give address within device.
+
+static cyg_bool
+at25dfxxx_to_local_addr(struct cyg_flash_dev *dev, cyg_flashaddr_t * addr)
+{
+ cyg_bool retval = false;
+
+ // Range check address before modifying it.
+ if ((*addr >= dev->start) && (*addr <= dev->end)) {
+ *addr -= dev->start;
+ retval = true;
+ }
+ return retval;
+}
+
+//=============================================================================
+// Wrapper functions for various SPI transactions.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Read back the 3-byte JEDEC ID, returning it as a 32-bit integer.
+// This function is called during flash initialisation, which can often be
+// called from the startup/idle thread. This means that we should always use
+// SPI polled mode in order to prevent the thread from attempting to sleep.
+
+static inline cyg_uint32
+at25dfxxx_spi_rdid(struct cyg_flash_dev *dev)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[4] = { AT25DFXXX_CMD_RDID, 0x0, 0x0, 0x0 };
+ cyg_uint8 rx_buf[4];
+ cyg_uint32 retval = 0;
+
+ // Carry out SPI transfer.
+ cyg_spi_transfer(spi_device, true, 4, tx_buf, rx_buf);
+
+ // Convert 3-byte ID to 32-bit integer.
+ retval |= ((cyg_uint32)rx_buf[1]) << 16;
+ retval |= ((cyg_uint32)rx_buf[2]) << 8;
+ retval |= ((cyg_uint32)rx_buf[3]);
+
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Send write enable command.
+
+static inline void
+at25dfxxx_spi_wren(struct cyg_flash_dev *dev)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[1] = { AT25DFXXX_CMD_WREN };
+ cyg_spi_transfer(spi_device, AT25DFXXX_POLLED, 1, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Send sector erase command. The address parameter is a device local address
+// within the sector to be erased.
+
+static inline void
+at25dfxxx_spi_se(struct cyg_flash_dev *dev, cyg_flashaddr_t addr)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ cyg_uint8 tx_buf[4] = { AT25DFXXX_CMD_SE,
+ (cyg_uint8)(addr >> 16), (cyg_uint8)(addr >> 8), (cyg_uint8)(addr)
+ };
+ cyg_spi_transfer(spi_device, AT25DFXXX_POLLED, 4, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Send sector erase command. The address parameter is a device local address
+// within the sector to be erased.
+
+static inline void
+at25dfxxx_spi_lock(struct cyg_flash_dev *dev, cyg_flashaddr_t addr)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[4] = { AT25DFXXX_CMD_LOCK,
+ (cyg_uint8)(addr >> 16), (cyg_uint8)(addr >> 8), (cyg_uint8)(addr)
+ };
+ cyg_spi_transfer(spi_device, AT25DFXXX_POLLED, 4, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Send sector erase command. The address parameter is a device local address
+// within the sector to be erased.
+
+static inline void
+at25dfxxx_spi_unlock(struct cyg_flash_dev *dev, cyg_flashaddr_t addr)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[4] = { AT25DFXXX_CMD_UNLOCK,
+ (cyg_uint8)(addr >> 16), (cyg_uint8)(addr >> 8), (cyg_uint8)(addr)
+ };
+ cyg_spi_transfer(spi_device, AT25DFXXX_POLLED, 4, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Read and return the 8-bit device status register.
+
+static inline cyg_uint8
+at25dfxxx_spi_rdsr(struct cyg_flash_dev *dev)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[2] = { AT25DFXXX_CMD_RDSR1, 0 };
+ cyg_uint8 rx_buf[2];
+
+ // Carry out SPI transfer and return the status byte.
+ cyg_spi_transfer(spi_device, AT25DFXXX_POLLED, 2, tx_buf, rx_buf);
+
+ return rx_buf[1];
+}
+
+//-----------------------------------------------------------------------------
+// Program a single page.
+
+static inline void
+at25dfxxx_spi_pp(struct cyg_flash_dev *dev, cyg_flashaddr_t addr,
+ cyg_uint8 *wbuf, cyg_uint32 wbuf_len)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[4] = { AT25DFXXX_CMD_PP,
+ (cyg_uint8)(addr >> 16), (cyg_uint8)(addr >> 8), (cyg_uint8)(addr)
+ };
+
+ // Implement the program operation as a multistage SPI transaction.
+ cyg_spi_transaction_begin(spi_device);
+ cyg_spi_transaction_transfer(spi_device, AT25DFXXX_POLLED, 4, tx_buf,
+ NULL, false);
+ cyg_spi_transaction_transfer(spi_device, AT25DFXXX_POLLED, wbuf_len, wbuf,
+ NULL, false);
+ cyg_spi_transaction_end(spi_device);
+}
+
+//-----------------------------------------------------------------------------
+// Implement reads to the specified buffer.
+
+static inline void
+at25dfxxx_spi_read(struct cyg_flash_dev *dev, cyg_flashaddr_t addr,
+ cyg_uint8 *rbuf, cyg_uint32 rbuf_len)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[6] = { AT25DFXXX_CMD_READ_OPCODE,
+ (cyg_uint8)(addr >> 16), (cyg_uint8)(addr >> 8), (cyg_uint8)(addr), 0,
+ 0
+ };
+
+ // Implement the read operation as a multistage SPI transaction.
+ cyg_spi_transaction_begin(spi_device);
+ cyg_spi_transaction_transfer(spi_device, AT25DFXXX_POLLED,
+ AT25DFXXX_CMD_READ_LEN, tx_buf, NULL, false);
+ cyg_spi_transaction_transfer(spi_device, AT25DFXXX_POLLED, rbuf_len, NULL,
+ rbuf, false);
+ cyg_spi_transaction_end(spi_device);
+}
+
+//=============================================================================
+// Standard Flash device API. All the following functions assume that a valid
+// SPI device handle is passed in the 'priv' reference of the flash device
+// data structure.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Initialize the SPI flash, reading back the flash parameters.
+
+static int
+at25dfxxx_init(struct cyg_flash_dev *dev)
+{
+ at25dfxxx_params *dev_params =
+ (at25dfxxx_params *) at25dfxxx_supported_devices;
+ cyg_uint32 device_id;
+ int retval = FLASH_ERR_INVALID;
+ cyg_uint8 i = 0;
+
+ // Find the device in the supported devices list.
+ device_id = at25dfxxx_spi_rdid(dev);
+ while ((dev_params->jedec_id != 0) && (dev_params->jedec_id != device_id)) {
+ dev_params++;
+ }
+
+ // Found supported device - update device parameters. AT25DFXXX devices
+ // have a uniform sector distribution, so only 1 block info record is
+ // required.
+ if (dev_params->jedec_id != 0) {
+
+ while ((dev_params->sector_size[i] !=
+ CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_BLOCK_SIZE)
+ && (dev_params->sector_size[i] != 0))
+ i++;
+
+ // Verify that the device supports the wanted geometry
+ if (dev_params->sector_size[i] !=
+ CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_BLOCK_SIZE) {
+ TRACE_AT25DFXXX("Init device with JEDEC ID 0x%06X\n",
+ dev_params->jedec_id);
+ TRACE_AT25DFXXX
+ ("SPI Flash Error, not supporting %dK sector size\n",
+ CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_BLOCK_SIZE);
+ return retval;
+ }
+
+#if defined(CYGPKG_DEVS_FLASH_SPI_AT25DFXXX_READ_MODE_RAPIDS)
+ if (dev_params->support_rapids != true) {
+ TRACE_AT25DFXXX("Init device with JEDEC ID 0x%06X\n",
+ dev_params->jedec_id);
+ TRACE_AT25DFXXX
+ ("SPI Flash Error, not supporting RapidS Opcode\n");
+ return retval;
+ }
+#endif
+
+ ASSERT_AT25DFXXX(dev->num_block_infos == 1,
+ "Only 1 block info record required.");
+ ASSERT_AT25DFXXX(dev->block_info != NULL,
+ "Null pointer to block info record.");
+
+ if ((dev->num_block_infos == 1) && (dev->block_info != NULL)) {
+ TRACE_AT25DFXXX("Init device with JEDEC ID 0x%06X.\n", device_id);
+
+ dev->end =
+ dev->start +
+ ((cyg_flashaddr_t) dev_params->sector_size[i] *
+ (cyg_flashaddr_t) (dev_params->sector_count[i])) - 1;
+
+ // Strictly speaking the block info fields are 'read only'.
+ // However, we have a legitimate reason for updating the contents
+ // here and can cast away the const.
+ ((cyg_flash_block_info_t *) dev->block_info)->block_size =
+ (size_t)(dev_params->sector_size[i]);
+ ((cyg_flash_block_info_t *) dev->block_info)->blocks =
+ (cyg_uint32)(dev_params->sector_count[i]);
+
+ retval = FLASH_ERR_OK;
+ }
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Erase a single sector of the flash.
+
+static int
+at25dfxxx_erase_block(struct cyg_flash_dev *dev, cyg_flashaddr_t block_base)
+{
+ cyg_flashaddr_t local_base = block_base;
+ int retval = FLASH_ERR_INVALID;
+ cyg_uint8 dev_status;
+
+ // Fix up the block address and send the sector erase command.
+ if (at25dfxxx_to_local_addr(dev, &local_base)) {
+ at25dfxxx_spi_wren(dev);
+ at25dfxxx_spi_se(dev, local_base);
+
+ // Spin waiting for the erase to complete.
+ do {
+ AT25DFXXX_DELAY_MS(1);
+ dev_status = at25dfxxx_spi_rdsr(dev);
+ } while (dev_status & AT25DFXXX_STATUS_BSY);
+
+ retval = FLASH_ERR_OK;
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Program an arbitrary number of pages into flash and verify written data.
+
+static int
+at25dfxxx_program(struct cyg_flash_dev *dev, cyg_flashaddr_t base,
+ const void *data, size_t len)
+{
+ cyg_flashaddr_t local_base = base;
+ int retval = FLASH_ERR_OK;
+ cyg_uint8 *tx_ptr = (cyg_uint8 *)data;
+ cyg_uint32 tx_bytes_left = (cyg_uint32)len;
+ cyg_uint32 tx_bytes;
+ cyg_uint8 dev_status;
+
+ // Fix up the block address.
+ if (!at25dfxxx_to_local_addr(dev, &local_base)) {
+ retval = FLASH_ERR_INVALID;
+ goto out;
+ }
+ // The start of the transaction may not be page aligned, so we need to work
+ // out how many bytes to transmit before we hit the first page boundary.
+ tx_bytes =
+ AT25DFXXX_PAGE_SIZE -
+ (((cyg_uint32)local_base) & (AT25DFXXX_PAGE_SIZE - 1));
+ if (tx_bytes > tx_bytes_left)
+ tx_bytes = tx_bytes_left;
+
+ // Perform page program operations.
+ while (tx_bytes_left) {
+ at25dfxxx_spi_wren(dev);
+ at25dfxxx_spi_pp(dev, local_base, tx_ptr, tx_bytes);
+
+ // Spin waiting for write to complete. This can take up to 5ms, so
+ // we use a polling interval of 1ms - which may get rounded up to the
+ // RTC tick granularity.
+ do {
+ AT25DFXXX_DELAY_MS(1);
+ dev_status = at25dfxxx_spi_rdsr(dev);
+ } while (dev_status & AT25DFXXX_STATUS_BSY);
+
+ // Update counters and data pointers for the next page.
+ tx_bytes_left -= tx_bytes;
+ tx_ptr += tx_bytes;
+ local_base += tx_bytes;
+ tx_bytes =
+ (tx_bytes_left >
+ AT25DFXXX_PAGE_SIZE) ? AT25DFXXX_PAGE_SIZE : tx_bytes_left;
+ }
+
+out:
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Read back an arbitrary amount of data from flash.
+
+static int
+at25dfxxx_read(struct cyg_flash_dev *dev, const cyg_flashaddr_t base,
+ void *data, size_t len)
+{
+ cyg_flashaddr_t local_base = base;
+ int retval = FLASH_ERR_INVALID;
+ cyg_uint8 *rx_ptr = (cyg_uint8 *)data;
+ cyg_uint32 rx_bytes_left = (cyg_uint32)len;
+ cyg_uint32 rx_bytes;
+
+ // Determine the maximum transfer size to use.
+ cyg_uint32 rx_block_size =
+ (CYGNUM_DEVS_FLASH_SPI_AT25DFXXX_READ_BLOCK_SIZE ==
+ 0) ? 0xFFFFFFFF : CYGNUM_DEVS_FLASH_SPI_AT25DFXXX_READ_BLOCK_SIZE;
+
+ // Fix up the block address and fill the read buffer.
+ if (at25dfxxx_to_local_addr(dev, &local_base)) {
+ while (rx_bytes_left) {
+ rx_bytes =
+ (rx_bytes_left <
+ rx_block_size) ? rx_bytes_left : rx_block_size;
+ at25dfxxx_spi_read(dev, local_base, rx_ptr, rx_bytes);
+
+ // Update counters and data pointers for next read block.
+ rx_bytes_left -= rx_bytes;
+ rx_ptr += rx_bytes;
+ local_base += rx_bytes;
+ }
+ retval = FLASH_ERR_OK;
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Lock sector
+
+static int
+at25dfxxx_lock(struct cyg_flash_dev *dev, cyg_flashaddr_t base)
+{
+ cyg_flashaddr_t local_base = base;
+ int retval = FLASH_ERR_INVALID;
+ cyg_uint8 dev_status;
+
+ // Fix up the block address and send the sector erase command.
+ if (at25dfxxx_to_local_addr(dev, &local_base)) {
+ at25dfxxx_spi_wren(dev);
+ at25dfxxx_spi_lock(dev, local_base);
+
+ // Spin waiting for the lock operation to complete.
+ do {
+ AT25DFXXX_DELAY_MS(1);
+ dev_status = at25dfxxx_spi_rdsr(dev);
+ } while (dev_status & AT25DFXXX_STATUS_BSY);
+ retval = FLASH_ERR_OK;
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Unlock sector
+
+static int
+at25dfxxx_unlock(struct cyg_flash_dev *dev, cyg_flashaddr_t base)
+{
+ cyg_flashaddr_t local_base = base;
+ int retval = FLASH_ERR_INVALID;
+ cyg_uint8 dev_status;
+
+ // Fix up the block address and send the sector erase command.
+ if (at25dfxxx_to_local_addr(dev, &local_base)) {
+ at25dfxxx_spi_wren(dev);
+ at25dfxxx_spi_unlock(dev, local_base);
+
+ // Spin waiting for the unlock operation to complete.
+ do {
+ AT25DFXXX_DELAY_MS(1);
+ dev_status = at25dfxxx_spi_rdsr(dev);
+ } while (dev_status & AT25DFXXX_STATUS_BSY);
+ retval = FLASH_ERR_OK;
+ }
+ return retval;
+}
+
+//=============================================================================
+// Fill in the driver data structures.
+//=============================================================================
+
+CYG_FLASH_FUNS(
+ cyg_devs_flash_spi_at25dfxxx_funs, // Exported name of function pointers
+ at25dfxxx_init, // Flash initialization
+ cyg_flash_devfn_query_nop, // Query operations not supported
+ at25dfxxx_erase_block, // Sector erase
+ at25dfxxx_program, // Program multiple pages
+ at25dfxxx_read, // Read arbitrary amount of data
+ at25dfxxx_lock, // Locking
+ at25dfxxx_unlock);
+
+//-----------------------------------------------------------------------------
+// EOF at25dfxxx.c
diff --git a/ecos/packages/devs/flash/spi/at25dfxxx/current/tests/at25dfxxx_test.c b/ecos/packages/devs/flash/spi/at25dfxxx/current/tests/at25dfxxx_test.c
new file mode 100644
index 0000000..9679840
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/at25dfxxx/current/tests/at25dfxxx_test.c
@@ -0,0 +1,398 @@
+//=============================================================================
+//
+// at25dfxxx_test.c
+//
+// SPI flash driver tests for Atmel AT95DFxxx flash
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand, updated for Atmel AT95DFxxx flash
+// Original(s): Chris Holgate
+// Date: 2011-04-25
+// Purpose: Atmel AT95DFxxx SPI flash driver stress tests.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/testcase.h> // Test macros
+#include <cyg/infra/cyg_ass.h> // Assertion macros
+#include <cyg/infra/diag.h> // Diagnostic output
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/hal/hal_if.h>
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/io/spi.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/at25dfxxx.h>
+
+// Required data structures.
+#include <cyg/io/flash_dev.h>
+
+#include <string.h>
+
+#include CYGHWR_MEMORY_LAYOUT_H
+
+static cyg_flash_info_t at25dfxxx_flash_info;
+
+//-----------------------------------------------------------------------------
+// Thread data structures.
+
+static cyg_uint32 stack [CYGNUM_HAL_STACK_SIZE_TYPICAL / 4];
+static cyg_thread thread_data;
+static cyg_handle_t thread_handle;
+
+//-----------------------------------------------------------------------------
+// Data transfer buffers.
+
+#define BUF_SIZE 1024
+
+static cyg_uint8 wbuf [BUF_SIZE];
+static cyg_uint8 rbuf [BUF_SIZE];
+
+//-----------------------------------------------------------------------------
+// Print out version information.
+
+void do_version (void)
+{
+ char *version = CYGACC_CALL_IF_MONITOR_VERSION();
+ if (version != NULL) diag_printf("%s", version);
+#ifdef HAL_PLATFORM_CPU
+ diag_printf("\nPlatform: %s (%s) %s\n",
+ HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
+#endif
+ diag_printf("RAM: %p-%p, ",
+ (void*)(CYGMEM_REGION_ram), (void*)(CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - 1));
+ diag_printf("(HEAP: %p-%p)\n",
+ (void*)(CYGMEM_SECTION_heap1), (void*)(CYGMEM_SECTION_heap1 + CYGMEM_SECTION_heap1_SIZE - 1));
+}
+
+//-----------------------------------------------------------------------------
+// Run checkerboard and inverse checkerboard writes over each sector in turn.
+
+cyg_uint32 run_test_1
+ (void)
+{
+ int status;
+ cyg_uint32 i, j;
+ cyg_uint32 errors = 0;
+ cyg_flashaddr_t base_addr, err_addr;
+
+ diag_printf ("Test 1 - write and verify checkerboard and inverse checkerboard.\n");
+
+ // Iterate over all flash sectors.
+ for (i = 0; i < at25dfxxx_flash_info.block_info->blocks; i++) {
+ base_addr = at25dfxxx_flash_info.start +
+ (i * at25dfxxx_flash_info.block_info->block_size);
+
+ // Unlock block.
+ status = cyg_flash_unlock (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Erase block.
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Set up buffer with checkerboard.
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = 0x55;
+ wbuf [j++] = 0xAA;
+ }
+
+ // Write the checkerboard to the entire sector.
+ for (j = 0; j < at25dfxxx_flash_info.block_info->block_size ; j += BUF_SIZE) {
+ status = cyg_flash_program (base_addr + j, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ }
+
+ // Read back the checkerboard and verify.
+ for (j = 0; j < at25dfxxx_flash_info.block_info->block_size; j += BUF_SIZE) {
+ status = cyg_flash_read (base_addr + j, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n",
+ base_addr + j, base_addr + j + BUF_SIZE - 1);
+ errors ++;
+ }
+ }
+
+ // Erase block.
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Set up buffer with inverse checkerboard.
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = 0xAA;
+ wbuf [j++] = 0x55;
+ }
+
+ // Write the checkerboard to the entire sector.
+ for (j = 0; j < at25dfxxx_flash_info.block_info->block_size; j += BUF_SIZE) {
+ status = cyg_flash_program (base_addr + j, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ }
+
+ // Read back the checkerboard and verify.
+ for (j = 0; j < at25dfxxx_flash_info.block_info->block_size; j += BUF_SIZE) {
+ status = cyg_flash_read (base_addr + j, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n",
+ base_addr + j, base_addr + j + BUF_SIZE - 1);
+ errors ++;
+ }
+ }
+ }
+ return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Write and verify counting sequence over all device.
+
+cyg_uint32 run_test_2
+ (void)
+{
+ int status;
+ cyg_uint32 i, j;
+ cyg_uint32 errors = 0;
+ cyg_flashaddr_t base_addr, err_addr;
+
+ diag_printf ("Test 2 - write and verify counting sequence.\n");
+
+ // Erase all flash sectors.
+ for (i = 0; i < at25dfxxx_flash_info.block_info->blocks; i++) {
+ base_addr = at25dfxxx_flash_info.start +
+ (i * at25dfxxx_flash_info.block_info->block_size);
+
+ // Erase block.
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ }
+
+ // Write counting sequence.
+ base_addr = at25dfxxx_flash_info.start;
+ for (i = 0; i < (at25dfxxx_flash_info.end - at25dfxxx_flash_info.start) / 4;) {
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = (cyg_uint8) ((i >> 0) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 8) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 16) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 24) & 0xFF);
+ i++;
+ }
+ status = cyg_flash_program (base_addr, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ base_addr += BUF_SIZE;
+ }
+
+ // Verify counting sequence.
+ base_addr = at25dfxxx_flash_info.start;
+ for (i = 0; i < (at25dfxxx_flash_info.end - at25dfxxx_flash_info.start) / 4;) {
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = (cyg_uint8) ((i >> 0) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 8) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 16) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 24) & 0xFF);
+ i++;
+ }
+ status = cyg_flash_read (base_addr, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n",
+ base_addr, base_addr + BUF_SIZE - 1);
+ errors ++;
+ }
+ base_addr += BUF_SIZE;
+ }
+ return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Perform non-aligned buffer read/write tests, spanning sector boundaries.
+
+cyg_uint32 run_test_3
+ (void)
+{
+ int status;
+ cyg_uint32 i, count;
+ cyg_uint32 errors = 0;
+ cyg_flashaddr_t base_addr, err_addr;
+
+ diag_printf ("Test 3 - test non-aligned writes and reads.\n");
+
+ // Fill the write buffer with a basic counting sequence.
+ count = 0;
+ for (i = 0; i < BUF_SIZE;) {
+ wbuf [i++] = (cyg_uint8) ((count >> 0) & 0xFF);
+ wbuf [i++] = (cyg_uint8) ((count >> 8) & 0xFF);
+ count++;
+ }
+
+ // Assuming 256 byte pages gives 256 possible alignments.
+ base_addr = at25dfxxx_flash_info.start + at25dfxxx_flash_info.block_info->block_size;
+ for (i = 1; i <= 256; i++) {
+
+ // Erase sectors either side of sector boundary.
+ status = cyg_flash_erase (base_addr - 1, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Write data spanning sector boundary.
+ status = cyg_flash_program (base_addr - i, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Verify data spanning sector boundary.
+ status = cyg_flash_read (base_addr - i, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n",
+ base_addr - i, base_addr - i + BUF_SIZE - 1);
+ errors ++;
+ }
+
+ // Use next sector boundary for next test.
+ base_addr += at25dfxxx_flash_info.block_info->block_size;
+ if (base_addr >= at25dfxxx_flash_info.end)
+ base_addr = at25dfxxx_flash_info.start + at25dfxxx_flash_info.block_info->block_size;
+ }
+ return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Run all M25Pxx SPI interface loopback tests.
+
+void run_tests
+ (void)
+{
+ cyg_uint32 errors = 0;
+
+ do_version();
+
+ diag_printf ("----\nChecking for AT25DFxxx compatible devices.\n");
+ cyg_flash_set_global_printf((cyg_flash_printf *)&diag_printf);
+ cyg_flash_init(NULL);
+
+ cyg_flash_get_info_addr(CYGNUM_DEVS_FLASH_SPI_AT25XXX_DEV0_MAP_ADDR,
+ &at25dfxxx_flash_info);
+
+ // Check that the device is intialised.
+ if (at25dfxxx_flash_info.start == at25dfxxx_flash_info.end) {
+ diag_printf ("AT25DFxxx device not initialised.\n");
+ errors ++;
+ goto out;
+ }
+
+ // Run the tests.
+ errors += run_test_1 ();
+ errors += run_test_2 ();
+ errors += run_test_3 ();
+
+out:
+ diag_printf ("----\nTests complete - detected %d errors in total.\n", errors);
+ if (errors == 0)
+ CYG_TEST_PASS_FINISH ("AT25DFxxx driver tests ran OK.");
+ else
+ CYG_TEST_FAIL_FINISH ("AT25DFxxx driver test FAILED.");
+}
+
+//-----------------------------------------------------------------------------
+// User startup - tests are run in their own thread.
+
+void cyg_user_start
+ (void)
+{
+ CYG_TEST_INIT();
+ cyg_thread_create(
+ 10, // Arbitrary priority
+ (cyg_thread_entry_t*) run_tests, // Thread entry point
+ 0, //
+ "test_thread", // Thread name
+ (cyg_uint8*) stack, // Stack
+ CYGNUM_HAL_STACK_SIZE_TYPICAL, // Stack size
+ &thread_handle, // Thread handle
+ &thread_data // Thread data structure
+ );
+ cyg_thread_resume(thread_handle);
+ cyg_scheduler_start();
+}
+
+//=============================================================================
diff --git a/ecos/packages/devs/flash/spi/m25pxx/current/ChangeLog b/ecos/packages/devs/flash/spi/m25pxx/current/ChangeLog
new file mode 100644
index 0000000..37d30de
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/m25pxx/current/ChangeLog
@@ -0,0 +1,49 @@
+2011-05-25 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * cdl/flash_m25pxx.cdl: fix active_if goal expression.
+
+2009-02-20 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * test/m25pxx_test.c (cyg_user_start): Call cyg_flash_init() with
+ NULL argument.
+
+2009-02-18 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * test/m25pxx_test.c (cyg_user_start): Update for minor flash API
+ mod to call cyg_flash_set_global_printf() to set printf
+ function.
+
+2009-02-05 Chris Holgate <chris@zynaptic.com>
+
+ * cdl/m25pxx.cdl:
+ * include/m25pxx.h:
+ * src/m25pxx.c:
+ * test/m25pxx_test.c:
+ New package - SPI flash driver for M25Pxx devices and compatibles.
+ Driver contributed by Chris Holgate. Includes a soak test which is
+ not part of the default tests as it requires a specific configuration
+ to be used - see test/m25pxx_test.c for details.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/spi/m25pxx/current/cdl/flash_m25pxx.cdl b/ecos/packages/devs/flash/spi/m25pxx/current/cdl/flash_m25pxx.cdl
new file mode 100644
index 0000000..436d082
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/m25pxx/current/cdl/flash_m25pxx.cdl
@@ -0,0 +1,77 @@
+##=============================================================================
+##
+## flash_m25pxx.cdl
+##
+## M25Pxx SPI flash driver configuration options.
+##
+##=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): Chris Holgate
+## Date: 2008-12-22
+## Purpose: Configure M25Pxx SPI flash driver.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SPI_M25PXX {
+ display "M25PXX flash memory support"
+ parent CYGPKG_IO_FLASH
+ active_if { CYGPKG_IO_FLASH && CYGPKG_IO_SPI }
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_INDIRECT_READS
+ include_dir cyg/io
+ compile m25pxx.c
+
+ description "
+ Flash memory support for Numonyx M25Pxx SPI flash devices and
+ compatibles. This driver implements the V2 flash driver API"
+
+cdl_option CYGNUM_DEVS_FLASH_SPI_M25PXX_READ_BLOCK_SIZE {
+ display "Maximum read block size"
+ description "
+ In theory it is possible to read back the entire flash contents using
+ a single SPI transaction. However, some SPI bus drivers have a maximum
+ transaction size - for example transactions may be limited to the
+ length of a DMA bounce buffer. Setting this option to a non-zero value
+ specifies the maximum SPI bus transfer size which will be used when
+ reading back data. Read requests for areas larger than this block size
+ will automatically be split into a series of smaller SPI bus transactions.
+ "
+ flavor data
+ default_value 0
+}
+}
diff --git a/ecos/packages/devs/flash/spi/m25pxx/current/include/m25pxx.h b/ecos/packages/devs/flash/spi/m25pxx/current/include/m25pxx.h
new file mode 100644
index 0000000..b7dffb5
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/m25pxx/current/include/m25pxx.h
@@ -0,0 +1,78 @@
+#ifndef CYGONCE_DEVS_FLASH_SPI_M25PXX_H
+#define CYGONCE_DEVS_FLASH_SPI_M25PXX_H
+
+//=============================================================================
+//
+// m25pxx.h
+//
+// SPI flash driver for Numonyx M25Pxx devices and compatibles.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Chris Holgate
+// Date: 2008-12-22
+// Purpose: Numonyx M25Pxx SPI flash driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// Required data structures.
+#include <cyg/io/flash_dev.h>
+
+// Exported handle on the driver function table.
+externC struct cyg_flash_dev_funs cyg_devs_flash_spi_m25pxx_funs;
+
+//-----------------------------------------------------------------------------
+// Macro used to generate a flash device object with the default M25PXX
+// settings. Even though the block info data structure is declared here, the
+// details are not filled in until the device type is inferred during
+// initialisation. This also applies to the 'end' field which is calculated
+// using the _start_ address and the inferred size of the device.
+// _name_ is the root name of the instantiated data structures.
+// _start_ is the base address of the device - for SPI based devices this can
+// have an arbitrary value, since the device is not memory mapped.
+// _spidev_ is a pointer to a SPI device object of type cyg_spi_device. This
+// is not typechecked during compilation so be careful!
+
+#define CYG_DEVS_FLASH_SPI_M25PXX_DRIVER(_name_, _start_, _spidev_) \
+struct cyg_flash_block_info _name_ ##_block_info; \
+CYG_FLASH_DRIVER(_name_, &cyg_devs_flash_spi_m25pxx_funs, 0, \
+ _start_, _start_, 1, & _name_ ##_block_info, (void*) _spidev_)
+
+//=============================================================================
+
+#endif // CYGONCE_DEVS_FLASH_SPI_M25PXX_H
diff --git a/ecos/packages/devs/flash/spi/m25pxx/current/src/m25pxx.c b/ecos/packages/devs/flash/spi/m25pxx/current/src/m25pxx.c
new file mode 100644
index 0000000..8ddd2ff
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/m25pxx/current/src/m25pxx.c
@@ -0,0 +1,473 @@
+//=============================================================================
+//
+// m25pxx.c
+//
+// SPI flash driver for Numonyx M25Pxx devices and compatibles.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Chris Holgate
+// Date: 2008-12-22
+// Purpose: Numonyx M25Pxx SPI flash driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/io/spi.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <pkgconf/devs_flash_spi_m25pxx.h>
+
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// Enable polled SPI operation for non-kernel builds.
+
+#ifdef CYGPKG_KERNEL
+#define M25PXX_POLLED false
+
+#else
+#define M25PXX_POLLED true
+#endif
+
+//-----------------------------------------------------------------------------
+// Implement delay functions for kernel and non-kernel builds. The kernel
+// build assumes that the API calls are made in the thread context.
+
+#ifdef CYGPKG_KERNEL
+#define M25PXX_DELAY_MS(_msdelay_) cyg_thread_delay (\
+ 1 + ((1000 * _msdelay_ * CYGNUM_HAL_RTC_DENOMINATOR) / (CYGNUM_HAL_RTC_NUMERATOR / 1000)))
+
+#else
+#define M25PXX_DELAY_MS(_msdelay_) CYGACC_CALL_IF_DELAY_US (_msdelay_ * 1000)
+#endif
+
+//-----------------------------------------------------------------------------
+// Maintenance and debug macros.
+
+#define TODO_M25P(_msg_) CYG_ASSERT(false, "TODO (M25P) : " _msg_)
+#define FAIL_M25P(_msg_) CYG_ASSERT(false, "FAIL (M25P) : " _msg_)
+#define ASSERT_M25P(_test_, _msg_) CYG_ASSERT(_test_, "FAIL (M25P) : " _msg_)
+#define TRACE_M25P(_msg_, _args_...) if (dev->pf) dev->pf ("M25PXX : " _msg_, ##_args_)
+
+//=============================================================================
+// Define M25Pxx SPI protocol.
+//=============================================================================
+
+typedef enum m25pxx_cmd {
+ M25PXX_CMD_WREN = 0x06, // Write enable.
+ M25PXX_CMD_WDRI = 0x04, // Write disable.
+ M25PXX_CMD_RDID = 0x9F, // Read identification.
+ M25PXX_CMD_RDSR = 0x05, // Read status register.
+ M25PXX_CMD_WRSR = 0x01, // Write status register.
+ M25PXX_CMD_READ = 0x03, // Read data.
+ M25PXX_CMD_FREAD = 0x0B, // Read data (fast transaction).
+ M25PXX_CMD_PP = 0x02, // Page program.
+ M25PXX_CMD_SE = 0xD8, // Sector erase.
+ M25PXX_CMD_BE = 0xC7, // Bulk erase.
+ M25PXX_CMD_RES = 0xAB, // Read electronic signature.
+} m25pxx_cmd;
+
+// Status register bitfields.
+#define M25PXX_STATUS_WIP 0x01 /* Write in progress. */
+#define M25PXX_STATUS_WEL 0x02 /* Write enable latch. */
+#define M25PXX_STATUS_BP0 0x04 /* Block protect 0. */
+#define M25PXX_STATUS_BP1 0x08 /* Block protect 1. */
+#define M25PXX_STATUS_BP2 0x10 /* Block protect 2. */
+#define M25PXX_STATUS_SRWD 0x80 /* Status register write protect. */
+
+// Page size of 256 bytes appears to be common for all devices.
+#define M25PXX_PAGE_SIZE 256
+
+//=============================================================================
+// Array containing a list of supported devices. This allows the device
+// parameters to be dynamically detected on initialisation.
+//=============================================================================
+
+typedef struct m25pxx_params {
+ cyg_uint16 sector_size; // Number of pages in a sector.
+ cyg_uint16 sector_count; // Number of sectors on device.
+ cyg_uint32 jedec_id; // 3 byte JEDEC identifier for this device.
+} m25pxx_params;
+
+static const m25pxx_params m25pxx_supported_devices [] = {
+ { // Support for Numonyx 128 MBit devices.
+ sector_size : 1024,
+ sector_count : 64,
+ jedec_id : 0x00202018
+ },
+ { // Support for Numonyx 64 MBit devices.
+ sector_size : 256,
+ sector_count : 128,
+ jedec_id : 0x00202017
+ },
+ { // Support for Numonyx 16 MBit devices.
+ sector_size : 256,
+ sector_count : 64,
+ jedec_id : 0x00202016
+ },
+ { // Support for Numonyx 16 MBit devices.
+ sector_size : 256,
+ sector_count : 32,
+ jedec_id : 0x00202015
+ },
+ { // Support for Numonyx 8 MBit devices.
+ sector_size : 256,
+ sector_count : 16,
+ jedec_id : 0x00202014
+ },
+ { // Support for Numonyx 4 MBit devices.
+ sector_size : 256,
+ sector_count : 8,
+ jedec_id : 0x00202013
+ },
+ { // Support for Numonyx 2 MBit devices.
+ sector_size : 256,
+ sector_count : 4,
+ jedec_id : 0x00202012
+ },
+ { // Support for Numonyx 1 MBit devices.
+ sector_size : 128,
+ sector_count : 4,
+ jedec_id : 0x00202011
+ },
+ { // Support for Numonyx 512 KBit devices.
+ sector_size : 128,
+ sector_count : 2,
+ jedec_id : 0x00202010
+ },
+ { // Null terminating entry.
+ sector_size : 0,
+ sector_count : 0,
+ jedec_id : 0
+ }
+};
+
+//=============================================================================
+// Utility functions for address calculations.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Strips out any device address offset to give address within device.
+
+static cyg_bool m25pxx_to_local_addr
+ (struct cyg_flash_dev* dev, cyg_flashaddr_t* addr)
+{
+ cyg_bool retval = false;
+
+ // Range check address before modifying it.
+ if ((*addr >= dev->start) && (*addr <= dev->end)) {
+ *addr -= dev->start;
+ retval = true;
+ }
+ return retval;
+}
+
+//=============================================================================
+// Wrapper functions for various SPI transactions.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Read back the 3-byte JEDEC ID, returning it as a 32-bit integer.
+// This function is called during flash initialisation, which can often be
+// called from the startup/idle thread. This means that we should always use
+// SPI polled mode in order to prevent the thread from attempting to sleep.
+
+static inline cyg_uint32 m25pxx_spi_rdid
+ (struct cyg_flash_dev *dev)
+{
+ cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+ const cyg_uint8 tx_buf [4] = { M25PXX_CMD_RDID, 0, 0, 0 };
+ cyg_uint8 rx_buf [4];
+ cyg_uint32 retval = 0;
+
+ // Carry out SPI transfer.
+ cyg_spi_transfer (spi_device, true, 4, tx_buf, rx_buf);
+
+ // Convert 3-byte ID to 32-bit integer.
+ retval |= ((cyg_uint32) rx_buf[1]) << 16;
+ retval |= ((cyg_uint32) rx_buf[2]) << 8;
+ retval |= ((cyg_uint32) rx_buf[3]);
+
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Send write enable command.
+
+static inline void m25pxx_spi_wren
+ (struct cyg_flash_dev *dev)
+{
+ cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+ const cyg_uint8 tx_buf [1] = { M25PXX_CMD_WREN };
+ cyg_spi_transfer (spi_device, M25PXX_POLLED, 1, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Send sector erase command. The address parameter is a device local address
+// within the sector to be erased.
+
+static inline void m25pxx_spi_se
+ (struct cyg_flash_dev *dev, cyg_flashaddr_t addr)
+{
+ cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+ const cyg_uint8 tx_buf [4] = { M25PXX_CMD_SE,
+ (cyg_uint8) (addr >> 16), (cyg_uint8) (addr >> 8), (cyg_uint8) (addr) };
+ cyg_spi_transfer (spi_device, M25PXX_POLLED, 4, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Read and return the 8-bit device status register.
+
+static inline cyg_uint8 m25pxx_spi_rdsr
+ (struct cyg_flash_dev *dev)
+{
+ cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+ const cyg_uint8 tx_buf [2] = { M25PXX_CMD_RDSR, 0 };
+ cyg_uint8 rx_buf [2];
+
+ // Carry out SPI transfer and return the status byte.
+ cyg_spi_transfer (spi_device, M25PXX_POLLED, 2, tx_buf, rx_buf);
+ return rx_buf [1];
+}
+
+//-----------------------------------------------------------------------------
+// Program a single page.
+
+static inline void m25pxx_spi_pp
+ (struct cyg_flash_dev *dev, cyg_flashaddr_t addr, cyg_uint8* wbuf, cyg_uint32 wbuf_len)
+{
+ cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+ const cyg_uint8 tx_buf [4] = { M25PXX_CMD_PP,
+ (cyg_uint8) (addr >> 16), (cyg_uint8) (addr >> 8), (cyg_uint8) (addr) };
+
+ // Implement the program operation as a multistage SPI transaction.
+ cyg_spi_transaction_begin (spi_device);
+ cyg_spi_transaction_transfer (spi_device, M25PXX_POLLED, 4, tx_buf, NULL, false);
+ cyg_spi_transaction_transfer (spi_device, M25PXX_POLLED, wbuf_len, wbuf, NULL, false);
+ cyg_spi_transaction_end (spi_device);
+}
+
+//-----------------------------------------------------------------------------
+// Implement fast reads to the specified buffer.
+
+static inline void m25pxx_spi_fread
+ (struct cyg_flash_dev *dev, cyg_flashaddr_t addr, cyg_uint8* rbuf, cyg_uint32 rbuf_len)
+{
+ cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+ const cyg_uint8 tx_buf [5] = { M25PXX_CMD_FREAD,
+ (cyg_uint8) (addr >> 16), (cyg_uint8) (addr >> 8), (cyg_uint8) (addr), 0 };
+
+ // Implement the read operation as a multistage SPI transaction.
+ cyg_spi_transaction_begin (spi_device);
+ cyg_spi_transaction_transfer (spi_device, M25PXX_POLLED, 5, tx_buf, NULL, false);
+ cyg_spi_transaction_transfer (spi_device, M25PXX_POLLED, rbuf_len, NULL, rbuf, false);
+ cyg_spi_transaction_end (spi_device);
+}
+
+//=============================================================================
+// Standard Flash device API. All the following functions assume that a valid
+// SPI device handle is passed in the 'priv' reference of the flash device
+// data structure.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Initialise the SPI flash, reading back the flash parameters.
+
+static int m25pxx_init
+ (struct cyg_flash_dev *dev)
+{
+ m25pxx_params* dev_params = (m25pxx_params*) m25pxx_supported_devices;
+ cyg_uint32 device_id;
+ int retval = FLASH_ERR_INVALID;
+
+ // Find the device in the supported devices list.
+ device_id = m25pxx_spi_rdid (dev);
+ while ((dev_params->jedec_id != 0) && (dev_params->jedec_id != device_id)) {
+ dev_params ++;
+ }
+
+ // Found supported device - update device parameters. M25PXX devices have a
+ // uniform sector distribution, so only 1 block info record is required.
+ if (dev_params->jedec_id != 0) {
+ ASSERT_M25P (dev->num_block_infos == 1, "Only 1 block info record required.");
+ ASSERT_M25P (dev->block_info != NULL, "Null pointer to block info record.");
+ if ((dev->num_block_infos == 1) && (dev->block_info != NULL)) {
+ TRACE_M25P ("Init device with JEDEC ID 0x%06X.\n", device_id);
+ dev->end = dev->start + (M25PXX_PAGE_SIZE * (cyg_flashaddr_t) dev_params->sector_size *
+ (cyg_flashaddr_t) dev_params->sector_count) - 1;
+
+ // Strictly speaking the block info fields are 'read only'. However, we
+ // have a legitimate reason for updating the contents here and can cast
+ // away the const.
+ ((cyg_flash_block_info_t*) dev->block_info)->block_size =
+ M25PXX_PAGE_SIZE * (size_t) dev_params->sector_size;
+ ((cyg_flash_block_info_t*) dev->block_info)->blocks =
+ (cyg_uint32) dev_params->sector_count;
+ retval = FLASH_ERR_OK;
+ }
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Erase a single sector of the flash.
+
+static int m25pxx_erase_block
+ (struct cyg_flash_dev *dev, cyg_flashaddr_t block_base)
+{
+ cyg_flashaddr_t local_base = block_base;
+ int retval = FLASH_ERR_INVALID;
+ cyg_uint8 dev_status;
+
+ // Fix up the block address and send the sector erase command.
+ if (m25pxx_to_local_addr (dev, &local_base)) {
+ m25pxx_spi_wren (dev);
+ m25pxx_spi_se (dev, local_base);
+
+ // Spin waiting for the erase to complete. This can take between 1 and 3
+ // seconds, so we use a polling interval of 1/2 sec.
+ do {
+ M25PXX_DELAY_MS (500);
+ dev_status = m25pxx_spi_rdsr (dev);
+ } while (dev_status & M25PXX_STATUS_WIP);
+
+ retval = FLASH_ERR_OK;
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Program an arbitrary number of pages into flash and verify written data.
+
+static int m25pxx_program
+ (struct cyg_flash_dev *dev, cyg_flashaddr_t base, const void* data, size_t len)
+{
+ cyg_flashaddr_t local_base = base;
+ int retval = FLASH_ERR_OK;
+ cyg_uint8* tx_ptr = (cyg_uint8*) data;
+ cyg_uint32 tx_bytes_left = (cyg_uint32) len;
+ cyg_uint32 tx_bytes;
+ cyg_uint8 dev_status;
+
+ // Fix up the block address.
+ if (!m25pxx_to_local_addr (dev, &local_base)) {
+ retval = FLASH_ERR_INVALID;
+ goto out;
+ }
+
+ // The start of the transaction may not be page aligned, so we need to work
+ // out how many bytes to transmit before we hit the first page boundary.
+ tx_bytes = M25PXX_PAGE_SIZE - (((cyg_uint32) local_base) & (M25PXX_PAGE_SIZE - 1));
+ if (tx_bytes > tx_bytes_left) tx_bytes = tx_bytes_left;
+
+ // Perform page program operations.
+ while (tx_bytes_left) {
+ m25pxx_spi_wren (dev);
+ m25pxx_spi_pp (dev, local_base, tx_ptr, tx_bytes);
+
+ // Spin waiting for write to complete. This can take up to 5ms, so
+ // we use a polling interval of 1ms - which may get rounded up to the
+ // RTC tick granularity.
+ do {
+ M25PXX_DELAY_MS (1);
+ dev_status = m25pxx_spi_rdsr (dev);
+ } while (dev_status & M25PXX_STATUS_WIP);
+
+ // Update counters and data pointers for the next page.
+ tx_bytes_left -= tx_bytes;
+ tx_ptr += tx_bytes;
+ local_base += tx_bytes;
+ tx_bytes = (tx_bytes_left > M25PXX_PAGE_SIZE) ? M25PXX_PAGE_SIZE : tx_bytes_left;
+ }
+
+out:
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Read back an arbitrary amount of data from flash.
+
+static int m25pxx_read
+ (struct cyg_flash_dev *dev, const cyg_flashaddr_t base, void* data, size_t len)
+{
+ cyg_flashaddr_t local_base = base;
+ int retval = FLASH_ERR_INVALID;
+ cyg_uint8* rx_ptr = (cyg_uint8*) data;
+ cyg_uint32 rx_bytes_left = (cyg_uint32) len;
+ cyg_uint32 rx_bytes;
+
+ // Determine the maximum transfer size to use.
+ cyg_uint32 rx_block_size = (CYGNUM_DEVS_FLASH_SPI_M25PXX_READ_BLOCK_SIZE == 0) ?
+ 0xFFFFFFFF : CYGNUM_DEVS_FLASH_SPI_M25PXX_READ_BLOCK_SIZE;
+
+ // Fix up the block address and fill the read buffer.
+ if (m25pxx_to_local_addr (dev, &local_base)) {
+ while (rx_bytes_left) {
+ rx_bytes = (rx_bytes_left < rx_block_size) ? rx_bytes_left : rx_block_size;
+ m25pxx_spi_fread (dev, local_base, rx_ptr, rx_bytes);
+
+ // Update counters and data pointers for next read block.
+ rx_bytes_left -= rx_bytes;
+ rx_ptr += rx_bytes;
+ local_base += rx_bytes;
+ }
+ retval = FLASH_ERR_OK;
+ }
+ return retval;
+}
+
+//=============================================================================
+// Fill in the driver data structures.
+//=============================================================================
+
+CYG_FLASH_FUNS (
+ cyg_devs_flash_spi_m25pxx_funs, // Exported name of function pointers.
+ m25pxx_init, // Flash initialisation.
+ cyg_flash_devfn_query_nop, // Query operations not supported.
+ m25pxx_erase_block, // Sector erase.
+ m25pxx_program, // Program multiple pages.
+ m25pxx_read, // Read arbitrary amount of data.
+ cyg_flash_devfn_lock_nop, // Locking not supported (no per-sector locks).
+ cyg_flash_devfn_unlock_nop
+);
+
+//=============================================================================
diff --git a/ecos/packages/devs/flash/spi/m25pxx/current/test/m25pxx_test.c b/ecos/packages/devs/flash/spi/m25pxx/current/test/m25pxx_test.c
new file mode 100644
index 0000000..587155e
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/m25pxx/current/test/m25pxx_test.c
@@ -0,0 +1,396 @@
+//=============================================================================
+//
+// m25pxx_test.c
+//
+// SPI flash driver tests for Numonyx M25Pxx devices and compatibles.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Chris Holgate
+// Date: 2008-12-22
+// Purpose: Numonyx M25Pxx SPI flash driver stress tests.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/testcase.h> // Test macros
+#include <cyg/infra/cyg_ass.h> // Assertion macros
+#include <cyg/infra/diag.h> // Diagnostic output
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/hal/hal_if.h>
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/io/spi.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/m25pxx.h>
+
+#include <string.h>
+
+#include CYGHWR_MEMORY_LAYOUT_H
+
+//-----------------------------------------------------------------------------
+// Set up the SPI intertface on the ST STM3210E eval board for the STM32. The
+// M25PXX device is connected to SPI bus 1. To configure the board for this
+// test, jumper JP3 must be open and SPI1 should be set up in configtool so
+// that chip select 1 corresponds to GPIO number 18 (PB2) and 50MHz I/O is
+// enabled. If the data area is in external RAM, SPI1 must be configured with
+// bounce buffers of at least 256 bytes and the M25PXX read data block size
+// should be set to the same size as the bounce buffers.
+
+#ifdef CYGPKG_HAL_CORTEXM_STM32_STM3210E_EVAL
+#include <cyg/io/spi_stm32.h>
+
+CYG_DEVS_SPI_CORTEXM_STM32_DEVICE (
+ m25pxx_spi_device, 1, 0, false, 0, 0, 25000000, 1, 1, 1
+);
+
+#endif
+
+//-----------------------------------------------------------------------------
+// Instantiate the M25Pxx device driver.
+
+CYG_DEVS_FLASH_SPI_M25PXX_DRIVER (
+ m25pxx_flash_device, 0, &m25pxx_spi_device
+);
+
+//-----------------------------------------------------------------------------
+// Thread data structures.
+
+static cyg_uint32 stack [CYGNUM_HAL_STACK_SIZE_TYPICAL / 4];
+static cyg_thread thread_data;
+static cyg_handle_t thread_handle;
+
+//-----------------------------------------------------------------------------
+// Data transfer buffers.
+
+#define BUF_SIZE 1024
+
+static cyg_uint8 wbuf [BUF_SIZE];
+static cyg_uint8 rbuf [BUF_SIZE];
+
+//-----------------------------------------------------------------------------
+// Print out version information.
+
+void do_version (void)
+{
+ char *version = CYGACC_CALL_IF_MONITOR_VERSION();
+ if (version != NULL) diag_printf("%s", version);
+#ifdef HAL_PLATFORM_CPU
+ diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
+#endif
+ diag_printf("RAM: %p-%p, ", (void*)(CYGMEM_REGION_ram), (void*)(CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - 1));
+ diag_printf("(HEAP: %p-%p)\n", (void*)(CYGMEM_SECTION_heap1), (void*)(CYGMEM_SECTION_heap1 + CYGMEM_SECTION_heap1_SIZE - 1));
+}
+
+//-----------------------------------------------------------------------------
+// Run checkerboard and inverse checkerboard writes over each sector in turn.
+
+cyg_uint32 run_test_1
+ (void)
+{
+ int status;
+ cyg_uint32 i, j;
+ cyg_uint32 errors = 0;
+ cyg_flashaddr_t base_addr, err_addr;
+
+ diag_printf ("Test 1 - write and verify checkerboard and inverse checkerboard.\n");
+
+ // Iterate over all flash sectors.
+ for (i = 0; i < m25pxx_flash_device.block_info->blocks; i++) {
+ base_addr = m25pxx_flash_device.start + (i * m25pxx_flash_device.block_info->block_size);
+
+ // Erase block.
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Set up buffer with checkerboard.
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = 0x55;
+ wbuf [j++] = 0xAA;
+ }
+
+ // Write the checkerboard to the entire sector.
+ for (j = 0; j < m25pxx_flash_device.block_info->block_size; j += BUF_SIZE) {
+ status = cyg_flash_program (base_addr + j, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ }
+
+ // Read back the checkerboard and verify.
+ for (j = 0; j < m25pxx_flash_device.block_info->block_size; j += BUF_SIZE) {
+ status = cyg_flash_read (base_addr + j, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n", base_addr + j, base_addr + j + BUF_SIZE - 1);
+ errors ++;
+ }
+ }
+
+ // Erase block.
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Set up buffer with inverse checkerboard.
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = 0xAA;
+ wbuf [j++] = 0x55;
+ }
+
+ // Write the checkerboard to the entire sector.
+ for (j = 0; j < m25pxx_flash_device.block_info->block_size; j += BUF_SIZE) {
+ status = cyg_flash_program (base_addr + j, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ }
+
+ // Read back the checkerboard and verify.
+ for (j = 0; j < m25pxx_flash_device.block_info->block_size; j += BUF_SIZE) {
+ status = cyg_flash_read (base_addr + j, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n", base_addr + j, base_addr + j + BUF_SIZE - 1);
+ errors ++;
+ }
+ }
+ }
+ return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Write and verify counting sequence over all device.
+
+cyg_uint32 run_test_2
+ (void)
+{
+ int status;
+ cyg_uint32 i, j;
+ cyg_uint32 errors = 0;
+ cyg_flashaddr_t base_addr, err_addr;
+
+ diag_printf ("Test 2 - write and verify counting sequence.\n");
+
+ // Erase all flash sectors.
+ for (i = 0; i < m25pxx_flash_device.block_info->blocks; i++) {
+ base_addr = m25pxx_flash_device.start + (i * m25pxx_flash_device.block_info->block_size);
+
+ // Erase block.
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ }
+
+ // Write counting sequence.
+ base_addr = m25pxx_flash_device.start;
+ for (i = 0; i < (m25pxx_flash_device.end - m25pxx_flash_device.start) / 4;) {
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = (cyg_uint8) ((i >> 0) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 8) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 16) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 24) & 0xFF);
+ i++;
+ }
+ status = cyg_flash_program (base_addr, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ base_addr += BUF_SIZE;
+ }
+
+ // Verify counting sequence.
+ base_addr = m25pxx_flash_device.start;
+ for (i = 0; i < (m25pxx_flash_device.end - m25pxx_flash_device.start) / 4;) {
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = (cyg_uint8) ((i >> 0) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 8) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 16) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 24) & 0xFF);
+ i++;
+ }
+ status = cyg_flash_read (base_addr, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n", base_addr, base_addr + BUF_SIZE - 1);
+ errors ++;
+ }
+ base_addr += BUF_SIZE;
+ }
+ return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Perform non-aligned buffer read/write tests, spanning sector boundaries.
+
+cyg_uint32 run_test_3
+ (void)
+{
+ int status;
+ cyg_uint32 i, count;
+ cyg_uint32 errors = 0;
+ cyg_flashaddr_t base_addr, err_addr;
+
+ diag_printf ("Test 3 - test non-aligned writes and reads.\n");
+
+ // Fill the write buffer with a basic counting sequence.
+ count = 0;
+ for (i = 0; i < BUF_SIZE;) {
+ wbuf [i++] = (cyg_uint8) ((count >> 0) & 0xFF);
+ wbuf [i++] = (cyg_uint8) ((count >> 8) & 0xFF);
+ count++;
+ }
+
+ // Assuming 256 byte pages gives 256 possible alignments.
+ base_addr = m25pxx_flash_device.start + m25pxx_flash_device.block_info->block_size;
+ for (i = 1; i <= 256; i++) {
+
+ // Erase sectors either side of sector boundary.
+ status = cyg_flash_erase (base_addr - 1, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Write data spanning sector boundary.
+ status = cyg_flash_program (base_addr - i, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Verify data spanning sector boundary.
+ status = cyg_flash_read (base_addr - i, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n", base_addr - i, base_addr - i + BUF_SIZE - 1);
+ errors ++;
+ }
+
+ // Use next sector boundary for next test.
+ base_addr += m25pxx_flash_device.block_info->block_size;
+ if (base_addr >= m25pxx_flash_device.end)
+ base_addr = m25pxx_flash_device.start + m25pxx_flash_device.block_info->block_size;
+ }
+ return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Run all M25Pxx SPI interface loopback tests.
+
+void run_tests
+ (void)
+{
+ cyg_uint32 errors = 0;
+
+ // Check that the device is intialised.
+ if (m25pxx_flash_device.start == m25pxx_flash_device.end) {
+ diag_printf ("M25Pxx device not initialised.\n");
+ errors ++;
+ goto out;
+ }
+
+ // Run the tests.
+ errors += run_test_1 ();
+ errors += run_test_2 ();
+ errors += run_test_3 ();
+
+out:
+ diag_printf ("----\nTests complete - detected %d errors in total.\n", errors);
+ if (errors == 0)
+ CYG_TEST_PASS_FINISH ("M25Pxx driver tests ran OK.");
+ else
+ CYG_TEST_FAIL_FINISH ("M25Pxx driver test FAILED.");
+}
+
+//-----------------------------------------------------------------------------
+// User startup - tests are run in their own thread.
+
+void cyg_user_start
+ (void)
+{
+ do_version();
+ diag_printf ("----\nChecking for M25Pxx compatible devices.\n");
+ cyg_flash_set_global_printf((cyg_flash_printf *)&diag_printf);
+ cyg_flash_init(NULL);
+ CYG_TEST_INIT();
+ cyg_thread_create(
+ 10, // Arbitrary priority
+ (cyg_thread_entry_t*) run_tests, // Thread entry point
+ 0, //
+ "test_thread", // Thread name
+ (cyg_uint8*) stack, // Stack
+ CYGNUM_HAL_STACK_SIZE_TYPICAL, // Stack size
+ &thread_handle, // Thread handle
+ &thread_data // Thread data structure
+ );
+ cyg_thread_resume(thread_handle);
+ cyg_scheduler_start();
+}
+
+//=============================================================================
diff --git a/ecos/packages/devs/flash/spi/sst25xx/current/ChangeLog b/ecos/packages/devs/flash/spi/sst25xx/current/ChangeLog
new file mode 100644
index 0000000..36678b7
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/sst25xx/current/ChangeLog
@@ -0,0 +1,38 @@
+2012-02-06 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/flash_sst25xx.cdl
+ * src/sst25xx.c:
+ * tests/flash_sst25xx_test.c: New file
+ Added tests [Bugzilla 1001450]
+
+2011-04-13 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * cdl/sst25xx.cdl:
+ * include/sst25xx.h:
+ * src/sst25xx.c:
+ New package - SPI flash driver for Silicon Storage Technology,
+ SST25xx devices.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/spi/sst25xx/current/cdl/flash_sst25xx.cdl b/ecos/packages/devs/flash/spi/sst25xx/current/cdl/flash_sst25xx.cdl
new file mode 100644
index 0000000..f06d065
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/sst25xx/current/cdl/flash_sst25xx.cdl
@@ -0,0 +1,145 @@
+##=============================================================================
+##
+## flash_sst25xx.cdl
+##
+## SST25xx SPI flash driver configuration options.
+##
+##=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+##
+## Author(s): ccoutand, updated for Silicon Storage Technology
+## SST25xx flash
+## Original(s): Chris Holgate
+## Date: 2011-04-25
+## Purpose: Configure SST25xx SPI flash driver.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SPI_SST25XX {
+ display "Silicon Storage Technology SST25xx flash memory support"
+ parent CYGPKG_IO_FLASH
+ active_if { CYGPKG_IO_FLASH && CYGPKG_IO_SPI }
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_BLOCK_LOCKING
+ implements CYGHWR_IO_FLASH_INDIRECT_READS
+
+ include_dir cyg/io
+ compile -library=libextras.a sst25xx.c
+
+ description "
+ Flash memory support for the Silicon Storage Technology SST25xx
+ SPI flash devices and compatibles. This driver implements the
+ V2 flash driver API"
+
+ cdl_interface CYGHWR_DEVS_FLASH_SPI_SST25XX_DEVICE {
+ display "Hardware SST25xx FLASH device drivers"
+ description "
+ This calculated option gives the number of SST25xx flash
+ devices on the current platform."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_SPI_SST25XX_SUPPORT_JEDECID {
+ display "Device supports JEDEC ID"
+ flavor bool
+ default_value 0
+
+ description "
+ Allow probing of the SPI flash(s) on the bus using the
+ JededID Opcode. Some device do not support this command
+ (SST25VF010A, SST25VF512A etc.)."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_SPI_SST25XX_BLOCK_SIZE {
+ display "Flash block size in bytes"
+ flavor data
+ legal_values { 4096 32768 65536 }
+ default_value { 4096 }
+
+ description "
+ Most SST25xx SPI flash devices can use block size of 4KB,
+ 32K or 64KB. This option allow users to select which flash
+ geometry to use. For device such as AT25F512 not supporting
+ 64K, selecting a wrong geometry will force the driver to
+ abort the initialization process."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_SPI_SST25XX_READ_MODE {
+ display "Flash read transaction"
+ flavor data
+ legal_values { "FAST" "SLOW" }
+ default_value { "FAST" }
+
+ description "
+ The SST25xx SPI flash devices differentiate read access
+ according to the throughput required for this operation. The
+ driver allows both fast and slow reading operation. The
+ option requires the physical layer to use the appropriate
+ SPI bus clock frequency."
+ }
+
+ cdl_option CYGNUM_DEVS_FLASH_SPI_SST25XX_READ_BLOCK_SIZE {
+ display "Maximum read block size"
+ flavor data
+ default_value 0
+
+ description "
+ In theory it is possible to read back the entire flash
+ contents using a single SPI transaction. However, some SPI
+ bus drivers have a maximum transaction size - for example
+ transactions may be limited to the length of a DMA bounce
+ buffer. Setting this option to a non-zero value specifies
+ the maximum SPI bus transfer size which will be used when
+ reading back data. Read requests for areas larger than
+ this block size will automatically be split into a series
+ of smaller SPI bus transactions."
+ }
+
+ cdl_component CYGPKG_DEVS_FLASH_SPI_SST25XX_TESTS {
+ display "SST25xx tests"
+ flavor data
+ active_if CYGPKG_KERNEL
+ active_if CYGPKG_IO_SPI
+ active_if { CYGHWR_DEVS_FLASH_SPI_SST25XX_DEVICE >= 1 }
+ no_define
+ calculated { "tests/flash_sst25xx_test.c" }
+ description "
+ This option specifies the set of tests for sst25 driver."
+ }
+}
+
+# EOF flash_sst25xx.cdl
diff --git a/ecos/packages/devs/flash/spi/sst25xx/current/include/sst25xx.h b/ecos/packages/devs/flash/spi/sst25xx/current/include/sst25xx.h
new file mode 100644
index 0000000..a1cc80f
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/sst25xx/current/include/sst25xx.h
@@ -0,0 +1,83 @@
+#ifndef CYGONCE_DEVS_FLASH_SPI_SST25XX_H
+#define CYGONCE_DEVS_FLASH_SPI_SST25XX_H
+
+//=============================================================================
+//
+// sst25xx.h
+//
+// SPI flash driver for Silicon Storage Technology SST25xx devices
+// and compatibles.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand, updated for Silicon Storage Technology SST25xx
+// flash
+// Original(s): Chris Holgate
+// Purpose: Silicon Storage Technology SST25xxx SPI flash driver
+// implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// Required data structures.
+#include <cyg/io/flash_dev.h>
+
+// Exported handle on the driver function table.
+externC struct cyg_flash_dev_funs cyg_devs_flash_spi_sst25xx_funs;
+
+//-----------------------------------------------------------------------------
+// Macro used to generate a flash device object with the default SST25XX
+// settings. Even though the block info data structure is declared here, the
+// details are not filled in until the device type is inferred during
+// initialization. This also applies to the 'end' field which is calculated
+// using the _start_ address and the inferred size of the device.
+// _name_ is the root name of the instantiated data structures.
+// _start_ is the base address of the device - for SPI based devices this can
+// have an arbitrary value, since the device is not memory mapped.
+// _spidev_ is a pointer to a SPI device object of type cyg_spi_device. This
+// is not typechecked during compilation so be careful!
+
+#define CYG_DEVS_FLASH_SPI_SST25XX_DRIVER(_name_, _start_, _spidev_) \
+struct cyg_flash_block_info _name_ ##_block_info; \
+CYG_FLASH_DRIVER(_name_, &cyg_devs_flash_spi_sst25xx_funs, 0, \
+ _start_, _start_, 1, & _name_ ##_block_info, (void*) _spidev_)
+
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_DEVS_FLASH_SPI_SST25XX_H
+// EOF sst25xx.h
diff --git a/ecos/packages/devs/flash/spi/sst25xx/current/src/sst25xx.c b/ecos/packages/devs/flash/spi/sst25xx/current/src/sst25xx.c
new file mode 100644
index 0000000..7f0cae6
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/sst25xx/current/src/sst25xx.c
@@ -0,0 +1,709 @@
+//=============================================================================
+//
+// sst25xx.c
+//
+// SPI flash driver for Silicon Storage Technology SST25xx devices
+// and compatibles.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand, updated for Silicon Storage Technology SST25xx
+// flash
+// Original(s): Chris Holgate
+// Date: 2011-04-25
+// Purpose: Silicon Storage Technology SST25xx SPI flash driver
+// implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/io/spi.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <pkgconf/devs_flash_spi_sst25xx.h>
+
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// Enable polled SPI operation for non-kernel builds.
+
+#ifdef CYGPKG_KERNEL
+# define SST25XX_POLLED false
+#else
+# define SST25XX_POLLED true
+#endif
+
+//-----------------------------------------------------------------------------
+// Implement delay functions for kernel and non-kernel builds. The kernel
+// build assumes that the API calls are made in the thread context.
+
+#ifdef CYGPKG_KERNEL
+#define SST25XX_DELAY_MS(_msdelay_) cyg_thread_delay \
+ (1 + ((1000 * _msdelay_ * CYGNUM_HAL_RTC_DENOMINATOR) / (CYGNUM_HAL_RTC_NUMERATOR / 1000)))
+
+#else
+#define SST25XX_DELAY_MS(_msdelay_) CYGACC_CALL_IF_DELAY_US (_msdelay_ * 1000)
+#endif
+
+// Byte / word programming takes 10 us max
+#define SST25XX_WAIT_CHIP_READY( dev ) \
+{ \
+ cyg_uint8 dev_status; \
+ do { \
+ HAL_DELAY_US (10); \
+ dev_status = sst25xx_spi_rdsr ( dev ); \
+ } while ( dev_status & SST25XX_STATUS_BSY ); \
+}
+
+//-----------------------------------------------------------------------------
+// Maintenance and debug macros.
+
+#define ASSERT_SST25XX(_test_, _msg_) CYG_ASSERT(_test_, "FAIL (SST25XX) : " _msg_)
+#define TRACE_SST25XX(_msg_, _args_...) if (dev->pf) dev->pf ("SST25XX : " _msg_, ##_args_)
+
+//=============================================================================
+// Define SST25VFxxx SPI protocol.
+//=============================================================================
+
+typedef enum sst25xx_cmd {
+ SST25XX_CMD_WREN = 0x06, // Write enable.
+ SST25XX_CMD_WDRI = 0x04, // Write disable.
+ SST25XX_CMD_RDJID = 0x9F, // Read JEDEC identification.
+ SST25XX_CMD_RDID = 0x90, // Read Manufacturer / Device identification.
+ SST25XX_CMD_RDSR = 0x05, // Read status register.
+ SST25XX_CMD_WRSR = 0x01, // Write status register.
+ SST25XX_CMD_READ = 0x03, // Read data
+ SST25XX_CMD_FREAD = 0x0B, // Read data (fast).
+ SST25XX_CMD_BP = 0x02, // Byte program.
+ SST25XX_CMD_AAI = 0xAD, // Word program (with address increment).
+ SST25XX_CMD_SE_4K = 0x20, // 4K sector erase.
+ SST25XX_CMD_SE_32K = 0x52, // 32K sector erase.
+ SST25XX_CMD_SE_64K = 0xD8, // 64K sector erase.
+ SST25XX_CMD_BE = 0xC7, // Chip erase.
+} sst25xx_cmd;
+
+// Status register bitfields.
+#define SST25XX_STATUS_BSY 0x01 /* Operation in progress. */
+#define SST25XX_STATUS_WEL 0x02 /* Write enable latch. */
+#define SST25XX_STATUS_BP0 0x04 /* Block Write Protect 0. */
+#define SST25XX_STATUS_BP1 0x08 /* Block Write Protect 1. */
+#define SST25XX_STATUS_BP2 0x10 /* Block Write Protect 2. */
+#define SST25XX_STATUS_BP3 0x20 /* Block Write Protect 3. */
+#define SST25XX_STATUS_AAI 0x40 /* Auto Address Increment Programming Status */
+#define SST25XX_STATUS_SPRL 0x80 /* Sector Protect Register Bit Lock. */
+
+#define SST25XX_LOCK_BITS ( SST25XX_STATUS_BP0 | SST25XX_STATUS_BP1 | \
+ SST25XX_STATUS_BP2 | SST25XX_STATUS_BP3 )
+
+#define SST25XX_MEMORY_ID 0x25
+
+// A few helper constants
+#ifndef SZ_1K
+# define SZ_1K 0x00000400
+# define SZ_2K 0x00000800
+# define SZ_4K 0x00001000
+# define SZ_8K 0x00002000
+# define SZ_16K 0x00004000
+# define SZ_32K 0x00008000
+# define SZ_64K 0x00010000
+#endif
+
+// Select read OPCODE
+#if defined(CYGPKG_DEVS_FLASH_SPI_SST25XX_READ_MODE_SLOW)
+# define SST25XX_CMD_READ_LEN 4
+# define SST25XX_CMD_READ_OPCODE SST25XX_CMD_READ
+#elif defined(CYGPKG_DEVS_FLASH_SPI_SST25XX_READ_MODE_FAST)
+# define SST25XX_CMD_READ_LEN 5
+# define SST25XX_CMD_READ_OPCODE SST25XX_CMD_FREAD
+#endif
+
+// Select sector size
+#if CYGPKG_DEVS_FLASH_SPI_SST25XX_BLOCK_SIZE == SZ_64K
+# define SST25XX_CMD_SE SST25XX_CMD_SE_64K
+#elif CYGPKG_DEVS_FLASH_SPI_SST25XX_BLOCK_SIZE == SZ_32K
+# define SST25XX_CMD_SE SST25XX_CMD_SE_32K
+#elif CYGPKG_DEVS_FLASH_SPI_SST25XX_BLOCK_SIZE == SZ_4K
+# define SST25XX_CMD_SE SST25XX_CMD_SE_4K
+#endif
+
+//=============================================================================
+// Array containing a list of supported devices. This allows the device
+// parameters to be dynamically detected on initialization.
+//=============================================================================
+
+typedef struct sst25xx_params {
+ cyg_uint16 sector_count[4]; // Number of sectors on device.
+ cyg_uint32 sector_size[4]; // Supported sector size(s) in Byte
+ cyg_uint32 jedec_id; // 3 byte JEDEC identifier for this device.
+} sst25xx_params;
+
+
+static const sst25xx_params sst25xx_supported_devices [] = {
+ // Some Silicon Storage Technology parts.
+ // Note1: Some part do not support the Read Jedec ID Opcode, instead,
+ // the Read ID Opcode is used which is backward compatible with all
+ // parts
+ // Note2: Not all parts can support sector size of 4, 32 or 64 KBytes
+ { // Support for SST 64 MBit devices (SST25VF064C).
+ sector_count : {2048, 256, 128, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ jedec_id : 0x00bf254B
+ },
+ { // Support for SST 32 MBit devices (SST25VF032B).
+ sector_count : {1024, 128, 64, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ jedec_id : 0x00bf254a
+ },
+ { // Support for SST 16 MBit devices (SST25VF016B).
+ sector_count : {512, 64, 32, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ jedec_id : 0x00bf2541
+ },
+ { // Support for SST 8 MBit devices (SST25VF080B).
+ sector_count : {256, 32, 16, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ jedec_id : 0x00bf258E
+ },
+ { // Support for SST 4 MBit devices (SST25VF040B).
+ sector_count : {128, 16, 8, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ jedec_id : 0x00bf258D
+ },
+ { // Support for SST 2 MBit devices (SST25VF020B).
+ sector_count : {64, 8, 4, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ jedec_id : 0x00bf258C
+ },
+ { // Support for SST 2 MBit devices (SST25LF020A).
+ sector_count : {64, 8, 0},
+ sector_size : {SZ_4K, SZ_32K, 0},
+ // Constructed Jedec ID from ID (0xBF43)
+ jedec_id : 0x00bf2543
+ },
+ { // Support for SST 1 MBit devices (SST25VF010A).
+ sector_count : {32, 4, 0},
+ sector_size : {SZ_4K, SZ_32K, 0},
+ // Constructed Jedec ID from ID (0xBF49)
+ jedec_id : 0x00bf2549
+ },
+ { // Support for SST 512 KBit devices (SST25VF512A).
+ sector_count : {16, 2, 0},
+ sector_size : {SZ_4K, SZ_32K, 0},
+ // Constructed Jedec ID from ID (0xBF48)
+ jedec_id : 0x00bf2548
+ },
+ { // Support for SST 512 KBit devices (SST25WF512).
+ sector_count : {16, 2, 0},
+ sector_size : {SZ_4K, SZ_32K, 0},
+ jedec_id : 0x00bf2501
+ },
+ { // Support for SST 1 MBit devices (SST25WF010).
+ sector_count : {32, 4, 0},
+ sector_size : {SZ_4K, SZ_32K, 0},
+ jedec_id : 0x00bf2502
+ },
+ { // Support for SST 2 MBit devices (SST25WF020).
+ sector_count : {64, 8, 4},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ jedec_id : 0x00bf2503
+ },
+ { // Support for SST 4 MBit devices (SST25WF040).
+ sector_count : {128, 16, 8, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ jedec_id : 0x00bf2504
+ },
+ { // Support for SST 8 MBit devices (SST25WF080).
+ sector_count : {256, 32, 16, 0},
+ sector_size : {SZ_4K, SZ_32K, SZ_64K, 0},
+ jedec_id : 0x00bf2505
+ },
+ { // Null terminating entry.
+ sector_count : {0},
+ sector_size : {0},
+ jedec_id : 0
+ }
+};
+
+//=============================================================================
+// Utility functions for address calculations.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Strips out any device address offset to give address within device.
+
+static cyg_bool
+sst25xx_to_local_addr(struct cyg_flash_dev *dev, cyg_flashaddr_t * addr)
+{
+ cyg_bool retval = false;
+
+ // Range check address before modifying it.
+ if ((*addr >= dev->start) && (*addr <= dev->end)) {
+ *addr -= dev->start;
+ retval = true;
+ }
+ return retval;
+}
+
+//=============================================================================
+// Wrapper functions for various SPI transactions.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Read back the 3-byte JEDEC ID, returning it as a 32-bit integer.
+// This function is called during flash initialization, which can often be
+// called from the startup/idle thread. This means that we should always use
+// SPI polled mode in order to prevent the thread from attempting to sleep.
+
+#if defined(CYGPKG_DEVS_FLASH_SPI_SST25XX_SUPPORT_JEDECID)
+
+static inline cyg_uint32
+sst25xx_spi_rdid(struct cyg_flash_dev *dev)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[4] = { SST25XX_CMD_RDJID, 0x0, 0x0, 0x0 };
+ cyg_uint8 rx_buf[4];
+ cyg_uint32 retval = 0;
+
+ // Carry out SPI transfer.
+ cyg_spi_transfer(spi_device, true, 4, tx_buf, rx_buf);
+
+ // Convert 3-byte ID to 32-bit integer.
+ retval |= ((cyg_uint32)rx_buf[1]) << 16;
+ retval |= ((cyg_uint32)rx_buf[2]) << 8;
+ retval |= ((cyg_uint32)rx_buf[3]);
+
+ return retval;
+}
+
+#else
+
+static inline cyg_uint32
+sst25xx_spi_rdid(struct cyg_flash_dev *dev)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[6] = { SST25XX_CMD_RDID, 0x0, 0x0, 0x0, 0x0, 0x0 };
+ cyg_uint8 rx_buf[6];
+ cyg_uint32 retval = 0;
+
+ // Carry out SPI transfer.
+ cyg_spi_transfer(spi_device, true, 6, tx_buf, rx_buf);
+
+ // Convert 2-byte ID to 32-bit Jedec ID.
+ retval |= ((cyg_uint32)rx_buf[4]) << 16;
+ retval |= (SST25XX_MEMORY_ID << 8);
+ retval |= ((cyg_uint32)rx_buf[5]);
+
+ return retval;
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+// Send write enable command.
+
+static inline void
+sst25xx_spi_wren(struct cyg_flash_dev *dev)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[1] = { SST25XX_CMD_WREN };
+ cyg_spi_transfer(spi_device, SST25XX_POLLED, 1, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Send write disable command.
+
+static inline void
+sst25xx_spi_wrdis(struct cyg_flash_dev *dev)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[1] = { SST25XX_CMD_WDRI };
+ cyg_spi_transfer(spi_device, SST25XX_POLLED, 1, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Send sector erase command. The address parameter is a device local address
+// within the sector to be erased.
+
+static inline void
+sst25xx_spi_se(struct cyg_flash_dev *dev, cyg_flashaddr_t addr)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ cyg_uint8 tx_buf[4] = { SST25XX_CMD_SE,
+ (cyg_uint8)(addr >> 16), (cyg_uint8)(addr >> 8), (cyg_uint8)(addr)
+ };
+ cyg_spi_transfer(spi_device, SST25XX_POLLED, 4, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Read and return the 8-bit device status register.
+
+static inline cyg_uint8
+sst25xx_spi_rdsr(struct cyg_flash_dev *dev)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[2] = { SST25XX_CMD_RDSR, 0 };
+ cyg_uint8 rx_buf[2];
+
+ // Carry out SPI transfer and return the status byte.
+ cyg_spi_transfer(spi_device, SST25XX_POLLED, 2, tx_buf, rx_buf);
+
+ return rx_buf[1];
+}
+
+//-----------------------------------------------------------------------------
+// Program a single byte.
+
+static inline void
+sst25xx_spi_pbyte(struct cyg_flash_dev *dev, cyg_flashaddr_t addr,
+ cyg_uint8 *wbuf)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[4] = { SST25XX_CMD_BP,
+ (cyg_uint8)(addr >> 16), (cyg_uint8)(addr >> 8), (cyg_uint8)(addr)
+ };
+
+ // Implement the program operation as a multistage SPI transaction.
+ cyg_spi_transaction_begin(spi_device);
+ cyg_spi_transaction_transfer(spi_device, SST25XX_POLLED, 4, tx_buf, NULL,
+ false);
+ cyg_spi_transaction_transfer(spi_device, SST25XX_POLLED, 1, wbuf, NULL,
+ false);
+ cyg_spi_transaction_end(spi_device);
+}
+
+//-----------------------------------------------------------------------------
+// Program word with automatic address increment
+
+static inline void
+sst25xx_spi_pword(struct cyg_flash_dev *dev, cyg_flashaddr_t addr,
+ cyg_uint8 *wbuf, cyg_bool first)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[4] = { SST25XX_CMD_AAI,
+ (cyg_uint8)(addr >> 16), (cyg_uint8)(addr >> 8), (cyg_uint8)(addr)
+ };
+
+ // Implement the program operation as a multistage SPI transaction.
+ cyg_spi_transaction_begin(spi_device);
+ // Only convey the address with the first transaction. In the following
+ // transfers, address will be incremented internally by the SPI flash
+ if (first == true) {
+ cyg_spi_transaction_transfer(spi_device, SST25XX_POLLED, 4, tx_buf,
+ NULL, false);
+ } else {
+ cyg_spi_transaction_transfer(spi_device, SST25XX_POLLED, 1, tx_buf,
+ NULL, false);
+ }
+ cyg_spi_transaction_transfer(spi_device, SST25XX_POLLED, 2, wbuf, NULL,
+ false);
+ cyg_spi_transaction_end(spi_device);
+}
+
+//-----------------------------------------------------------------------------
+// Implement reads to the specified buffer.
+
+static inline void
+sst25xx_spi_read(struct cyg_flash_dev *dev, cyg_flashaddr_t addr,
+ cyg_uint8 *rbuf, cyg_uint32 rbuf_len)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ const cyg_uint8 tx_buf[5] = { SST25XX_CMD_READ_OPCODE,
+ (cyg_uint8)(addr >> 16), (cyg_uint8)(addr >> 8), (cyg_uint8)(addr), 0
+ };
+
+ // Implement the read operation as a multistage SPI transaction.
+ cyg_spi_transaction_begin(spi_device);
+ cyg_spi_transaction_transfer(spi_device, SST25XX_POLLED,
+ SST25XX_CMD_READ_LEN, tx_buf, NULL, false);
+ cyg_spi_transaction_transfer(spi_device, SST25XX_POLLED, rbuf_len, NULL,
+ rbuf, false);
+ cyg_spi_transaction_end(spi_device);
+}
+
+
+//=============================================================================
+// Standard Flash device API. All the following functions assume that a valid
+// SPI device handle is passed in the 'priv' reference of the flash device
+// data structure.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Initialize the SPI flash, reading back the flash parameters.
+
+static int
+sst25xx_init(struct cyg_flash_dev *dev)
+{
+ sst25xx_params *dev_params = (sst25xx_params *) sst25xx_supported_devices;
+ cyg_uint32 device_id;
+ cyg_uint8 i = 0;
+ int retval = FLASH_ERR_INVALID;
+
+ // Find the device in the supported devices list.
+ device_id = sst25xx_spi_rdid(dev);
+
+ while ((dev_params->jedec_id != 0) && (dev_params->jedec_id != device_id)) {
+ dev_params++;
+ }
+
+ // Found supported device - update device parameters. SST25XX devices have
+ // a uniform sector distribution, so only 1 block info record is required.
+ if (dev_params->jedec_id != 0) {
+
+ // Find out is the wanted sector size is supported by the device
+ while ((dev_params->sector_size[i] !=
+ CYGPKG_DEVS_FLASH_SPI_SST25XX_BLOCK_SIZE)
+ && (dev_params->sector_size[i] != 0))
+ i++;
+
+ if (dev_params->sector_size[i] !=
+ CYGPKG_DEVS_FLASH_SPI_SST25XX_BLOCK_SIZE) {
+ TRACE_SST25XX("Init device with JEDEC ID 0x%06X\n",
+ dev_params->jedec_id);
+ TRACE_SST25XX("SPI Flash Error, not supporting %dK sector size\n",
+ CYGPKG_DEVS_FLASH_SPI_SST25XX_BLOCK_SIZE);
+ return retval;
+ }
+
+ ASSERT_SST25XX(dev->num_block_infos == 1,
+ "Only 1 block info record required.");
+ ASSERT_SST25XX(dev->block_info != NULL,
+ "Null pointer to block info record.");
+
+ if ((dev->num_block_infos == 1) && (dev->block_info != NULL)) {
+ TRACE_SST25XX("Init device with JEDEC ID 0x%06X.\n", device_id);
+ dev->end =
+ dev->start +
+ ((cyg_flashaddr_t) dev_params->sector_size[i] *
+ (cyg_flashaddr_t) (dev_params->sector_count[i])) - 1;
+
+ // Strictly speaking the block info fields are 'read only'.
+ // However, we have a legitimate reason for updating the contents
+ // here and can cast away the const.
+ ((cyg_flash_block_info_t *) dev->block_info)->block_size =
+ (size_t)(dev_params->sector_size[i]);
+ ((cyg_flash_block_info_t *) dev->block_info)->blocks =
+ (cyg_uint32)(dev_params->sector_count[i]);
+
+ retval = FLASH_ERR_OK;
+ }
+
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Erase a single sector of the flash.
+
+static int
+sst25xx_erase_block(struct cyg_flash_dev *dev, cyg_flashaddr_t block_base)
+{
+ cyg_flashaddr_t local_base = block_base;
+ int retval = FLASH_ERR_INVALID;
+ cyg_uint8 dev_status;
+
+ // Fix up the block address and send the sector erase command.
+ if (sst25xx_to_local_addr(dev, &local_base)) {
+ sst25xx_spi_wren(dev);
+ sst25xx_spi_se(dev, local_base);
+
+ // Spin waiting for the erase to complete. Erasing takes around
+ // 25 ms
+ do {
+ SST25XX_DELAY_MS(10);
+ dev_status = sst25xx_spi_rdsr(dev);
+ } while (dev_status & SST25XX_STATUS_BSY);
+
+ retval = FLASH_ERR_OK;
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Program an arbitrary number of pages into flash and verify written data.
+
+static int
+sst25xx_program(struct cyg_flash_dev *dev, cyg_flashaddr_t base,
+ const void *data, size_t len)
+{
+ cyg_uint8 *tx_ptr = (cyg_uint8 *)data;
+ cyg_flashaddr_t local_base = base;
+ cyg_flashaddr_t end;
+ size_t tx_len = len;
+ cyg_bool start_wxfer = true;
+ int retval = FLASH_ERR_OK;
+
+ // Fix up the block address.
+ if (!sst25xx_to_local_addr(dev, &local_base)) {
+ retval = FLASH_ERR_INVALID;
+ goto out;
+ }
+ end = local_base + len - 1;
+
+ // Start with a byte programming if the destination is not
+ // 16 bits aligned
+ if (local_base & (cyg_flashaddr_t) 0x1) {
+ sst25xx_spi_wren(dev);
+ sst25xx_spi_pbyte(dev, local_base, tx_ptr);
+ SST25XX_WAIT_CHIP_READY(dev);
+ sst25xx_spi_wrdis(dev);
+ tx_ptr += 1;
+ tx_len -= 1;
+ local_base = local_base + 1;
+ }
+ // Write word(s)
+ if (tx_len > 1) {
+ sst25xx_spi_wren(dev);
+ while (tx_len > 1) {
+ sst25xx_spi_pword(dev, local_base, tx_ptr, start_wxfer);
+ tx_ptr += 2;
+ tx_len -= 2;
+ start_wxfer = false;
+ SST25XX_WAIT_CHIP_READY(dev);
+ }
+ sst25xx_spi_wrdis(dev);
+ }
+ // Write last byte
+ if (tx_len) {
+ sst25xx_spi_wren(dev);
+ sst25xx_spi_pbyte(dev, end, tx_ptr);
+ SST25XX_WAIT_CHIP_READY(dev);
+ sst25xx_spi_wrdis(dev);
+ }
+
+out:
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Read back an arbitrary amount of data from flash.
+
+static int
+sst25xx_read(struct cyg_flash_dev *dev, const cyg_flashaddr_t base,
+ void *data, size_t len)
+{
+ cyg_flashaddr_t local_base = base;
+ int retval = FLASH_ERR_INVALID;
+ cyg_uint8 *rx_ptr = (cyg_uint8 *)data;
+ cyg_uint32 rx_bytes_left = (cyg_uint32)len;
+ cyg_uint32 rx_bytes;
+
+ // Determine the maximum transfer size to use.
+ cyg_uint32 rx_block_size =
+ (CYGNUM_DEVS_FLASH_SPI_SST25XX_READ_BLOCK_SIZE ==
+ 0) ? 0xFFFFFFFF : CYGNUM_DEVS_FLASH_SPI_SST25XX_READ_BLOCK_SIZE;
+
+ // Fix up the block address and fill the read buffer.
+ if (sst25xx_to_local_addr(dev, &local_base)) {
+ while (rx_bytes_left) {
+ rx_bytes =
+ (rx_bytes_left <
+ rx_block_size) ? rx_bytes_left : rx_block_size;
+ sst25xx_spi_read(dev, local_base, rx_ptr, rx_bytes);
+
+ // Update counters and data pointers for next read block.
+ rx_bytes_left -= rx_bytes;
+ rx_ptr += rx_bytes;
+ local_base += rx_bytes;
+ }
+ retval = FLASH_ERR_OK;
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Lock device
+
+static int
+sst25xx_lock(struct cyg_flash_dev *dev, cyg_flashaddr_t base)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ cyg_flashaddr_t local_base = base;
+ int retval = FLASH_ERR_INVALID;
+ const cyg_uint8 tx_buf[2] = { SST25XX_CMD_WRSR, SST25XX_LOCK_BITS };
+
+ if (sst25xx_to_local_addr(dev, &local_base)) {
+ sst25xx_spi_wren(dev);
+ cyg_spi_transfer(spi_device, SST25XX_POLLED, 2, tx_buf, NULL);
+ retval = FLASH_ERR_OK;
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Unlock device
+
+static int
+sst25xx_unlock(struct cyg_flash_dev *dev, cyg_flashaddr_t base)
+{
+ cyg_spi_device *spi_device = (cyg_spi_device *) dev->priv;
+ cyg_flashaddr_t local_base = base;
+ int retval = FLASH_ERR_INVALID;
+ const cyg_uint8 tx_buf[2] = { SST25XX_CMD_WRSR, 0x0 };
+
+ if (sst25xx_to_local_addr(dev, &local_base)) {
+ sst25xx_spi_wren(dev);
+ cyg_spi_transfer(spi_device, SST25XX_POLLED, 2, tx_buf, NULL);
+ retval = FLASH_ERR_OK;
+ }
+ return retval;
+}
+
+//=============================================================================
+// Fill in the driver data structures.
+//=============================================================================
+
+CYG_FLASH_FUNS (
+ cyg_devs_flash_spi_sst25xx_funs, // Exported name of function pointers.
+ sst25xx_init, // Flash initialization.
+ cyg_flash_devfn_query_nop, // Query operations not supported.
+ sst25xx_erase_block, // Sector erase.
+ sst25xx_program, // Program multiple pages.
+ sst25xx_read, // Read arbitrary amount of data.
+ sst25xx_lock, // Locking (lock the whole device).
+ sst25xx_unlock
+);
+
+//-----------------------------------------------------------------------------
+// EOF sst25xx.c
diff --git a/ecos/packages/devs/flash/spi/sst25xx/current/tests/flash_sst25xx_test.c b/ecos/packages/devs/flash/spi/sst25xx/current/tests/flash_sst25xx_test.c
new file mode 100644
index 0000000..f865728
--- /dev/null
+++ b/ecos/packages/devs/flash/spi/sst25xx/current/tests/flash_sst25xx_test.c
@@ -0,0 +1,430 @@
+//=============================================================================
+//
+// flash_sst25xx_test.c
+//
+// SPI flash driver tests for SST25XX SPI FLASH
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ilijak, updated for SST25xx flash
+// Original(s): Chris Holgate, Christian Coutand
+// Date: 2011-04-25
+// Purpose: SST25xx SPI flash driver stress tests.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/testcase.h> // Test macros
+#include <cyg/infra/cyg_ass.h> // Assertion macros
+#include <cyg/infra/diag.h> // Diagnostic output
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/hal/hal_if.h>
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/io/spi.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/sst25xx.h>
+
+// Required data structures.
+#include <cyg/io/flash_dev.h>
+
+#include <string.h>
+
+#include CYGHWR_MEMORY_LAYOUT_H
+
+cyg_flash_info_t sst25xx_flash_info;
+//-----------------------------------------------------------------------------
+// Thread data structures.
+
+static cyg_uint32 stack [CYGNUM_HAL_STACK_SIZE_TYPICAL / 4];
+static cyg_thread thread_data;
+static cyg_handle_t thread_handle;
+
+//-----------------------------------------------------------------------------
+// Data transfer buffers.
+
+//#define BUF_SIZE 1024
+#define BUF_SIZE 128
+
+static cyg_uint8 wbuf [BUF_SIZE];
+static cyg_uint8 rbuf [BUF_SIZE];
+
+//-----------------------------------------------------------------------------
+// Print out version information.
+
+void do_version (void)
+{
+ char *version = CYGACC_CALL_IF_MONITOR_VERSION();
+ if (version != NULL) diag_printf("%s", version);
+#ifdef HAL_PLATFORM_CPU
+ diag_printf("\nPlatform: %s (%s) %s\n",
+ HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
+#endif
+ diag_printf("RAM: %p-%p, ",
+ (void*)(CYGMEM_REGION_ram),
+ (void*)(CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - 1));
+ diag_printf("(HEAP: %p-%p)\n",
+ (void*)(CYGMEM_SECTION_heap1),
+ (void*)(CYGMEM_SECTION_heap1 + CYGMEM_SECTION_heap1_SIZE - 1));
+}
+
+//-----------------------------------------------------------------------------
+// Run checkerboard and inverse checkerboard writes over each sector in turn.
+
+cyg_uint32 run_test_1
+ (void)
+{
+ int status;
+ cyg_uint32 i, j;
+ cyg_uint32 errors = 0;
+ cyg_flashaddr_t base_addr, err_addr;
+
+ diag_printf ("Test 1 - write and verify checkerboard and inverse checkerboard.\n");
+ diag_printf (" Flash device at %p, block_info at %p start = 0x%08x, blocks = %d[0x%x]\n",
+ &sst25xx_flash_info,
+ sst25xx_flash_info.block_info, sst25xx_flash_info.start,
+ sst25xx_flash_info.block_info->blocks,
+ sst25xx_flash_info.block_info->blocks);
+
+ // Iterate over all flash sectors.
+ for (i = 0; i < sst25xx_flash_info.block_info->blocks; i++) {
+ base_addr = sst25xx_flash_info.start +
+ (i * sst25xx_flash_info.block_info->block_size);
+ if(!(i % 64))
+ diag_printf("\n%5d 0x%08x: ", i, base_addr-sst25xx_flash_info.start);
+ diag_printf(".");
+ // Unlock block.
+ status = cyg_flash_unlock (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Erase block.
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Set up buffer with checkerboard.
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = 0x55;
+ wbuf [j++] = 0xAA;
+ }
+
+ // Write the checkerboard to the entire sector.
+ for (j = 0; j < sst25xx_flash_info.block_info->block_size ; j += BUF_SIZE) {
+ status = cyg_flash_program (base_addr + j, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ }
+
+ // Read back the checkerboard and verify.
+ for (j = 0; j < sst25xx_flash_info.block_info->block_size; j += BUF_SIZE) {
+ status = cyg_flash_read (base_addr + j, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n",
+ base_addr + j, base_addr + j + BUF_SIZE - 1);
+ errors ++;
+ }
+ }
+
+ // Erase block.
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Set up buffer with inverse checkerboard.
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = 0xAA;
+ wbuf [j++] = 0x55;
+ }
+
+ // Write the checkerboard to the entire sector.
+ for (j = 0; j < sst25xx_flash_info.block_info->block_size; j += BUF_SIZE) {
+ status = cyg_flash_program (base_addr + j, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ }
+
+ // Read back the checkerboard and verify.
+ for (j = 0; j < sst25xx_flash_info.block_info->block_size; j += BUF_SIZE) {
+ status = cyg_flash_read (base_addr + j, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n",
+ base_addr + j, base_addr + j + BUF_SIZE - 1);
+ errors ++;
+ }
+ }
+ }
+ diag_printf("\n");
+ return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Write and verify counting sequence over all device.
+
+cyg_uint32 run_test_2
+ (void)
+{
+ int status;
+ cyg_uint32 i, j;
+ cyg_uint32 errors = 0;
+ cyg_flashaddr_t base_addr, err_addr;
+
+ diag_printf ("Test 2 - write and verify counting sequence.\n");
+
+ // Erase all flash sectors.
+ diag_printf("Erase all flash sectors\n");
+ for (i = 0; i < sst25xx_flash_info.block_info->blocks; i++) {
+ base_addr = sst25xx_flash_info.start +
+ (i * sst25xx_flash_info.block_info->block_size);
+ if(!(i % 64))
+ diag_printf("\n%5d: ", i);
+ diag_printf(".");
+
+ // Erase block.
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ }
+ diag_printf("\n");
+
+ // Write counting sequence.
+ diag_printf("Writing counting sequence\n");
+ base_addr = sst25xx_flash_info.start;
+ for (i = 0; i < (sst25xx_flash_info.end - sst25xx_flash_info.start) / 4;) {
+ if(!(i % (64*1024)))
+ diag_printf("\n%7d: ", i);
+ if(!(i % (32*64)))
+ diag_printf(".");
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = (cyg_uint8) ((i >> 0) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 8) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 16) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 24) & 0xFF);
+ i++;
+ }
+ status = cyg_flash_program (base_addr, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ base_addr += BUF_SIZE;
+ }
+ diag_printf("\n");
+
+ // Verify counting sequence.
+ diag_printf("Verifying counting sequence\n");
+ base_addr = sst25xx_flash_info.start;
+ for (i = 0; i < (sst25xx_flash_info.end - sst25xx_flash_info.start) / 4;) {
+ if(!(i % (64*1024)))
+ diag_printf("\n%7d: ", i);
+ if(!(i % (32*64)))
+ diag_printf(".");
+ for (j = 0; j < BUF_SIZE;) {
+ wbuf [j++] = (cyg_uint8) ((i >> 0) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 8) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 16) & 0xFF);
+ wbuf [j++] = (cyg_uint8) ((i >> 24) & 0xFF);
+ i++;
+ }
+ status = cyg_flash_read (base_addr, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n",
+ base_addr, base_addr + BUF_SIZE - 1);
+ errors ++;
+ }
+ base_addr += BUF_SIZE;
+ }
+ diag_printf("\n");
+ return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Perform non-aligned buffer read/write tests, spanning sector boundaries.
+
+cyg_uint32 run_test_3
+ (void)
+{
+ int status;
+ cyg_uint32 i, count;
+ cyg_uint32 errors = 0;
+ cyg_flashaddr_t base_addr, err_addr;
+
+ diag_printf ("Test 3 - test non-aligned writes and reads.\n");
+
+ // Fill the write buffer with a basic counting sequence.
+ count = 0;
+ for (i = 0; i < BUF_SIZE;) {
+ wbuf [i++] = (cyg_uint8) ((count >> 0) & 0xFF);
+ wbuf [i++] = (cyg_uint8) ((count >> 8) & 0xFF);
+ count++;
+ }
+ // Assuming 256 byte pages gives 256 possible alignments.
+ base_addr = sst25xx_flash_info.start + sst25xx_flash_info.block_info->block_size;
+ for (i = 1; i <= 256; i++) {
+ if(!(i % 32))
+ diag_printf("\n%5d: ", i);
+ diag_printf(".");
+
+ // Erase sectors either side of sector boundary.
+ status = cyg_flash_erase (base_addr - 1, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ status = cyg_flash_erase (base_addr, 1, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Write data spanning sector boundary.
+ status = cyg_flash_program (base_addr - i, wbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+
+ // Verify data spanning sector boundary.
+ status = cyg_flash_read (base_addr - i, rbuf, BUF_SIZE, &err_addr);
+ if (status != FLASH_ERR_OK) {
+ diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+ errors ++;
+ }
+ else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+ diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n",
+ base_addr - i, base_addr - i + BUF_SIZE - 1);
+ diag_printf ("Flash read data corruption %d.\n", i);
+ errors ++;
+ }
+
+ // Use next sector boundary for next test.
+ base_addr += sst25xx_flash_info.block_info->block_size;
+ if (base_addr >= sst25xx_flash_info.end)
+ base_addr = sst25xx_flash_info.start + sst25xx_flash_info.block_info->block_size;
+ }
+ diag_printf("\n\n");
+ return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Run all SST25xx SPI interface loopback tests.
+
+void run_tests
+ (void)
+{
+ cyg_uint32 errors = 0;
+
+ do_version();
+
+ // diag_printf ("----\nChecking for SST25xx compatible devices at %p\n", &sst25xx_flash_device);
+ diag_printf ("----\nChecking for SST25xx compatible devices.\n");
+ cyg_flash_set_global_printf((cyg_flash_printf *)&diag_printf);
+ cyg_flash_init(NULL);
+
+ cyg_flash_get_info_addr(CYGNUM_DEVS_FLASH_SPI_SST25XX_DEV0_MAP_ADDR, &sst25xx_flash_info);
+
+ // Check that the device is intialised.
+ if (sst25xx_flash_info.start == sst25xx_flash_info.end) {
+ diag_printf ("SST25xx device not initialised.\n");
+ errors ++;
+ goto out;
+ }
+
+ // Run the tests.
+ errors += run_test_1 ();
+ errors += run_test_2 ();
+// errors += run_test_3 ();
+
+out:
+ diag_printf ("----\nTests complete - detected %d errors in total.\n", errors);
+ if (errors == 0)
+ CYG_TEST_PASS_FINISH ("SST25xx driver tests ran OK.");
+ else
+ CYG_TEST_FAIL_FINISH ("SST25xx driver test FAILED.");
+}
+
+//-----------------------------------------------------------------------------
+// User startup - tests are run in their own thread.
+
+void cyg_user_start
+ (void)
+{
+ CYG_TEST_INIT();
+ cyg_thread_create(
+ 10, // Arbitrary priority
+ (cyg_thread_entry_t*) run_tests, // Thread entry point
+ 0, //
+ "test_thread", // Thread name
+ (cyg_uint8*) stack, // Stack
+ CYGNUM_HAL_STACK_SIZE_TYPICAL, // Stack size
+ &thread_handle, // Thread handle
+ &thread_data // Thread data structure
+ );
+ cyg_thread_resume(thread_handle);
+ cyg_scheduler_start();
+}
+
+//=============================================================================
+
diff --git a/ecos/packages/devs/flash/sst/39vf400/current/ChangeLog b/ecos/packages/devs/flash/sst/39vf400/current/ChangeLog
new file mode 100644
index 0000000..660d066
--- /dev/null
+++ b/ecos/packages/devs/flash/sst/39vf400/current/ChangeLog
@@ -0,0 +1,34 @@
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/flash_sst_39vf400.cdl:
+ Don't implement CYGHWR_IO_FLASH_DEVICE here. Leave it for
+ the chip driver.
+
+2003-07-24 Chris Garry <cgarry@sweeneydesign.co.uk>
+
+ * include/flash_sst_39vf400.inl:
+ * cdl/flash_sst_39vf400.cdl: New package/file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/sst/39vf400/current/cdl/flash_sst_39vf400.cdl b/ecos/packages/devs/flash/sst/39vf400/current/cdl/flash_sst_39vf400.cdl
new file mode 100755
index 0000000..d6d0e1f
--- /dev/null
+++ b/ecos/packages/devs/flash/sst/39vf400/current/cdl/flash_sst_39vf400.cdl
@@ -0,0 +1,60 @@
+# ====================================================================
+#
+# flash_sst_39vf400.cdl
+#
+# FLASH memory - Hardware support for SST SST39vf400 device
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Chris Garry <cgarry@sweeneydesign.co.uk>
+# Contributors:
+# Date: 2003-04-21
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SST_39VF400 {
+ display "SST 39VF400 FLASH memory support"
+ description "FLASH memory device support for SST 39VF400"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ active_if CYGINT_DEVS_FLASH_SST_39VF400_REQUIRED
+
+ include_dir cyg/io
+}
+
+# EOF flash_sst_39vf400.cdl
diff --git a/ecos/packages/devs/flash/sst/39vf400/current/include/flash_sst_39vf400.inl b/ecos/packages/devs/flash/sst/39vf400/current/include/flash_sst_39vf400.inl
new file mode 100755
index 0000000..a39fd11
--- /dev/null
+++ b/ecos/packages/devs/flash/sst/39vf400/current/include/flash_sst_39vf400.inl
@@ -0,0 +1,388 @@
+#ifndef CYGONCE_DEVS_FLASH_SST_39VF400_INL
+#define CYGONCE_DEVS_FLASH_SST_39VF400_INL
+//==========================================================================
+//
+// flash_sst_39vf4000.inl
+//
+// SST SST39VF400 FLASH driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Chris Garry <cgarry@sweeneydesign.co.uk>
+// Contributors:
+// Date: 2003-04-21
+// Purpose:
+// Description: SST SST39VF400 flash driver
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_sst_39vf400.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_diag.h> /* HAL_DELAY_US */
+#include <cyg/infra/diag.h> /* Required for diag_printf */
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+//----------------------------------------------------------------------------
+// Platform code must define the below
+// #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel)
+// #define CYGNUM_FLASH_SERIES : Number of devices in series
+// #define CYGNUM_FLASH_BASE : Base address of the FLASH
+//
+// Note:
+// Currently the driver only supports CYGNUM_FLASH_INTERLEAVE = 1 and
+// CYGNUM_FLASH_SERIES = 1
+
+
+// Definitions for the SST 39VF400A part
+#define SST_ID 0x00BF /* SST Manufacturer's ID code */
+#define SST_39VF400A 0x2780 /* SST39VF400/SST39VF400A device code */
+#define CYGNUM_FLASH_SECTOR_SIZE (0x1000) /* Size of physical sectors */
+#define CYGNUM_FLASH_BLOCK_SIZE (0x1000) /* Driver 'blocks' may be a multiple of physical sectors */
+#define CYGNUM_FLASH_BLOCK_NUM (0x80000/CYGNUM_FLASH_BLOCK_SIZE) /* Number of blocks */
+#define CYGNUM_FLASH_WIDTH (16) /* This part is always 16 bits wide */
+#define CYGNUM_FLASH_BLANK (1)
+
+
+#ifndef FLASH_P2V
+# define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_)))
+#endif
+#ifndef CYGHWR_FLASH_AM29XXXXX_PLF_INIT
+# define CYGHWR_FLASH_AM29XXXXX_PLF_INIT()
+#endif
+
+// Structure to hold device ID
+typedef struct
+{
+ cyg_uint16 man_id;
+ cyg_uint16 dev_id;
+} device_id_t;
+
+// FLASH registers
+volatile cyg_uint16 *flash_data_add0 = (cyg_uint16 *)(CYGNUM_FLASH_BASE);
+volatile cyg_uint16 *flash_data_add1 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x0001 << 1));
+volatile cyg_uint16 *flash_cmd_add1 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x5555 << 1));
+volatile cyg_uint16 *flash_cmd_add2 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x2AAA << 1));
+volatile cyg_uint16 *flash_cmd_add3 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x5555 << 1));
+volatile cyg_uint16 *flash_cmd_add4 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x5555 << 1));
+volatile cyg_uint16 *flash_cmd_add5 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x2AAA << 1));
+
+
+//----------------------------------------------------------------------------
+// Now that device properties are defined, include magic for defining
+// accessor type and constants.
+#include <cyg/io/flash_dev.h>
+
+//----------------------------------------------------------------------------
+// Functions that put the flash device into non-read mode must reside
+// in RAM.
+static device_id_t get_device_id(void) __attribute__ ((section (".2ram.get_device_id")));
+int flash_erase_block(void* block, unsigned int size)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int flash_program_buf(void* addr, void* data, int len)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+
+//----------------------------------------------------------------------------
+// Get Device ID
+//
+// Reads the manufacturer and part number codes for the device
+//
+static device_id_t get_device_id(void)
+{
+ device_id_t device_id;
+ int i;
+
+ /* Issue the Software ID command */
+ *flash_cmd_add1 = 0xAAAA;
+ *flash_cmd_add2 = 0x5555;
+ *flash_cmd_add3 = 0x9090;
+
+ /* Tida delay time, Tida = 150 ns */
+ /* Can use any function that is in ROM */
+ for (i = 0; i < 100; i++)
+ {
+ /* Do nothing */
+ }
+
+ /* Read the product ID */
+ device_id.man_id = *flash_data_add0 & 0xFF;
+ device_id.dev_id = *flash_data_add1;
+
+ /* Issue the Software ID EXIT command */
+ *flash_data_add0 = 0xF0F0;
+
+ /* Tida delay time, Tida = 150 ns */
+ /* Can use any function that is in ROM */
+ for (i = 0; i < 100; i++)
+ {
+ /* Do nothing */
+ }
+
+ return(device_id);
+}
+
+
+//----------------------------------------------------------------------------
+// Initialize driver details
+//
+int flash_hwr_init(void)
+{
+ device_id_t device_id;
+
+ /* Call the function to get the device ID */
+ device_id = get_device_id();
+
+ /* Determine whether there is a SST39VF400A installed or not */
+ if ((device_id.man_id != SST_ID) || (device_id.dev_id != SST_39VF400A))
+ {
+ return FLASH_ERR_DRV_WRONG_PART;
+ }
+
+ // Hard wired for now
+ flash_info.block_size = CYGNUM_FLASH_BLOCK_SIZE;
+ flash_info.blocks = CYGNUM_FLASH_BLOCK_NUM;
+ flash_info.start = (void *)CYGNUM_FLASH_BASE;
+ flash_info.end = (void *)(CYGNUM_FLASH_BASE + (flash_info.block_size * flash_info.blocks));
+
+ return FLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// Map a hardware status to a package error
+int flash_hwr_map_error(int e)
+{
+ return e;
+}
+
+
+//----------------------------------------------------------------------------
+// See if a range of FLASH addresses overlaps currently running code
+bool flash_code_overlaps(void *start, void *end)
+{
+ extern unsigned char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
+
+//----------------------------------------------------------------------------
+// Erase Block
+// This function actually uses the sector erase command instead of the block
+// erase command. this allows for the effective block size to be smaller
+// than 64K (as small as the 4K sector size)
+int flash_erase_block(void* block, unsigned int size)
+{
+
+ volatile cyg_uint16 *block_addr;
+ volatile cyg_uint16 *verify_addr;
+ int verify_failed;
+ cyg_uint32 i, timeout;
+ int j;
+ int retry;
+
+ block_addr = block;
+
+ for (j = 0; j < (size / CYGNUM_FLASH_SECTOR_SIZE); j++)
+ {
+ retry = 0;
+ while (retry < 16)
+ {
+ /* Issue the Sector-Erase command */
+ *flash_cmd_add1 = 0xAAAA;
+ *flash_cmd_add2 = 0x5555;
+ *flash_cmd_add3 = 0x8080;
+ *flash_cmd_add4 = 0xAAAA;
+ *flash_cmd_add5 = 0x5555;
+ *block_addr = 0x3030; /* Sector Erase command */
+
+ /* Wait for the Erase operation to complete */
+ /* With a timeout to stop the board locking up with a H/W error*/
+ timeout = 0;
+ i = 0;
+ while (i < 5)
+ {
+ if (*block_addr == 0xFFFF)
+ {
+ i++;
+ }
+ else
+ {
+ i = 0;
+ }
+
+ if (++timeout > 0x01000000)
+ {
+ /* Timeout - return with ERROR status */
+ return (FLASH_ERR_DRV_TIMEOUT);
+ }
+ }
+
+ /* Verify this sector has been erased */
+ verify_addr = block_addr;
+ verify_failed = 0;
+ while ((cyg_uint32)(verify_addr) < ((cyg_uint32)block_addr + (cyg_uint32)CYGNUM_FLASH_SECTOR_SIZE))
+ {
+ if (*verify_addr != 0xFFFF)
+ {
+ /* Error verifying segment data */
+ retry++;
+ verify_failed = 1;
+ break;
+ }
+ ++verify_addr;
+ }
+
+ if (verify_failed == 0)
+ {
+ /* Sector erase verified */
+ break;
+ }
+ }
+
+ /* Increment the block address by 1 sector */
+ (cyg_uint32)block_addr += CYGNUM_FLASH_SECTOR_SIZE;
+ }
+
+ /* Verify the entire block has been set to all 0xFFFFs */
+ block_addr = block;
+ while ((cyg_uint32)(block_addr) < ((cyg_uint32)block + (cyg_uint32)size))
+ {
+ if (*block_addr != 0xFFFF)
+ {
+ /* Error verifying data */
+ return (FLASH_ERR_DRV_VERIFY);
+ }
+
+ ++block_addr;
+ }
+
+ return (FLASH_ERR_OK);
+}
+
+
+//----------------------------------------------------------------------------
+// Program Buffer
+int
+flash_program_buf(void* addr, void* data, int len)
+{
+ volatile cyg_uint16 *write_ptr;
+ volatile cyg_uint16 *data_ptr;
+ int i;
+ cyg_uint32 timeout;
+ cyg_uint16 read_data1, read_data2;
+
+ write_ptr = addr; /* Initialise local pointers */
+ data_ptr = data;
+
+ /* Loop for writing the data */
+ while ((cyg_uint32)write_ptr < ((cyg_uint32)addr + (cyg_uint32)len))
+ {
+ /* Write word of data to FLASH */
+ /* Issue the Word-Program command */
+ *flash_cmd_add1 = 0xAAAA;
+ *flash_cmd_add2 = 0x5555;
+ *flash_cmd_add3 = 0xA0A0;
+ /* Write data word to FLASH */
+ *write_ptr = *data_ptr;
+
+ /* Wait for the operation to complete */
+ /* Wait for the Erase operation to complete */
+ /* With a timeout to stop the board locking up with a H/W error*/
+ timeout = 0;
+ i = 0;
+ while (i < 5)
+ {
+ read_data1 = *write_ptr;
+ read_data2 = *write_ptr;
+ if (read_data1 == read_data2)
+ {
+ /* Bit 6 can no longer be toggling */
+ i++;
+ }
+ else
+ {
+ i = 0;
+ }
+
+ if (++timeout > 0x01000000)
+ {
+ /* Timeout - return with ERROR status */
+ return (FLASH_ERR_DRV_TIMEOUT);
+ }
+ }
+
+ /* Increment pointers to next words */
+ ++write_ptr;
+ ++data_ptr;
+ }
+
+ /* Data write complete - verify the data */
+ write_ptr = addr; /* Re-initialise local pointers */
+ data_ptr = data;
+
+ /* Loop for verifying the data */
+ while ((cyg_uint32)write_ptr < ((cyg_uint32)addr + (cyg_uint32)len))
+ {
+ if (*write_ptr != *data_ptr)
+ {
+ /* Error verifying data */
+ return (FLASH_ERR_DRV_VERIFY);
+ }
+
+ /* Increment pointers to next words */
+ ++write_ptr;
+ ++data_ptr;
+ }
+
+ return (FLASH_ERR_OK);
+}
+
+#endif // CYGONCE_DEVS_FLASH_SST_39VF400_INL
+
+
+
+
+
+
+
diff --git a/ecos/packages/devs/flash/sst/39vfxxx/current/ChangeLog b/ecos/packages/devs/flash/sst/39vfxxx/current/ChangeLog
new file mode 100755
index 0000000..8c09638
--- /dev/null
+++ b/ecos/packages/devs/flash/sst/39vfxxx/current/ChangeLog
@@ -0,0 +1,75 @@
+2004-11-29 Bart Veer <bartv@ecoscentric.com>
+
+ * include/flash_sst_39vfxxx.inl: eliminate hwr_map_error(), no
+ longer needed by the generic flash code.
+ * include/flash_sst_39vfxxx.inl: use the dummy lock/unlock
+ functions provided by the generic flash code.
+
+2004-11-25 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_sst_39vfxxx.cdl: this V2 driver relies on the generic
+ flash code to handle the cache
+
+2004-11-22 Bart Veer <bartv@ecoscentric.com>
+
+ * include/flash_sst_39vfxxx.inl: assume static initialization and
+ adjust const's in various parameters
+ * include/flash_sst_39vfxxx.inl: rename cyg_block_info to
+ cyg_flash_block_info
+
+2004-09-14 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/flash_sst_39vfxxx.inl: Set the end address to the last
+ valid address in flash, not the first invalid address.
+
+2004-08-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/flash_sst_39vfxxx.inl: The structure declared by
+ CYG_FLASH_FUNS should be static so we can instantiate the
+ driver multiple times.
+
+2004-08-04 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/flash_sst_39vfxxx.inl: Added support for the SST39VF160
+ device.
+
+2004-07-16 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/flash_sst_39vfxxx.inl: Modified the driver to make use
+ of the new flash device API.
+
+2006-12-21 Wang Cui <iucgnaw@msn.com>
+
+ * include/flash_sst_39vfxxx.inl: Add supported devices:
+ SST39VF160, SST39VF1601, SST39VF1602, SST39VF320, SST39VF3201,
+ SST39VF3202, SST39VF6401, SST39VF6402,
+
+2003-10-02 Roland Caßebohm <r.cassebohm@visionsystems.de>
+
+ * include/flash_sst_39vfxxx.inl:
+ * cdl/flash_sst_39vfxxx.cdl: New package cloned from at29xxxx driver.
+ Supported devices: SST39VF080, SST39VF016 and SST39VF400.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl b/ecos/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl
new file mode 100755
index 0000000..f652a74
--- /dev/null
+++ b/ecos/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl
@@ -0,0 +1,62 @@
+# ====================================================================
+#
+# flash_sst_39vfxxx.cdl
+#
+# FLASH memory - Hardware support for SST 39VFxxx parts
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov, rcassebohm
+# Date: 2001-02-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SST_39VFXXX {
+ display "SST 39VFXXX FLASH memory support"
+ description "FLASH memory device support for SST 39VFXXX"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+
+ active_if CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_NEEDS_CACHE_HANDLED
+
+ include_dir cyg/io
+}
diff --git a/ecos/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl b/ecos/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
new file mode 100755
index 0000000..1fa39a4
--- /dev/null
+++ b/ecos/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
@@ -0,0 +1,393 @@
+#ifndef CYGONCE_DEVS_FLASH_SST_39VFXXX_INL
+#define CYGONCE_DEVS_FLASH_SST_39VFXXX_INL
+//==========================================================================
+//
+// flash_sst_39vfxxx.inl
+//
+// SST 39VFxxx series flash driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jskov, rcassebohm, Andrew Lunn
+// Date: 2001-02-21
+// Purpose:
+// Description:
+//
+// Notes: FLASH_P2V is not properly used.
+// Needs locking.
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/infra/cyg_ass.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+//----------------------------------------------------------------------------
+// Common device details.
+#define FLASH_Read_ID FLASHWORD( 0x90 )
+#define FLASH_Read_ID_Exit FLASHWORD( 0xF0 )
+#define FLASH_Reset FLASHWORD( 0xFF )
+#define FLASH_Program FLASHWORD( 0xA0 )
+#define FLASH_Block_Erase FLASHWORD( 0x30 )
+
+#define FLASH_Data FLASHWORD( 0x80 ) // Data complement
+#define FLASH_Busy FLASHWORD( 0x40 ) // "Toggle" bit
+#define FLASH_Err FLASHWORD( 0x20 )
+#define FLASH_Sector_Erase_Timer FLASHWORD( 0x08 )
+
+#define FLASH_Setup_Addr1 (0x5555)
+#define FLASH_Setup_Addr2 (0x2AAA)
+#define FLASH_Setup_Code1 FLASHWORD( 0xAA )
+#define FLASH_Setup_Code2 FLASHWORD( 0x55 )
+#define FLASH_Setup_Erase FLASHWORD( 0x80 )
+
+// Platform code must define the below
+// #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel)
+// #define CYGNUM_FLASH_SERIES : Number of devices in series
+// And select one of the below device variants
+
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF080
+# define FLASH_BLOCK_SIZE (0x1000*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS (256)
+# define CYGNUM_FLASH_BASE_MASK (0xFFF00000u) // 1024kB devices
+# define CYGNUM_FLASH_WIDTH (8)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0xBF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0xD8)
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF016
+# define FLASH_BLOCK_SIZE (0x1000*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS (512)
+# define CYGNUM_FLASH_BASE_MASK (0xFFE00000u) // 2048kB devices
+# define CYGNUM_FLASH_WIDTH (8)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0xBF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0xD9)
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF400
+# define FLASH_BLOCK_SIZE (0x1000*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS (0x80000/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFFF80000u) // 512kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x2780)
+#endif
+
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF160
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((2*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFFE00000u) // 2048kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x2782)
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF1601
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((2*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFFE00000u) // 2048kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x234B)
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF1602
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((2*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFFE00000u) // 2048kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x234A)
+#endif
+
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF320
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((4*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFFC00000u) // 4096kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x2784)
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF3201
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((4*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFFC00000u) // 4096kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x235B)
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF3202
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((4*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFFC00000u) // 4096kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x235A)
+#endif
+
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF6401
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((8*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFF800000u) // 8184kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x236B)
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF6402
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((8*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFF800000u) // 8184kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x236A)
+#endif
+
+#define FLASH_DEVICE_SIZE (FLASH_BLOCK_SIZE*FLASH_NUM_REGIONS)
+#define CYGNUM_FLASH_DEVICES (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
+
+//----------------------------------------------------------------------------
+// Now that device properties are defined, include magic for defining
+// accessor type and constants.
+#include <cyg/io/flash_dev.h>
+
+//----------------------------------------------------------------------------
+// Functions that put the flash device into non-read mode must reside
+// in RAM.
+static size_t sst_query(struct cyg_flash_dev *dev, void* data, size_t len)
+ __attribute__ ((section (".2ram.flash_query")));
+static int sst_erase_block(struct cyg_flash_dev *dev, cyg_flashaddr_t block_base)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+static int sst_program(struct cyg_flash_dev *dev, cyg_flashaddr_t base,
+ const void* data, size_t length)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+
+
+//----------------------------------------------------------------------------
+// Initialize driver details
+static int
+sst_init(struct cyg_flash_dev *dev)
+{
+ flash_data_t id[2];
+
+ dev->funs->flash_query(dev,id,sizeof(id));
+
+ // Check that flash_id data is matching the one the driver was
+ // configured for.
+ if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER
+ || id[1] != CYGNUM_FLASH_ID_DEVICE)
+ return CYG_FLASH_ERR_DRV_WRONG_PART;
+ return CYG_FLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// Flash Query
+//
+// Only reads the manufacturer and part number codes for the first
+// device(s) in series. It is assumed that any devices in series
+// will be of the same type.
+
+static size_t
+sst_query(struct cyg_flash_dev *dev, void* data, size_t len)
+{
+ volatile flash_data_t *ROM;
+ flash_data_t* id = (flash_data_t*) data;
+ int i;
+
+ CYG_ASSERT(len == 2, "Invalid length");
+
+ ROM = (volatile flash_data_t*) dev->start;
+
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Read_ID;
+
+ // FIXME: 10ms delay
+ for (i = 10000; i > 0; i--);
+
+ // Manufacturers' code
+ id[0] = ROM[0];
+ // Part number
+ id[1] = ROM[1];
+
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Read_ID_Exit;
+
+ // FIXME: 10ms delay
+ for (i = 10000; i > 0; i--);
+
+ return len;
+}
+
+//----------------------------------------------------------------------------
+// Erase Block
+static int
+sst_erase_block(struct cyg_flash_dev *dev, cyg_flashaddr_t block_base)
+{
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* addr_ptr = (volatile flash_data_t*) block_base;
+ int len = dev->block_info[0].block_size;
+ int res = CYG_FLASH_ERR_OK;
+
+ while ((CYG_FLASH_ERR_OK == res) && (len > 0)) {
+ int timeout;
+ flash_data_t state, prev_state;
+
+ // Base address of device(s) being programmed.
+ ROM = (volatile flash_data_t*)((unsigned long)block_base & ~(FLASH_DEVICE_SIZE-1));
+
+ // Program data [byte] - 6 step sequence
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Erase;
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ *addr_ptr = FLASH_Block_Erase;
+
+ // Wait for completion (bit 6 stops toggling)
+ timeout = 5000000;
+ prev_state = *addr_ptr & FLASH_Busy;
+ while (true) {
+ state = *addr_ptr & FLASH_Busy;
+ if (prev_state == state) {
+ break;
+ }
+ if (--timeout == 0) {
+ res = CYG_FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ prev_state = state;
+ }
+ // Verify loaded data bytes
+ while (len > 0) {
+ if (*addr_ptr != FLASH_BlankValue) {
+ // Only update return value if erase operation was OK
+ if (CYG_FLASH_ERR_OK == res) res = CYG_FLASH_ERR_DRV_VERIFY;
+ break;
+ }
+ addr_ptr++;
+ len -= sizeof(*addr_ptr);
+ }
+ }
+ return CYG_FLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// Program Buffer
+static int
+sst_program(struct cyg_flash_dev *dev, cyg_flashaddr_t base,
+ const void* data, size_t length)
+{
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* addr_ptr = (volatile flash_data_t*) base;
+ volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
+ size_t len = length;
+ int res = CYG_FLASH_ERR_OK;
+
+#if 0
+ CYG_ASSERT((unsigned long)data_ptr & (sizeof(flash_data_t)-1) == 0,
+ "Data not properly aligned");
+ CYG_ASSERT((unsigned long)addr_ptr & (CYGNUM_FLASH_INTERLEAVE*sizeof(flash_data_t)-1) == 0,
+ "Addr not properly aligned (to first interleaved device)");
+#endif
+ while ((CYG_FLASH_ERR_OK == res) && (len > 0)) {
+ int timeout;
+ flash_data_t state, prev_state;
+
+ // Base address of device(s) being programmed.
+ ROM = (volatile flash_data_t*)((unsigned long)base & ~(FLASH_DEVICE_SIZE-1));
+
+ // Program data [byte] - 4 step sequence
+ ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
+ ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
+ ROM[FLASH_Setup_Addr1] = FLASH_Program;
+ *addr_ptr = *data_ptr;
+
+ // Wait for completion (bit 6 stops toggling)
+ timeout = 5000000;
+ prev_state = *addr_ptr & FLASH_Busy;
+ while (true) {
+ state = *addr_ptr & FLASH_Busy;
+ if (prev_state == state) {
+ break;
+ }
+ if (--timeout == 0) {
+ res = CYG_FLASH_ERR_DRV_TIMEOUT;
+ break;
+ }
+ prev_state = state;
+ }
+
+ // Verify loaded data bytes
+ if (*addr_ptr != *data_ptr) {
+ // Only update return value if program operation was OK
+ if (CYG_FLASH_ERR_OK == res) res = CYG_FLASH_ERR_DRV_VERIFY;
+ break;
+ }
+ addr_ptr++;
+ data_ptr++;
+ len -= sizeof(*data_ptr);
+ }
+
+ // Ideally, we'd want to return not only the failure code, but also
+ // the address/device that reported the error.
+ return res;
+}
+
+static const CYG_FLASH_FUNS(cyg_sst_funs,
+ sst_init,
+ sst_query,
+ sst_erase_block,
+ sst_program,
+ NULL, // read
+ cyg_flash_devfn_lock_nop,
+ cyg_flash_devfn_unlock_nop);
+
+#endif // CYGONCE_DEVS_FLASH_SST_39VFXXX_INL
diff --git a/ecos/packages/devs/flash/synth/current/ChangeLog b/ecos/packages/devs/flash/synth/current/ChangeLog
new file mode 100644
index 0000000..e8f364d
--- /dev/null
+++ b/ecos/packages/devs/flash/synth/current/ChangeLog
@@ -0,0 +1,122 @@
+2009-02-26 Bart Veer <bartv@ecoscentric.com>
+
+ * tests/flash1.c, tests/flash2.c: fix breakage caused by banner
+ change.
+
+2009-02-20 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * tests/flash2.c (cyg_user_start): Call cyg_flash_init with
+ NULL arg.
+
+2009-02-18 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * tests/flash2.c (cyg_user_start): Update for minor flash API
+ mod to call cyg_flash_set_global_printf() to set printf
+ function.
+
+2008-12-23 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/flash_erase_block.c:
+ * src/flash_program_buf.c:
+ Implemented simulation of proper NOR flash writes. General cleanup.
+
+2008-12-18 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/synth.c: Fixed error check of mmap call.
+
+2008-11-19 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * tests/flash2.c: Fixed a few warnings.
+
+2008-11-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * Merge from flash_v2 branch:
+
+ 2004-12-02 Bart Veer <bartv@ecoscentric.com>
+
+ * src/synth.c: explicitly include <cyg/io/flash_dev.h> rather than
+ just defining _FLASH_PRIVATE_
+ * tests/flash2.c (cyg_user_start): update as per the v2 testcase
+
+ 2004-11-22 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_synth.cdl: fix testcase definitions
+
+ 2004-08-03 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/flash_synth.cdl: Indicate we need the legacy device API.
+ * cdl/flash_synth.cdl:
+ * tests/flash2.c: Added a second test case for the new API.
+
+2005-08-02 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * tests/flash1.c (cyg_user_start): Fix a compiler warning about
+ signedness of pointers.
+
+2005-07-30 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/synth.c (flash_hwr_init): Cast to keep the compiler happy.
+
+2005-03-27 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * tests/flash1.c: gcc 3.x does not like string continuing
+ over lines with the " open.
+
+2004-12-15 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/synth.c: Moved cyg_hal_sys_mmap into the HAL.
+
+2003-11-20 Jani Monoses <jani@iv.ro>
+
+ * tests/flash1.c: Update flash_init() call to reflect
+ new prototype.
+
+2002-01-23 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/flash_synth.cdl: Add CYGMEM_FLASH_SYNTH_BASE to allow
+ imposition of base address.
+ Add CYGSEM_FLASH_SYNTH_FILE_WRITEBACK to allow changes to be
+ reflected in the underlying file.
+ * src/synth.c (flash_hwr_init): Implement CYGMEM_FLASH_SYNTH_BASE and
+ CYGSEM_FLASH_SYNTH_FILE_WRITEBACK using appropriate args to mmap().
+ Include <string.h> to avoid warning.
+
+2002-01-11 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/synth.c (flash_hwr_init): Initialize to 0xff if the file
+ needs creating.
+ * cdl/flash_synth.cdl: requires errno codes.
+
+2002-01-08 Jonathan Larmour <jlarmour@redhat.com>
+2001-11-1 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * First version. Implements synthetic flash for the synthetic
+ target.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
+
diff --git a/ecos/packages/devs/flash/synth/current/cdl/flash_synth.cdl b/ecos/packages/devs/flash/synth/current/cdl/flash_synth.cdl
new file mode 100644
index 0000000..0351b89
--- /dev/null
+++ b/ecos/packages/devs/flash/synth/current/cdl/flash_synth.cdl
@@ -0,0 +1,130 @@
+# ====================================================================
+#
+# flash_synth.cdl
+#
+# FLASH memory - Synthetic flash driver for Synthetic target
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): andrew.lunn@ascom.ch
+# Contributors: jlarmour
+# Date: 2000-10-30
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SYNTH {
+ display "Synthetic FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGINT_ISO_ERRNO_CODES
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "FLASH memory device support for Synthetic target"
+ compile synth.c flash_erase_block.c flash_program_buf.c flash_query.c
+
+ cdl_option CYGMEM_FLASH_SYNTH_BASE {
+ display "Base address of flash"
+ flavor booldata
+ default_value 0
+ description "
+ If enabled, controls where in the synth target memory map the
+ flash is mapped. WARNING: This must be somewhere
+ the host Linux kernel is prepaired to mmap a file. It
+ must be page aligned. For hosts with recent x86 Linux kernels,
+ a value of 0x40000000 is likely appropriate. When disabled,
+ the driver will automatically use whatever address the kernel
+ provides it with."
+ }
+
+ cdl_option CYGSEM_FLASH_SYNTH_FILE_WRITEBACK {
+ display "FLASH changes modify the underlying file"
+ flavor booldata
+ default_value 0
+ description "
+ If enabled, changes made to the contents of the emulated
+ FLASH are reflected in the underlying file. Otherwise,
+ the file will be left unaffected by any changes the program
+ makes to FLASH contents."
+ }
+
+ cdl_option CYGNUM_FLASH_SYNTH_BLOCKSIZE {
+ display "Size of one block of synth flash"
+ flavor data
+ default_value 65536
+ legal_values 4096 to 999999
+ requires { (CYGNUM_FLASH_SYNTH_BLOCKSIZE % 4096) == 0 }
+ description "
+ This controls the size of one block of flash. This is
+ the minimum size that can be erased."
+ }
+
+ cdl_option CYGNUM_FLASH_SYNTH_NUMBLOCKS {
+ display "Number of blocks in the synth flash"
+ flavor data
+ default_value 16
+ description "
+ This controls how many blocks there are in the flash"
+ }
+
+ cdl_option CYGDAT_FLASH_SYNTH_FILENAME {
+ display "Name of file emulating synth flash"
+ flavor data
+ default_value { "\"synth.flash\"" }
+ description "
+ This is the name of the file which holds the contents of
+ the flash. It is mmap'ed into memory and written for flash
+ program & erase operations. It will be created if it does
+ not exist."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_SYNTH_TESTS {
+ display "Synth flash tests"
+ flavor data
+ no_define
+ calculated { "tests/flash1 tests/flash2"}
+ description "
+ This option specifies the set of tests for the synth flash package."
+ }
+}
+
+# EOF flash_synth.cdl
diff --git a/ecos/packages/devs/flash/synth/current/src/flash_erase_block.c b/ecos/packages/devs/flash/synth/current/src/flash_erase_block.c
new file mode 100644
index 0000000..34ad907
--- /dev/null
+++ b/ecos/packages/devs/flash/synth/current/src/flash_erase_block.c
@@ -0,0 +1,94 @@
+//==========================================================================
+//
+// flash_erase_block.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andrew.lunn@ascom.ch
+// Contributors: andrew.lunn
+// Date: 2001-10-30
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "synth.h"
+
+#include <cyg/hal/hal_io.h>
+#include <pkgconf/devs_flash_synth.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+#include <string.h> // memset
+
+#ifndef MIN
+#define MIN(x,y) ((x)<(y) ? (x) : (y))
+#endif
+
+int flash_erase_block(volatile flash_t *block, unsigned int block_size)
+{
+ unsigned int offset = (unsigned int) block;
+ size_t remaining;
+ int write_size;
+
+ // This helps speed up the erasing
+ static cyg_uint8 empty[4096];
+ static cyg_bool empty_inited;
+
+ offset -= (unsigned int) cyg_dev_flash_synth_base;
+
+ cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset,
+ CYG_HAL_SYS_SEEK_SET);
+
+ if (!empty_inited) {
+ memset(empty, 0xff, sizeof(empty));
+ empty_inited = true;
+ }
+
+ remaining = flash_info.block_size;
+
+ while (remaining) {
+ write_size = MIN(remaining, sizeof(empty));
+ cyg_hal_sys_write(cyg_dev_flash_synth_flashfd, empty, write_size);
+ remaining -= write_size;
+ }
+
+ return FLASH_ERR_OK;
+}
diff --git a/ecos/packages/devs/flash/synth/current/src/flash_program_buf.c b/ecos/packages/devs/flash/synth/current/src/flash_program_buf.c
new file mode 100644
index 0000000..6eb50f9
--- /dev/null
+++ b/ecos/packages/devs/flash/synth/current/src/flash_program_buf.c
@@ -0,0 +1,93 @@
+//==========================================================================
+//
+// flash_program_buf.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Andrew.Lunn@ascom.ch
+// Contributors: andrew.lunn
+// Date: 2001-10-30
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include "synth.h"
+
+#include <pkgconf/devs_flash_synth.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/io/flash.h>
+
+#ifndef MIN
+#define MIN(x,y) ((x)<(y) ? (x) : (y))
+#endif
+
+int
+flash_program_buf(volatile flash_t *addr, flash_t *data, int len,
+ unsigned long block_mask, int buffer_size)
+{
+ unsigned int offset = (unsigned int) addr;
+ cyg_uint8 *buf = (cyg_uint8 *) data;
+
+ // This helps speed up the programming
+ static cyg_uint8 tmp[4096];
+
+ offset -= (unsigned int) cyg_dev_flash_synth_base;
+
+ while (len > 0) {
+ int i;
+ int write_size = MIN(len, sizeof(tmp));
+ // Writing to NOR flash only sets bits from 1 to 0, not vice-versa
+ cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset,
+ CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_read(cyg_dev_flash_synth_flashfd, tmp, write_size);
+ for (i = 0; i < write_size; i++)
+ tmp[i] = tmp[i] & buf[i];
+ cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset,
+ CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_write(cyg_dev_flash_synth_flashfd, tmp, write_size);
+ // Process next chunk
+ buf += write_size;
+ offset += write_size;
+ len -= write_size;
+ }
+
+ return FLASH_ERR_OK;
+}
diff --git a/ecos/packages/devs/flash/synth/current/src/flash_query.c b/ecos/packages/devs/flash/synth/current/src/flash_query.c
new file mode 100644
index 0000000..8d7d510
--- /dev/null
+++ b/ecos/packages/devs/flash/synth/current/src/flash_query.c
@@ -0,0 +1,61 @@
+//==========================================================================
+//
+// flash_query.c
+//
+// Flash programming - query device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andrew.lunn@ascom.ch
+// Contributors: andrew.lunn
+// Date: 2001-10-30
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define QUERY "Linux Synthetic Flash"
+
+#include <string.h> // memcpy
+
+int
+flash_query(unsigned char *data)
+{
+ memcpy(data,QUERY,sizeof(QUERY));
+ return 0;
+}
diff --git a/ecos/packages/devs/flash/synth/current/src/synth.c b/ecos/packages/devs/flash/synth/current/src/synth.c
new file mode 100644
index 0000000..e4ef6ee
--- /dev/null
+++ b/ecos/packages/devs/flash/synth/current/src/synth.c
@@ -0,0 +1,157 @@
+//==========================================================================
+//
+// synth.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andrew.lunn@ascom.ch
+// Contributors: jlarmour
+// Date: 2001-10-30
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_flash_synth.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/infra/cyg_ass.h>
+#include <errno.h>
+#include <string.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include "synth.h"
+
+/* Holds the fd for the flash file */
+int cyg_dev_flash_synth_flashfd;
+
+/* Holds the base address of the mmap'd region */
+flash_t *cyg_dev_flash_synth_base;
+
+int
+flash_hwr_init(void)
+{
+ flash_info.block_size = CYGNUM_FLASH_SYNTH_BLOCKSIZE;
+ flash_info.buffer_size = 0;
+ flash_info.blocks = CYGNUM_FLASH_SYNTH_NUMBLOCKS;
+
+ cyg_dev_flash_synth_flashfd = cyg_hal_sys_open(CYGDAT_FLASH_SYNTH_FILENAME,
+ CYG_HAL_SYS_O_RDWR,
+ CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
+ if (cyg_dev_flash_synth_flashfd == -ENOENT) {
+ long w, bytesleft;
+ char buf[128];
+
+ cyg_dev_flash_synth_flashfd = cyg_hal_sys_open(
+ CYGDAT_FLASH_SYNTH_FILENAME,
+ CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT,
+ CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
+ CYG_ASSERT( cyg_dev_flash_synth_flashfd >= 0,
+ "Opening of the file for the synth flash failed!");
+ // fill with 0xff
+ memset( buf, 0xff, sizeof(buf) );
+ bytesleft = CYGNUM_FLASH_SYNTH_BLOCKSIZE * CYGNUM_FLASH_SYNTH_NUMBLOCKS;
+ while (bytesleft > 0)
+ {
+ int bytesneeded;
+ bytesneeded = bytesleft < sizeof(buf) ? bytesleft : sizeof(buf);
+
+ w = cyg_hal_sys_write( cyg_dev_flash_synth_flashfd, buf,
+ bytesneeded );
+ CYG_ASSERT(w == bytesneeded, "initialization of flash file failed");
+ bytesleft -= bytesneeded;
+ } // while
+ }
+ CYG_ASSERT( cyg_dev_flash_synth_flashfd >= 0,
+ "Opening of the file for the synth flash failed!");
+ if ( cyg_dev_flash_synth_flashfd <= 0 ) {
+ return FLASH_ERR_HWR;
+ }
+ cyg_dev_flash_synth_base = (flash_t *)cyg_hal_sys_mmap(
+#ifdef CYGMEM_FLASH_SYNTH_BASE
+ (void *)CYGMEM_FLASH_SYNTH_BASE,
+#else
+ NULL,
+#endif
+ (CYGNUM_FLASH_SYNTH_BLOCKSIZE * CYGNUM_FLASH_SYNTH_NUMBLOCKS),
+ CYG_HAL_SYS_PROT_READ,
+#ifdef CYGSEM_FLASH_SYNTH_FILE_WRITEBACK
+ CYG_HAL_SYS_MAP_SHARED
+#else
+ CYG_HAL_SYS_MAP_PRIVATE
+#endif
+#ifdef CYGMEM_FLASH_SYNTH_BASE
+ |CYG_HAL_SYS_MAP_FIXED
+#endif
+ , cyg_dev_flash_synth_flashfd, 0 );
+ CYG_ASSERT( cyg_dev_flash_synth_base != (void *) -1, "mmap of flash file failed!" );
+
+ if (cyg_dev_flash_synth_base == (void *) -1) {
+ return FLASH_ERR_HWR;
+ }
+ flash_info.start = cyg_dev_flash_synth_base;
+ flash_info.end = (void *)(((char *)cyg_dev_flash_synth_base) -1 +
+ (CYGNUM_FLASH_SYNTH_BLOCKSIZE * CYGNUM_FLASH_SYNTH_NUMBLOCKS));
+
+ return FLASH_ERR_OK;
+}
+
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int err)
+{
+ return err;
+}
+
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
+
+// EOF synth.c
diff --git a/ecos/packages/devs/flash/synth/current/src/synth.h b/ecos/packages/devs/flash/synth/current/src/synth.h
new file mode 100644
index 0000000..3f9993b
--- /dev/null
+++ b/ecos/packages/devs/flash/synth/current/src/synth.h
@@ -0,0 +1,63 @@
+#ifndef CYGONCE_DEVS_FLASH_SYNTH_SYNTH_H
+#define CYGONCE_DEVS_FLASH_SYNTH_SYNTH_H
+//==========================================================================
+//
+// synth.h
+//
+// synth Flash programming - device constants, etc.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andrew.lunn@ascom.ch
+// Contributors: andrew.lunn
+// Date: 2001-10-30
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <cyg/infra/cyg_type.h>
+
+typedef unsigned long flash_t;
+__externC int cyg_dev_flash_synth_flashfd;
+__externC flash_t *cyg_dev_flash_synth_base;
+
+#endif // CYGONCE_DEVS_FLASH_SYNTH_SYNTH_H
+// ------------------------------------------------------------------------
+// EOF synth.h
diff --git a/ecos/packages/devs/flash/synth/current/tests/flash1.c b/ecos/packages/devs/flash/synth/current/tests/flash1.c
new file mode 100644
index 0000000..779e6c8
--- /dev/null
+++ b/ecos/packages/devs/flash/synth/current/tests/flash1.c
@@ -0,0 +1,190 @@
+/* Hey, the copyright is useful for something! */
+
+static char copyright[] =
+"//=========================================================================="
+"//"
+"// flash1.c"
+"//"
+"// Test flash operations for the synth target synth flash driver"
+"//"
+"//=========================================================================="
+"// ####ECOSGPLCOPYRIGHTBEGIN#### "
+"// ------------------------------------------- "
+"// This file is part of eCos, the Embedded Configurable Operating System. "
+"// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. "
+"// "
+"// eCos is free software; you can redistribute it and/or modify it under "
+"// the terms of the GNU General Public License as published by the Free "
+"// Software Foundation; either version 2 or (at your option) any later "
+"// version. "
+"// "
+"// eCos is distributed in the hope that it will be useful, but WITHOUT "
+"// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License "
+"// for more details. "
+"// "
+"// You should have received a copy of the GNU General Public License "
+"// along with eCos; if not, write to the Free Software Foundation, Inc., "
+"// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. "
+"// "
+"// As a special exception, if other files instantiate templates or use "
+"// macros or inline functions from this file, or you compile this file "
+"// and link it with other works to produce a work based on this file, "
+"// this file does not by itself cause the resulting work to be covered by "
+"// the GNU General Public License. However the source code for this file "
+"// must still be made available in accordance with section (3) of the GNU "
+"// General Public License v2. "
+"// "
+"// This exception does not invalidate any other reasons why a work based "
+"// on this file might be covered by the GNU General Public License. "
+"// ------------------------------------------- "
+"// ####ECOSGPLCOPYRIGHTEND####"
+"//=========================================================================="
+"//#####DESCRIPTIONBEGIN####"
+"//"
+"// Author(s): andrew.lunn@ascom.ch"
+"// Contributors: andrew.lunn"
+"// Date: 2000-10-31"
+"// Purpose: Test a flash driver"
+"// Description: Try out a number of flash operations and make sure"
+"// what is in the flash is what we expeect."
+"// "
+"//####DESCRIPTIONEND####"
+"//"
+"//=========================================================================="
+;
+
+#include <cyg/io/flash.h>
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+#include <string.h>
+
+#ifndef CYGINT_ISO_STRING_STRFUNCS
+# define NA_MSG "Need string functions for test"
+#endif
+#ifndef CYGSEM_IO_FLASH_LEGACY_API
+# define NA_MSG "Need legacy IO FLASH API for test"
+#endif
+
+#ifdef NA_MSG
+void cyg_user_start(void)
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( NA_MSG );
+}
+#else
+
+//==========================================================================
+// main
+
+void cyg_user_start(void)
+{
+ int ret;
+ char data[1024];
+ void *flash_start, *flash_end;
+ int block_size, blocks;
+ char *prog_start;
+ unsigned char * ptr;
+
+ CYG_TEST_INIT();
+
+ ret=flash_init((_printf *)diag_printf);
+
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_init");
+
+ flash_dev_query(data);
+ CYG_TEST_PASS_FAIL(!strncmp(data,"Linux Synthetic Flash",sizeof(data)),
+ "flash_query");
+
+ ret = flash_get_limits(NULL,&flash_start,&flash_end);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_get_limits");
+
+ ret = flash_get_block_info(&block_size, &blocks);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_get_block_info");
+
+ /* Erase the whole flash. Not recommended on real hardware since this
+ will probably erase the bootloader etc!!! */
+ ret=flash_erase(flash_start,block_size * blocks,NULL);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_erase1");
+
+ /* check that its actually been erased, and test the mmap area */
+ for (ptr=flash_start,ret=0; ptr < (unsigned char *)flash_end; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0),"flash empty check");
+
+ ret = flash_program(flash_start,&copyright,sizeof(copyright),NULL);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_program1");
+
+ /* Check the contents made it into the flash */
+ CYG_TEST_PASS_FAIL(!strncmp(flash_start,copyright,sizeof(copyright)),
+ "flash program contents");
+
+ /* .. and check nothing else changed */
+ for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0;
+ ptr < (unsigned char *)flash_end; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0),"flash program overrun check");
+
+ /* Program over a block boundary */
+ prog_start = (char *)flash_start + block_size - sizeof(copyright)/2;
+ ret = flash_program(prog_start,&copyright,sizeof(copyright),NULL);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_program2");
+
+ /* Check the first version is still OK */
+ CYG_TEST_PASS_FAIL(!strncmp(flash_start,copyright,sizeof(copyright)),
+ "Original contents");
+
+ CYG_TEST_PASS_FAIL(!strncmp(prog_start,copyright,sizeof(copyright)),
+ "New program contents");
+
+ /* Check the bit in between is still erased */
+ for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0;
+ ptr < (unsigned char *)prog_start; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+ CYG_TEST_PASS_FAIL((ret == 0),"flash erase check1");
+
+ /* Erase the second block and make sure the first is not erased */
+ ret=flash_erase((void *)((unsigned)flash_start+block_size),
+ block_size,NULL);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_erase2");
+
+ /* Check the erase worked */
+ for (ptr=(unsigned char *)flash_start+block_size,ret=0;
+ ptr < (unsigned char *)flash_start+block_size*2; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0), "flash erase check2");
+
+ /* Lastly check the first half of the copyright message is still there */
+ CYG_TEST_PASS_FAIL(!strncmp(prog_start,copyright,sizeof(copyright)/2),
+ "Block 1 OK");
+
+#if 0
+ /* This test it fatal! Its not run by default!
+ Check the flash is read only, by trying to write to it. We expect
+ to get an exception */
+
+ *(char *)flash_start = 'a';
+#endif
+
+ CYG_TEST_PASS_FINISH("flash1");
+}
+
+#endif /* ifndef NA_MSG */
+
+/* EOF flash1.c */
diff --git a/ecos/packages/devs/flash/synth/current/tests/flash2.c b/ecos/packages/devs/flash/synth/current/tests/flash2.c
new file mode 100644
index 0000000..21681ba
--- /dev/null
+++ b/ecos/packages/devs/flash/synth/current/tests/flash2.c
@@ -0,0 +1,209 @@
+/* Hey, the copyright is useful for something! */
+
+static char copyright[] =
+"//=========================================================================="
+"//"
+"// flash1.c"
+"//"
+"// Test flash operations for the synth target synth flash driver"
+"//"
+"//=========================================================================="
+"// ####ECOSGPLCOPYRIGHTBEGIN#### "
+"// ------------------------------------------- "
+"// This file is part of eCos, the Embedded Configurable Operating System. "
+"// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc. "
+"// "
+"// eCos is free software; you can redistribute it and/or modify it under "
+"// the terms of the GNU General Public License as published by the Free "
+"// Software Foundation; either version 2 or (at your option) any later "
+"// version. "
+"// "
+"// eCos is distributed in the hope that it will be useful, but WITHOUT "
+"// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License "
+"// for more details. "
+"// "
+"// You should have received a copy of the GNU General Public License "
+"// along with eCos; if not, write to the Free Software Foundation, Inc., "
+"// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. "
+"// "
+"// As a special exception, if other files instantiate templates or use "
+"// macros or inline functions from this file, or you compile this file "
+"// and link it with other works to produce a work based on this file, "
+"// this file does not by itself cause the resulting work to be covered by "
+"// the GNU General Public License. However the source code for this file "
+"// must still be made available in accordance with section (3) of the GNU "
+"// General Public License v2. "
+"// "
+"// This exception does not invalidate any other reasons why a work based "
+"// on this file might be covered by the GNU General Public License. "
+"// ------------------------------------------- "
+"// ####ECOSGPLCOPYRIGHTEND####"
+"//=========================================================================="
+"//#####DESCRIPTIONBEGIN####"
+"//"
+"// Author(s): andrew.lunn@ascom.ch"
+"// Contributors: andrew.lunn"
+"// Date: 2000-10-31"
+"// Purpose: Test a flash driver"
+"// Description: Try out a number of flash operations and make sure"
+"// what is in the flash is what we expeect."
+"// "
+"//####DESCRIPTIONEND####"
+"//"
+"//==========================================================================&"
+;
+
+#include <pkgconf/devs_flash_synth.h>
+#include <cyg/io/flash.h>
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+#include <string.h>
+
+#ifndef CYGINT_ISO_STRING_STRFUNCS
+# define NA_MSG "Need string functions for test"
+#endif
+
+#ifdef NA_MSG
+void cyg_user_start(void)
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( NA_MSG );
+}
+#else
+
+//==========================================================================
+// main
+
+void cyg_user_start(void)
+{
+ int ret;
+ cyg_flashaddr_t flash_start=0, flash_end=0;
+ cyg_flash_info_t info;
+ int block_size=0, blocks=0;
+ cyg_flashaddr_t prog_start;
+ unsigned char * ptr;
+ cyg_uint32 i=0;
+ cyg_uint32 j;
+
+ CYG_TEST_INIT();
+
+ cyg_flash_set_global_printf((cyg_flash_printf *)&diag_printf);
+ ret=cyg_flash_init(NULL);
+
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_init");
+
+ do {
+ ret = cyg_flash_get_info(i, &info);
+ if (ret == CYG_FLASH_ERR_OK) {
+ diag_printf("INFO: Nth=%d, start=%p, end=%p\n",
+ i, (void *) info.start, (void *) info.end);
+ if (i == 0) {
+ flash_start = info.start;
+ flash_end = info.end;
+ block_size = info.block_info[0].block_size;
+ blocks = info.block_info[0].blocks;
+ }
+ for (j=0;j < info.num_block_infos; j++) {
+ diag_printf("INFO:\t block_size %zd, blocks %u\n",
+ info.block_info[j].block_size,
+ info.block_info[j].blocks);
+ }
+ }
+ i++;
+ } while (ret != CYG_FLASH_ERR_INVALID);
+
+ /* Erase the whole flash. Not recommended on real hardware since this
+ will probably erase the bootloader etc!!! */
+ ret=cyg_flash_erase(flash_start,block_size * blocks,NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_erase1");
+
+ /* check that its actually been erased, and test the mmap area */
+ for (ptr=(unsigned char *)flash_start,ret=0;
+ ptr <= (unsigned char *)flash_end; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0),"flash empty check");
+
+ ret = cyg_flash_program(flash_start,&copyright,sizeof(copyright),NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program1");
+
+ /* Check the contents made it into the flash */
+ CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
+ copyright,sizeof(copyright)),
+ "flash program contents");
+
+ /* .. and check nothing else changed */
+ for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0;
+ ptr < (unsigned char *)flash_end; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0),"flash program overrun check");
+
+ /* Program over a block boundary */
+ prog_start = flash_start + block_size - sizeof(copyright)/2;
+ ret = cyg_flash_program(prog_start,&copyright,sizeof(copyright),NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program2");
+
+ /* Check the first version is still OK */
+ CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
+ copyright,
+ sizeof(copyright)),
+ "Original contents");
+
+ CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
+ copyright,
+ sizeof(copyright)),
+ "New program contents");
+
+ /* Check the bit in between is still erased */
+ for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0;
+ ptr < (unsigned char *)prog_start; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+ CYG_TEST_PASS_FAIL((ret == 0),"flash erase check1");
+
+ /* Erase the second block and make sure the first is not erased */
+ ret=cyg_flash_erase(flash_start+block_size,block_size,NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_erase2");
+
+ /* Check the erase worked */
+ for (ptr=(unsigned char *)flash_start+block_size,ret=0;
+ ptr < (unsigned char *)flash_start+block_size*2;
+ ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0), "flash erase check2");
+
+ /* Lastly check the first half of the copyright message is still there */
+ CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
+ copyright,
+ sizeof(copyright)/2),
+ "Block 1 OK");
+
+#if 0
+ /* This test is be fatal! Its not run by default!
+ Check the flash is read only, by trying to write to it. We expect
+ to get an exception */
+
+ *(char *)flash_start = 'a';
+#endif
+
+ CYG_TEST_PASS_FINISH("flash1");
+}
+
+#endif /* ifndef NA_MSG */
+
+/* EOF flash2.c */
diff --git a/ecos/packages/devs/flash/synthv2/current/ChangeLog b/ecos/packages/devs/flash/synthv2/current/ChangeLog
new file mode 100644
index 0000000..2c8ed26
--- /dev/null
+++ b/ecos/packages/devs/flash/synthv2/current/ChangeLog
@@ -0,0 +1,113 @@
+2009-02-20 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * tests/flash2.c (cyg_user_start): Call cyg_flash_init() with
+ NULL argument.
+ * tests/flash3.c (cyg_user_start): Ditto.
+
+2009-02-18 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * tests/flash2.c (cyg_user_start): Update for minor flash API
+ mod to call cyg_flash_set_global_printf() to set printf
+ function.
+ * tests/flash3.c (cyg_user_start): Ditto.
+
+2008-12-23 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/synth.c: Implemented simulation of proper NOR flash writes.
+ General cleanup.
+
+2008-12-18 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/synth.c: Fixed error check of mmap call.
+
+2008-11-28 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * tests/flash[23].c: Fixed copy'n'paste typos in a naming: flash1 ->
+ flash{2,3}.
+
+2008-11-19 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/synth.c: Removed cyg_hal_sys_do_mmap() wrapper function.
+ * tests/flash1.c, tests/flash2.c, tests/flash3.c:
+ Fixed a few compiler warnings.
+
+2004-12-02 Bart Veer <bartv@ecoscentric.com>
+
+ * include/synth.h, src/synth.c: explicitly include
+ <cyg/io/flash_dev.h> rather than just defining _FLASH_PRIVATE_
+
+2004-11-29 Bart Veer <bartv@ecoscentric.com>
+
+ * src/synth.c: eliminate hwr_map_error() support, no longer needed
+
+ * src/synth.c: use the dummy lock/unlock functions provided by the
+ generic flash package.
+
+2004-11-22 Bart Veer <bartv@ecoscentric.com>
+
+ * include/synth.h, src/synth.c, tests/flash3.c: merge the config
+ and priv structures. Adjust device driver API as per changes to
+ the generic flash code.
+ * tests/flash2.c, tests/flash3.c: do not depend on both synthetic
+ flash drivers being loaded.
+ * include/synth.h (struct cyg_flash_synth_priv): rename
+ cyg_block_info to cyg_flash_block_info
+
+2004-11-21 Bart Veer <bartv@ecoscentric.com>
+
+ * tests/flash1.c (cyg_user_start):
+ CYGSEM_IO_FLASH_LEGACY_DEVICE_API has been removed, use
+ CYGHWR_IO_FLASH_DEVICE_LEGACY instead
+ * cdl/flash_synth.cdl: CYGHWR_IO_FLASH_DEVICE_V2 is now implicit
+
+2004-09-14 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/synth.c (synth_flash_erase_block): Remove asserts which are
+ no longer true.
+
+2004-09-09 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/flash_synth.c: Allow the use of arbitary sized block.
+ * test/flash3.c: Allow the use of small blocks
+
+2004-08-21 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * tests/flash[23].c: Removed calls to cyg_flash_get_block_info()
+ and cyg_flash_get_limits() which have been removed.
+
+2004-08-03 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/flash_synth.cdl: Indicate we use the V2 device API.
+
+2004-07-17 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * First version. Implements synthetic flash using the new flash
+ API.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
+
+
diff --git a/ecos/packages/devs/flash/synthv2/current/cdl/flash_synth.cdl b/ecos/packages/devs/flash/synthv2/current/cdl/flash_synth.cdl
new file mode 100644
index 0000000..8a367c8
--- /dev/null
+++ b/ecos/packages/devs/flash/synthv2/current/cdl/flash_synth.cdl
@@ -0,0 +1,144 @@
+# ====================================================================
+#
+# flash_synth.cdl
+#
+# FLASH memory - Synthetic flash driver for Synthetic target
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): andrew.lunn@ascom.ch
+# Contributors: jlarmour
+# Date: 2000-10-30
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SYNTH_V2 {
+ display "Synthetic FLASH memory support"
+
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires CYGINT_ISO_ERRNO_CODES
+
+ implements CYGHWR_IO_FLASH_DEVICE
+
+ include_dir cyg/flash
+ description "FLASH memory device support for Synthetic target"
+ compile -library=libextras.a synth.c
+
+ cdl_option CYGMEM_FLASH_SYNTH_V2_BASE {
+ display "Base address of flash"
+ flavor data
+ default_value 0
+ description "
+ Controls where in the synth target memory map the
+ flash is mapped. WARNING: This must be somewhere
+ the host Linux kernel is prepaired to mmap a file. It
+ must be page aligned. For hosts with recent x86 Linux kernels,
+ a value of 0x40000000 is likely appropriate. When 0
+ the driver will automatically use whatever address the kernel
+ provides it with."
+ }
+
+ cdl_option CYGNUM_FLASH_SYNTH_V2_BLOCKSIZE {
+ display "Size of one block of synth flash"
+ flavor data
+ default_value 65536
+ legal_values 512 to 999999
+ description "
+ This controls the size of one block of flash. This is
+ the minimum size that can be erased."
+ }
+
+ cdl_option CYGNUM_FLASH_SYNTH_V2_NUMBLOCKS {
+ display "Number of blocks in the synth flash"
+ flavor data
+ default_value 15
+ description "
+ This controls how many main blocks there are in the flash"
+ }
+
+ cdl_option CYGNUM_FLASH_SYNTH_V2_NUMBOOT_BLOCKS {
+ display "Number of boot blocks in the synth flash"
+ flavor data
+ default_value 8
+ description "
+ This controls the number of boot blocks the synthetic
+ device has. A value of zero disables the support of boot blocks"
+ }
+
+ cdl_option CYGNUM_FLASH_SYNTH_V2_BOOT_BLOCKSIZE {
+ display "Size of the boot blocks in the synth flash"
+ flavor data
+ default_value 8192
+ description "
+ This controls the size of boot blocks the synthetic
+ device has"
+ }
+
+ cdl_option CYGNUM_FLASH_SYNTH_V2_BOOT_BLOCK_BOTTOM {
+ display "Is the boot blocks at the bottom of the flash"
+ flavor bool
+ default_value 1
+ description "
+ This controls where the boot blocks are. If true the boot
+ blocks are at the bottom of the memory space, otherwise
+ they are at the top of the memory space."
+ }
+
+ cdl_option CYGDAT_FLASH_SYNTH_V2_FILENAME {
+ display "Name of file emulating synth flash"
+ flavor data
+ default_value { "\"synthv2.flash\"" }
+ description "
+ This is the name of the file which holds the contents of
+ the flash. It is mmap'ed into memory and written for flash
+ program & erase operations. It will be created if it does
+ not exist."
+ }
+
+ cdl_option CYGPKG_DEVS_FLASH_SYNTH_V2_TESTS {
+ display "Synth flash tests"
+ flavor data
+ no_define
+ calculated { "tests/flash1.c tests/flash2.c tests/flash3.c"}
+ description "
+ This option specifies the set of tests for the synth flash package."
+ }
+}
+
+# EOF flash_synth.cdl
diff --git a/ecos/packages/devs/flash/synthv2/current/include/synth.h b/ecos/packages/devs/flash/synthv2/current/include/synth.h
new file mode 100644
index 0000000..a1e9213
--- /dev/null
+++ b/ecos/packages/devs/flash/synthv2/current/include/synth.h
@@ -0,0 +1,77 @@
+#ifndef DEV_FLASH_SYNTHV2_SYNTH_H
+#define DEV_FLASH_SYNTHV2_SYNTH_H
+//==========================================================================
+//
+// synth.h
+//
+// Synthetic Flash driver header
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Andrew Lunn
+// Contributors: Andrew Lunn
+// Date: 2004-07-03
+// Purpose: Header file for the synthetic flash device
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+// Structure of data private to each flash device
+struct cyg_flash_synth_priv
+{
+ // Configuration parameters,
+ size_t block_size;
+ cyg_uint32 blocks;
+ size_t boot_block_size;
+ cyg_uint32 boot_blocks;
+ cyg_bool boot_block_bottom;
+ char * filename;
+ // Run-time data
+ int flashfd;
+ // Space for the block layout
+ struct cyg_flash_block_info block_info[2];
+};
+
+extern const struct cyg_flash_dev_funs cyg_flash_synth_funs;
+
+#endif
+
+
diff --git a/ecos/packages/devs/flash/synthv2/current/src/synth.c b/ecos/packages/devs/flash/synthv2/current/src/synth.c
new file mode 100644
index 0000000..23003e6
--- /dev/null
+++ b/ecos/packages/devs/flash/synthv2/current/src/synth.c
@@ -0,0 +1,275 @@
+//==========================================================================
+//
+// synth.c
+//
+// Flash programming
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): andrew.lunn@ascom.ch
+// Contributors: jlarmour
+// Date: 2001-10-30
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/devs_flash_synth_v2.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/infra/cyg_ass.h>
+#include <string.h>
+
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+#include <cyg/flash/synth.h>
+
+#ifndef MIN
+#define MIN(x,y) ((x)<(y) ? (x) : (y))
+#endif
+
+static int
+synth_flash_init(struct cyg_flash_dev *dev)
+{
+ struct cyg_flash_synth_priv *priv =
+ (struct cyg_flash_synth_priv *) dev->priv;
+ cyg_flashaddr_t base;
+ int flags = CYG_HAL_SYS_MAP_SHARED;
+
+ priv->flashfd = cyg_hal_sys_open(
+ priv->filename,
+ CYG_HAL_SYS_O_RDWR,
+ CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
+
+ if (priv->flashfd == -ENOENT) {
+ long w, bytesleft;
+ char buf[128];
+
+ priv->flashfd = cyg_hal_sys_open(
+ priv->filename,
+ CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT,
+ CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
+ CYG_ASSERT(priv->flashfd >= 0,
+ "Opening of the file for the synth flash failed!");
+
+ // Fill with 0xff
+ memset(buf, 0xff, sizeof(buf));
+ bytesleft = priv->block_size * priv->blocks +
+ priv->boot_block_size * priv->boot_blocks;
+ while (bytesleft > 0) {
+ int bytesneeded;
+ bytesneeded = bytesleft < sizeof(buf) ? bytesleft : sizeof(buf);
+ w = cyg_hal_sys_write(priv->flashfd, buf, bytesneeded);
+ CYG_ASSERT(w == bytesneeded, "initialization of flash file failed");
+ bytesleft -= bytesneeded;
+ }
+ }
+
+ CYG_ASSERT(priv->flashfd >= 0,
+ "Opening of the file for the synth flash failed!");
+
+ if (priv->flashfd <= 0)
+ return CYG_FLASH_ERR_HWR;
+
+ if (dev->start != 0)
+ flags |= CYG_HAL_SYS_MAP_FIXED;
+
+ base = (cyg_flashaddr_t) cyg_hal_sys_mmap(
+ (void *) dev->start,
+ priv->blocks * priv->block_size +
+ priv->boot_block_size * priv->boot_blocks,
+ CYG_HAL_SYS_PROT_READ,
+ flags,
+ priv->flashfd,
+ 0l);
+ CYG_ASSERT(base != -1, "mmap of flash file failed!");
+ if (base == -1)
+ return CYG_FLASH_ERR_HWR;
+
+ dev->start = base;
+ dev->end = base + (priv->blocks * priv->block_size) +
+ (priv->boot_blocks * priv->boot_block_size) - 1;
+ if (priv->boot_blocks) {
+ if (priv->boot_block_bottom) {
+ priv->block_info[0].block_size = priv->boot_block_size;
+ priv->block_info[0].blocks = priv->boot_blocks;
+ priv->block_info[1].block_size = priv->block_size;
+ priv->block_info[1].blocks = priv->blocks;
+ } else {
+ priv->block_info[0].block_size = priv->block_size;
+ priv->block_info[0].blocks = priv->blocks;
+ priv->block_info[1].block_size = priv->boot_block_size;
+ priv->block_info[1].blocks = priv->boot_blocks;
+ }
+ dev->num_block_infos = 2;
+ } else {
+ priv->block_info[0].block_size = priv->block_size;
+ priv->block_info[0].blocks = priv->blocks;
+ dev->num_block_infos = 1;
+ }
+ dev->block_info = &priv->block_info[0];
+
+ return CYG_FLASH_ERR_OK;
+}
+
+// Return the size of the block which is at the given address.
+// __inline__ so that we know it will be in RAM, not ROM.
+static __inline__ size_t
+flash_block_size(struct cyg_flash_dev *dev, const cyg_flashaddr_t addr)
+{
+ int i;
+ cyg_flashaddr_t offset;
+
+ CYG_ASSERT((addr >= dev->start) && (addr <= dev->end), "Not inside device");
+
+ offset = addr - dev->start;
+ for (i=0; i < dev->num_block_infos; i++) {
+ if (offset < (dev->block_info[i].blocks *
+ dev->block_info[i].block_size))
+ return dev->block_info[i].block_size;
+ offset = offset -
+ (dev->block_info[i].blocks * dev->block_info[i].block_size);
+ }
+ CYG_FAIL("Programming error");
+ return 0;
+}
+
+static int
+synth_flash_erase_block(struct cyg_flash_dev *dev,
+ cyg_flashaddr_t block_base)
+{
+ const struct cyg_flash_synth_priv *priv = dev->priv;
+ cyg_flashaddr_t offset = block_base;
+ size_t remaining;
+ int write_size;
+
+ // This helps speed up the erasing
+ static cyg_uint8 empty[4096];
+ static cyg_bool empty_inited;
+
+ offset -= dev->start;
+
+ cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET);
+
+ if (!empty_inited) {
+ memset(empty, 0xff, sizeof(empty));
+ empty_inited = true;
+ }
+
+ remaining = flash_block_size(dev, block_base);
+
+ while (remaining) {
+ write_size = MIN(remaining, sizeof(empty));
+ cyg_hal_sys_write(priv->flashfd, empty, write_size);
+ remaining -= write_size;
+ }
+
+ return CYG_FLASH_ERR_OK;
+}
+
+static int
+synth_flash_program (struct cyg_flash_dev *dev,
+ cyg_flashaddr_t base,
+ const void* data, size_t len)
+{
+ const struct cyg_flash_synth_priv *priv = dev->priv;
+ cyg_flashaddr_t offset = base;
+ cyg_uint8 *buf = (cyg_uint8 *) data;
+
+ // This helps speed up the programming
+ static cyg_uint8 tmp[4096];
+
+ offset -= dev->start;
+
+ while (len > 0) {
+ int i;
+ int write_size = MIN(len, sizeof(tmp));
+ // Writing to NOR flash only sets bits from 1 to 0, not vice-versa
+ cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_read(priv->flashfd, tmp, write_size);
+ for (i = 0; i < write_size; i++)
+ tmp[i] = tmp[i] & buf[i];
+ cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_write(priv->flashfd, tmp, write_size);
+ // Process next chunk
+ buf += write_size;
+ offset += write_size;
+ len -= write_size;
+ }
+
+ return CYG_FLASH_ERR_OK;
+}
+
+#define QUERY "Linux Synthetic Flash"
+
+static size_t
+synth_flash_query(struct cyg_flash_dev *dev, void * data, size_t len)
+{
+ memcpy(data, QUERY, sizeof(QUERY));
+ return sizeof(QUERY);
+}
+
+const CYG_FLASH_FUNS(cyg_flash_synth_funs,
+ synth_flash_init,
+ synth_flash_query,
+ synth_flash_erase_block,
+ synth_flash_program,
+ NULL, // read
+ cyg_flash_devfn_lock_nop,
+ cyg_flash_devfn_unlock_nop);
+
+static struct cyg_flash_synth_priv synth_flash_priv = {
+ .block_size = CYGNUM_FLASH_SYNTH_V2_BLOCKSIZE,
+ .blocks = CYGNUM_FLASH_SYNTH_V2_NUMBLOCKS,
+ .boot_block_size = CYGNUM_FLASH_SYNTH_V2_BOOT_BLOCKSIZE,
+ .boot_blocks = CYGNUM_FLASH_SYNTH_V2_NUMBOOT_BLOCKS,
+ .boot_block_bottom = CYGNUM_FLASH_SYNTH_V2_BOOT_BLOCK_BOTTOM,
+ .filename = CYGDAT_FLASH_SYNTH_V2_FILENAME,
+ .flashfd = -1
+};
+
+CYG_FLASH_DRIVER(cyg_flash_synth_flashdev,
+ &cyg_flash_synth_funs,
+ 0, // flags
+ CYGMEM_FLASH_SYNTH_V2_BASE, // Start, if 0 will be updated by init
+ 0, // end, filled in by init
+ 0, // number of block_info's, filled in by init
+ synth_flash_priv.block_info,
+ &synth_flash_priv);
+
+// EOF synth.c
diff --git a/ecos/packages/devs/flash/synthv2/current/tests/flash1.c b/ecos/packages/devs/flash/synthv2/current/tests/flash1.c
new file mode 100644
index 0000000..e2fd6f3
--- /dev/null
+++ b/ecos/packages/devs/flash/synthv2/current/tests/flash1.c
@@ -0,0 +1,194 @@
+/* Hey, the copyright is usefull for something! */
+
+static char copyright[] =
+"//=========================================================================="
+"//"
+"// flash1.c"
+"//"
+"// Test flash operations for the synth target synth flash driver"
+"//"
+"//=========================================================================="
+"// ####ECOSGPLCOPYRIGHTBEGIN#### "
+"// ------------------------------------------- "
+"// This file is part of eCos, the Embedded Configurable Operating System. "
+"// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. "
+"// "
+"// eCos is free software; you can redistribute it and/or modify it under "
+"// the terms of the GNU General Public License as published by the Free "
+"// Software Foundation; either version 2 or (at your option) any later "
+"// version. "
+"// "
+"// eCos is distributed in the hope that it will be useful, but WITHOUT "
+"// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License "
+"// for more details. "
+"// "
+"// You should have received a copy of the GNU General Public License "
+"// along with eCos; if not, write to the Free Software Foundation, Inc., "
+"// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. "
+"// "
+"// As a special exception, if other files instantiate templates or use "
+"// macros or inline functions from this file, or you compile this file "
+"// and link it with other works to produce a work based on this file, "
+"// this file does not by itself cause the resulting work to be covered by "
+"// the GNU General Public License. However the source code for this file "
+"// must still be made available in accordance with section (3) of the GNU "
+"// General Public License v2. "
+"// "
+"// This exception does not invalidate any other reasons why a work based "
+"// on this file might be covered by the GNU General Public License. "
+"// ------------------------------------------- "
+"// ####ECOSGPLCOPYRIGHTEND#### "
+"//=========================================================================="
+"//#####DESCRIPTIONBEGIN####"
+"//"
+"// Author(s): andrew.lunn@ascom.ch"
+"// Contributors: andrew.lunn"
+"// Date: 2000-10-31"
+"// Purpose: Test a flash driver"
+"// Description: Try out a number of flash operations and make sure"
+"// what is in the flash is what we expeect."
+"// "
+"//####DESCRIPTIONEND####"
+"//"
+"//=========================================================================="
+;
+
+#include <cyg/io/flash.h>
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+#include <string.h>
+
+#ifndef CYGINT_ISO_STRING_STRFUNCS
+# define NA_MSG "Need string functions for test"
+#endif
+#ifndef CYGSEM_IO_FLASH_LEGACY_API
+# define NA_MSG "Need legacy IO FLASH API for test"
+#endif
+
+#ifdef NA_MSG
+void cyg_user_start(void)
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( NA_MSG );
+}
+#else
+
+//==========================================================================
+// main
+
+void cyg_user_start(void)
+{
+ int ret;
+#ifdef CYGHWR_IO_FLASH_DEVICE_LEGACY
+ char data[1024];
+#endif
+ void *flash_start, *flash_end;
+ int block_size, blocks;
+ char *prog_start;
+ unsigned char * ptr;
+
+ CYG_TEST_INIT();
+
+ ret=flash_init((_printf *)diag_printf);
+
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_init");
+
+#ifdef CYGHWR_IO_FLASH_DEVICE_LEGACY
+ //Strictly speaking, this is a device driver call, not a user API call.
+ flash_dev_query(data);
+ CYG_TEST_PASS_FAIL(!strncmp(data,"Linux Synthetic Flash",sizeof(data)),
+ "flash_query");
+#endif
+ ret = flash_get_limits(NULL,&flash_start,&flash_end);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_get_limits");
+
+ ret = flash_get_block_info(&block_size, &blocks);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_get_block_info");
+
+ /* Erase the whole flash. Not recommended on real hardware since this
+ will probably erase the bootloader etc!!! */
+ ret=flash_erase(flash_start,block_size * blocks,NULL);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_erase1");
+
+ /* check that its actually been erased, and test the mmap area */
+ for (ptr=flash_start,ret=0; ptr < (unsigned char *)flash_end; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0),"flash empty check");
+
+ ret = flash_program(flash_start,&copyright,sizeof(copyright),NULL);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_program1");
+
+ /* Check the contents made it into the flash */
+ CYG_TEST_PASS_FAIL(!strncmp(flash_start,copyright,sizeof(copyright)),
+ "flash program contents");
+
+ /* .. and check nothing else changed */
+ for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0;
+ ptr < (unsigned char *)flash_end; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0),"flash program overrun check");
+
+ /* Program over a block boundary */
+ prog_start = (char *)flash_start + block_size - sizeof(copyright)/2;
+ ret = flash_program(prog_start,&copyright,sizeof(copyright),NULL);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_program2");
+
+ /* Check the first version is still OK */
+ CYG_TEST_PASS_FAIL(!strncmp(flash_start,copyright,sizeof(copyright)),
+ "Original contents");
+
+ CYG_TEST_PASS_FAIL(!strncmp(prog_start,copyright,sizeof(copyright)),
+ "New program contents");
+
+ /* Check the bit in between is still erased */
+ for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0;
+ ptr < (unsigned char *)prog_start; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+ CYG_TEST_PASS_FAIL((ret == 0),"flash erase check1");
+
+ /* Erase the second block and make sure the first is not erased */
+ ret=flash_erase((void *)((unsigned)flash_start+block_size),
+ block_size,NULL);
+ CYG_TEST_PASS_FAIL((ret == FLASH_ERR_OK),"flash_erase2");
+
+ /* Check the erase worked */
+ for (ptr=(unsigned char *)flash_start+block_size,ret=0;
+ ptr < (unsigned char *)flash_start+block_size*2; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0), "flash erase check2");
+
+ /* Lastly check the first half of the copyright message is still there */
+ CYG_TEST_PASS_FAIL(!strncmp(prog_start,copyright,sizeof(copyright)/2),
+ "Block 1 OK");
+
+#if 0
+ /* This test it fatal! Its not run by default!
+ Check the flash is read only, by trying to write to it. We expect
+ to get an exception */
+
+ *(char *)flash_start = 'a';
+#endif
+
+ CYG_TEST_PASS_FINISH("flash1");
+}
+
+#endif /* ifndef NA_MSG */
+
+/* EOF flash1.c */
diff --git a/ecos/packages/devs/flash/synthv2/current/tests/flash2.c b/ecos/packages/devs/flash/synthv2/current/tests/flash2.c
new file mode 100644
index 0000000..3bdae4a
--- /dev/null
+++ b/ecos/packages/devs/flash/synthv2/current/tests/flash2.c
@@ -0,0 +1,215 @@
+/* Hay, the copyright is usefull for something! */
+
+static char copyright[] =
+"//=========================================================================="
+"//"
+"// flash2.c"
+"//"
+"// Test flash operations for the synth target synth flash driver"
+"//"
+"//=========================================================================="
+"// ####ECOSGPLCOPYRIGHTBEGIN#### "
+"// ------------------------------------------- "
+"// This file is part of eCos, the Embedded Configurable Operating System. "
+"// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc. "
+"// "
+"// eCos is free software; you can redistribute it and/or modify it under "
+"// the terms of the GNU General Public License as published by the Free "
+"// Software Foundation; either version 2 or (at your option) any later "
+"// version. "
+"// "
+"// eCos is distributed in the hope that it will be useful, but WITHOUT "
+"// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License "
+"// for more details. "
+"// "
+"// You should have received a copy of the GNU General Public License "
+"// along with eCos; if not, write to the Free Software Foundation, Inc., "
+"// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. "
+"// "
+"// As a special exception, if other files instantiate templates or use "
+"// macros or inline functions from this file, or you compile this file "
+"// and link it with other works to produce a work based on this file, "
+"// this file does not by itself cause the resulting work to be covered by "
+"// the GNU General Public License. However the source code for this file "
+"// must still be made available in accordance with section (3) of the GNU "
+"// General Public License v2. "
+"// "
+"// This exception does not invalidate any other reasons why a work based "
+"// on this file might be covered by the GNU General Public License. "
+"// ------------------------------------------- "
+"// ####ECOSGPLCOPYRIGHTEND#### "
+"//=========================================================================="
+"//#####DESCRIPTIONBEGIN####"
+"//"
+"// Author(s): andrew.lunn@ascom.ch"
+"// Contributors: andrew.lunn"
+"// Date: 2000-10-31"
+"// Purpose: Test a flash driver"
+"// Description: Try out a number of flash operations and make sure"
+"// what is in the flash is what we expeect."
+"// "
+"//####DESCRIPTIONEND####"
+"//"
+"//==========================================================================&"
+;
+
+#include <pkgconf/system.h>
+#ifdef CYGPKG_DEVS_FLASH_SYNTH_V2
+#include <pkgconf/devs_flash_synth_v2.h>
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SYNTH
+#include <pkgconf/devs_flash_synth.h>
+#endif
+#include <cyg/io/flash.h>
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+
+#include <string.h>
+
+#ifndef CYGINT_ISO_STRING_STRFUNCS
+# define NA_MSG "Need string functions for test"
+#endif
+
+#ifdef NA_MSG
+void cyg_user_start(void)
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( NA_MSG );
+}
+#else
+
+//==========================================================================
+// main
+
+void cyg_user_start(void)
+{
+ int ret;
+ cyg_flashaddr_t flash_start=0, flash_end=0;
+ cyg_flash_info_t info;
+ cyg_uint32 i=0;
+ cyg_uint32 j;
+ int block_size=0, blocks=0;
+ cyg_flashaddr_t prog_start;
+ unsigned char * ptr;
+
+ CYG_TEST_INIT();
+
+ cyg_flash_set_global_printf((cyg_flash_printf *)&diag_printf);
+ ret=cyg_flash_init(NULL);
+
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_init");
+
+ do {
+ ret = cyg_flash_get_info(i, &info);
+ if (ret == CYG_FLASH_ERR_OK) {
+ diag_printf("INFO: Nth=%d, start=%p, end=%p\n",
+ i, (void *) info.start, (void *) info.end);
+ if (i == 0) {
+ flash_start = info.start;
+ flash_end = info.end;
+ block_size = info.block_info[0].block_size;
+ blocks = info.block_info[0].blocks;
+ }
+ for (j=0;j < info.num_block_infos; j++) {
+ diag_printf("INFO:\t block_size %zd, blocks %u\n",
+ info.block_info[j].block_size,
+ info.block_info[j].blocks);
+ }
+ }
+ i++;
+ } while (ret != CYG_FLASH_ERR_INVALID);
+
+ /* Erase the whole flash. Not recommended on real hardware since this
+ will probably erase the bootloader etc!!! */
+ ret=cyg_flash_erase(flash_start,block_size * blocks,NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_erase1");
+
+ /* check that its actually been erased, and test the mmap area */
+ for (ptr=(unsigned char *)flash_start,ret=0;
+ ptr <= (unsigned char *)flash_end; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0),"flash empty check");
+
+ ret = cyg_flash_program(flash_start,&copyright,sizeof(copyright),NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program1");
+
+ /* Check the contents made it into the flash */
+ CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
+ copyright,sizeof(copyright)),
+ "flash program contents");
+
+ /* .. and check nothing else changed */
+ for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0;
+ ptr < (unsigned char *)flash_end; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0),"flash program overrun check");
+
+ /* Program over a block boundary */
+ prog_start = flash_start + block_size - sizeof(copyright)/2;
+ ret = cyg_flash_program(prog_start,&copyright,sizeof(copyright),NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program2");
+
+ /* Check the first version is still OK */
+ CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
+ copyright,
+ sizeof(copyright)),
+ "Original contents");
+
+ CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
+ copyright,
+ sizeof(copyright)),
+ "New program contents");
+
+ /* Check the bit in between is still erased */
+ for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0;
+ ptr < (unsigned char *)prog_start; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+ CYG_TEST_PASS_FAIL((ret == 0),"flash erase check1");
+
+ /* Erase the second block and make sure the first is not erased */
+ ret=cyg_flash_erase(flash_start+block_size,block_size,NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_erase2");
+
+ /* Check the erase worked */
+ for (ptr=(unsigned char *)flash_start+block_size,ret=0;
+ ptr < (unsigned char *)flash_start+block_size*2;
+ ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0), "flash erase check2");
+
+ /* Lastly check the first half of the copyright message is still there */
+ CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
+ copyright,
+ sizeof(copyright)/2),
+ "Block 1 OK");
+
+#if 0
+ /* This test is be fatal! Its not run by default!
+ Check the flash is read only, by trying to write to it. We expect
+ to get an exception */
+
+ *(char *)flash_start = 'a';
+#endif
+
+ CYG_TEST_PASS_FINISH("flash2");
+}
+
+#endif /* ifndef NA_MSG */
+
+/* EOF flash2.c */
diff --git a/ecos/packages/devs/flash/synthv2/current/tests/flash3.c b/ecos/packages/devs/flash/synthv2/current/tests/flash3.c
new file mode 100644
index 0000000..d44d44a
--- /dev/null
+++ b/ecos/packages/devs/flash/synthv2/current/tests/flash3.c
@@ -0,0 +1,248 @@
+/* Hay, the copyright is usefull for something! */
+
+static char copyright[] =
+"//=========================================================================="
+"//"
+"// flash3.c"
+"//"
+"// Test flash operations for the synth target synth flash driver"
+"//"
+"//=========================================================================="
+"// ####ECOSGPLCOPYRIGHTBEGIN#### "
+"// ------------------------------------------- "
+"// This file is part of eCos, the Embedded Configurable Operating System. "
+"// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc. "
+"// "
+"// eCos is free software; you can redistribute it and/or modify it under "
+"// the terms of the GNU General Public License as published by the Free "
+"// Software Foundation; either version 2 or (at your option) any later "
+"// version. "
+"// "
+"// eCos is distributed in the hope that it will be useful, but WITHOUT "
+"// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License "
+"// for more details. "
+"// "
+"// You should have received a copy of the GNU General Public License "
+"// along with eCos; if not, write to the Free Software Foundation, Inc., "
+"// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. "
+"// "
+"// As a special exception, if other files instantiate templates or use "
+"// macros or inline functions from this file, or you compile this file "
+"// and link it with other works to produce a work based on this file, "
+"// this file does not by itself cause the resulting work to be covered by "
+"// the GNU General Public License. However the source code for this file "
+"// must still be made available in accordance with section (3) of the GNU "
+"// General Public License v2. "
+"// "
+"// This exception does not invalidate any other reasons why a work based "
+"// on this file might be covered by the GNU General Public License. "
+"// ------------------------------------------- "
+"// ####ECOSGPLCOPYRIGHTEND#### "
+"//=========================================================================="
+"//#####DESCRIPTIONBEGIN####"
+"//"
+"// Author(s): andrew.lunn@ascom.ch"
+"// Contributors: andrew.lunn"
+"// Date: 2000-10-31"
+"// Purpose: Test a flash driver"
+"// Description: Try out a number of flash operations and make sure"
+"// what is in the flash is what we expeect."
+"// "
+"//####DESCRIPTIONEND####"
+"//"
+"//==========================================================================&"
+;
+
+#include <pkgconf/system.h>
+#ifdef CYGPKG_DEVS_FLASH_SYNTH_V2
+#include <pkgconf/devs_flash_synth_v2.h>
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SYNTH
+#include <pkgconf/devs_flash_synth.h>
+#endif
+#include <cyg/io/flash.h>
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+#include <cyg/flash/synth.h>
+
+#include <string.h>
+
+#ifndef CYGINT_ISO_STRING_STRFUNCS
+# define NA_MSG "Need string functions for test"
+#endif
+
+#ifdef NA_MSG
+void cyg_user_start(void)
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( NA_MSG );
+}
+#else
+
+static struct cyg_flash_synth_priv synth_flash_priv3 = {
+ .block_size = CYGNUM_FLASH_SYNTH_V2_BLOCKSIZE,
+ .blocks = CYGNUM_FLASH_SYNTH_V2_NUMBLOCKS,
+ .boot_block_size = CYGNUM_FLASH_SYNTH_V2_BOOT_BLOCKSIZE,
+ .boot_blocks = CYGNUM_FLASH_SYNTH_V2_NUMBOOT_BLOCKS,
+ .boot_block_bottom = CYGNUM_FLASH_SYNTH_V2_BOOT_BLOCK_BOTTOM,
+ .filename = "synth.flash3",
+ .flashfd = -1
+};
+
+CYG_FLASH_DRIVER(cyg_flash_synth_flashdev_flash3,
+ &cyg_flash_synth_funs,
+ 0, // flags
+ 0x40020000, // start
+ 0, // end, filled in by init
+ 0, // number of block_info's, filled in by init
+ synth_flash_priv3.block_info,
+ &synth_flash_priv3);
+
+//==========================================================================
+// main
+
+void cyg_user_start(void)
+{
+ int ret;
+ cyg_flashaddr_t flash_start=0, flash_end=0;
+ cyg_flash_info_t info;
+ cyg_uint32 i=0;
+ cyg_uint32 j;
+ int block_size=0, blocks=0;
+ cyg_flashaddr_t prog_start;
+ unsigned char * ptr;
+ size_t copyright_len;
+
+ CYG_TEST_INIT();
+
+ // Reference the flash dev so the linker does not throw it away
+ CYG_REFERENCE_OBJECT(cyg_flash_synth_flashdev_flash3);
+
+ cyg_flash_set_global_printf((cyg_flash_printf *)&diag_printf);
+ ret=cyg_flash_init(NULL);
+
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_init");
+
+ do {
+ ret = cyg_flash_get_info(i, &info);
+ if (ret == CYG_FLASH_ERR_OK) {
+ diag_printf("INFO: Nth=%d, start=%p, end=%p\n",
+ i, (void *) info.start, (void *) info.end);
+ if (i == 0) {
+ flash_start = info.start;
+ flash_end = info.end;
+ block_size = info.block_info[0].block_size;
+ blocks = info.block_info[0].blocks;
+ }
+
+ for (j=0;j < info.num_block_infos; j++) {
+ diag_printf("INFO:\t block_size %zd, blocks %u\n",
+ info.block_info[j].block_size,
+ info.block_info[j].blocks);
+ }
+ }
+ i++;
+ } while (ret != CYG_FLASH_ERR_INVALID);
+
+ /* Erase the whole flash. Not recommended on real hardware since this
+ will probably erase the bootloader etc!!! */
+ ret=cyg_flash_erase(flash_start,block_size * blocks,NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_erase1");
+
+ /* check that its actually been erased, and test the mmap area */
+ for (ptr=(unsigned char *)flash_start,ret=0;
+ ptr <= (unsigned char *)flash_end; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0),"flash empty check");
+
+ // With small blocks we have to use less of the copyright messages
+ // Since we make assumptions about fitting the message into a
+ // block.
+ if (block_size < sizeof(copyright)*2/3) {
+ copyright_len = block_size / 3;
+ } else {
+ copyright_len = sizeof(copyright);
+ }
+
+ ret = cyg_flash_program(flash_start,&copyright,copyright_len,NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program1");
+
+ /* Check the contents made it into the flash */
+ CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
+ copyright,copyright_len),
+ "flash program contents");
+
+ /* .. and check nothing else changed */
+ for (ptr=(unsigned char *)flash_start+copyright_len,ret=0;
+ ptr < (unsigned char *)flash_end; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0),"flash program overrun check");
+
+ prog_start = flash_start + block_size - copyright_len/2;
+ ret = cyg_flash_program(prog_start,&copyright,copyright_len,NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program2");
+
+ /* Check the first version is still OK */
+ CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
+ copyright,
+ copyright_len),
+ "Original contents");
+
+ CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
+ copyright,
+ copyright_len),
+ "New program contents");
+
+ /* Check the bit in between is still erased */
+ for (ptr=(unsigned char *)flash_start+copyright_len,ret=0;
+ ptr < (unsigned char *)prog_start; ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+ CYG_TEST_PASS_FAIL((ret == 0),"flash erase check1");
+
+ /* Erase the second block and make sure the first is not erased */
+ ret=cyg_flash_erase(flash_start+block_size,block_size,NULL);
+ CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_erase2");
+
+ /* Check the erase worked */
+ for (ptr=(unsigned char *)flash_start+block_size,ret=0;
+ ptr < (unsigned char *)flash_start+block_size*2;
+ ptr++) {
+ if (*ptr != 0xff) {
+ ret++;
+ }
+ }
+
+ CYG_TEST_PASS_FAIL((ret == 0), "flash erase check2");
+
+ /* Lastly check the first half of the copyright message is still there */
+ CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
+ copyright,
+ copyright_len/2),
+ "Block 1 OK");
+
+#if 0
+ /* This test is be fatal! Its not run by default!
+ Check the flash is read only, by trying to write to it. We expect
+ to get an exception */
+
+ *(char *)flash_start = 'a';
+#endif
+
+ CYG_TEST_PASS_FINISH("flash3");
+}
+
+#endif /* ifndef NA_MSG */
+
+/* EOF flash3.c */
diff --git a/ecos/packages/devs/flash/toshiba/tc58xxx/current/ChangeLog b/ecos/packages/devs/flash/toshiba/tc58xxx/current/ChangeLog
new file mode 100644
index 0000000..64a1ac9
--- /dev/null
+++ b/ecos/packages/devs/flash/toshiba/tc58xxx/current/ChangeLog
@@ -0,0 +1,53 @@
+2004-11-20 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_toshiba_tc58xxx.cdl: NAND flash requires indirect read
+ support in the main flash code
+
+2004-08-03 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/flash_toshiba_tc58xxx.cdl: Indicate we need the legacy device API
+
+2004-08-24 Gary Thomas <gary@mlbassoc.com>
+
+ * include/flash_tc58xxx.inl: Initial implementation of NAND ECC
+ support (used by JFFS2).
+
+2004-03-07 Gary Thomas <gary@mlbassoc.com>
+
+ * include/flash_tc58xxx.inl: Page addressing was wrong for large (> 32MB) devices.
+
+2004-02-25 Gary Thomas <gary@mlbassoc.com>
+
+ * include/flash_tc58xxx_parts.inl:
+ * include/flash_tc58xxx.inl: Add support for TC58DVG02 (128MB) part.
+
+2003-09-19 Gary Thomas <gary@mlbassoc.com>
+
+ * include/flash_tc58xxx_parts.inl:
+ * include/flash_tc58xxx.inl:
+ * cdl/flash_toshiba_tc58xxx.cdl: New package - support for NAND FLASH
+ devices from Toshiba
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl b/ecos/packages/devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl
new file mode 100644
index 0000000..4911ae3
--- /dev/null
+++ b/ecos/packages/devs/flash/toshiba/tc58xxx/current/cdl/flash_toshiba_tc58xxx.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# flash_toshiba_tc58xxx.cdl
+#
+# FLASH memory - Hardware support for Toshiba TC58xxx parts
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Gary Thomas <gary@mlbassoc.com>
+# Contributors:
+# Date: 2003-09-02
+# Description: FLASH drivers for Toshiba TC58xxx NAND devices. Based on
+# Atmel AT49xxxx drivers by Jani Monoses <jani@iv.ro>
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_TOSHIBA_TC58XXX {
+ display "Toshiba TC58XXX FLASH memory support"
+ description "FLASH memory device support for Toshiba TC58XXX"
+ parent CYGPKG_IO_FLASH
+ active_if CYGPKG_IO_FLASH
+ requires { CYGSEM_IO_FLASH_READ_INDIRECT == 1 }
+
+ active_if CYGINT_DEVS_FLASH_TOSHIBA_TC58XXX_REQUIRED
+
+ implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_LEGACY
+ implements CYGHWR_IO_FLASH_INDIRECT_READS
+
+ include_dir cyg/io
+}
+
+# EOF flash_toshiba_tc58xxx.cdl
diff --git a/ecos/packages/devs/flash/toshiba/tc58xxx/current/include/flash_tc58xxx.inl b/ecos/packages/devs/flash/toshiba/tc58xxx/current/include/flash_tc58xxx.inl
new file mode 100644
index 0000000..bddbe94
--- /dev/null
+++ b/ecos/packages/devs/flash/toshiba/tc58xxx/current/include/flash_tc58xxx.inl
@@ -0,0 +1,688 @@
+#ifndef CYGONCE_DEVS_FLASH_TOSHIBA_TC58XXX_INL
+#define CYGONCE_DEVS_FLASH_TOSHIBA_TC58XXX_INL
+//==========================================================================
+//
+// flash_tc58xxx.inl
+//
+// Toshiba Tc58xxx series flash driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Gary Thomas <gary@mlbassoc.com>
+// Contributors:
+// Date: 2003-09-02
+// Purpose:
+// Description: FLASH drivers for Toshiba NAND FLASH TC58xxx devices.
+// Based on Atmel AT49xxxx drivers by Jani Monoses <jani@iv.ro>
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// FIXME! Someday add support for ECC data & fixups of bad sectors
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/infra/diag.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+// Low level debugging
+// 1 - command level - prints messages about read/write/erase commands
+// 2 - hardware level - shows all NAND device I/O data
+#define FLASH_DEBUG 0
+
+//----------------------------------------------------------------------------
+// Common device details.
+#define FLASH_Read_ID FLASHWORD(0x90)
+#define FLASH_Reset FLASHWORD(0xFF)
+#define FLASH_Read_Mode1 FLASHWORD(0x00)
+#define FLASH_Read_Mode2 FLASHWORD(0x01)
+#define FLASH_Read_Mode3 FLASHWORD(0x50)
+#define FLASH_Program FLASHWORD(0x10)
+#define FLASH_Send_Data FLASHWORD(0x80)
+#define FLASH_Status FLASHWORD(0x70)
+#define FLASH_Block_Erase FLASHWORD(0x60)
+#define FLASH_Start_Erase FLASHWORD(0xD0)
+
+#define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x98)
+
+//----------------------------------------------------------------------------
+// Now that device properties are defined, include magic for defining
+// accessor type and constants.
+#include <cyg/io/flash_dev.h>
+
+//----------------------------------------------------------------------------
+// Information about supported devices
+typedef struct flash_dev_info {
+ flash_data_t device_id;
+ cyg_uint32 block_size;
+ cyg_uint32 page_size;
+ cyg_int32 block_count;
+ cyg_uint32 base_mask;
+ cyg_uint32 device_size;
+} flash_dev_info_t;
+
+static const flash_dev_info_t* flash_dev_info;
+static const flash_dev_info_t supported_devices[] = {
+#include <cyg/io/flash_tc58xxx_parts.inl>
+};
+#define NUM_DEVICES (sizeof(supported_devices)/sizeof(flash_dev_info_t))
+
+//----------------------------------------------------------------------------
+// Functions that put the flash device into non-read mode must reside
+// in RAM.
+void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
+int flash_erase_block(void* block, unsigned int size)
+ __attribute__ ((section (".2ram.flash_erase_block")));
+int flash_program_buf(void* addr, void* data, int len)
+ __attribute__ ((section (".2ram.flash_program_buf")));
+
+//----------------------------------------------------------------------------
+// Initialize driver details
+int
+flash_hwr_init(void)
+{
+ flash_data_t id[4];
+ int i;
+
+#ifdef CYGHWR_FLASH_TC58XXX_PLF_INIT
+ CYGHWR_FLASH_TC58XXX_PLF_INIT();
+#endif
+
+ flash_dev_query(id);
+
+ // Check that flash_id data is matching the one the driver was
+ // configured for.
+
+ // Check manufacturer
+ if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER) {
+ diag_printf("Can't identify FLASH - manufacturer is: %x, should be %x\n",
+ id[0], CYGNUM_FLASH_ID_MANUFACTURER);
+ return FLASH_ERR_DRV_WRONG_PART;
+ }
+
+ // Look through table for device data
+ flash_dev_info = supported_devices;
+ for (i = 0; i < NUM_DEVICES; i++) {
+ if (flash_dev_info->device_id == id[1])
+ break;
+ flash_dev_info++;
+ }
+
+ // Did we find the device? If not, return error.
+ if (NUM_DEVICES == i) {
+ diag_printf("Can't identify FLASH - device is: %x, supported: ", id[1]);
+ for (i = 0; i < NUM_DEVICES; i++) {
+ diag_printf("%x ", supported_devices[i].device_id);
+ }
+ diag_printf("\n");
+ return FLASH_ERR_DRV_WRONG_PART;
+ }
+
+ // Fill in device details
+ flash_info.block_size = flash_dev_info->block_size;
+ flash_info.blocks = flash_dev_info->block_count * CYGNUM_FLASH_SERIES;
+ flash_info.start = (void *)CYGNUM_FLASH_BASE;
+ flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (flash_dev_info->device_size * CYGNUM_FLASH_SERIES));
+ return FLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// Map a hardware status to a package error
+int
+flash_hwr_map_error(int e)
+{
+ return e;
+}
+
+
+//----------------------------------------------------------------------------
+// See if a range of FLASH addresses overlaps currently running code
+bool
+flash_code_overlaps(void *start, void *end)
+{
+ extern unsigned char _stext[], _etext[];
+
+ return ((((unsigned long)&_stext >= (unsigned long)start) &&
+ ((unsigned long)&_stext < (unsigned long)end)) ||
+ (((unsigned long)&_etext >= (unsigned long)start) &&
+ ((unsigned long)&_etext < (unsigned long)end)));
+}
+
+static void
+put_NAND(volatile flash_data_t *ROM, flash_data_t val)
+{
+ *ROM = val;
+#if FLASH_DEBUG > 1
+ diag_printf("%02x ", val);
+#endif
+}
+
+//----------------------------------------------------------------------------
+// Flash Query
+//
+// Only reads the manufacturer and part number codes for the first
+// device(s) in series. It is assumed that any devices in series
+// will be of the same type.
+
+void
+flash_query(void* data)
+{
+ flash_data_t* id = (flash_data_t*) data;
+ volatile flash_data_t *ROM;
+
+ ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
+ // Send initial RESET command
+ CYGHWR_FLASH_TC58XXX_CE(1);
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+ put_NAND(ROM, FLASH_Reset);
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+ CYGHWR_FLASH_TC58XXX_CE(0);
+ // Now, wait for a good while
+ CYGACC_CALL_IF_DELAY_US(10000); // Actually 10ms
+ // Issue device query
+ CYGHWR_FLASH_TC58XXX_CE(1);
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+ put_NAND(ROM, FLASH_Read_ID);
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+ CYGHWR_FLASH_TC58XXX_ALE(1);
+ put_NAND(ROM, 0x00); // Dummy address
+ CYGHWR_FLASH_TC58XXX_ALE(0);
+ // Minimum 100ns delay after deasserting ALE
+ CYGACC_CALL_IF_DELAY_US(10); // Actually 10us
+ id[0] = *ROM;
+ id[1] = *ROM;
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+ put_NAND(ROM, FLASH_Reset);
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+ CYGHWR_FLASH_TC58XXX_CE(0);
+}
+
+//----------------------------------------------------------------------------
+// Erase Block
+int
+flash_erase_block(void* block, unsigned int size)
+{
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* b_p = (volatile flash_data_t*) block;
+ int res = FLASH_ERR_OK;
+ int cnt = 0;
+ flash_data_t stat;
+
+#if FLASH_DEBUG > 0
+ diag_printf("%s - block: %x, size: %d\n", __FUNCTION__, block, size);
+#endif
+ ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
+ // Erase the next block
+#if FLASH_DEBUG > 1
+ diag_printf("<< ");
+#endif
+ CYGHWR_FLASH_TC58XXX_CE(1);
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+ put_NAND(ROM, FLASH_Block_Erase);
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+ CYGHWR_FLASH_TC58XXX_ALE(1);
+ put_NAND(ROM, ((unsigned long)b_p & 0x0001FE00) >> 9); // A9..A16
+ put_NAND(ROM, ((unsigned long)b_p & 0x01FE0000) >> 17); // A17..A24
+ if (flash_dev_info->device_size > 0x02000000) {
+ put_NAND(ROM, ((unsigned long)b_p & 0x06000000) >> 25); // A26..A27
+ }
+ CYGHWR_FLASH_TC58XXX_ALE(0);
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+ put_NAND(ROM, FLASH_Start_Erase);
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+ CYGACC_CALL_IF_DELAY_US(10);
+ while (!CYGHWR_FLASH_TC58XXX_RDY()) cnt++; // Wait for operation to complete
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+ put_NAND(ROM, FLASH_Status);
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+ stat = *ROM;
+ CYGHWR_FLASH_TC58XXX_CE(0);
+#if FLASH_DEBUG > 1
+ diag_printf(">>\n");
+#endif
+#if FLASH_DEBUG > 0
+ diag_printf("block: %x, stat: %x, count = %d\n", b_p, stat, cnt);
+#endif
+ if (stat != 0xC0) {
+ diag_printf("Status after erase: %x\n", stat);
+ if ((stat & 0x80) == 0x00) {
+ res = FLASH_ERR_PROTECT;
+ } else {
+ res = FLASH_ERR_ERASE;
+ }
+ }
+ return res;
+}
+
+//
+// ECC support - adapted from Linux:
+//
+// drivers/mtd/nand_ecc.c
+//
+// Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
+// Toshiba America Electronics Components, Inc.
+//
+
+static const unsigned char _nand_ecc_precalc_table[] = {
+ 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
+ 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
+ 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
+ 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
+ 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
+ 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
+ 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
+ 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
+ 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
+ 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
+ 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
+ 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
+ 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
+ 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
+ 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
+ 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
+};
+
+static void
+_nand_trans_result(unsigned char reg2, unsigned char reg3,
+ unsigned char *ecc0, unsigned char *ecc1)
+{
+ unsigned char a, b, i, tmp1, tmp2;
+
+ /* Initialize variables */
+ a = b = 0x80;
+ tmp1 = tmp2 = 0;
+
+ /* Calculate first ECC byte */
+ for (i = 0; i < 4; i++) {
+ if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
+ tmp1 |= b;
+ b >>= 1;
+ if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
+ tmp1 |= b;
+ b >>= 1;
+ a >>= 1;
+ }
+
+ /* Calculate second ECC byte */
+ b = 0x80;
+ for (i = 0; i < 4; i++) {
+ if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
+ tmp2 |= b;
+ b >>= 1;
+ if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
+ tmp2 |= b;
+ b >>= 1;
+ a >>= 1;
+ }
+
+ /* Store two of the ECC bytes */
+ *ecc0 = tmp1;
+ *ecc1 = tmp2;
+}
+
+//
+// Calculate 3 byte ECC on 256 bytes of data
+//
+static void
+_nand_page_ECC(unsigned char *data, unsigned char *ecc0,
+ unsigned char *ecc1, unsigned char *ecc2)
+{
+ unsigned char idx, reg1, reg2, reg3;
+ int j;
+
+ /* Initialize variables */
+ reg1 = reg2 = reg3 = 0;
+ *ecc0 = *ecc1 = *ecc2 = 0;
+
+ /* Build up column parity */
+ for(j = 0; j < 256; j++) {
+ /* Get CP0 - CP5 from table */
+ idx = _nand_ecc_precalc_table[*data++];
+ reg1 ^= (idx & 0x3f);
+ /* All bit XOR = 1 ? */
+ if (idx & 0x40) {
+ reg3 ^= (unsigned char) j;
+ reg2 ^= ~((unsigned char) j);
+ }
+ }
+
+ /* Create non-inverted ECC code from line parity */
+ _nand_trans_result(reg2, reg3, ecc0, ecc1);
+
+ /* Calculate final ECC code */
+ *ecc0 = ~*ecc0;
+ *ecc1 = ~*ecc1;
+ *ecc2 = ((~reg1) << 2) | 0x03;
+}
+
+//
+// Correct a buffer via ECC (1 bit, 256 byte block)
+// Return: 0 => No error
+// 1 => Corrected
+// 2 => Not corrected, ECC updated
+// -1 => Not correctable
+//
+int
+_nand_correct_data(unsigned char *dat, unsigned char *read_ecc, unsigned char *calc_ecc)
+{
+ unsigned char a, b, c, d1, d2, d3, add, bit, i;
+
+ /* Do error detection */
+ d1 = calc_ecc[0] ^ read_ecc[0];
+ d2 = calc_ecc[1] ^ read_ecc[1];
+ d3 = calc_ecc[2] ^ read_ecc[2];
+
+ if ((d1 | d2 | d3) == 0) {
+ /* No errors */
+ return 0;
+ } else {
+ a = (d1 ^ (d1 >> 1)) & 0x55;
+ b = (d2 ^ (d2 >> 1)) & 0x55;
+ c = (d3 ^ (d3 >> 1)) & 0x54;
+
+ /* Found and will correct single bit error in the data */
+ if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
+ c = 0x80;
+ add = 0;
+ a = 0x80;
+ for (i=0; i<4; i++) {
+ if (d1 & c)
+ add |= a;
+ c >>= 2;
+ a >>= 1;
+ }
+ c = 0x80;
+ for (i=0; i<4; i++) {
+ if (d2 & c)
+ add |= a;
+ c >>= 2;
+ a >>= 1;
+ }
+ bit = 0;
+ b = 0x04;
+ c = 0x80;
+ for (i=0; i<3; i++) {
+ if (d3 & c)
+ bit |= b;
+ c >>= 2;
+ b >>= 1;
+ }
+ b = 0x01;
+ a = dat[add];
+ a ^= (b << bit);
+ dat[add] = a;
+ return 1;
+ } else {
+ i = 0;
+ while (d1) {
+ if (d1 & 0x01)
+ ++i;
+ d1 >>= 1;
+ }
+ while (d2) {
+ if (d2 & 0x01)
+ ++i;
+ d2 >>= 1;
+ }
+ while (d3) {
+ if (d3 & 0x01)
+ ++i;
+ d3 >>= 1;
+ }
+ if (i == 1) {
+ /* ECC Code Error Correction */
+ read_ecc[0] = calc_ecc[0];
+ read_ecc[1] = calc_ecc[1];
+ read_ecc[2] = calc_ecc[2];
+ return 2;
+ } else {
+ /* Uncorrectable Error */
+ return -1;
+ }
+ }
+ }
+
+ /* Should never happen */
+ return -1;
+}
+
+
+//----------------------------------------------------------------------------
+// Program Buffer
+int
+flash_program_buf(void* addr, void* data, int len)
+{
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr;
+ volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
+ int res = FLASH_ERR_OK;
+ int i, cnt;
+ flash_data_t stat;
+ unsigned char oob[16];
+
+ ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
+#if FLASH_DEBUG > 0
+ diag_printf("%s - addr: %x, data: %x, len: %d, FLASH: %p/%d\n",
+ __FUNCTION__, addr, data, len, ROM, sizeof(flash_data_t));
+#endif
+ while (len > 0) {
+ CYGHWR_FLASH_TC58XXX_CE(1);
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+#if FLASH_DEBUG > 1
+ diag_printf("<< ");
+#endif
+ put_NAND(ROM, FLASH_Read_Mode1);
+ put_NAND(ROM, FLASH_Send_Data);
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+ CYGHWR_FLASH_TC58XXX_ALE(1);
+ put_NAND(ROM, ((unsigned long)addr_ptr & 0x000000FF) >> 0); // A0..A7
+ put_NAND(ROM, ((unsigned long)addr_ptr & 0x0001FE00) >> 9); // A9..A16
+ put_NAND(ROM, ((unsigned long)addr_ptr & 0x01FE0000) >> 17); // A17..A24
+ if (flash_dev_info->device_size > 0x02000000) {
+ put_NAND(ROM, ((unsigned long)addr_ptr & 0x06000000) >> 25); // A26..A27
+ }
+ CYGHWR_FLASH_TC58XXX_ALE(0);
+#if FLASH_DEBUG > 1
+ diag_printf(">>\n");
+#endif
+ // Caculate OOB data for page (ECC)
+ for (i = 0; i < 16; i++) {
+ oob[i] = 0xFF;
+ }
+ // Calculate ECC for page
+ _nand_page_ECC((unsigned char *)&data_ptr[0], &oob[0], &oob[1], &oob[2]);
+ _nand_page_ECC((unsigned char *)&data_ptr[256], &oob[3], &oob[6], &oob[7]);
+ // Move one page of data to buffer
+ for (i = 0; i < 512; i++) {
+ put_NAND(ROM, *data_ptr++);
+#if FLASH_DEBUG > 1
+ if ((i % 16) == 15) diag_printf("\n");
+#endif
+ }
+ // OOB data
+ for (i = 0; i < 16; i++) {
+ put_NAND(ROM, oob[i]);
+#if FLASH_DEBUG > 1
+ if ((i % 16) == 15) diag_printf("\n");
+#endif
+ }
+#if FLASH_DEBUG > 1
+ diag_printf("<< ");
+#endif
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+ put_NAND(ROM, FLASH_Program);
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+ CYGACC_CALL_IF_DELAY_US(1); // Actually 200ns
+ cnt = 0;
+ CYGACC_CALL_IF_DELAY_US(10);
+ while (!CYGHWR_FLASH_TC58XXX_RDY()) cnt++; // Wait for page data to be ready
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+ put_NAND(ROM, FLASH_Status);
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+#if FLASH_DEBUG > 1
+ diag_printf(">>\n");
+#endif
+ stat = *ROM;
+ CYGHWR_FLASH_TC58XXX_CE(0);
+#if FLASH_DEBUG > 0
+ diag_printf("program at %x, stat: %x, count = %d\n", addr_ptr, stat, cnt);
+#endif
+ addr_ptr += 512; len -= 512;
+ if (stat != 0xC0) {
+ diag_printf("Status after write: %x\n", stat);
+ if ((stat & 0x80) == 0x00) {
+ res = FLASH_ERR_PROTECT;
+ } else {
+ res = FLASH_ERR_PROGRAM;
+ }
+ }
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------------
+// Read data into buffer
+int
+flash_read_buf(void* addr, void* data, int len)
+{
+ volatile flash_data_t* ROM;
+ volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr;
+ volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
+ flash_data_t *page;
+ int res = FLASH_ERR_OK;
+ int i, cnt, offset;
+ flash_data_t stat;
+ unsigned char oob[16], dev_oob[16];
+
+ ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
+#if FLASH_DEBUG > 1
+ diag_printf("<< ");
+#endif
+ CYGHWR_FLASH_TC58XXX_CE(1);
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+ if (((unsigned long)addr & 0x100) == 0) {
+ // Mode 1 - reads from start of line
+ put_NAND(ROM, FLASH_Read_Mode1);
+ } else {
+ // Mode 2 - reads from second half of line
+ put_NAND(ROM, FLASH_Read_Mode2);
+ }
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+ CYGHWR_FLASH_TC58XXX_ALE(1);
+ put_NAND(ROM, ((unsigned long)addr_ptr & 0x000000FF) >> 0); // A0..A7
+ put_NAND(ROM, ((unsigned long)addr_ptr & 0x0001FE00) >> 9); // A9..A16
+ put_NAND(ROM, ((unsigned long)addr_ptr & 0x01FE0000) >> 17); // A17..A24
+ if (flash_dev_info->device_size > 0x02000000) {
+ put_NAND(ROM, ((unsigned long)addr_ptr & 0x06000000) >> 25); // A26..A27
+ }
+ CYGHWR_FLASH_TC58XXX_ALE(0);
+#if FLASH_DEBUG > 1
+ diag_printf(">>\n");
+#endif
+ cnt = 0;
+ CYGACC_CALL_IF_DELAY_US(10);
+ while (!CYGHWR_FLASH_TC58XXX_RDY()) cnt++; // Wait for page data to be ready
+#if FLASH_DEBUG > 0
+ diag_printf("Read data starting at %p, count = %d\n", data_ptr, cnt);
+#endif
+ offset = 0;
+ page = (unsigned char *)data_ptr;
+ while (len-- > 0) {
+ *data_ptr++ = *ROM;
+ if (++offset == 0x200) {
+ // Data page has been read, fetch ECC/OOB data
+ for (i = 0; i < 16; i++) {
+ dev_oob[i] = *ROM;
+ }
+ // Calculate actual ECC on page
+ _nand_page_ECC(&page[0], &oob[0], &oob[1], &oob[2]);
+ _nand_page_ECC(&page[256], &oob[3], &oob[6], &oob[7]);
+ // Check & repair if possible
+ if ((oob[0] != dev_oob[0]) || (oob[1] != dev_oob[1]) || (oob[2] != dev_oob[2]) ||
+ (oob[3] != dev_oob[3]) || (oob[6] != dev_oob[6]) || (oob[7] != dev_oob[7])) {
+ unsigned char read_ecc[3], calc_ecc[3];
+ int res;
+
+ read_ecc[0] = dev_oob[0]; calc_ecc[0] = oob[0];
+ read_ecc[1] = dev_oob[1]; calc_ecc[1] = oob[1];
+ read_ecc[2] = dev_oob[2]; calc_ecc[2] = oob[2];
+ res = _nand_correct_data(&page[0], read_ecc, calc_ecc);
+ if ((res != 0) && (res != 1)) {
+ diag_printf("ECC failed\n");
+ res = FLASH_ERR_HWR;
+ break;
+ }
+ read_ecc[0] = dev_oob[3]; calc_ecc[0] = oob[3];
+ read_ecc[1] = dev_oob[6]; calc_ecc[1] = oob[6];
+ read_ecc[2] = dev_oob[7]; calc_ecc[2] = oob[7];
+ res = _nand_correct_data(&page[256], read_ecc, calc_ecc);
+ if ((res != 0) && (res != 1)) {
+ diag_printf("ECC failed\n");
+ res = FLASH_ERR_HWR;
+ break;
+ }
+ }
+ cnt = 0;
+ CYGACC_CALL_IF_DELAY_US(10);
+ while (!CYGHWR_FLASH_TC58XXX_RDY()) cnt++; // Wait for page data to be ready
+#if FLASH_DEBUG > 0
+ diag_printf("Read data starting at %p, count = %d\n", data_ptr, cnt);
+#endif
+ offset = 0;
+ page = (unsigned char *)data_ptr;
+ }
+ }
+ CYGHWR_FLASH_TC58XXX_CLE(1);
+ put_NAND(ROM, FLASH_Status);
+ CYGHWR_FLASH_TC58XXX_CLE(0);
+ stat = *ROM;
+ CYGHWR_FLASH_TC58XXX_CE(0);
+ if (stat != 0xC0) {
+ diag_printf("Status after read: %x\n", stat);
+ res = FLASH_ERR_HWR;
+ }
+ return res;
+}
+
+#endif // CYGONCE_DEVS_FLASH_TOSHIBA_TC58XXX_INL
+
+// EOF flash_tc58xxx.inl
diff --git a/ecos/packages/devs/flash/toshiba/tc58xxx/current/include/flash_tc58xxx_parts.inl b/ecos/packages/devs/flash/toshiba/tc58xxx/current/include/flash_tc58xxx_parts.inl
new file mode 100644
index 0000000..8aa343d
--- /dev/null
+++ b/ecos/packages/devs/flash/toshiba/tc58xxx/current/include/flash_tc58xxx_parts.inl
@@ -0,0 +1,86 @@
+#ifndef CYGONCE_DEVS_FLASH_TOSHIBA_TC58XXX_PARTS_INL
+#define CYGONCE_DEVS_FLASH_TOSHIBA_TC58XXX_PARTS_INL
+//==========================================================================
+//
+// flash_tc58xxx_parts.inl
+//
+// Toshiba Tc58xxx series part descriptions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Gary Thomas <gary@mlbassoc.com>
+// Contributors:
+// Date: 2003-09-02
+// Purpose: Should be included from the flash_tc58xxx.inl file only.
+// Description: Toshiba Tc58xxx part descriptions
+// Roughly based on Atmel AT49xxxx work by Jani Monoses <jani@iv.ro>
+//
+// FIXME: Add configury for selecting bottom/top bootblocks
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// Platform code must define the below
+// #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel)
+// #define CYGNUM_FLASH_SERIES : Number of devices in series
+// #define CYGNUM_FLASH_WIDTH : Width of devices on platform
+// #define CYGNUM_FLASH_BASE : Address of first device
+// And select one of the below device variants
+
+#if defined(CYGHWR_DEVS_FLASH_TOSHIBA_TC58256)
+{ // 256Mb (32MB)
+ device_id : FLASHWORD(0x75),
+ block_size : 0x4000 * CYGNUM_FLASH_INTERLEAVE,
+ page_size : 0x200 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 2048,
+ device_size: 0x2000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x2000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+},
+#endif
+#if defined(CYGHWR_DEVS_FLASH_TOSHIBA_TC58DVG02)
+{ // 1024Mb (128MB)
+ device_id : FLASHWORD(0x79),
+ block_size : 0x4000 * CYGNUM_FLASH_INTERLEAVE,
+ page_size : 0x200 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 8192,
+ device_size: 0x8000000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x8000000 * CYGNUM_FLASH_INTERLEAVE - 1),
+},
+#endif
+#endif // ifndef CYGONCE_DEVS_FLASH_TOSHIBA_TC58XXX_PARTS_INL
+
+// EOF flash_tc58xxx_parts.inl
diff --git a/ecos/packages/devs/framebuf/synth/current/ChangeLog b/ecos/packages/devs/framebuf/synth/current/ChangeLog
new file mode 100644
index 0000000..32011e9
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/ChangeLog
@@ -0,0 +1,49 @@
+2009-07-14 Bart Veer <bartv@ecoscentric.com>
+
+ * host/configure.in: allow builds on x86_64 machines.
+
+ * host/configure, host/aclocal.m4, host/Makefile.in: regenerate.
+
+2009-02-09 Bart Veer <bartv@ecoscentric.com>
+
+ * src/synthfb_init.cxx: initialize at DEV_CHAR priority, not IO
+
+2009-02-07 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/framebuf_synth.tcl: Pass gen_synthfb.tcl to tclsh directly.
+
+2009-01-08 John Dallaway <john@dallaway.org.uk>
+
+ * src/gen_synthfb.tcl: Specify script interpreter via /usr/bin/env.
+
+2008-12-30 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/framebuf_synth.cdl: Reference per-package documentation.
+
+2008-10-06 Bart Veer <bartv@ecoscentric.com>
+
+ * synthetic target framebuffer driver imported into anoncvs
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/framebuf/synth/current/cdl/framebuf_synth.cdl b/ecos/packages/devs/framebuf/synth/current/cdl/framebuf_synth.cdl
new file mode 100644
index 0000000..23c12d4
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/cdl/framebuf_synth.cdl
@@ -0,0 +1,259 @@
+# ====================================================================
+#
+# framebuf_synth.cdl
+#
+# Framebuffer device driver for the synthetic target.
+#
+# ====================================================================
+# ####ECOSGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+#
+# eCos is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 or (at your option) any later
+# version.
+#
+# eCos is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with eCos; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered by
+# the GNU General Public License. However the source code for this file
+# must still be made available in accordance with section (3) of the GNU
+# General Public License v2.
+#
+# This exception does not invalidate any other reasons why a work based
+# on this file might be covered by the GNU General Public License.
+# -------------------------------------------
+# ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Date: 2005-10-24
+#
+#####DESCRIPTIONEND####
+#========================================================================
+
+cdl_package CYGPKG_DEVS_FRAMEBUF_SYNTH {
+ display "Synthetic Target Framebuffer device driver"
+ doc ref/devs-framebuf-synth-ref.html
+ parent CYGPKG_IO_FRAMEBUF
+ active_if CYGPKG_IO_FRAMEBUF
+ hardware
+ include_files
+
+ description "
+ This package provides a framebuffer device driver for the
+ synthetic target."
+
+ for { set _fb 0 } { $_fb < 4 } { incr _fb } {
+ cdl_component CYGPKG_DEVS_FRAMEBUF_SYNTH_FB$_fb {
+ display "Provide framebuffer device fb$_fb"
+ description "
+ The synthetic target framebuffer driver can provide up to
+ four framebuffer devices, named fb0 to fb3. Each device's
+ width, height, depth, and colour format can be controlled.
+ This option enables device fb$_fb"
+
+ flavor bool
+ default_value [expr $_fb ? 0 : 1]
+ implements CYGINT_IO_FRAMEBUF_DEVICES
+ implements CYGHWR_IO_FRAMEBUF_FUNCTIONALITY_DOUBLE_BUFFER
+ requires is_substr(CYGDAT_IO_FRAMEBUF_DEVICES, \" fb[set _fb] \")
+
+ cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_WIDTH {
+ display "fb$_fb width"
+ flavor data
+ default_value 320
+ legal_values 16 to 4096
+ }
+
+ cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_HEIGHT {
+ display "fb$_fb height"
+ flavor data
+ default_value 240
+ legal_values 16 to 4096
+ }
+
+ cdl_option CYGDAT_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_FORMAT {
+ display "fb$_fb format"
+ flavor data
+ if { 0 } {
+ legal_values { "1BPP_BE_PAL888" "1BPP_LE_PAL888"
+ "2BPP_BE_PAL888" "2BPP_LE_PAL888"
+ "4BPP_BE_PAL888" "4BPP_LE_PAL888"
+ "8BPP_PAL888" "8BPP_TRUE_332"
+ "16BPP_TRUE_565" "16BPP_TRUE_555"
+ "32BPP_TRUE_0888"
+ }
+ } else {
+ legal_values {
+ "8BPP_PAL888" "8BPP_TRUE_332"
+ "16BPP_TRUE_565" "16BPP_TRUE_555"
+ "32BPP_TRUE_0888"
+ }
+ }
+ default_value { "8BPP_PAL888" }
+ if { 0 } {
+ description "
+ Each synthetic target framebuffer device can be configured
+ to emulate a particular format. This consists of three fields:
+ depth, endianness, and colour. The depth is in bits per pixel
+ and can be 1bpp, 2bpp, 4bpp, 8bpp, 16bpp or 32bpp. The endianness
+ is only relevant for 1bpp, 2bpp and 4bpp devices and affects how
+ pixels are organized within each byte. Colour can be either
+ paletted or true colour. 1bpp, 2bpp and 4bpp implies paletted, and
+ 16bpp and 32bpp implies true colour. 8bpp can be either paletted
+ or true colour. For 1bpp the default palette is monochrome with
+ colour 0 == black. For 2bpp the default palette is greyscale with
+ colour 0 == black. For 4bpp the default palette is EGA. For 8bpp
+ the default palette is VGA. The application can change these
+ default palettes as required to match the hardware being emulated."
+ } else {
+ description "
+ Each synthetic target framebuffer device can be configured
+ to emulate a particular format. This consists of two fields:
+ depth and colour. The depth is in bits per pixel and can be
+ 8bpp, 16bpp or 32bpp. Colour can be either paletted or true colour.
+ 16bpp and 32bpp implies true colour. 8bpp can be either paletted
+ or true colour. For 8bpp the default palette is VGA. The application
+ can change these default palettes as required to match the hardware being emulated."
+ }
+ }
+
+ cdl_component CYGIMP_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_VIEWPORT {
+ display "fb$_fb provides viewport support"
+ default_value 0
+ implements CYGHWR_IO_FRAMEBUF_FUNCTIONALITY_VIEWPORT
+ description "
+ Optionally framebuffer device $_fb can support a viewport.
+ In other words only a subset of the framebuffer, the viewport,
+ is actually visible on the display and application code can
+ move this viewport."
+
+ cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_VIEWPORT_WIDTH {
+ display "fb$_fb viewport width"
+ flavor data
+ default_value CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_WIDTH
+ legal_values 16 to CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_WIDTH
+ }
+
+ cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_VIEWPORT_HEIGHT {
+ display "fb$_fb viewport height"
+ flavor data
+ default_value CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_HEIGHT
+ legal_values 16 to CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_HEIGHT
+ }
+ }
+
+ cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set _fb]_PAGE_FLIPPING {
+ display "fb$_fb supports page flipping"
+ flavor booldata
+ default_value 0
+ legal_values 2 3 4
+ description "
+ Optionally framebuffer device $_fb can support page flipping.
+ The device supports between two and four pages, only one
+ of which is visible on the display. This allows code to
+ update one page without disturbing what is currently visible."
+ }
+ }
+
+ # Eliminate any framebuffer devices that are no longer enabled.
+ requires (CYGPKG_DEVS_FRAMEBUF_SYNTH_FB$_fb || !is_substr(CYGDAT_IO_FRAMEBUF_DEVICES, \" fb[set _fb] \"))
+ }
+
+ cdl_component CYGPKG_DEVS_FRAMEBUF_SYNTH_FUNCTIONALITY {
+ display "Functionality supported by the enabled framebuffer(s)"
+ flavor none
+ description "
+ The generic framebuffer code needs configure-time information about
+ functionality of the enabled framebuffer or framebuffers. Usually
+ all this information is fixed by the hardware, but the synthetic
+ target framebuffer support is more flexible than real hardware. To
+ cope with this some dummy options are needed."
+
+ active_if { CYGPKG_DEVS_FRAMEBUF_SYNTH_FB0 ||
+ CYGPKG_DEVS_FRAMEBUF_SYNTH_FB1 ||
+ CYGPKG_DEVS_FRAMEBUF_SYNTH_FB2 ||
+ CYGPKG_DEVS_FRAMEBUF_SYNTH_FB3 }
+ make -priority=1 {
+ <PREFIX>/include/cyg/io/framebufs/synth_fb.h : \
+ <PACKAGE>/src/gen_synthfb.tcl \
+ <PREFIX>/include/pkgconf/devs_framebuf_synth.h
+ tclsh $< $(PREFIX)
+ }
+ compile synthfb.c
+ compile -library=libextras.a synthfb_init.cxx
+
+ cdl_option CYGHWR_DEVS_FRAMEBUF_SYNTH_FUNCTIONALITY_32BPP {
+ display "One or more of the enabled framebuffer devices has a depth of 32bpp"
+ calculated { is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB0_FORMAT, "32BPP") ||
+ is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB1_FORMAT, "32BPP") ||
+ is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB2_FORMAT, "32BPP") ||
+ is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB3_FORMAT, "32BPP") }
+ implements CYGHWR_IO_FRAMEBUF_FUNCTIONALITY_32BPP
+ }
+
+ cdl_option CYGHWR_DEVS_FRAMEBUF_SYNTH_FUNCTIONALITY_PALETTED {
+ display "One or more of the enabled framebuffer devices uses a paletted display"
+ calculated { is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB0_FORMAT, "PAL") ||
+ is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB1_FORMAT, "PAL") ||
+ is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB2_FORMAT, "PAL") ||
+ is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB3_FORMAT, "PAL") }
+ implements CYGHWR_IO_FRAMEBUF_FUNCTIONALITY_PALETTE
+ implements CYGHWR_IO_FRAMEBUF_FUNCTIONALITY_WRITEABLE_PALETTE
+ }
+
+ cdl_option CYGHWR_DEVS_FRAMEBUF_SYNTH_TRUE_COLOUR {
+ display "One or more of the enabled framebuffer devices uses a true colour display"
+ calculated { is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB0_FORMAT, "TRUE") ||
+ is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB1_FORMAT, "TRUE") ||
+ is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB2_FORMAT, "TRUE") ||
+ is_substr(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB3_FORMAT, "TRUE") }
+ implements CYGHWR_IO_FRAMEBUF_FUNCTIONALITY_TRUE_COLOUR
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_FRAMEBUF_SYNTH_OPTIONS {
+ display "Framebuffer build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building the synthetic
+ target framebuffer device driver."
+
+ cdl_option CYGPKG_DEVS_FRAMEBUF_SYNTH_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for building
+ the synthetic target framebuffer device driver. These flags
+ are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_FRAMEBUF_SYNTH_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for building
+ the synthetic target framebuffer device driver. These flags
+ are removed from the set of global flags if present."
+ }
+ }
+}
diff --git a/ecos/packages/devs/framebuf/synth/current/doc/synth_framebuf.sgml b/ecos/packages/devs/framebuf/synth/current/doc/synth_framebuf.sgml
new file mode 100644
index 0000000..7c0083e
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/doc/synth_framebuf.sgml
@@ -0,0 +1,237 @@
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- synth_framebuf.sgml -->
+<!-- -->
+<!-- Synthetic target frame buffer device -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2008 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2008/10/07 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<part id="devs-framebuf-synth-ref">
+ <title>Synthetic Target Framebuffer Device</title>
+
+<refentry id="devs-framebuf-synth">
+ <refmeta>
+ <refentrytitle>Synthetic Target Framebuffer Device</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Synthetic Target Framebuffer Device</refname>
+ <refpurpose>Emulate framebuffer hardware in the synthetic target</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="devs-framebuf-synth-overview"><title>Overview</title>
+ <para>
+This package <varname>CYGPKG_DEVS_FRAMEBUF_SYNTH</varname> provides a
+framebuffer device driver for the eCos synthetic target.
+ </para>
+ <informalfigure PgWide=1>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="synthfb.png" Scalefit=1 Align="Center">
+ </imageobject>
+ </mediaobject>
+ </informalfigure>
+ <para>
+The driver supports up to four framebuffer devices
+<varname>fb0</varname>, <varname>fb1</varname>, <varname>fb2</varname>
+and <varname>fb3</varname>. The width, height, depth, and display
+format of each framebuffer can be controlled via configuration
+options. It is also possible to set a viewport for each device and to
+enable page flipping.
+ </para>
+ <para>
+To use the framebuffer support the eCos application must run inside an
+X session, not from the console, and it must be started with
+<parameter>--io</parameter> to enable the I/O auxiliary. The I/O
+auxiliary will start a separate instance of a host-side utility
+<application>framebuf</application> for each target-side framebuffer
+device. The <application>framebuf</application> utility can access the
+eCos framebuffer data via a shared memory region and draw it to the
+screen using X library calls. It needs the X server to run with a
+TrueColor visual and a display of depth of 24 or 32 bits per pixel.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-framebuf-synth-install"><title>Installation</title>
+ <para>
+The synthetic target framebuffer driver depends on host-side support
+which must be built and installed. The relevant code resides in the
+<filename class="directory">host</filename> subdirectory of the
+synthetic target framebuffer package, and building it involves the
+standard <command>configure</command>, <command>make</command> and
+<command>make install</command> steps. This will build and install a
+utility program <application>framebuf</application> that does the
+actual drawing of the eCos framebuffer contents to the host-side X
+display. It will also install a Tcl script and some support files.
+<application>framebuf</application> is an X11 application so can only
+be built on Linux systems with the appropriate X11 development package
+or packages.
+ </para>
+ <para>
+There are two main ways of building the host-side software. It is
+possible to build both the generic host-side software and all
+package-specific host-side software, including the framebuffer
+support, in a single build tree. This involves using the
+<command>configure</command> script at the toplevel of the eCos
+repository. For more information on this, see the
+<filename>README.host</filename> file at the top of the repository.
+Note that if you have an existing build tree which does not include
+the synthetic target framebuffer support then it will be necessary to
+rerun the toplevel configure script: the search for appropriate
+packages happens at configure time.
+ </para>
+ <para>
+The alternative is to build just the host-side for this package.
+This requires a separate build directory, building directly in the
+source tree is disallowed. The <command>configure</command> options
+are much the same as for a build from the toplevel, and the
+<filename>README.host</filename> file can be consulted for more
+details. It is essential that the framebuffer support be configured with
+the same <option>--prefix</option> option as other eCos host-side
+software, especially the I/O auxiliary provided by the architectural
+synthetic target HAL package, otherwise the I/O auxiliary will be
+unable to locate the framebuffer support.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-framebuf-synth-config"><title>Configuration</title>
+ <para>
+The package is loaded automatically when creating a configuration for
+the synthetic target. However it is inactive unless the generic
+framebuffer support <varname>CYGPKG_IO_FRAMEBUF</varname> is also
+added to the configuration, for example by <computeroutput>ecosconfig
+add framebuf</computeroutput>.
+ </para>
+ <para>
+By default the package enables a single framebuffer device
+<varname>fb0</varname> with a corresponding
+<structname>cyg_fb</structname> data structure
+<varname>cyg_synth_fb0</varname>. The default settings for this device
+are 320 by 240 pixels, a depth of 8 bits per pixel, a paletted
+display, no viewport support, and no page flipping. All of these
+settings can be changed by configuration options inside the CDL
+component <varname>CYGPKG_DEVS_FRAMEBUF_SYNTH_FB0</varname>. The
+supported display formats are: 8 bpp paletted; 8bpp true colour 332;
+16bpp true 565; 16bpp true 555; and 32bpp 0888. This allows the
+synthetic target to match the actual display capabilities of the
+hardware that is being emulated. If the actual hardware has more than
+one framebuffer device then this can be emulated by enabling
+additional components
+<varname>CYGPKG_DEVS_FRAMEBUF_SYNTH_FB1</varname> &hellip;, and
+setting the appropriate options.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-framebuf-synth-customization"><title>Customization</title>
+ <para>
+In addition to the target-side configurability it is possible to
+customize the host-side behaviour. For example, the default behaviour
+is for <varname>fb0</varname> to be drawn inside the I/O auxiliary's
+main window, if it is not too large. <varname>fb1</varname>,
+<varname>fb2</varname> and <varname>fb3</varname> will be drawn inside
+separate toplevel windows, as will <varname>fb0</varname> if that has
+been configured too large for embedding in the main window. This
+behaviour can be changed by providing a custom Tcl/Tk procedure that
+creates the containing frame for the framebuffer device.
+ </para>
+ <para>
+Customization involves adding a <structname>synth_device</structname>
+<varname>framebuf</varname> section to the <filename>.tdf</filename>
+target definition file, usually <filename>default.tdf</filename> or
+<filename>~/.ecos/synth/default.tdf</filename>.
+ </para>
+ <programlisting width=72>
+proc my_framebuf_create_frame { &hellip } {
+ &hellip;
+}
+
+synth_device framebuf {
+ fb2_magnification 2
+ create_frame_proc my_framebuf_create_frame
+}
+ </programlisting>
+ <para>
+The pixel size on the host display may be rather smaller than on the
+final hardware, causing a serious mismatch between the application's
+appearance when using synthetic target emulation and when using real
+hardware. To reduce this problem the host-side can magnify the
+target-side framebuffer devices. In the example above each target-side
+pixel in device <varname>fb2</varname> will be drawn using 2*2 pixels
+on the host side. Valid magnifications are 1, 2, 3 and 4. With a
+magnification of 4 an eCos framebuffer device of 320*240 pixels will
+be drawn in an X window of 1280*960 pixels.
+ </para>
+ <para>
+The <parameter>create_frame_proc</parameter> entry can be used to
+specify a custom Tcl/Tk procedure that will create the containing Tk
+frames for the host-side displays. This procedure can be written for a
+specific configuration, but it is supplied with all the parameters
+associated with the framebuffer device so can be more generic. An
+example is supplied in the package's <filename
+class="directory">misc</filename> subdirectory:
+ </para>
+ <orderedlist>
+ <listitem><para>
+Create a configuration for the synthetic target with the default
+template.
+ </para></listitem>
+ <listitem><para>
+Import the <filename>example.ecm</filename> configuration fragment
+from the <filename class="directory">misc</filename> subdirectory.
+This will add the generic framebuffer support package, enable all four
+framebuffer devices, and configure each device. Build the resulting
+configuration.
+ </para></listitem>
+ <listitem><para>
+Compile the <filename>example.c</filename> program and link it against
+the eCos configuration.
+ </para></listitem>
+ <listitem><para>
+Incorporate the <filename>example.tdf</filename> fragment into the
+appropriate target definition file, typically
+<filename>default.tdf</filename> or
+<filename>~/.ecos/synth/default.tdf</filename>.
+ </para></listitem>
+ <listitem><para>
+Run the example executable. The four framebuffer devices should get
+instantiated in a separate window in a single column.
+<varname>FB0</varname> just contains a static display.
+<varname>FB1</varname> supports two pages, one with vertical stripes
+and one with horizontal stripes, and the two pages are flipped at
+regular intervals. <varname>FB2</varname> has a static display similar
+to <varname>FB0</varname>, but is drawn in a viewport of only 160x120
+pixels. However <filename>example.tdf</filename> magnifies this by 2
+so it appears the same size as the other devices. The application
+moves the viewport around the underlying framebuffer device.
+<varname>FB3</varname> is also a static display, a simple set of
+vertical stripes. However this framebuffer is paletted and the palette
+is changed at regular intervals, causing apparent movement.
+ </para></listitem>
+ </orderedlist>
+ </refsect1>
+
+</refentry>
+</part>
diff --git a/ecos/packages/devs/framebuf/synth/current/doc/synthfb.png b/ecos/packages/devs/framebuf/synth/current/doc/synthfb.png
new file mode 100644
index 0000000..bd5d479
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/doc/synthfb.png
Binary files differ
diff --git a/ecos/packages/devs/framebuf/synth/current/host/Makefile.am b/ecos/packages/devs/framebuf/synth/current/host/Makefile.am
new file mode 100644
index 0000000..0674f5c
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/Makefile.am
@@ -0,0 +1,86 @@
+## Process this file with automake to produce Makefile.in
+## =====================================================================
+##
+## Makefile.am
+##
+## Build support for the host-side synthetic target support,
+## the ethernetpackage.
+##
+## =====================================================================
+# ####ECOSGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2008 Free Software Foundation, Inc.
+#
+# eCos is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 or (at your option) any later
+# version.
+#
+# eCos is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with eCos; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered by
+# the GNU General Public License. However the source code for this file
+# must still be made available in accordance with section (3) of the GNU
+# General Public License v2.
+#
+# This exception does not invalidate any other reasons why a work based
+# on this file might be covered by the GNU General Public License.
+# -------------------------------------------
+# ####ECOSGPLCOPYRIGHTEND####
+## =====================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): bartv
+## Contact(s): bartv
+## Date: 2005/10/28
+## Version: 0.01
+##
+######DESCRIPTIONEND####
+## =====================================================================
+
+AUTOMAKE_OPTIONS = 1.10 foreign
+
+## The synthetic target support consists of a single program framebuf,
+## a Tcl script, and some additional data files. These are
+## all installed in a single directory $(libexec)/ecos/<package>_<version>/
+## Neither the framebuf executable nor any of the scripts are directly
+## executable, instead framebuf gets fork()'d/execve()'d by the Tcl
+## script so $(libexec) is appropriate. Strictly speaking the
+## Tcl scripts and data files are architecture-independent so should
+## probably be installed in an analogous directory below $(datadir),
+## but that would add more directories for little real gain. The scripts
+## are treated as data files since they should not be executed directly,
+## i.e. they should not be installed with the execute bit set.
+
+AM_CFLAGS = @ecos_CFLAGS@ -DECOSYNTH_VERSION=\"@VERSION@\" \
+ -DECOS_REPOSITORY=\"@ECOS_REPOSITORY@\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DPKG_DIR=\"@PACKAGE_DIR@\" \
+ -DPKG_VERSION=\"@PACKAGE_VERSION@\" \
+ -DPKG_INSTALL=\"@PACKAGE_INSTALL@\"
+AM_CXXFLAGS = @ecos_CXXFLAGS@
+INCLUDES = @ecos_INCLUDES@
+LIBS = @ecos_LIBS@ @ecos_LDADD@
+
+if SUPPORTED
+framebufdir = $(libexecdir)/ecos/@PACKAGE_INSTALL@
+framebuf_PROGRAMS = framebuf
+framebuf_DATA = framebuf.tcl framebuf.tdf framebuf_icon.xbm framebuf_iconmask.xbm
+framebuf_SOURCES = framebuf.c
+framebuf_LDADD = -L/usr/X11R6/lib -lX11
+
+## Manual dependencies
+framebuf.$(OBJEXT) : Makefile ../src/protocol.h
+
+endif
diff --git a/ecos/packages/devs/framebuf/synth/current/host/Makefile.in b/ecos/packages/devs/framebuf/synth/current/host/Makefile.in
new file mode 100644
index 0000000..3d1401d
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/Makefile.in
@@ -0,0 +1,720 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# ####ECOSGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2008 Free Software Foundation, Inc.
+#
+# eCos is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 or (at your option) any later
+# version.
+#
+# eCos is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with eCos; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered by
+# the GNU General Public License. However the source code for this file
+# must still be made available in accordance with section (3) of the GNU
+# General Public License v2.
+#
+# This exception does not invalidate any other reasons why a work based
+# on this file might be covered by the GNU General Public License.
+# -------------------------------------------
+# ####ECOSGPLCOPYRIGHTEND####
+#######DESCRIPTIONBEGIN####
+######DESCRIPTIONEND####
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@SUPPORTED_TRUE@framebuf_PROGRAMS = framebuf$(EXEEXT)
+subdir = .
+DIST_COMMON = $(am__configure_deps) \
+ $(srcdir)/../../../../../../acsupport/config.guess \
+ $(srcdir)/../../../../../../acsupport/config.sub \
+ $(srcdir)/../../../../../../acsupport/depcomp \
+ $(srcdir)/../../../../../../acsupport/install-sh \
+ $(srcdir)/../../../../../../acsupport/missing \
+ $(srcdir)/../../../../../../acsupport/mkinstalldirs \
+ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/configure ../../../../../../acsupport/ChangeLog \
+ ../../../../../../acsupport/config.guess \
+ ../../../../../../acsupport/config.sub \
+ ../../../../../../acsupport/depcomp \
+ ../../../../../../acsupport/install-sh \
+ ../../../../../../acsupport/ltconfig \
+ ../../../../../../acsupport/ltmain.sh \
+ ../../../../../../acsupport/missing \
+ ../../../../../../acsupport/mkinstalldirs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/../../../../../../acsupport/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(SHELL) \
+ $(top_srcdir)/../../../../../../acsupport/mkinstalldirs
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(framebufdir)" \
+ "$(DESTDIR)$(framebufdir)"
+PROGRAMS = $(framebuf_PROGRAMS)
+am__framebuf_SOURCES_DIST = framebuf.c
+@SUPPORTED_TRUE@am_framebuf_OBJECTS = framebuf.$(OBJEXT)
+framebuf_OBJECTS = $(am_framebuf_OBJECTS)
+framebuf_DEPENDENCIES =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/../../../../../../acsupport/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(framebuf_SOURCES)
+DIST_SOURCES = $(am__framebuf_SOURCES_DIST)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+DATA = $(framebuf_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d "$(distdir)" \
+ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr "$(distdir)"; }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECOS_REPOSITORY = @ECOS_REPOSITORY@
+EXEEXT = @EXEEXT@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @ecos_LIBS@ @ecos_LDADD@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSVC_SRCDIR = @MSVC_SRCDIR@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_DIR = @PACKAGE_DIR@
+PACKAGE_INSTALL = @PACKAGE_INSTALL@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+ecos_CFLAGS = @ecos_CFLAGS@
+ecos_CXXFLAGS = @ecos_CXXFLAGS@
+ecos_INCLUDES = @ecos_INCLUDES@
+ecos_LDADD = @ecos_LDADD@
+ecos_LIBS = @ecos_LIBS@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = 1.10 foreign
+AM_CFLAGS = @ecos_CFLAGS@ -DECOSYNTH_VERSION=\"@VERSION@\" \
+ -DECOS_REPOSITORY=\"@ECOS_REPOSITORY@\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DPKG_DIR=\"@PACKAGE_DIR@\" \
+ -DPKG_VERSION=\"@PACKAGE_VERSION@\" \
+ -DPKG_INSTALL=\"@PACKAGE_INSTALL@\"
+
+AM_CXXFLAGS = @ecos_CXXFLAGS@
+INCLUDES = @ecos_INCLUDES@
+@SUPPORTED_TRUE@framebufdir = $(libexecdir)/ecos/@PACKAGE_INSTALL@
+@SUPPORTED_TRUE@framebuf_DATA = framebuf.tcl framebuf.tdf framebuf_icon.xbm framebuf_iconmask.xbm
+@SUPPORTED_TRUE@framebuf_SOURCES = framebuf.c
+@SUPPORTED_TRUE@framebuf_LDADD = -L/usr/X11R6/lib -lX11
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+install-framebufPROGRAMS: $(framebuf_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(framebufdir)" || $(MKDIR_P) "$(DESTDIR)$(framebufdir)"
+ @list='$(framebuf_PROGRAMS)'; test -n "$(framebufdir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(framebufdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(framebufdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-framebufPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(framebuf_PROGRAMS)'; test -n "$(framebufdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(framebufdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(framebufdir)" && rm -f $$files
+
+clean-framebufPROGRAMS:
+ -test -z "$(framebuf_PROGRAMS)" || rm -f $(framebuf_PROGRAMS)
+framebuf$(EXEEXT): $(framebuf_OBJECTS) $(framebuf_DEPENDENCIES)
+ @rm -f framebuf$(EXEEXT)
+ $(LINK) $(framebuf_OBJECTS) $(framebuf_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/framebuf.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+install-framebufDATA: $(framebuf_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(framebufdir)" || $(MKDIR_P) "$(DESTDIR)$(framebufdir)"
+ @list='$(framebuf_DATA)'; test -n "$(framebufdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(framebufdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(framebufdir)" || exit $$?; \
+ done
+
+uninstall-framebufDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(framebuf_DATA)'; test -n "$(framebufdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(framebufdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(framebufdir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @$(am__cd) '$(distuninstallcheck_dir)' \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(framebufdir)" "$(DESTDIR)$(framebufdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-framebufPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-framebufDATA install-framebufPROGRAMS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-framebufDATA uninstall-framebufPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
+ clean-framebufPROGRAMS clean-generic ctags dist dist-all \
+ dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ dist-xz \
+ dist-zip distcheck distclean distclean-compile \
+ distclean-generic distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am \
+ install-framebufDATA install-framebufPROGRAMS install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-framebufDATA \
+ uninstall-framebufPROGRAMS
+
+
+@SUPPORTED_TRUE@framebuf.$(OBJEXT) : Makefile ../src/protocol.h
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ecos/packages/devs/framebuf/synth/current/host/acinclude.m4 b/ecos/packages/devs/framebuf/synth/current/host/acinclude.m4
new file mode 100644
index 0000000..9357e7d
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/acinclude.m4
@@ -0,0 +1,43 @@
+dnl Process this file with aclocal to get an aclocal.m4 file. Then
+dnl process that with autoconf.
+dnl ====================================================================
+dnl
+dnl acinclude.m4
+dnl
+dnl ====================================================================
+dnl ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+dnl -------------------------------------------
+dnl This file is part of the eCos host tools.
+dnl Copyright (C) 2005 Free Software Foundation, Inc.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 or (at your option) any
+dnl later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the
+dnl Free Software Foundation, Inc., 51 Franklin Street,
+dnl Fifth Floor, Boston, MA 02110-1301, USA.
+dnl -------------------------------------------
+dnl ####ECOSHOSTGPLCOPYRIGHTEND####
+dnl ====================================================================
+dnl#####DESCRIPTIONBEGIN####
+dnl
+dnl Author(s): bartv
+dnl Contact(s): bartv
+dnl Date: 2005/10/28
+dnl Version: 0.01
+dnl
+dnl####DESCRIPTIONEND####
+dnl ====================================================================
+
+dnl Access shared macros.
+dnl AM_CONDITIONAL needs to be mentioned here or else aclocal does not
+dnl incorporate the macro into aclocal.m4
+sinclude(../../../../../../acsupport/acinclude.m4)
diff --git a/ecos/packages/devs/framebuf/synth/current/host/aclocal.m4 b/ecos/packages/devs/framebuf/synth/current/host/aclocal.m4
new file mode 100644
index 0000000..4cbba05
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/aclocal.m4
@@ -0,0 +1,992 @@
+# generated automatically by aclocal 1.11 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.63],,
+[m4_warning([this file was generated for autoconf 2.63.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/ecos/packages/devs/framebuf/synth/current/host/configure b/ecos/packages/devs/framebuf/synth/current/host/configure
new file mode 100755
index 0000000..692bcb2
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/configure
@@ -0,0 +1,5580 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.63.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+ if (eval ":") 2>/dev/null; then
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+
+ if test $as_have_required = yes && (eval ":
+(as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=\$LINENO
+ as_lineno_2=\$LINENO
+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+ :
+else
+ as_candidate_shells=
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ case $as_dir in
+ /*)
+ for as_base in sh bash ksh sh5; do
+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+ done;;
+ esac
+done
+IFS=$as_save_IFS
+
+
+ for as_shell in $as_candidate_shells $SHELL; do
+ # Try only shells that exist, to save several forks.
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+ CONFIG_SHELL=$as_shell
+ as_have_required=yes
+ if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+ (exit $1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+ break
+fi
+
+fi
+
+ done
+
+ if test "x$CONFIG_SHELL" != x; then
+ for as_var in BASH_ENV ENV
+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ done
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+ if test $as_have_required = no; then
+ echo This script requires a shell more modern than all the
+ echo shells that I found on your system. Please install a
+ echo modern shell, or manually run the script under such a
+ echo shell if you do have one.
+ { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+ echo No shell found that supports shell functions.
+ echo Please tell bug-autoconf@gnu.org about your system,
+ echo including any error possibly output before this message.
+ echo This can help us improve future autoconf versions.
+ echo Configuration will now proceed without shell functions.
+}
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="framebuf.c"
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+SUPPORTED_FALSE
+SUPPORTED_TRUE
+PACKAGE_INSTALL
+PACKAGE_DIR
+ECOS_REPOSITORY
+MSVC_FALSE
+MSVC_TRUE
+MSVC_SRCDIR
+ecos_LIBS
+ecos_INCLUDES
+ecos_LDADD
+ecos_CXXFLAGS
+ecos_CFLAGS
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+enable_dependency_tracking
+enable_debug
+enable_ansi
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { $as_echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { $as_echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2
+ { (exit 1); exit 1; }; } ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ { $as_echo "$as_me: error: working directory cannot be determined" >&2
+ { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ { $as_echo "$as_me: error: pwd does not report name of working directory" >&2
+ { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2
+ { (exit 1); exit 1; }; }
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-debug do a debug rather than a release build
+ --enable-ansi do an ANSI rather than a unicode build
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.63
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.63. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args '$ac_arg'"
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_aux_dir=
+for ac_dir in ../../../../../../acsupport "$srcdir"/../../../../../../acsupport; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in ../../../../../../acsupport \"$srcdir\"/../../../../../../acsupport" >&5
+$as_echo "$as_me: error: cannot find install-sh or install.sh in ../../../../../../acsupport \"$srcdir\"/../../../../../../acsupport" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking that a separate build tree is being used" >&5
+$as_echo_n "checking that a separate build tree is being used... " >&6; }
+ ecos_cwd=`/bin/pwd`
+ if test "${srcdir}" = "." ; then
+ srcdir=${ecos_cwd}
+ fi
+ if test "${ecos_cwd}" = "${srcdir}" ; then
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:$LINENO: error: This configure script should not be run inside the source tree. Instead please use a separate build tree" >&5
+$as_echo "$as_me: error: This configure script should not be run inside the source tree. Instead please use a separate build tree" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ { { $as_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
+$as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
+ { (exit 1); exit 1; }; }
+
+{ $as_echo "$as_me:$LINENO: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ { { $as_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+$as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+ { (exit 1); exit 1; }; }
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
+$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
+$as_echo "$as_me: error: invalid value of canonical build" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:$LINENO: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+$as_echo "$as_me: error: invalid value of canonical host" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+am__api_version='1.11'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ { { $as_echo "$as_me:$LINENO: error: unsafe absolute working directory name" >&5
+$as_echo "$as_me: error: unsafe absolute working directory name" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ { { $as_echo "$as_me:$LINENO: error: unsafe srcdir value: \`$srcdir'" >&5
+$as_echo "$as_me: error: unsafe srcdir value: \`$srcdir'" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&5
+$as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+$as_echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+{ $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:$LINENO: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+done
+IFS=$as_save_IFS
+
+fi
+
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ test -d ./--version && rmdir ./--version
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:$LINENO: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+$as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=eCos_synthetic_target_framebuf
+ VERSION=0.1
+
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+{ $as_echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+
+{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_c89=$ac_arg
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:$LINENO: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:$LINENO: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:$LINENO: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CXXFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CXX" am_compiler_list=
+
+{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CXX_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+ am__fastdepCXX_TRUE=
+ am__fastdepCXX_FALSE='#'
+else
+ am__fastdepCXX_TRUE='#'
+ am__fastdepCXX_FALSE=
+fi
+
+
+
+
+
+ ecos_CFLAGS=""
+ ecos_CXXFLAGS=""
+ ecos_LDADD=""
+ ecos_INCLUDES=""
+ ecos_LIBS=""
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking \"for Visual C++\"" >&5
+$as_echo_n "checking \"for Visual C++\"... " >&6; }
+ MSVC="no";
+ if test "${CC}" = "cl" ; then
+ MSVC="yes"
+ CXX="cl"
+ MSVC_SRCDIR=${srcdir}
+
+
+ if test "${MSVC}" = "yes" ; then
+ MSVC_SRCDIR=`cygpath -w ${MSVC_SRCDIR} | tr \\\\\\\\ /`
+ fi
+
+
+ ecos_INCLUDES="${ecos_INCLUDES} \"-I${MSVC_SRCDIR}\""
+ ecos_LDADD="-link"
+ ecos_LIBS="advapi32.lib"
+ fi
+ if test "${MSVC}" = "yes"; then
+ MSVC_TRUE=
+ MSVC_FALSE='#'
+else
+ MSVC_TRUE='#'
+ MSVC_FALSE=
+fi
+
+ if test "${MSVC}" = "yes" ; then
+ { $as_echo "$as_me:$LINENO: result: unfortunately yes" >&5
+$as_echo "unfortunately yes" >&6; }
+ else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking \"the default compiler flags\"" >&5
+$as_echo_n "checking \"the default compiler flags\"... " >&6; }
+
+ ecosflags_enable_debug="no"
+ # Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then
+ enableval=$enable_debug; case "${enableval}" in
+ yes) ecosflags_enable_debug="yes" ;;
+ *) ecosflags_enable_debug="no" ;;
+ esac
+fi
+
+
+ ecosflags_enable_ansi="no"
+ if test "${MSVC}" = "yes" ; then
+ # Check whether --enable-ansi was given.
+if test "${enable_ansi+set}" = set; then
+ enableval=$enable_ansi; case "${enableval}" in
+ yes) ecosflags_enable_ansi="yes" ;;
+ *) ecosflags_enable_ansi="no" ;;
+ esac
+fi
+
+ fi
+
+ if test "${GCC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -pipe -Wall -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -pipe -Wall -Wpointer-arith -Wcast-qual -Woverloaded-virtual"
+ elif test "${MSVC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -nologo -W3"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -nologo -W3 -GR -GX"
+ else
+ { { $as_echo "$as_me:$LINENO: error: \"default flags for ${CC} are not known\"" >&5
+$as_echo "$as_me: error: \"default flags for ${CC} are not known\"" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ if test "${ecosflags_enable_debug}" = "yes" ; then
+ if test "${GCC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -g -O0"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -g -O0"
+ elif test "${MSVC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -MDd -Zi"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -MDd -Zi"
+ fi
+ else
+ if test "${GCC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -O2"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -O2"
+ elif test "${MSVC}" = "yes" ; then
+ ecos_CFLAGS="${ecos_CFLAGS} -MD -O2"
+ ecos_CXXFLAGS="${ecos_CXXFLAGS} -MD -O2"
+ fi
+ fi
+
+ CFLAGS="${ac_save_CFLAGS}"
+ CXXFLAGS="${ac_save_CXXFLAGS}"
+
+ { $as_echo "$as_me:$LINENO: result: done" >&5
+$as_echo "done" >&6; }
+
+
+
+ package_dir=`cd ${srcdir} && /bin/pwd`
+ PACKAGE_VERSION=`dirname ${package_dir}`
+ PACKAGE_VERSION=`basename ${PACKAGE_VERSION}`
+
+ package_dir=`dirname ${package_dir}`
+ package_dir=`dirname ${package_dir}`
+
+ possibles="${package_dir}/.. ${package_dir}/../.. ${package_dir}/../../.. ${package_dir}/../../../.."
+ possibles="${possibles} ${package_dir}/../../../../.. ${package_dir}/../../../../../.."
+
+ repository_root=""
+ for i in ${possibles}; do
+ if test -d "$i/"acsupport""; then
+ repository_root=$i
+ break
+ fi
+ done
+
+ if test "${repository_root}" = "" ; then
+ { { $as_echo "$as_me:$LINENO: error: Failed to identify this package's position within the eCos repository" >&5
+$as_echo "$as_me: error: Failed to identify this package's position within the eCos repository" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ ECOS_REPOSITORY=`cd "${repository_root}/packages/pkgconf/.." && /bin/pwd`
+
+ PACKAGE_DIR=`echo ${package_dir} | sed -e "s:${ECOS_REPOSITORY}/::"`
+
+ PACKAGE_INSTALL="${PACKAGE_DIR}/${PACKAGE_VERSION}"
+
+
+
+
+
+
+
+case "${host}" in
+ i[34567]86-*-linux-gnu* ) SUPPORTED="yes";;
+ x86_64-*-linux-gnu* ) SUPPORTED="yes";;
+ * ) SUPPORTED="no"
+esac
+if test "${SUPPORTED}" = "no" ; then
+ { $as_echo "$as_me:$LINENO: WARNING: Synthetic target framebuffer support is only available on x86 Linux hosts" >&5
+$as_echo "$as_me: WARNING: Synthetic target framebuffer support is only available on x86 Linux hosts" >&2;}
+fi
+
+ if test "${SUPPORTED}" = "yes"; then
+ SUPPORTED_TRUE=
+ SUPPORTED_FALSE='#'
+else
+ SUPPORTED_TRUE='#'
+ SUPPORTED_FALSE=
+fi
+
+
+
+ac_config_files="$ac_config_files Makefile:Makefile.in"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${MSVC_TRUE}" && test -z "${MSVC_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"MSVC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"MSVC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${SUPPORTED_TRUE}" && test -z "${SUPPORTED_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"SUPPORTED\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"SUPPORTED\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.63. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTION]... [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.63,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_FILES="$CONFIG_FILES '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { $as_echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile:Makefile.in" ;;
+
+ *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ $as_echo "$as_me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=' '
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5
+$as_echo "$as_me: error: could not setup config files machinery" >&2;}
+ { (exit 1); exit 1; }; }
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5
+$as_echo "$as_me: error: invalid tag $ac_tag" >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ ac_file_inputs="$ac_file_inputs '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:$LINENO: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+
+
+ :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir=$dirpart/$fdir
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+
+ esac
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/ecos/packages/devs/framebuf/synth/current/host/configure.in b/ecos/packages/devs/framebuf/synth/current/host/configure.in
new file mode 100644
index 0000000..c91ebb4
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/configure.in
@@ -0,0 +1,94 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl ====================================================================
+dnl
+dnl configure.in
+dnl
+dnl configure script for eCos synthetic target framebuffer
+dnl host-side support
+dnl
+dnl ====================================================================
+dnl ####ECOSGPLCOPYRIGHTBEGIN####
+dnl -------------------------------------------
+dnl This file is part of eCos, the Embedded Configurable Operating System.
+dnl Copyright (C) 2008 Free Software Foundation, Inc.
+dnl
+dnl eCos is free software; you can redistribute it and/or modify it under
+dnl the terms of the GNU General Public License as published by the Free
+dnl Software Foundation; either version 2 or (at your option) any later
+dnl version.
+dnl
+dnl eCos is distributed in the hope that it will be useful, but WITHOUT
+dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+dnl for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with eCos; if not, write to the Free Software Foundation, Inc.,
+dnl 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+dnl
+dnl As a special exception, if other files instantiate templates or use
+dnl macros or inline functions from this file, or you compile this file
+dnl and link it with other works to produce a work based on this file,
+dnl this file does not by itself cause the resulting work to be covered by
+dnl the GNU General Public License. However the source code for this file
+dnl must still be made available in accordance with section (3) of the GNU
+dnl General Public License v2.
+dnl
+dnl This exception does not invalidate any other reasons why a work based
+dnl on this file might be covered by the GNU General Public License.
+dnl -------------------------------------------
+dnl ####ECOSGPLCOPYRIGHTEND####
+dnl ====================================================================
+dnl#####DESCRIPTIONBEGIN####
+dnl
+dnl Author(s): bartv
+dnl Contact(s): bartv
+dnl Date: 2005/10/28
+dnl Version: 0.01
+dnl
+dnl####DESCRIPTIONEND####
+dnl ====================================================================
+
+
+AC_INIT(framebuf.c)
+
+dnl Pick up the support files from the top-level acsupport directory.
+AC_CONFIG_AUX_DIR(../../../../../../acsupport)
+
+dnl The current version of the synthetic target is implemented only for
+dnl x86 Linux platforms, so a test is appropriate here. However
+dnl it is not a good idea for the configure script to report an error:
+dnl that would prevent any top-level configury working for other
+dnl platforms. Instead an automake conditional is used to suppress adding
+dnl targets to the build. Unfortunately it is still necessary to
+dnl perform most of the tests or you run into problems with e.g.
+dnl automake's dependency handling.
+
+ECOS_CHECK_BUILD_ne_SRC
+AC_CANONICAL_HOST
+AM_INIT_AUTOMAKE(eCos_synthetic_target_framebuf,0.1,0)
+AM_MAINTAINER_MODE
+AC_PROG_CC
+AC_PROG_CXX
+AC_OBJEXT
+AC_EXEEXT
+ECOS_PROG_MSVC
+ECOS_PROG_STANDARD_COMPILER_FLAGS
+ECOS_PACKAGE_DIRS
+
+case "${host}" in
+ i[[34567]]86-*-linux-gnu* ) SUPPORTED="yes";;
+ x86_64-*-linux-gnu* ) SUPPORTED="yes";;
+ * ) SUPPORTED="no"
+esac
+if test "${SUPPORTED}" = "no" ; then
+ AC_MSG_WARN([Synthetic target framebuffer support is only available on x86 Linux hosts])
+fi
+
+AM_CONDITIONAL(SUPPORTED, test "${SUPPORTED}" = "yes")
+
+dnl There is no real need for a config.h file at this time, since the code
+dnl is specific to x86 Linux. This may change in future.
+dnl AM_CONFIG_HEADER(config.h:config.h.in)
+
+AC_OUTPUT(Makefile:Makefile.in)
diff --git a/ecos/packages/devs/framebuf/synth/current/host/framebuf.c b/ecos/packages/devs/framebuf/synth/current/host/framebuf.c
new file mode 100644
index 0000000..bb2bf0a
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/framebuf.c
@@ -0,0 +1,1487 @@
+//============================================================================
+//
+// framebuf.c
+//
+// A utility program to perform low-level ethernet operations
+//
+//============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contact(s): bartv
+// Date: 2005/10/28
+// Version: 0.01
+// Description:
+// Implementation of a framebuffer device. This script should only ever
+// be run from inside the ecosynth auxiliary.
+//
+// This program is fork'ed by the framebuf.tcl script running inside
+// the synthetic target auxiliary. It is responsible for performing the
+// low-level framebuffer accesses.
+//
+//####DESCRIPTIONEND####
+//============================================================================
+
+// We want to instantiate multiple conversion routines for the different
+// graphics formats, with extensive use of macros for efficiences. Multiple
+// C #include's are used for this.
+#ifndef RENDERFN
+# include <stdio.h>
+# include <stdarg.h>
+# include <stdlib.h>
+# include <string.h>
+# include <time.h>
+# include <signal.h>
+# include <limits.h>
+# include <unistd.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <sys/param.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/socket.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <X11/Xlib.h>
+
+// The protocol between host and target is defined by a private
+// target-side header.
+# include "../src/protocol.h"
+
+// ----------------------------------------------------------------------------
+// Globals
+// First the variables needed for X operations. The window is created by
+// Tcl/Tk code and its id is supplied as an argument.
+static Display* host_display;
+static Window host_win = 0;
+static GC host_gc;
+static XImage* host_image;
+
+// R, G & B shifts for the host-side. Used for palette conversion.
+static int host_r_shift;
+static int host_g_shift;
+static int host_b_shift;
+
+// The image data. Only 32bpp is supported.
+// NOTE: this is not 64-bit clean.
+static unsigned int* img_fb;
+
+// This is used for display depths up to and including 16bpp -
+// 256K of static data is irrelevant for a Linux host-side app.
+// 32bpp will have to be handled differently.
+static unsigned int host_palette[65536];
+
+// The current function for rendering target-side data
+static void (*render_fn)(int, int, int, int);
+
+// And palette init and update functions.
+static void (*palette_init_fn)(void);
+static void (*palette_update_fn)(void);
+
+// Positions. With target-side viewports, magnification, and the
+// possibility of windows being resized, this can
+// get very messy.
+//
+// The target-side framebuffer consists of n pages, each of
+// width*height pixels, plus possibly padding at the end of each
+// scanline.
+//
+// img_fb consists of viewport_width*viewport_height pixels.
+// At magnification 1 each pixel is a 32-bit unsigned int, but
+// at higher magnification each pixel takes up mag^2 unsigned
+// ints.
+//
+// win_width and win_height determine the current window dimensions in
+// target pixel units, i.e. ignoring magnification. x_win_width
+// and x_win_height are the same dimensions in X pixels, so
+// mag*win_width. These dimensions are provided by X configure events.
+// They may be smaller, the same size, or larger than the viewport.
+//
+// A coordinate (target_x,target_y) within the current page
+// corresponds to (target_x - viewport_x, target_y - viewport_y).
+// within host_image and within the window.
+//
+// For an X expose event we get X windows coordinates.
+
+// The actually visible window dimensions. If the Tk window gets
+// resized then only part of the image data may be visible. These
+// variables change in response to X configure events.
+static int win_width;
+static int win_height;
+static int x_win_width;
+static int x_win_height;
+
+// Target-side framebuffer.
+//
+// The synth_fb_data structure at the start of the shared memory region.
+static synth_fb_data* shared_fb_data;
+
+// The target-side framebuffer starts at shared_fb_data->framebuf[0].
+// However that is not necessarily where the visible data starts
+// because of page flipping and viewport support. This always points
+// at the top-left corner of visible data.
+static void* target_fb;
+
+// Parameters supplied by the target.
+static int target_id;
+static int target_depth;
+static int target_le;
+static int target_width;
+static int target_height;
+static int target_viewport_width;
+static int target_viewport_height;
+static int target_stride;
+static int target_number_pages;
+static char* target_format;
+
+// Parameters supplied by a host-side configuration file
+static int config_magnification;
+
+// Communication between host and target happens partially through the
+// shared memory region and partially through a fifo, the latter
+// allowing for select(). shared_fb_data already points at the shared
+// memory region.
+static char shm_name[L_tmpnam];
+static int shm_created;
+static int shm_fd;
+static char fifo_t2h_name[L_tmpnam];
+static int fifo_t2h_created;
+static int fifo_t2h_fd;
+static char fifo_h2t_name[L_tmpnam];
+static int fifo_h2t_created;
+static int fifo_h2t_fd;
+
+// An atexit() handler for cleaning up the fifos and shared memory.
+static void
+atexit_handler(void)
+{
+ if (shm_created) {
+ unlink(shm_name);
+ }
+ if (fifo_t2h_created) {
+ unlink(fifo_t2h_name);
+ }
+ if (fifo_h2t_created) {
+ unlink(fifo_h2t_name);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Diagnostics. Warnings and errors are sent up to the I/O auxiliary for
+// display there. Debug output goes straight to stderr
+
+// Set the DEBUG_LEVEL to 0 for no debugging, 3 for maximum debugging.
+#define DEBUG_LEVEL 0
+#define DEBUG(_level_, _str_, ...) \
+ if (_level_ <= DEBUG_LEVEL) { \
+ fprintf(stderr, "%d: " _str_, target_id, ## __VA_ARGS__); \
+ }
+
+#if 0
+static void
+warn(char* fmt, ...)
+{
+ char buf[512];
+ va_list args;
+ va_start(args, fmt);
+
+ sprintf(buf, "Warning (fb%d) : ", target_id);
+ vsnprintf(buf + strlen(buf), 512 - strlen(buf), fmt, args);
+ buf[511] = '\0';
+
+ (void) write(1, buf, strlen(buf));
+}
+#endif
+
+static void
+error(char* fmt, ...)
+{
+ char buf[512];
+ va_list args;
+ va_start(args, fmt);
+
+ sprintf(buf, "Error (fb%d) : ", target_id);
+ vsnprintf(buf + strlen(buf), 512 - strlen(buf), fmt, args);
+ buf[511] = '\0';
+
+ (void) write(1, buf, strlen(buf));
+ exit(1);
+}
+
+// ----------------------------------------------------------------------------
+// Host-side.
+//
+// The main redraw routines. schedule_redraw() can get called as a result of:
+//
+// 1) an X expose event.
+// 2) a message from the Tk code affecting the on/off setting of
+// the framebuffer.
+// 3) a message from the target-side code indicating some of the
+// target-side data has changed, or some other event such as
+// viewport repositioning or page flipping.
+//
+// It just maintains a bounding box. do_redraw() does the real work and
+// is called from inside the main loop.
+
+static int redraw_pending = 0;
+static int x_redraw_x, x_redraw_y, x_redraw_width, x_redraw_height;
+
+static void
+do_redraw(void)
+{
+ while (redraw_pending) {
+ redraw_pending = 0;
+ DEBUG(3, "do_redraw: win_x %d, win_y %d, width %d, height %d\n", x_redraw_x, x_redraw_y, x_redraw_width, x_redraw_height);
+ XPutImage(host_display, host_win, host_gc, host_image, x_redraw_x, x_redraw_y, x_redraw_x, x_redraw_y, x_redraw_width, x_redraw_height);
+ XFlush(host_display);
+ }
+}
+
+static void
+schedule_redraw(int x_new_x, int x_new_y, int x_new_width, int x_new_height)
+{
+ if (! redraw_pending) {
+ redraw_pending = 1;
+ x_redraw_x = x_new_x;
+ x_redraw_y = x_new_y;
+ x_redraw_width = x_new_width;
+ x_redraw_height = x_new_height;
+ } else {
+ if (x_redraw_x > x_new_x) {
+ x_redraw_x = x_new_x;
+ } else {
+ x_new_width += (x_new_x - x_redraw_x);
+ }
+ if (x_redraw_y > x_new_y) {
+ x_redraw_y = x_new_y;
+ } else {
+ x_new_height += (x_new_y - x_redraw_y);
+ }
+ if (x_new_width > x_redraw_width) {
+ x_redraw_width = x_new_width;
+ }
+ if (x_new_height > x_redraw_height) {
+ x_redraw_height = x_new_height;
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Utility for blanking the screen
+static void
+blackout(void)
+{
+ memset(img_fb, 0, target_viewport_width * target_viewport_height * sizeof(int) * config_magnification * config_magnification);
+ if (0 != host_win) {
+ schedule_redraw(0, 0, x_win_width, x_win_height);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// This function gets called when the main select() indicates the
+// X server is trying to send some data.
+static void
+handle_X_event(void)
+{
+ XEvent event;
+
+ XNextEvent(host_display, &event);
+ switch(event.type) {
+ case Expose:
+ {
+ // In theory this code should be able to do partial redraws for every
+ // expose event, but that does not seem to work reliably. Instead do a
+ // full redraw, but only for the final event in a sequence.
+ if (0 == event.xexpose.count) {
+ DEBUG(3, "X expose event, x %d, y %d, width %d, height %d\n",
+ event.xexpose.x, event.xexpose.y, event.xexpose.width, event.xexpose.height);
+ schedule_redraw(0, 0, x_win_width, x_win_height);
+ }
+ break;
+ }
+
+ case ConfigureNotify:
+ {
+ DEBUG(2, "X configure notify event, width %d, height %d\n", event.xconfigure.width, event.xconfigure.height);
+ x_win_width = event.xconfigure.width;
+ x_win_height = event.xconfigure.height;
+ win_width = (x_win_width + config_magnification - 1) / config_magnification;
+ win_height = (x_win_height + config_magnification - 1) / config_magnification;
+
+ if (shared_fb_data->display_on && shared_fb_data->blank_on) {
+ (*render_fn)(0 + shared_fb_data->viewport_x, 0 + shared_fb_data->viewport_y, win_width, win_height);
+ } else {
+ blackout();
+ }
+ break;
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Conversion routines
+
+// This dummy function is installed to handle draw requests before the
+// window is mapped - until that time the exact render function is unknown.
+static void
+dummy_render_fn(int target_x, int target_y, int width, int height)
+{
+ DEBUG(2, "rendering: target_x %d, target_y %d, width %d, height %d\n", target_x, target_y, width, height);
+ DEBUG(2, " : window has not been mapped on to the display yet\n");
+}
+#else // RENDERFN
+
+// These functions get instantiated N times for the N different
+// graphics formats. We need to take the target-side region defined by
+// x/y/width/height, render it into the image data, and then redraw
+// the relevant part of the image data. There is no point rendering more
+// data than is visible.
+
+static void
+RENDERFN(1, TARGET_FORMAT)(int target_x, int target_y, int width, int height)
+{
+ int x, y;
+ int win_x, win_y;
+ unsigned int* img_data;
+ unsigned int colour;
+ TARGET_DATA;
+
+ DEBUG(2, "rendering: target_x %d, target_y %d, width %d, height %d\n", target_x, target_y, width, height);
+ if ((0 == host_win) || !shared_fb_data->display_on || !shared_fb_data->blank_on) {
+ DEBUG(2, " : no-op, host_win %d, display_on %d, blank_on %d\n", (int)host_win, shared_fb_data->display_on, shared_fb_data->blank_on);
+ return;
+ }
+ DEBUG(2, " : current viewport x %d, y %d\n", shared_fb_data->viewport_x, shared_fb_data->viewport_y);
+
+ win_x = target_x - shared_fb_data->viewport_x;
+ win_y = target_y - shared_fb_data->viewport_y;
+ if (win_x < 0) {
+ width += win_x;
+ win_x = 0;
+ }
+ if (win_y < 0) {
+ height += win_y;
+ win_y = 0;
+ }
+ if ((win_x + width) > win_width) {
+ width = win_width - win_x;
+ }
+ if ((win_y + height) > win_height) {
+ height = win_height - win_y;
+ }
+ DEBUG(2, " : after clipping, win_x %d, win_y %d, width %d, height %d\n", win_x, win_y, width, height);
+ if ((width < 0) || (height < 0)) {
+ return;
+ }
+
+ img_data = img_fb + (win_y * target_viewport_width) + win_x;
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ colour = TARGET_NEXT_COLOUR();
+ *img_data++ = colour;
+ }
+ img_data += (target_viewport_width - width);
+ TARGET_NEXT_LINE();
+ }
+ schedule_redraw(win_x, win_y, width, height);
+}
+
+static void
+RENDERFN(2, TARGET_FORMAT)(int target_x, int target_y, int width, int height)
+{
+ int x, y;
+ int win_x, win_y;
+ unsigned int* img_data0;
+ unsigned int* img_data1;
+ unsigned int colour;
+ TARGET_DATA;
+
+ DEBUG(2, "rendering: target_x %d, target_y %d, width %d, height %d\n", target_x, target_y, width, height);
+ if ((0 == host_win) || !shared_fb_data->display_on || !shared_fb_data->blank_on) {
+ DEBUG(2, " : no-op, host_win %d, display_on %d, blank_on %d\n", (int)host_win, shared_fb_data->display_on, shared_fb_data->blank_on);
+ return;
+ }
+ DEBUG(2, " : current viewport x %d, y %d\n", shared_fb_data->viewport_x, shared_fb_data->viewport_y);
+ win_x = target_x - shared_fb_data->viewport_x;
+ win_y = target_y - shared_fb_data->viewport_y;
+ if (win_x < 0) {
+ width += win_x;
+ win_x = 0;
+ }
+ if (win_y < 0) {
+ height += win_y;
+ win_y = 0;
+ }
+ if ((win_x + width) > win_width) {
+ width = win_width - win_x;
+ }
+ if ((win_y + height) > win_height) {
+ height = win_height - win_y;
+ }
+ DEBUG(2, " : after clipping, target_x %d, target_y %d, width %d, height %d\n", target_x, target_y, width, height);
+ if ((width < 0) || (height < 0)) {
+ return;
+ }
+
+
+ for (y = 0; y < height; y++) {
+ img_data0 = img_fb + (2 * (win_y + y) * (2 * target_viewport_width)) + (2 * win_x);
+ img_data1 = img_data0 + (2 * target_viewport_width);
+ for (x = 0; x < width; x++) {
+ colour = TARGET_NEXT_COLOUR();
+ *img_data0++ = colour;
+ *img_data0++ = colour;
+ *img_data1++ = colour;
+ *img_data1++ = colour;
+ }
+ TARGET_NEXT_LINE();
+ }
+ schedule_redraw(2 * win_x, 2 * win_y, 2 * width, 2 * height);
+}
+
+static void
+RENDERFN(3, TARGET_FORMAT)(int target_x, int target_y, int width, int height)
+{
+ int x, y;
+ int win_x, win_y;
+ unsigned int* img_data0;
+ unsigned int* img_data1;
+ unsigned int* img_data2;
+ unsigned int colour;
+ TARGET_DATA;
+
+ DEBUG(2, "rendering: target_x %d, target_y %d, width %d, height %d\n", target_x, target_y, width, height);
+ if ((0 == host_win) || !shared_fb_data->display_on || !shared_fb_data->blank_on) {
+ DEBUG(2, " : no-op, host_win %d, display_on %d, blank_on %d\n", (int)host_win, shared_fb_data->display_on, shared_fb_data->blank_on);
+ return;
+ }
+ DEBUG(2, " : current viewport x %d, y %d\n", shared_fb_data->viewport_x, shared_fb_data->viewport_y);
+ win_x = target_x - shared_fb_data->viewport_x;
+ win_y = target_y - shared_fb_data->viewport_y;
+ if (win_x < 0) {
+ width += win_x;
+ win_x = 0;
+ }
+ if (win_y < 0) {
+ height += win_y;
+ win_y = 0;
+ }
+ if ((win_x + width) > win_width) {
+ width = win_width - win_x;
+ }
+ if ((win_y + height) > win_height) {
+ height = win_height - win_y;
+ }
+ DEBUG(2, " : after clipping, target_x %d, target_y %d, width %d, height %d\n", target_x, target_y, width, height);
+ if ((width < 0) || (height < 0)) {
+ return;
+ }
+
+ for (y = 0; y < height; y++) {
+ img_data0 = img_fb + (3 * (win_y + y) * (3 * target_viewport_width)) + (3 * win_x);
+ img_data1 = img_data0 + (3 * target_viewport_width);
+ img_data2 = img_data1 + (3 * target_viewport_width);
+
+ for (x = 0; x < width; x++) {
+ colour = TARGET_NEXT_COLOUR();
+ *img_data0++ = colour;
+ *img_data0++ = colour;
+ *img_data0++ = colour;
+ *img_data1++ = colour;
+ *img_data1++ = colour;
+ *img_data1++ = colour;
+ *img_data2++ = colour;
+ *img_data2++ = colour;
+ *img_data2++ = colour;
+ }
+ TARGET_NEXT_LINE();
+ }
+ schedule_redraw(3 * win_x, 3 * win_y, 3 * width, 3 * height);
+}
+
+static void
+RENDERFN(4, TARGET_FORMAT)(int target_x, int target_y, int width, int height)
+{
+ int x, y;
+ int win_x, win_y;
+ unsigned int* img_data0;
+ unsigned int* img_data1;
+ unsigned int* img_data2;
+ unsigned int* img_data3;
+ unsigned int colour;
+ TARGET_DATA;
+
+ DEBUG(2, "rendering: target_x %d, target_y %d, width %d, height %d\n", target_x, target_y, width, height);
+ if ((0 == host_win) || !shared_fb_data->display_on || !shared_fb_data->blank_on) {
+ DEBUG(2, " : no-op, host_win %d, display_on %d, blank_on %d\n", (int)host_win, shared_fb_data->display_on, shared_fb_data->blank_on);
+ return;
+ }
+ DEBUG(2, " : current viewport x %d, y %d\n", shared_fb_data->viewport_x, shared_fb_data->viewport_y);
+ win_x = target_x - shared_fb_data->viewport_x;
+ win_y = target_y - shared_fb_data->viewport_y;
+ if (win_x < 0) {
+ width += win_x;
+ win_x = 0;
+ }
+ if (win_y < 0) {
+ height += win_y;
+ win_y = 0;
+ }
+ if ((win_x + width) > win_width) {
+ width = win_width - win_x;
+ }
+ if ((win_y + height) > win_height) {
+ height = win_height - win_y;
+ }
+ DEBUG(2, " : after clipping, target_x %d, target_y %d, width %d, height %d\n", target_x, target_y, width, height);
+ if ((width < 0) || (height < 0)) {
+ return;
+ }
+
+ for (y = 0; y < height; y++) {
+ img_data0 = img_fb + (4 * (win_y + y) * (4 * target_viewport_width)) + (4 * win_x);
+ img_data1 = img_data0 + (4 * target_viewport_width);
+ img_data2 = img_data1 + (4 * target_viewport_width);
+ img_data3 = img_data2 + (4 * target_viewport_width);
+
+ for (x = 0; x < width; x++) {
+ colour = TARGET_NEXT_COLOUR();
+ *img_data0++ = colour;
+ *img_data0++ = colour;
+ *img_data0++ = colour;
+ *img_data0++ = colour;
+ *img_data1++ = colour;
+ *img_data1++ = colour;
+ *img_data1++ = colour;
+ *img_data1++ = colour;
+ *img_data2++ = colour;
+ *img_data2++ = colour;
+ *img_data2++ = colour;
+ *img_data2++ = colour;
+ *img_data3++ = colour;
+ *img_data3++ = colour;
+ *img_data3++ = colour;
+ *img_data3++ = colour;
+ }
+ TARGET_NEXT_LINE();
+ }
+ schedule_redraw(4 * win_x, 4 * win_y, 4 * width, 4 * height);
+}
+
+#endif
+#ifndef RENDERFN
+
+# define RENDERFN_AUX(_magnification_, _format_) render_ ## _magnification_ ## _ ## _format_
+# define RENDERFN(_magnification_, _format_) RENDERFN_AUX(_magnification_, _format_)
+
+// ----------------------------------------------------------------------------
+// 1bpp, BE. It is convenient to always render in byte-multiples
+# define TARGET_FORMAT 1BPP_BE
+
+# define TARGET_DATA \
+ unsigned char* target_fb_current; \
+ unsigned int mask; \
+ width += target_x & 0x07; \
+ target_x &= ~0x07; \
+ width = (width + 7) & ~0x07; \
+ target_fb_current = ((unsigned char*)target_fb) + \
+ (target_y * target_stride) + (target_x >> 3); \
+ mask = 0x0080
+
+# define TARGET_NEXT_COLOUR() \
+ ({ \
+ unsigned int next_colour; \
+ next_colour = host_palette[*target_fb_current & mask]; \
+ mask >>= 1; \
+ if (0 == mask) { \
+ target_fb_current += 1; \
+ mask = 0x0080; \
+ } \
+ next_colour; \
+ })
+
+# define TARGET_NEXT_LINE() \
+ target_fb_current += target_stride - (width >> 3)
+
+# include "framebuf.c"
+# undef TARGET_FORMAT
+# undef TARGET_DATA
+# undef TARGET_NEXT_COLOUR
+# undef TARGET_NEXT_LINE
+
+// ----------------------------------------------------------------------------
+// 1bpp, LE
+# define TARGET_FORMAT 1BPP_LE
+
+# define TARGET_DATA \
+ unsigned char* target_fb_current; \
+ unsigned int mask; \
+ width += target_x & 0x07; \
+ target_x &= ~0x07; \
+ width = (width + 7) & ~0x07; \
+ target_fb_current = ((unsigned char*)target_fb) + \
+ (target_y * target_stride) + (target_x >> 3); \
+ mask = 0x0001
+
+# define TARGET_NEXT_COLOUR() \
+ ({ \
+ unsigned int next_colour; \
+ next_colour = host_palette[*target_fb_current & mask]; \
+ mask <<= 1; \
+ if (0x0100 == mask) { \
+ target_fb_current += 1; \
+ mask = 0x0001; \
+ } \
+ next_colour; \
+ })
+
+# define TARGET_NEXT_LINE() \
+ target_fb_current += target_stride - (width >> 3)
+
+# include "framebuf.c"
+# undef TARGET_FORMAT
+# undef TARGET_DATA
+# undef TARGET_NEXT_COLOUR
+# undef TARGET_NEXT_LINE
+
+// ----------------------------------------------------------------------------
+// 2bpp, BE
+# define TARGET_FORMAT 2BPP_BE
+
+# define TARGET_DATA \
+ unsigned char* target_fb_current; \
+ unsigned int mask; \
+ width += target_x & 0x03; \
+ target_x &= ~0x03; \
+ width = (width + 3) & ~0x03; \
+ target_fb_current = ((unsigned char*)target_fb) + \
+ (target_y * target_stride) + (target_x >> 2); \
+ mask = 0x00C0
+
+# define TARGET_NEXT_COLOUR() \
+ ({ \
+ unsigned int next_colour; \
+ next_colour = host_palette[*target_fb_current & mask]; \
+ mask >>= 2; \
+ if (0x00 == mask) { \
+ target_fb_current += 1; \
+ mask = 0x00C0; \
+ } \
+ next_colour; \
+ })
+
+# define TARGET_NEXT_LINE() \
+ target_fb_current += target_stride - (width >> 2)
+
+# include "framebuf.c"
+# undef TARGET_FORMAT
+# undef TARGET_DATA
+# undef TARGET_NEXT_COLOUR
+# undef TARGET_NEXT_LINE
+
+// ----------------------------------------------------------------------------
+// 2bpp, LE
+# define TARGET_FORMAT 2BPP_LE
+
+# define TARGET_DATA \
+ unsigned char* target_fb_current; \
+ unsigned int mask; \
+ width += target_x & 0x03; \
+ target_x &= ~0x03; \
+ width = (width + 3) & ~0x03; \
+ target_fb_current = ((unsigned char*)target_fb) + \
+ (target_y * target_stride) + (target_x >> 2); \
+ mask = 0x0003
+
+# define TARGET_NEXT_COLOUR() \
+ ({ \
+ unsigned int next_colour; \
+ next_colour = host_palette[*target_fb_current & mask]; \
+ mask <<= 2; \
+ if (0x0300 == mask) { \
+ target_fb_current += 1; \
+ mask = 0x0003; \
+ } \
+ next_colour; \
+ })
+
+# define TARGET_NEXT_LINE() \
+ target_fb_current += target_stride - (width >> 2)
+
+# include "framebuf.c"
+# undef TARGET_FORMAT
+# undef TARGET_DATA
+# undef TARGET_NEXT_COLOUR
+# undef TARGET_NEXT_LINE
+
+// ----------------------------------------------------------------------------
+// 4bpp, BE
+# define TARGET_FORMAT 4BPP_BE
+
+# define TARGET_DATA \
+ unsigned char* target_fb_current; \
+ unsigned int mask; \
+ width += target_x & 0x01; \
+ target_x &= ~0x01; \
+ width = (width + 1) & ~0x01; \
+ target_fb_current = ((unsigned char*)target_fb) + \
+ (target_y * target_stride) + (target_x >> 1); \
+ mask = 0x00F0
+
+# define TARGET_NEXT_COLOUR() \
+ ({ \
+ unsigned int next_colour; \
+ next_colour = host_palette[*target_fb_current & mask]; \
+ mask >>= 4; \
+ if (0 == mask) { \
+ target_fb_current += 1; \
+ mask = 0x00F0; \
+ } \
+ next_colour; \
+ })
+
+# define TARGET_NEXT_LINE() \
+ target_fb_current += target_stride - (width >> 1)
+
+# include "framebuf.c"
+# undef TARGET_FORMAT
+# undef TARGET_DATA
+# undef TARGET_NEXT_COLOUR
+# undef TARGET_NEXT_LINE
+
+// ----------------------------------------------------------------------------
+// 4bpp, LE
+# define TARGET_FORMAT 4BPP_LE
+
+# define TARGET_DATA \
+ unsigned char* target_fb_current; \
+ unsigned int mask; \
+ width += target_x & 0x01; \
+ target_x &= ~0x01; \
+ width = (width + 1) & ~0x01; \
+ target_fb_current = ((unsigned char*)target_fb) + \
+ (target_y * target_stride) + (target_x >> 1); \
+ mask = 0x000F
+
+# define TARGET_NEXT_COLOUR() \
+ ({ \
+ unsigned int next_colour; \
+ next_colour = host_palette[*target_fb_current & mask]; \
+ mask <<= 4; \
+ if (0x0F00 == mask) { \
+ target_fb_current += 1; \
+ mask = 0x000F; \
+ } \
+ next_colour; \
+ })
+
+# define TARGET_NEXT_LINE() \
+ target_fb_current += target_stride - (width >> 2)
+
+# include "framebuf.c"
+# undef TARGET_FORMAT
+# undef TARGET_DATA
+# undef TARGET_NEXT_COLOUR
+# undef TARGET_NEXT_LINE
+
+// ----------------------------------------------------------------------------
+// 8bpp, paletted or true colour. In the case of a true colour display the
+// host_palette array will have been filled in appropriately for 332 so
+// conversion to 32-bit true colour again just involves indirecting through
+// the palette, rather than the more expensive bit masking and shifting.
+# define TARGET_FORMAT 8BPP
+
+# define TARGET_DATA \
+ unsigned char* target_fb_current; \
+ target_fb_current = ((unsigned char*)target_fb) + \
+ (target_y * target_stride) + target_x
+
+# define TARGET_NEXT_COLOUR() host_palette[*target_fb_current++]
+
+# define TARGET_NEXT_LINE() \
+ target_fb_current += (target_stride - width)
+
+# include "framebuf.c"
+# undef TARGET_FORMAT
+# undef TARGET_DATA
+# undef TARGET_NEXT_COLOUR
+# undef TARGET_NEXT_LINE
+
+// ----------------------------------------------------------------------------
+// 16bpp. Again this is handled via the host_palette array, suitably
+// initialized for either 555 or 565
+# define TARGET_FORMAT 16BPP
+
+# define TARGET_DATA \
+ unsigned short* target_fb_current; \
+ target_fb_current = ((unsigned short*)target_fb) + \
+ (target_y * (target_stride >> 1)) + target_x
+
+# define TARGET_NEXT_COLOUR() host_palette[*target_fb_current++]
+
+# define TARGET_NEXT_LINE() \
+ target_fb_current += ((target_stride >> 1) - width)
+
+# include "framebuf.c"
+# undef TARGET_FORMAT
+# undef TARGET_DATA
+# undef TARGET_NEXT_COLOUR
+# undef TARGET_NEXT_LINE
+
+// ----------------------------------------------------------------------------
+// 32bpp, 0888, no swapping
+
+# define TARGET_FORMAT 32BPP
+
+# define TARGET_DATA \
+ unsigned int* target_fb_current; \
+ target_fb_current = ((unsigned int*)target_fb) + \
+ (target_y * (target_stride >> 2)) + target_x
+
+# define TARGET_NEXT_COLOUR() *target_fb_current++ & 0x00FFFFFF
+
+# define TARGET_NEXT_LINE() \
+ target_fb_current += ((target_stride >> 2) - width)
+
+# include "framebuf.c"
+# undef TARGET_FORMAT
+# undef TARGET_DATA
+# undef TARGET_NEXT_COLOUR
+# undef TARGET_NEXT_LINE
+
+// ----------------------------------------------------------------------------
+// 32bpp, 0888, but the host uses 8880.
+# define TARGET_FORMAT 32BPP_SWAPPED
+
+# define TARGET_DATA \
+ unsigned int* target_fb_current; \
+ target_fb_current = ((unsigned int*)target_fb) + \
+ (target_y * (target_stride >> 2)) + target_x
+
+# define TARGET_NEXT_COLOUR() \
+ ({ \
+ unsigned int _colour_ = *target_fb_current++; \
+ _colour_ = \
+ ((_colour_ & 0x000000FF) << 24) | \
+ ((_colour_ & 0x0000FF00) << 16) | \
+ ((_colour_ & 0x00FF0000) << 8); \
+ _colour_; \
+ })
+
+# define TARGET_NEXT_LINE() \
+ target_fb_current += ((target_stride >> 2) - width)
+
+# include "framebuf.c"
+# undef TARGET_FORMAT
+# undef TARGET_DATA
+# undef TARGET_NEXT_COLOUR
+# undef TARGET_NEXT_LINE
+
+// ----------------------------------------------------------------------------
+// Palette management. 8bpp and 16bpp true colour can be initialized
+// statically. 32bpp does not involve the host_palette array at all.
+// Other formats involve dynamic palette updating.
+
+static void
+palette_initialize_8bpp_332(void)
+{
+ static const unsigned char expand2[4] = { 0x00, 0x55, 0xAA, 0xFF };
+ static const unsigned char expand3[8] = { 0x00, 0x20 + 4, 0x40 + 9, 0x60 + 13, 0x80 + 18, 0xA0 + 22, 0xC0 + 27, 0xE0 + 31 };
+ int i;
+ for (i = 0; i < 256; i++) {
+ int r = (i & 0x00E0) >> 5;
+ int g = (i & 0x001C) >> 2;
+ int b = (i & 0x0003) >> 0;
+ host_palette[i] = (expand3[r] << host_r_shift) | (expand3[g] << host_g_shift) | (expand2[b] << host_b_shift);
+ }
+}
+
+static void
+palette_initialize_16bpp_555(void)
+{
+ static const unsigned char expand5[32] = {
+ 0x00 + 0, 0x08 + 0, 0x10 + 0, 0x18 + 0, 0x20 + 1, 0x28 + 1, 0x30 + 1, 0x38 + 1,
+ 0x40 + 2, 0x48 + 2, 0x50 + 2, 0x58 + 2, 0x60 + 3, 0x68 + 3, 0x70 + 3, 0x78 + 3,
+ 0x80 + 4, 0x88 + 4, 0x90 + 4, 0x98 + 4, 0xA0 + 5, 0xA8 + 5, 0xB0 + 5, 0xB8 + 5,
+ 0xC0 + 6, 0xC8 + 6, 0xD0 + 6, 0xD8 + 6, 0xE0 + 7, 0xE8 + 7, 0xF0 + 7, 0xF8 + 7,
+ };
+ int i;
+ for (i = 0; i < 65536; i++) {
+ int r = (i & 0x00007C00) >> 10;
+ int g = (i & 0x000003E0) >> 5;
+ int b = (i & 0x0000001F) >> 0;
+ host_palette[i] = (expand5[r] << host_r_shift) | (expand5[g] << host_g_shift) | (expand5[b] << host_b_shift);
+ }
+}
+
+static void
+palette_initialize_16bpp_565(void)
+{
+ static const unsigned char expand5[32] = {
+ 0x00 + 0, 0x08 + 0, 0x10 + 0, 0x18 + 0, 0x20 + 1, 0x28 + 1, 0x30 + 1, 0x38 + 1,
+ 0x40 + 2, 0x48 + 2, 0x50 + 2, 0x58 + 2, 0x60 + 3, 0x68 + 3, 0x70 + 3, 0x78 + 3,
+ 0x80 + 4, 0x88 + 4, 0x90 + 4, 0x98 + 4, 0xA0 + 5, 0xA8 + 5, 0xB0 + 5, 0xB8 + 5,
+ 0xC0 + 6, 0xC8 + 6, 0xD0 + 6, 0xD8 + 6, 0xE0 + 7, 0xE8 + 7, 0xF0 + 7, 0xF8 + 7,
+ };
+ static const unsigned char expand6[64] = {
+ 0x00 + 0, 0x04 + 0, 0x08 + 0, 0x0C + 0, 0x10 + 0, 0x14 + 0, 0x18 + 0, 0x1C + 0,
+ 0x20 + 0, 0x24 + 0, 0x28 + 0, 0x2C + 0, 0x30 + 0, 0x34 + 0, 0x38 + 0, 0x3C + 0,
+ 0x40 + 1, 0x44 + 1, 0x48 + 1, 0x4C + 1, 0x50 + 1, 0x54 + 1, 0x58 + 1, 0x5C + 1,
+ 0x60 + 1, 0x64 + 1, 0x68 + 1, 0x6C + 1, 0x70 + 1, 0x74 + 1, 0x78 + 1, 0x7C + 1,
+ 0x80 + 2, 0x84 + 2, 0x88 + 2, 0x8C + 2, 0x90 + 2, 0x94 + 2, 0x98 + 2, 0x9C + 2,
+ 0xA0 + 2, 0xA4 + 2, 0xA8 + 2, 0xAC + 2, 0xB0 + 2, 0xB4 + 2, 0xB8 + 2, 0xBC + 2,
+ 0xC0 + 3, 0xC4 + 3, 0xC8 + 3, 0xCC + 3, 0xD0 + 3, 0xD4 + 3, 0xD8 + 3, 0xDC + 3,
+ 0xE0 + 3, 0xE4 + 3, 0xE8 + 3, 0xEC + 3, 0xF0 + 3, 0xF4 + 3, 0xF8 + 3, 0xFC + 3,
+ };
+ int i;
+ for (i = 0; i < 65536; i++) {
+ int r = (i & 0x0000F800) >> 11;
+ int g = (i & 0x000007E0) >> 5;
+ int b = (i & 0x0000001F) >> 0;
+ host_palette[i] = (expand5[r] << host_r_shift) | (expand6[g] << host_g_shift) | (expand5[b] << host_b_shift);
+ }
+}
+
+static void
+palette_update(void)
+{
+ int i, j;
+ unsigned char* target_palette;
+ int r, g, b;
+
+ target_palette = shared_fb_data->palette;
+ for (i = 0; i < (0x01 << target_depth); i++) {
+ r = *target_palette++;
+ g = *target_palette++;
+ b = *target_palette++;
+ host_palette[i] = (r << host_r_shift) | (g << host_g_shift) | (b << host_b_shift);
+ }
+
+ // Make sure the palette is replicated throughout the first 256
+ // entries. That way when rendering <8bpp data we can just mask
+ // the target-side bytes without having to shift.
+ for (j = 0; i < 256; i++, j++) {
+ host_palette[i] = host_palette[j];
+ }
+}
+
+// ----------------------------------------------------------------------------
+// This array is used to map the various display formats etc. on to
+// render functions.
+static struct _render_details {
+ char* rd_format;
+ unsigned int rd_endianness_matters;
+ unsigned int rd_le;
+ void (*rd_palette_init)(void);
+ void (*rd_palette_update)(void);
+ void (*rd_render_fns[4])(int, int, int, int);
+} render_array[] = {
+ // 32BPP must come first
+ { "32BPP_TRUE_0888", 0, 0, NULL, NULL,
+ { &render_1_32BPP, &render_2_32BPP, &render_3_32BPP, &render_4_32BPP }
+ },
+ { "16BPP_TRUE_555", 0, 0, &palette_initialize_16bpp_555, NULL,
+ { &render_1_16BPP, &render_2_16BPP, &render_3_16BPP, &render_4_16BPP }
+ },
+ { "16BPP_TRUE_565", 0, 0, &palette_initialize_16bpp_565, NULL,
+ { &render_1_16BPP, &render_2_16BPP, &render_3_16BPP, &render_4_16BPP }
+ },
+ { "8BPP_TRUE_332", 0, 0, &palette_initialize_8bpp_332, NULL,
+ { &render_1_8BPP, &render_2_8BPP, &render_3_8BPP, &render_4_8BPP }
+ },
+ { "8BPP_PAL888", 0, 0, NULL, &palette_update,
+ { &render_1_8BPP, &render_2_8BPP, &render_3_8BPP, &render_4_8BPP }
+ },
+ { "4BPP_PAL888", 1, 1, NULL, &palette_update,
+ { &render_1_4BPP_LE, &render_2_4BPP_LE, &render_3_4BPP_LE, &render_4_4BPP_LE }
+ },
+ { "4BPP_PAL888", 1, 0, NULL, &palette_update,
+ { &render_1_4BPP_BE, &render_2_4BPP_BE, &render_3_4BPP_BE, &render_4_4BPP_BE }
+ },
+ { "2BPP_PAL888", 1, 1, NULL, &palette_update,
+ { &render_1_2BPP_LE, &render_2_2BPP_LE, &render_3_2BPP_LE, &render_4_2BPP_LE }
+ },
+ { "2BPP_PAL888", 1, 0, NULL, &palette_update,
+ { &render_1_2BPP_BE, &render_2_2BPP_BE, &render_3_2BPP_BE, &render_4_2BPP_BE }
+ },
+ { "1BPP_PAL888", 1, 1, NULL, &palette_update,
+ { &render_1_1BPP_LE, &render_2_1BPP_LE, &render_3_1BPP_LE, &render_4_1BPP_LE }
+ },
+ { "1BPP_PAL888", 1, 0, NULL, &palette_update,
+ { &render_1_1BPP_BE, &render_2_1BPP_BE, &render_3_1BPP_BE, &render_4_1BPP_BE }
+ },
+ { NULL }
+};
+
+
+// ----------------------------------------------------------------------------
+// Communication between host and target
+//
+// When the target wants to wake up the host it sends a single byte down
+// a fifo, typically after having filled in appropriate fields in the
+// shared memory region.
+static void
+handle_target_request(void)
+{
+ unsigned char buf[1];
+ int result;
+
+ result = read(fifo_t2h_fd, buf, 1);
+ if (-1 == result) {
+ if (EINTR == errno) {
+ return;
+ }
+ error("unexpected error %d (%s) reading fifo command from target-side code", errno, strerror(errno));
+ }
+ if (0 == result) {
+ // The target-side must have exited. Do not follow suit yet. Instead
+ // exit only when the I/O auxiliary exits.
+ DEBUG(1, "eCos application has exited\n");
+ close(fifo_t2h_fd);
+ fifo_t2h_fd = -1;
+ return;
+ }
+
+ switch(buf[0]) {
+ case SYNTH_FB_OK:
+ {
+ // The target has finished initializing. This may have
+ // involved filling in the palette
+ DEBUG(1, "target request SYNTH_FB_OK, eCos application has connected.\n");
+ if (palette_update_fn) {
+ (*palette_update_fn)();
+ }
+ break;
+ }
+
+ case SYNTH_FB_SYNC:
+ {
+ // The target has updated part of the display.
+ DEBUG(2, "target request SYNC, x0 %d, y0 %d, x1 %d, y1 %d\n",
+ shared_fb_data->sync_x0, shared_fb_data->sync_y0, shared_fb_data->sync_x1, shared_fb_data->sync_y1);
+ (*render_fn)(shared_fb_data->sync_x0, shared_fb_data->sync_y0,
+ (shared_fb_data->sync_x1 - shared_fb_data->sync_x0),
+ (shared_fb_data->sync_y1 - shared_fb_data->sync_y0));
+ break;
+ }
+
+ case SYNTH_FB_WRITE_PALETTE:
+ {
+ // The target-side palette has been updated. Adjust the
+ // host-side palette and then render the whole window with
+ // the curent colours (unless blanked).
+ DEBUG(1, "target request WRITE_PALETTE\n");
+ if (palette_update_fn) {
+ (*palette_update_fn)();
+ }
+ (*render_fn)(shared_fb_data->viewport_x, shared_fb_data->viewport_y, win_width, win_height);
+ }
+
+ case SYNTH_FB_BLANK:
+ {
+ DEBUG(1, "target request blank, display should be %s\n", shared_fb_data->blank_on ? "on" : "off");
+ if (shared_fb_data->blank_on) {
+ (*render_fn)(shared_fb_data->viewport_x, shared_fb_data->viewport_y, win_width, win_height);
+ } else {
+ blackout();
+ }
+ break;
+ }
+
+ case SYNTH_FB_VIEWPORT:
+ {
+ // Just rerender the whole display as per the new viewport position.
+ DEBUG(1, "target request move viewport to x %d, y %d\n", shared_fb_data->viewport_x, shared_fb_data->viewport_y);
+ (*render_fn)(shared_fb_data->viewport_x, shared_fb_data->viewport_y, win_width, win_height);
+ break;
+ }
+
+ case SYNTH_FB_PAGE_FLIP:
+ {
+ int page_size = target_height * target_stride;
+ DEBUG(1, "target request page flip to page %d\n", shared_fb_data->page_visible);
+ target_fb = (void*)(((char*)&(shared_fb_data->framebuf[0])) + (page_size * shared_fb_data->page_visible));
+ (*render_fn)(shared_fb_data->viewport_x, shared_fb_data->viewport_y, win_width, win_height);
+ break;
+ }
+ }
+
+ // Send a single-byte response back to the target
+ DEBUG(2, "target request handled\n");
+ buf[0] = SYNTH_FB_OK;
+ do {
+ result = write(fifo_h2t_fd, buf, 1);
+ } while ((result < 0) && (errno == EINTR));
+ if (result < 0) {
+ error("unexpected error %d (%s) writing fifo status to target-side code", errno, strerror(errno));
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Communication from the Tcl/Tk script
+static void
+handle_mapped(int winid)
+{
+ Status result;
+ XWindowAttributes attr;
+ XGCValues gc_values;
+ Visual* visual;
+ int i;
+
+ DEBUG(1, "X window %d has been mapped\n", winid);
+ if (0 != (int)host_win) {
+ error(" window has already been mapped.\n");
+ }
+
+ host_win = (Window)winid;
+ result = XGetWindowAttributes(host_display, host_win, &attr);
+ if (0 == result) {
+ error("failed to get window attributes.");
+ }
+ gc_values.graphics_exposures = False;
+ host_gc = XCreateGC(host_display, host_win, GCGraphicsExposures, &gc_values);
+ result = XSelectInput(host_display, host_win, ExposureMask | StructureNotifyMask);
+
+ // The Tcl script has already checked that we are on a 24/32 bit display.
+ // We need to know the colour shifts and possibly adjust the render array.
+ visual = attr.visual;
+ DEBUG(1, " red_mask 0x%08lx, green_mask 0x%08lx, blue_mask 0x%08lx\n", visual->red_mask, visual->green_mask, visual->blue_mask);
+ if ((0x00FF0000 == visual->red_mask) && (0x0000FF00 == visual->green_mask) && (0x000000FF == visual->blue_mask)) {
+ // 0888, nothing special needed
+ host_r_shift = 16;
+ host_g_shift = 8;
+ host_b_shift = 0;
+ } else if ((0x0000FF00 == visual->red_mask) && (0x00FF0000 == visual->green_mask) && (0xFF000000 == visual->blue_mask)) {
+ // 8880
+ host_r_shift = 8;
+ host_g_shift = 16;
+ host_b_shift = 24;
+ render_array[0].rd_render_fns[0] = &render_1_32BPP_SWAPPED;
+ render_array[0].rd_render_fns[1] = &render_2_32BPP_SWAPPED;
+ render_array[0].rd_render_fns[2] = &render_3_32BPP_SWAPPED;
+ render_array[0].rd_render_fns[3] = &render_4_32BPP_SWAPPED;
+ }
+
+ // Time to figure out which render function etc. to use.
+ render_fn = (void (*)(int, int, int, int)) NULL;
+ for (i = 0; render_array[i].rd_format; i++) {
+ if ((0 == strcmp(render_array[i].rd_format, target_format)) &&
+ (!render_array[i].rd_endianness_matters || (render_array[i].rd_le == target_le))) {
+
+ render_fn = render_array[i].rd_render_fns[config_magnification - 1];
+ palette_init_fn = render_array[i].rd_palette_init;
+ palette_update_fn = render_array[i].rd_palette_update;
+ break;
+ }
+ }
+ if (NULL == render_fn) {
+ error("Target format not supported.");
+ }
+
+ // Now it is possible to create the XImage structure, the fifos,
+ // and the shared memory region for interaction with the target.
+ // The XImage needs to be large enough for the viewport. That may
+ // be larger than the actually visible window, but the window may
+ // get resized.
+ host_image = XCreateImage(host_display, visual,
+ 24, // image depth. 24 bits of colour info.
+ ZPixmap,
+ 0, // offset
+ NULL, // data, filled in later
+ target_viewport_width * config_magnification,
+ target_viewport_height * config_magnification,
+ 32, // bitmap_pad
+ 0 // bytes_per_line, calculated by X
+ );
+ if (NULL == host_image) {
+ error("Failed to allocate XImage structure.");
+ }
+ host_image->data = (void*)img_fb;
+
+ x_win_width = attr.width;
+ x_win_height = attr.height;
+ win_width = (x_win_width + config_magnification - 1) / config_magnification;
+ win_height = (x_win_height + config_magnification - 1) / config_magnification;
+ DEBUG(1, " mapped window, X width %d, X height %d, win width %d, win height %d, blank on %d, display on %d\n",
+ x_win_width, x_win_height, win_width, win_height, shared_fb_data->blank_on, shared_fb_data->display_on);
+
+ // The palette may get initialized locally or by the target, depending
+ // on the mode.
+ if (palette_init_fn) {
+ (*palette_init_fn)();
+ }
+ if (palette_update_fn) {
+ (*palette_update_fn)();
+ }
+ if (shared_fb_data->display_on && shared_fb_data->blank_on) {
+ (*render_fn)(shared_fb_data->viewport_x, shared_fb_data->viewport_y, win_width, win_height);
+ } else {
+ // Just draw the initial blank screen.
+ blackout();
+ }
+}
+
+static void
+handle_auxiliary_request(void)
+{
+ synth_fb_auxiliary_request req;
+ int result;
+
+ result = read(0, &req, sizeof(synth_fb_auxiliary_request));
+ if (result <= 0) {
+ // The I/O auxiliary has terminated, so assume the window has gone as well.
+ exit(0);
+ }
+ DEBUG(2, "handle_auxiliary request %d\n", req.command);
+ switch (req.command) {
+ case SYNTH_FB_AUX_MAPPED:
+ {
+ handle_mapped(req.arg1);
+ break;
+ }
+ case SYNTH_FB_AUX_ON:
+ {
+ // This is used when the target-side switches the display
+ // off and back on, rather than just blanking it. Treat it
+ // the same as blanking.
+ DEBUG(1, "Target has switched the display on\n");
+ shared_fb_data->display_on = 1;
+ (*render_fn)(shared_fb_data->viewport_x, shared_fb_data->viewport_y, win_width, win_height);
+ break;
+ }
+ case SYNTH_FB_AUX_OFF:
+ {
+ DEBUG(1, "Target has switched the display off\n");
+ shared_fb_data->display_on = 0;
+ blackout();
+ break;
+ }
+ case SYNTH_FB_AUX_REDRAW:
+ {
+ DEBUG(1, "Auxiliary has requested a redraw\n");
+ schedule_redraw(0, 0, x_win_width, x_win_height);
+ }
+ }
+ DEBUG(2, "handle_auxiliary request done\n");
+}
+
+// Report an error to ecosynth during initialization. This means a
+// single byte 0, followed by a string.
+static void
+report_init_error(char* msg)
+{
+ write(1, "0", 1);
+ write(1, msg, strlen(msg));
+ close(1);
+ exit(0);
+}
+
+// ----------------------------------------------------------------------------
+int
+main(int argc, char** argv)
+{
+ int size;
+ fd_set read_fds;
+ int max_fd;
+
+ atexit(&atexit_handler);
+ signal(SIGPIPE, SIG_IGN);
+
+ if (12 != argc) {
+ report_init_error("Incorrect number of arguments.");
+ }
+ target_id = (int) strtoul(argv[1], NULL, 0);
+ target_depth = (int) strtoul(argv[2], NULL, 0);
+ target_le = (int) strtoul(argv[3], NULL, 0);
+ target_width = (int) strtoul(argv[4], NULL, 0);
+ target_height = (int) strtoul(argv[5], NULL, 0);
+ target_viewport_width = (int) strtoul(argv[6], NULL, 0);
+ target_viewport_height = (int) strtoul(argv[7], NULL, 0);
+ target_stride = (int) strtoul(argv[8], NULL, 0);
+ target_number_pages = (int) strtoul(argv[9], NULL, 0);
+ target_format = argv[10];
+ config_magnification = (int) strtoul(argv[11], NULL, 0);
+
+ if ((target_depth != 1) && (target_depth != 2) && (target_depth != 4) && (target_depth != 8) && (target_depth != 16) && (target_depth != 32)) {
+ report_init_error("Invalid target depth.");
+ }
+ if ((target_width < 16) || (target_width > 4096)) {
+ report_init_error("Invalid target width.");
+ }
+ if ((target_height < 16) || (target_height > 4096)) {
+ report_init_error("Invalid target height.");
+ }
+ if ((target_viewport_width < 16) || (target_viewport_width > target_width)) {
+ report_init_error("Invalid target viewport width.");
+ }
+ if ((target_viewport_height < 16) || (target_viewport_height > target_height)) {
+ report_init_error("Invalid target viewport height.");
+ }
+ if ((target_number_pages < 1) || (target_number_pages > 4)) {
+ report_init_error("Invalid target number of pages.");
+ }
+ if ((config_magnification < 1) || (config_magnification > 4)) {
+ report_init_error("Invalid config magnification.");
+ }
+
+ host_display = XOpenDisplay(NULL);
+ if (NULL == host_display) {
+ report_init_error("Failed to open X display.");
+ }
+ img_fb = (unsigned int*) malloc(target_viewport_width * target_viewport_height * sizeof(int) * config_magnification * config_magnification);
+ if (NULL == img_fb) {
+ report_init_error("Failed to allocate XImage data.");
+ }
+ blackout();
+
+ // Use of tmpnam() is generally discouraged and generates a linker
+ // warning, but only three temporary file names are needed and
+ // there are no root privileges involved so security is not a big
+ // issue. mkstemp() cannot easily be used with fifos.
+ if (NULL == tmpnam(fifo_t2h_name)) {
+ report_init_error("Failed to create unique file name for target->host fifo.");
+ }
+ if (0 != mkfifo(fifo_t2h_name, S_IRUSR | S_IWUSR)) {
+ report_init_error("Failed to create target->host fifo.");
+ }
+ // Opening O_RDONLY or O_WRONLY will result in blocking until the
+ // other end is open as well, which is not what is wanted here.
+ // Instead we use the Linux feature of opening with O_RDWR which
+ // gives non-blocking behaviour.
+ fifo_t2h_created = 1;
+ fifo_t2h_fd = open(fifo_t2h_name, O_RDWR);
+ if (-1 == fifo_t2h_fd) {
+ report_init_error("Failed to open target->host fifo.");
+ }
+ if (NULL == tmpnam(fifo_h2t_name)) {
+ report_init_error("Failed to create unique file name for host->target fifo.");
+ }
+ if (0 != mkfifo(fifo_h2t_name, S_IRUSR | S_IWUSR)) {
+ report_init_error("Failed to create host->target fifo.");
+ }
+ fifo_h2t_created = 1;
+ fifo_h2t_fd = open(fifo_h2t_name, O_RDWR);
+ if (-1 == fifo_h2t_fd) {
+ report_init_error("Failed to open target->host fifo.");
+ }
+
+ size = sizeof(synth_fb_data) + (target_height * target_stride * target_number_pages);
+ if (NULL == tmpnam(shm_name)) {
+ report_init_error("Failed to create unique file name for shared memory.");
+ }
+ shm_fd = open(shm_name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ if (shm_fd < 0) {
+ report_init_error("Failed to open file for shared memory region.");
+ }
+ shm_created = 1;
+ if (ftruncate(shm_fd, size) < 0) {
+ report_init_error("Failed to set shared memory file size.");
+ }
+
+ shared_fb_data = (synth_fb_data*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
+ if (shared_fb_data == (synth_fb_data*)MAP_FAILED) {
+ report_init_error("Failed to mmap shared memory file.");
+ }
+ target_fb = &(shared_fb_data->framebuf[0]);
+
+ shared_fb_data->connected = 0;
+ shared_fb_data->fifo_to_framebuf = -1;
+ shared_fb_data->fifo_from_framebuf = -1;
+ shared_fb_data->devid = target_id;
+ shared_fb_data->sync_x0 = 0;
+ shared_fb_data->sync_y0 = 0;
+ shared_fb_data->sync_x1 = target_viewport_width;
+ shared_fb_data->sync_y1 = target_viewport_height;
+ shared_fb_data->display_on = 0;
+ shared_fb_data->blank_on = 1;
+ shared_fb_data->viewport_x = 0;
+ shared_fb_data->viewport_y = 0;
+ shared_fb_data->page_visible = 0;
+
+ render_fn = &dummy_render_fn;
+ msync(shared_fb_data, size, MS_SYNC);
+
+ // Everything seems to be in order. Report back to the auxiliary.
+ {
+ char buf[513];
+ if ((strlen(shm_name) + strlen(fifo_t2h_name) + strlen(fifo_h2t_name) + 3) > 512) {
+ report_init_error("Temporary path names too long.");
+ }
+ buf[0] = '1';
+ strcpy(&(buf[1]), shm_name);
+ strcat(&(buf[1]), ";");
+ strcat(&(buf[1]), fifo_t2h_name);
+ strcat(&(buf[1]), ";");
+ strcat(&(buf[1]), fifo_h2t_name);
+ strcat(&(buf[1]), ";");
+ write(1, buf, 2 + strlen(&(buf[1])));
+ }
+
+ // Now we just loop, processing events. We want to select on file descriptor
+ // 0 from the auxiliary, the X file descriptor, and the fifo t2h descriptor.
+ // The latter may go away. X should never go away, and if the auxiliary goes
+ // away we exit immediately.
+ max_fd = MAX(ConnectionNumber(host_display), fifo_t2h_fd);
+ while ( 1 ) {
+ while (XPending(host_display) > 0) {
+ handle_X_event();
+ }
+ FD_ZERO(&read_fds);
+ FD_SET(0, &read_fds);
+ FD_SET(ConnectionNumber(host_display), &read_fds);
+ if (-1 != fifo_t2h_fd) {
+ FD_SET(fifo_t2h_fd, &read_fds);
+ }
+ DEBUG(3, "framebuf main loop: selecting on 0x%08x\n", *(int*)&read_fds);
+ do_redraw();
+ if (select(max_fd + 1, &read_fds, NULL, NULL, NULL) >= 0) {
+ if (FD_ISSET(0, &read_fds)) {
+ DEBUG(2, "framebuf main loop: auxiliary request\n");
+ handle_auxiliary_request();
+ }
+ if ((-1 != fifo_t2h_fd) && FD_ISSET(fifo_t2h_fd, &read_fds)) {
+ DEBUG(2, "framebuf main loop: target request\n");
+ handle_target_request();
+ }
+ if (FD_ISSET(ConnectionNumber(host_display), &read_fds)) {
+ DEBUG(3, "framebuf main loop: X request\n");
+ (void)XEventsQueued(host_display, QueuedAfterReading);
+ }
+ }
+ }
+
+ exit(EXIT_SUCCESS);
+}
+#endif // INSTANTIATE_CONVERTER
diff --git a/ecos/packages/devs/framebuf/synth/current/host/framebuf.tcl b/ecos/packages/devs/framebuf/synth/current/host/framebuf.tcl
new file mode 100644
index 0000000..b113c42
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/framebuf.tcl
@@ -0,0 +1,375 @@
+# {{{ Banner
+
+# ============================================================================
+#
+# framebuf.tcl
+#
+# Framebuffer support for the eCos synthetic target I/O auxiliary
+#
+# ============================================================================
+# ####ECOSGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2008 Free Software Foundation, Inc.
+#
+# eCos is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 or (at your option) any later
+# version.
+#
+# eCos is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with eCos; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered by
+# the GNU General Public License. However the source code for this file
+# must still be made available in accordance with section (3) of the GNU
+# General Public License v2.
+#
+# This exception does not invalidate any other reasons why a work based
+# on this file might be covered by the GNU General Public License.
+# -------------------------------------------
+# ####ECOSGPLCOPYRIGHTEND####
+# ============================================================================
+# #####DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Contact(s): bartv
+# Date: 2005/10/28
+# Version: 0.01
+# Description:
+# Implementation of a framebuffer device. This script should only ever
+# be run from inside the ecosynth auxiliary.
+#
+# ####DESCRIPTIONEND####
+# ============================================================================
+
+# }}}
+
+# Overview
+#
+# The synthetic framebuffer package supports up to four framebuffer
+# devices. The eCos framebuffers are displayed by a separate C program
+# framebuf which gets spawned by this script. framebuf operates using
+# low-level X library calls. Doing the drawing inside Tcl/Tk would be
+# far too slow, and trying to draw directly to an X display from inside
+# an eCos application would be complicated.
+#
+# When an eCos framebuffer is switched on for the first time it will
+# result in a device instantiation in this script. A suitable frame
+# is created, and once it is mapped the framebuf program is started.
+# The device data string from the target includes a protocol version
+# number, target display depth, width and height, display format, etc.
+
+namespace eval framebuf {
+
+ # Protocol between the target-side and the auxiliary, as per protocol.h
+ variable SYNTH_FB_INIT 0x01
+ variable SYNTH_FB_ABORT 0x02
+ variable SYNTH_FB_ON 0x03
+ variable SYNTH_FB_OFF 0x04
+
+ # Protocol between the auxiliary and the framebuf program
+ variable SYNTH_FB_AUX_MAPPED 0x01
+ variable SYNTH_FB_AUX_ON 0x02
+ variable SYNTH_FB_AUX_OFF 0x03
+ variable SYNTH_FB_AUX_REDRAW 0x04
+
+ variable init_ok 1
+ array set settings []
+
+ # Set DEBUG_LEVEL to between 0 for no debug output, 2 for maximum
+ variable DEBUG_LEVEL 0
+ proc DEBUG { level devid msg } {
+ if { $level < $framebuf::DEBUG_LEVEL } {
+ if { [info exists framebuf::settings($devid,fbid)] } {
+ set fbid $framebuf::settings($devid,fbid)
+ } else {
+ set fbid "<unknown>"
+ }
+ puts -nonewline stderr "framebuf.tcl (fb$fbid): $msg"; flush stderr
+ }
+ }
+
+ # One-off initialization.
+ variable install_dir $synth::device_install_dir
+ variable framebuf_executable [file join $framebuf::install_dir "framebuf"]
+ if { ! [file exists $framebuf_executable] } {
+ synth::report_error "Framebuffer device, framebuf executable has not been installed in $framebuf::install_dir.\n"
+ set init_ok 0
+ } elseif { ! [file executable $framebuf_executable] } {
+ synth::report_error "Framebuffer device, installed program $framebuf_executable is not executable.\n"
+ set init_ok 0
+ }
+
+ if { ! [file exists [file join $framebuf::install_dir "framebuf_icon.xbm"]] ||
+ ! [file exists [file join $framebuf::install_dir "framebuf_iconmask.xbm"]] } {
+ synth::report_error "Framebuffer device, bitmap support files have not been installed.\n"
+ set init_ok =
+ }
+
+ # A default function for creating the Tk frame for an eCos
+ # framebuffer device. Framebuffer 0 is usually part of the
+ # main window, unless it would take up too much space.
+ # Unfortunately at this stage of initialization there is no
+ # easy way to work out how big . is going to be so some
+ # hard-wired numbers are used instead.
+ proc default_create_frame { fbid magnification depth little_endian width height viewport_width viewport_height stride number_pages format } {
+
+ puts "default_create_frame $fbid mag $magnification width $viewport_width height $viewport_height"
+ set viewport_width [expr $viewport_width * $magnification]
+ set viewport_height [expr $viewport_height * $magnification]
+ puts "default_create_frame $fbid mag $magnification width $viewport_width height $viewport_height"
+
+ if { (0 == $fbid) && ($viewport_height <= 240) && ($viewport_width <= 640) } {
+ frame .fb$fbid -container 1 -height $viewport_height -width $viewport_width
+ pack .fb$fbid -in .main.n -expand 0 -anchor nw
+ return .fb$fbid
+ } else {
+ toplevel .fb$fbid
+ frame .fb$fbid.frame -container 1 -height $viewport_height -width $viewport_width
+ pack .fb$fbid.frame -side top -expand 0 -anchor nw
+ wm title .fb$fbid "Synth FB[set fbid] [set width]*[set height]*[set depth]bpp"
+ wm iconbitmap .fb$fbid "@[file join $framebuf::install_dir framebuf_icon.xbm]"
+ wm iconmask .fb$fbid "@[file join $framebuf::install_dir framebuf_iconmask.xbm]"
+ wm iconname .fb$fbid "Synth FB[set fbid]"
+ wm protocol .fb$fbid WM_DELETE_WINDOW { }
+ return .fb$fbid.frame
+ }
+ }
+
+ variable create_frame_proc default_create_frame
+
+ if { [synth::tdf_has_option "framebuf" "create_frame_proc"] } {
+ set framebuf::create_frame_proc [synth::tdf_get_option "framebuf" "create_frame_proc"]
+ }
+
+ # Optional magnification
+ for { set i 0 } { $i < 4 } { incr i } {
+ set framebuf::settings(fb$i,magnification) 1
+ if { [synth::tdf_has_option "framebuf" "fb[set i]_magnification"] } {
+ set magnification [synth::tdf_get_option "framebuf" "fb[set i]_magnification"]
+ if { ! [string is integer -strict $magnification] } {
+ synth::report_error [concat
+ "Framebuf device, invalid value in target definition file $synth::target_definition\n"
+ " fb[set i]_magnification should be a simple integer, not $magnification\n"]
+ set init_ok 0
+ } elseif { ($magnification < 1) || ($magnification > 4) } {
+ synth::report_error [concat
+ "Framebuf device, invalid value in target definition file $synth::target_definition\n"
+ " fb[set i]_magnification should be 1, 2, 3 or 4.\n"]
+ set init_ok 0
+ } else {
+ set framebuf::settings(fb$i,magnification) $magnification
+ }
+ }
+ }
+
+ proc handle_framebuf_reply { devid } {
+ DEBUG 1 $devid "reading reply from framebuf program\n"
+ if { ! $framebuf::settings($devid,got_reply) } {
+ # The first message from the framebuf program indicates success+pathnames or failure+message
+ # This will wake up a vwait in the instantiate proc
+ set framebuf::settings($devid,reply) [read $framebuf::settings($devid,fd)]
+ set framebuf::settings($devid,got_reply) 1
+ } else {
+ # The framebuf program sends back no other data, but may issue warnings or failures
+ synth::report [read $framebuf::settings($devid,fd)]
+ }
+ }
+
+ proc send_framebuf_request { devid code arg1 arg2 } {
+ # FIXME handle endianness
+ set auxiliary_request [binary format iii $code $arg1 $arg2]
+ puts -nonewline $framebuf::settings($devid,fd) $auxiliary_request
+ flush $framebuf::settings($devid,fd)
+ }
+
+ proc handle_ecos_request { devid reqcode arg1 arg2 reqdata reqlen reply_len } {
+ DEBUG 1 $devid "got request $reqcode from eCos application\n"
+ if { $framebuf::SYNTH_FB_INIT == $reqcode } {
+ # This request is used after instantiation to get hold of the connectivity information
+ synth::send_reply 1 [string length $framebuf::settings($devid,connectivity)] $framebuf::settings($devid,connectivity)
+ } elseif { $framebuf::SYNTH_FB_ABORT == $reqcode } {
+ # FIXME: kill off the framebuf program? Destroy the window/frame?
+ synth::report_error "framebuf: eCos application has failed to connect to host-side framebuf program"
+ synth::report_error " : graphical display is not operational"
+ } elseif { $framebuf::SYNTH_FB_ON == $reqcode } {
+ send_framebuf_request $devid $framebuf::SYNTH_FB_AUX_ON 0 0
+ } elseif { $framebuf::SYNTH_FB_OFF == $reqcode } {
+ send_framebuf_request $devid $framebuf::SYNTH_FB_AUX_OFF 0 0
+ } else {
+ synth::report_error "framebuf: got invalid request $reqcode from eCos application"
+ }
+ }
+
+ proc mapped { devid } {
+ DEBUG 1 $devid "frame has been mapped\n"
+ bind $framebuf::settings($devid,frame) <Map> ""
+ send_framebuf_request $devid $framebuf::SYNTH_FB_AUX_MAPPED [winfo id $framebuf::settings($devid,frame)] 0
+ # This should not be necessary, but sometimes there are problems
+ # with an initial XPutImage() not actually drawing anything.
+ after 250 framebuf::send_framebuf_request $devid $framebuf::SYNTH_FB_AUX_REDRAW 0 0
+ }
+
+ proc instantiate { devid name data } {
+
+ DEBUG 1 $devid "instantiate devid $devid, name $name, data $data\n"
+
+ if { ! $synth::flag_gui } {
+ # If we are not running under a windowing system we cannot
+ # show the framebuffer data. Just stuck to the default
+ # memory framebuffer.
+ return ""
+ }
+
+ if { [info exists framebuf::settings($name,id)] } {
+ synth::report_error "Framebuf device: attempt to create several $name instances\n"
+ return ""
+ }
+
+ # Check that the framebuf program can actually handle this display.
+ set depth [winfo depth .]
+ if { (24 != $depth) && (32 != $depth) } {
+ synth::report_error "Framebuf device: requires 24bpp or 32bpp X display\n"
+ return ""
+ }
+ set visual [winfo visual .]
+ if { ![string equal "truecolor" $visual] && ![string equal "directcolor" $visual] } {
+ synth::report_error "Framebuf device: requires a truecolor or directcolor X display\n"
+ return ""
+ }
+
+ # Data is a set of comma-separated parameters, mostly numeric,
+ # describing the desired framebuffer device. The first number
+ # is a protocol number as per ../src/protocol.h
+ set junk ""
+ set protocol 0
+ if { ! [regexp -- {^(\d*),.*} $data junk protocol] } {
+ synth::report_error "Framebuf device: missing protocol number for device $name\n"
+ return ""
+ }
+ if { $protocol != 1 } {
+ synth::report_error "Framebuf device: protocol mismatch\n \
+ Target uses protocol version $protocol\n \
+ Host is only up to version 1\n"
+ return ""
+ }
+ set framebuf::settings($devid,name) $name
+ set result [regexp -- {^(\d*),(\d*),(\d*),(\d*),(\d*),(\d*),(\d*),(\d*),(\d*),(\d*),(.*)$} $data junk protocol \
+ framebuf::settings($devid,fbid) \
+ framebuf::settings($devid,depth) \
+ framebuf::settings($devid,little_endian) \
+ framebuf::settings($devid,width) \
+ framebuf::settings($devid,height) \
+ framebuf::settings($devid,viewport_width) \
+ framebuf::settings($devid,viewport_height) \
+ framebuf::settings($devid,stride) \
+ framebuf::settings($devid,number_pages) \
+ framebuf::settings($devid,format)]
+ if { ! $result } {
+ synth::report_error "Framebuf device: invalid parameter string $data\n"
+ return ""
+ }
+ set framebuf::settings($devid,magnification) $framebuf::settings(fb$framebuf::settings($devid,fbid),magnification)
+
+ # Spawn the framebuf process. Its stdin and stdout are pipes
+ # connected to ecosynth. Its stderr is redirected to the current
+ # tty for debugging/diagnostics.
+ set cmd "|$framebuf::framebuf_executable "
+ append cmd "$framebuf::settings($devid,fbid) "
+ append cmd "$framebuf::settings($devid,depth) "
+ append cmd "$framebuf::settings($devid,little_endian) "
+ append cmd "$framebuf::settings($devid,width) "
+ append cmd "$framebuf::settings($devid,height) "
+ append cmd "$framebuf::settings($devid,viewport_width) "
+ append cmd "$framebuf::settings($devid,viewport_height) "
+ append cmd "$framebuf::settings($devid,stride) "
+ append cmd "$framebuf::settings($devid,number_pages) "
+ append cmd "$framebuf::settings($devid,format) "
+ append cmd "$framebuf::settings($devid,magnification) "
+
+ DEBUG 1 $devid "spawning framebuf program : $cmd\n"
+ if { [catch { set framebuf::settings($devid,fd) [open "$cmd 2>/dev/tty" "w+"] } message] } {
+ synth::report_error "Failed to spawn framebuf process for device $name\n $message"
+ return ""
+ }
+ set framebuf::settings($devid,reply) 0
+ set framebuf::settings($devid,got_reply) 0
+ fconfigure $framebuf::settings($devid,fd) -translation binary -blocking 0
+ fileevent $framebuf::settings($devid,fd) readable "framebuf::handle_framebuf_reply $devid"
+
+ # Now wait for the framebuf device to initialize. It should send back a single byte,
+ # 0 for failure followed by an error string, 1 for success followed by a string with
+ # the connectivity information.
+ DEBUG 1 $devid "waiting for initial reply from framebuf program\n"
+ vwait framebuf::settings($devid,reply)
+ if { "" == $framebuf::settings($devid,reply) } {
+ synth::report_error "framebuf process for device $name exited unexpectedly.\n"
+ catch { close $framebuf::settings($devid,fd) }
+ return ""
+ }
+ set code [string index $framebuf::settings($devid,reply) 0]
+ if { "0" == $code } {
+ synth::report_error "framebuf process was unable to initialize eCos device $name\n $message"
+ catch { close $framebuf::settings($devid,fd) }
+ return ""
+ }
+ if { "1" != $code } {
+ synth::report_error "Unexpected response $code from framebuf process for eCos device $name\n"
+ catch { close $framebuf::settings($devid,fd) }
+ return ""
+ }
+ set framebuf::settings($devid,connectivity) [string range $framebuf::settings($devid,reply) 1 end]
+
+ # Now the the framebuf program is up and running, create the frame.
+ # Doing this earlier could result in spurious frames appearing if
+ # the framebuf program failed, and also causes timing problems
+ # between the <Map> binding and the framebuf program being ready.
+ DEBUG 1 $devid "invoking create_frame procedure $framebuf::create_frame_proc\n"
+ set framebuf::settings($devid,frame) \
+ [$framebuf::create_frame_proc \
+ $framebuf::settings($devid,fbid) \
+ $framebuf::settings($devid,magnification) \
+ $framebuf::settings($devid,depth) \
+ $framebuf::settings($devid,little_endian) \
+ $framebuf::settings($devid,width) \
+ $framebuf::settings($devid,height) \
+ $framebuf::settings($devid,viewport_width) \
+ $framebuf::settings($devid,viewport_height) \
+ $framebuf::settings($devid,stride) \
+ $framebuf::settings($devid,number_pages) \
+ $framebuf::settings($devid,format) \
+ ]
+ DEBUG 1 $devid "frame is $framebuf::settings($devid,frame)\n"
+ if { "" == $framebuf::settings($devid,frame) } {
+ return ""
+ }
+
+ # Everything appears to be up and running. When the frame becomes visible,
+ # inform the framebuf program.
+ if { [winfo ismapped $framebuf::settings($devid,frame)] } {
+ framebuf::mapped $devid
+ } else {
+ bind $framebuf::settings($devid,frame) <Map> "framebuf::mapped $devid"
+ }
+ DEBUG 1 $devid "instantiate succeeded, connectivity $framebuf::settings($devid,connectivity)\n"
+
+ return framebuf::handle_ecos_request
+ }
+}
+
+if { $framebuf::init_ok } {
+ return framebuf::instantiate
+} else {
+ synth::report "Framebuffer cannot be instantiated, initialization failed.\n"
+ return ""
+}
diff --git a/ecos/packages/devs/framebuf/synth/current/host/framebuf.tdf b/ecos/packages/devs/framebuf/synth/current/host/framebuf.tdf
new file mode 100644
index 0000000..1ed1b83
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/framebuf.tdf
@@ -0,0 +1,37 @@
+# Target definition file fragment for framebuffer devices.
+#
+# The main support available is for controlled creation
+# of the Tk frames in which the eCos framebuffer data will
+# be displayed. By default the main framebuf.tcl script will
+# create the
+
+proc my_framebuf_create_frame { id magnification depth little_endian width height viewport_width viewport_height stride number_pages format} {
+
+ toplevel .ecosfb$id
+ wm title .ecosfb$id "eCos FB[set id]: $width*$height*\#depth"
+ wm iconbitmap .ecosfb$id $framebuf::image_framebuf_icon
+ wm iconmask .ecosfb$id $framebuf::image_framebufmask_icon
+ wm protocol .ecosfb$id ""
+
+ frame .ecosfb$id.frame -container 1 -height [expr $magnification * $viewport_height] -width [expr $magnification * $viewport_width]
+ pack .ecosfb$id.frame -side top -expand 0
+
+ return .ecosfb$id.frame
+}
+
+synth_device framebuf {
+
+ # Customize how the eCos framebuffer appears on the X display.
+ # The argument should be a function which takes a long list of
+ # arguments, as above, and returns a Tk frame id. Spawning the
+ # C program is still the responsibility of the main framebuf.tcl
+ # script.
+ create_frame_proc my_framebuf_create_frame
+
+ # Optional magnification for all four permitted framebuffer
+ # devices. Magnification can be 1, 2, 3 or 4
+ # fb0_magnification 2
+ # fb1_magnification 4
+ # fb2_magnification 3
+ # fb4_magnification 1
+}
diff --git a/ecos/packages/devs/framebuf/synth/current/host/framebuf_icon.xbm b/ecos/packages/devs/framebuf/synth/current/host/framebuf_icon.xbm
new file mode 100644
index 0000000..91a79ec
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/framebuf_icon.xbm
@@ -0,0 +1,10 @@
+#define framebuf_icon_width 40
+#define framebuf_icon_height 16
+static unsigned char framebuf_icon_bits[] = {
+ 0xfc, 0xff, 0xff, 0xff, 0x3f, 0x06, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00,
+ 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x80, 0xc1, 0x54, 0xba, 0xe2,
+ 0x86, 0x21, 0x55, 0x92, 0x22, 0x8a, 0x21, 0xd4, 0x92, 0x22, 0x8a, 0xc1,
+ 0xd4, 0x92, 0xe3, 0x86, 0x01, 0x49, 0x93, 0x22, 0x8a, 0x01, 0x49, 0x93,
+ 0x22, 0x8a, 0x21, 0x49, 0x92, 0x22, 0x8a, 0xc1, 0x48, 0x92, 0x22, 0x86,
+ 0x01, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0xc0, 0x06, 0x00,
+ 0x00, 0x00, 0x60, 0xfc, 0xff, 0xff, 0xff, 0x3f};
diff --git a/ecos/packages/devs/framebuf/synth/current/host/framebuf_iconmask.xbm b/ecos/packages/devs/framebuf/synth/current/host/framebuf_iconmask.xbm
new file mode 100644
index 0000000..4c143a2
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/host/framebuf_iconmask.xbm
@@ -0,0 +1,10 @@
+#define ecosiconmask_width 40
+#define ecosiconmask_height 16
+static unsigned char ecosiconmask_bits[] = {
+ 0xfc, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff,
+ 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0x3f};
diff --git a/ecos/packages/devs/framebuf/synth/current/misc/example.c b/ecos/packages/devs/framebuf/synth/current/misc/example.c
new file mode 100644
index 0000000..6590284
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/misc/example.c
@@ -0,0 +1,377 @@
+//==========================================================================
+//
+// example.c
+//
+// Demonstration of the synthetic target framebuffer capabilities
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//###DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2008-10-06
+//
+//###DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/io/framebuf.h>
+#include <cyg/kernel/kapi.h>
+#include <string.h>
+#include <stdio.h>
+
+#define BLACK colours[0x00]
+#define BLUE colours[0x01]
+#define GREEN colours[0x02]
+#define CYAN colours[0x03]
+#define RED colours[0x04]
+#define MAGENTA colours[0x05]
+#define BROWN colours[0x06]
+#define LIGHTGREY colours[0x07]
+#define DARKGREY colours[0x08]
+#define LIGHTBLUE colours[0x09]
+#define LIGHTGREEN colours[0x0A]
+#define LIGHTCYAN colours[0x0B]
+#define LIGHTRED colours[0x0C]
+#define LIGHTMAGENTA colours[0x0D]
+#define YELLOW colours[0x0E]
+#define WHITE colours[0x0F]
+
+// ----------------------------------------------------------------------------
+// FB0. 320x240 32bpp true 0888. Just draw a simple image as per the fb.c
+// example and return to main().
+
+static void
+fb0_thread(cyg_addrword_t arg)
+{
+#define FRAMEBUF cyg_synth_fb0
+ static cyg_ucount32 colours[16];
+ cyg_ucount16 block_width;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ colours[i] = cyg_fb_make_colour(&FRAMEBUF,
+ cyg_fb_palette_vga[i + i + i], cyg_fb_palette_vga[i + i + i + 1],cyg_fb_palette_vga[i + i + i + 2]);
+ }
+
+ cyg_fb_on(&FRAMEBUF);
+ // A white background
+ cyg_fb_fill_block(&FRAMEBUF, 0, 0, FRAMEBUF.fb_width, FRAMEBUF.fb_height, WHITE);
+ // A black block in the middle, 25 pixels in.
+ cyg_fb_fill_block(&FRAMEBUF, 25, 25, FRAMEBUF.fb_width - 50, FRAMEBUF.fb_height - 50, BLACK);
+
+ // Four diagonal lines in the corners. Red in the top left, blue in the top right,
+ // green in the bottom left, and yellow in the bottom right.
+ for (i = 0; i < 25; i++) {
+ cyg_fb_write_pixel(&FRAMEBUF, i, i, RED);
+ cyg_fb_write_pixel(&FRAMEBUF, (FRAMEBUF.fb_width - 1) - i, i, BLUE);
+ cyg_fb_write_pixel(&FRAMEBUF, i, (FRAMEBUF.fb_height - 1) - i, GREEN);
+ cyg_fb_write_pixel(&FRAMEBUF, (FRAMEBUF.fb_width - 1) - i, (FRAMEBUF.fb_height - 1) - i, YELLOW);
+ }
+
+ // Horizontal and vertical lines. Cyan at the top, magenta on the bottom,
+ // brown on the left, lightgrey on the right.
+ cyg_fb_write_hline(&FRAMEBUF, 25, 12, FRAMEBUF.fb_width - 50, CYAN);
+ cyg_fb_write_hline(&FRAMEBUF, 25, FRAMEBUF.fb_height - 12, FRAMEBUF.fb_width - 50, MAGENTA);
+ cyg_fb_write_vline(&FRAMEBUF, 12, 25, FRAMEBUF.fb_height - 50, BROWN);
+ cyg_fb_write_vline(&FRAMEBUF, FRAMEBUF.fb_width - 12, 25, FRAMEBUF.fb_height - 50, LIGHTGREY);
+
+ // And 14 vertical stripes, from blue to yellow, in the centre of the box.
+ block_width = (FRAMEBUF.fb_width - 100) / 14;
+ for (i = 1; i <= 14; i++) {
+ cyg_fb_fill_block(&FRAMEBUF, 50 + ((i - 1) * block_width), 50, block_width, FRAMEBUF.fb_height - 100, colours[i]);
+ }
+
+ cyg_fb_synch(&FRAMEBUF, CYG_FB_UPDATE_NOW);
+#undef FRAMEBUF
+}
+
+// ----------------------------------------------------------------------------
+// FB1, 320x240 15bpp, true 555, two pages. Draw a set of horizontal lines
+// in one page, vertical lines in the other, and flip between them at
+// one second intervals.
+
+static void
+fb1_thread(cyg_addrword_t arg)
+{
+#define FRAMEBUF cyg_synth_fb1
+ static cyg_ucount32 colours[16];
+ struct cyg_fb_ioctl_page_flip page_flip;
+ size_t len;
+ int result;
+ int i;
+
+ cyg_fb_on(&FRAMEBUF);
+ for (i = 0; i < 16; i++) {
+ colours[i] = cyg_fb_make_colour(&FRAMEBUF,
+ cyg_fb_palette_vga[i + i + i], cyg_fb_palette_vga[i + i + i + 1],cyg_fb_palette_vga[i + i + i + 2]);
+ }
+
+ // Draw the horizontal stripes on page 0.
+ page_flip.fbpf_visible_page = 0;
+ page_flip.fbpf_drawable_page = 1;
+ page_flip.fbpf_when = CYG_FB_UPDATE_NOW;
+ len = sizeof(page_flip);
+ result = cyg_fb_ioctl(&FRAMEBUF, CYG_FB_IOCTL_PAGE_FLIPPING_SET_PAGES, &page_flip, &len);
+ if (result != 0) {
+ fprintf(stderr, "fb1_thread: initial page flip failed.\n");
+ }
+ // 16 colours, 240 rows -> 15 rows/colour
+ for (i = 0; i < 16; i++) {
+ cyg_fb_fill_block(&FRAMEBUF, 0, 15 * i, 320, 15, colours[i]);
+ }
+
+ // Show the horizontal stripes and draw the vertical stripes on page 0.
+ page_flip.fbpf_visible_page = 1;
+ page_flip.fbpf_drawable_page = 0;
+ page_flip.fbpf_when = CYG_FB_UPDATE_NOW;
+ len = sizeof(page_flip);
+ result = cyg_fb_ioctl(&FRAMEBUF, CYG_FB_IOCTL_PAGE_FLIPPING_SET_PAGES, &page_flip, &len);
+ if (result != 0) {
+ fprintf(stderr, "fb1_thread: second page flip failed.\n");
+ }
+ // 16 colours, 320 columns -> 20 columns/colour
+ for (i = 0; i < 16; i++) {
+ cyg_fb_fill_block(&FRAMEBUF, 20 * i, 0, 20, 240, colours[i]);
+ }
+
+ for ( i = 0; ; i = 1 - i) {
+ page_flip.fbpf_visible_page = i;
+ page_flip.fbpf_drawable_page = 1 - i;
+ page_flip.fbpf_when = CYG_FB_UPDATE_NOW;
+ len = sizeof(page_flip);
+ result = cyg_fb_ioctl(&FRAMEBUF, CYG_FB_IOCTL_PAGE_FLIPPING_SET_PAGES, &page_flip, &len);
+ if (result != 0) {
+ fprintf(stderr, "fb1_thread: ongoing page flip failed.\n");
+ }
+ cyg_thread_delay(100);
+ }
+#undef FRAMEBUF
+}
+
+// ----------------------------------------------------------------------------
+// FB2, 320x240 15bpp, true 565, with a 160x120 viewport. Draw a simple image
+// as per the fbmacro.c example. Then move around within the viewport in a
+// clockwise direction at 110ms intervals.
+
+static void
+fb2_thread(cyg_addrword_t arg)
+{
+#define FRAMEBUF fb2
+#define WIDTH 320
+#define HEIGHT 240
+
+ static cyg_ucount32 colours[16];
+ cyg_ucount16 block_width;
+ int i, j;
+ int x = 0, y = 0;
+ CYG_FB_PIXEL0_VAR(FRAMEBUF);
+ CYG_FB_PIXEL1_VAR(FRAMEBUF);
+ cyg_fb_ioctl_viewport viewport;
+ size_t len;
+
+ CYG_FB_ON(FRAMEBUF);
+ for (i = 0; i < 16; i++) {
+ colours[i] = CYG_FB_MAKE_COLOUR(FRAMEBUF,
+ cyg_fb_palette_vga[i + i + i], cyg_fb_palette_vga[i + i + i + 1],cyg_fb_palette_vga[i + i + i + 2]);
+ }
+ // A white background
+ CYG_FB_FILL_BLOCK(FRAMEBUF, 0, 0, WIDTH, HEIGHT, WHITE);
+ // A black block in the middle, 25 pixels in.
+ CYG_FB_FILL_BLOCK(FRAMEBUF, 32, 32, WIDTH - 64, HEIGHT - 64, BLACK);
+
+ // Four diagonal lines in the corners. Red in the top left, blue in the top right,
+ // green in the bottom left, and yellow in the bottom right.
+ for (i = 0; i < 32; i++) {
+ CYG_FB_WRITE_PIXEL(FRAMEBUF, i, i, RED);
+ CYG_FB_WRITE_PIXEL(FRAMEBUF, (WIDTH - 1) - i, i, BLUE);
+ CYG_FB_WRITE_PIXEL(FRAMEBUF, i, (HEIGHT - 1) - i, GREEN);
+ CYG_FB_WRITE_PIXEL(FRAMEBUF, (WIDTH - 1) - i, (HEIGHT - 1) - i, YELLOW);
+ }
+
+ // Horizontal and vertical lines. Cyan at the top, magenta on the bottom,
+ // brown on the left, lightgrey on the right.
+ CYG_FB_WRITE_HLINE(FRAMEBUF, 32, 16, WIDTH - 64, CYAN);
+ CYG_FB_WRITE_HLINE(FRAMEBUF, 32, HEIGHT - 16, WIDTH - 64, MAGENTA);
+ CYG_FB_WRITE_VLINE(FRAMEBUF, 16, 32, HEIGHT - 64, BROWN);
+ CYG_FB_WRITE_VLINE(FRAMEBUF, WIDTH - 16, 32, HEIGHT - 64, LIGHTGREY);
+
+ // Top left, diagonal lines away from 0,0 with increasing spacing horizontally
+ for (i = 0; i < 16; i++) {
+ CYG_FB_PIXEL0_SET(FRAMEBUF, i + 16, i);
+ for (j = 0; j < 16; j++) {
+ CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]);
+ CYG_FB_PIXEL0_ADDX(FRAMEBUF, j);
+ }
+ }
+
+ // Top right, diagonal lines away from the corner, with increasing spacing horizontally
+ for (i = 0; i < 16; i++) {
+ CYG_FB_PIXEL0_SET(FRAMEBUF, WIDTH - (i + 16), i);
+ for (j = 0; j < 16; j++) {
+ CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]);
+ CYG_FB_PIXEL0_ADDX(FRAMEBUF, -1 * j);
+ }
+ }
+
+ // Top left, diagonal lines away from the corner, with increasing spacing vertically
+ for (i = 0; i < 16; i++) {
+ CYG_FB_PIXEL0_SET(FRAMEBUF, i, i + 16);
+ for (j = 0; j < 16; j++) {
+ CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]);
+ CYG_FB_PIXEL0_ADDY(FRAMEBUF, j);
+ }
+ }
+ // Bottom left, diagonal lines away from the corner, with increasing spacing vertically
+ for (i = 0; i < 16; i++) {
+ CYG_FB_PIXEL0_SET(FRAMEBUF, i, HEIGHT - (i + 16));
+ for (j = 0; j < 16; j++) {
+ CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]);
+ CYG_FB_PIXEL0_ADDY(FRAMEBUF, -1 * j);
+ }
+ }
+
+ // Thin vertical bars in the top-middle of the screen, between the hline and the box.
+ // Starting in the center and moving out with increasing spacing.
+ for (j = 0; j < 8; j++) {
+ CYG_FB_PIXEL0_SET(FRAMEBUF, (WIDTH / 2) - 2, 20 + j);
+ CYG_FB_PIXEL0_GET(FRAMEBUF, x, y);
+ CYG_FB_PIXEL1_SET(FRAMEBUF, x + 3, y);
+ for (i = 0; i < 16; i++) {
+ CYG_FB_PIXEL0_ADDX(FRAMEBUF, -1 * i);
+ CYG_FB_PIXEL1_ADDX(FRAMEBUF, i);
+ CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]);
+ CYG_FB_PIXEL1_WRITE(FRAMEBUF, colours[i]);
+ }
+ }
+
+ block_width = (WIDTH - 100) / 14;
+ for (i = 1; i <= 14; i++) {
+ CYG_FB_FILL_BLOCK(FRAMEBUF, 50 + ((i - 1) * block_width), 50, block_width, HEIGHT - 100, colours[i]);
+ }
+
+
+ for ( ; ; ) {
+ for (x = 0; x <= 160; x += 5) {
+ viewport.fbvp_x = x;
+ viewport.fbvp_y = 0;
+ viewport.fbvp_when = CYG_FB_UPDATE_NOW;
+ len = sizeof(viewport);
+ CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len);
+ cyg_thread_delay(11);
+ }
+ for (y = 0; y < 120; y += 5) {
+ viewport.fbvp_x = 160;
+ viewport.fbvp_y = y;
+ viewport.fbvp_when = CYG_FB_UPDATE_NOW;
+ len = sizeof(viewport);
+ CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len);
+ cyg_thread_delay(11);
+ }
+ for (x = 160; x >= 0; x -= 5) {
+ viewport.fbvp_x = x;
+ viewport.fbvp_y = 120;
+ viewport.fbvp_when = CYG_FB_UPDATE_NOW;
+ len = sizeof(viewport);
+ CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len);
+ cyg_thread_delay(11);
+ }
+ for (y = 120; y >= 0; y -= 5) {
+ viewport.fbvp_x = 0;
+ viewport.fbvp_y = y;
+ viewport.fbvp_when = CYG_FB_UPDATE_NOW;
+ len = sizeof(viewport);
+ CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len);
+ cyg_thread_delay(11);
+ }
+ }
+#undef FRAMEBUF
+#undef WIDTH
+#undef HEIGHT
+}
+
+// ----------------------------------------------------------------------------
+// FB3, 320x240 8bpp, paletted 888. Draw a series of vertical stripes, 5 pixels
+// wide, and rotate through the palette at 210ms intervals.
+
+static void
+fb3_thread(cyg_addrword_t arg)
+{
+#define FRAMEBUF fb3
+ static cyg_uint8 palette[(128 +16) * 3];
+ int i;
+
+ CYG_FB_ON(FRAMEBUF);
+
+ // Read in the first 128 palette entries, and copy the first 16
+ // entries to give a wrap-around. After 128 the palette gets less
+ // interesting.
+ CYG_FB_READ_PALETTE(FRAMEBUF, 0, 128, palette);
+ memcpy(&(palette[128 * 3]), palette, 16 * 3);
+
+ for (i = 0; i < 32; i++) {
+ CYG_FB_FILL_BLOCK(FRAMEBUF, 10 * i, 0, 10, 240, i);
+ }
+
+ for ( i = 0; ; i = (i + 1) % 128 ) {
+ cyg_thread_delay(21);
+ CYG_FB_WRITE_PALETTE(FRAMEBUF, 0, 64, &(palette[i * 3]), CYG_FB_UPDATE_NOW);
+ }
+#undef FRAMEBUF
+}
+
+// ----------------------------------------------------------------------------
+// main(). Start up separate threads for FB1 and FB2, run the FB0 code since
+// it just does some drawing and finishes, then run the FB3 code.
+static cyg_thread fb1_thread_data;
+static cyg_handle_t fb1_thread_handle;
+static unsigned char fb1_thread_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+static cyg_thread fb2_thread_data;
+static cyg_handle_t fb2_thread_handle;
+static unsigned char fb2_thread_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+
+int
+main(int argc, char** argv)
+{
+ cyg_thread_create(10, &fb1_thread, 0, "fb1", fb1_thread_stack, CYGNUM_HAL_STACK_SIZE_TYPICAL, &fb1_thread_handle, &fb1_thread_data);
+ cyg_thread_create(10, &fb2_thread, 0, "fb2", fb2_thread_stack, CYGNUM_HAL_STACK_SIZE_TYPICAL, &fb2_thread_handle, &fb2_thread_data);
+ cyg_thread_resume(fb1_thread_handle);
+ cyg_thread_resume(fb2_thread_handle);
+ fb0_thread(0);
+ fb3_thread(0);
+ return 0;
+}
+
diff --git a/ecos/packages/devs/framebuf/synth/current/misc/example.ecm b/ecos/packages/devs/framebuf/synth/current/misc/example.ecm
new file mode 100644
index 0000000..1581343
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/misc/example.ecm
@@ -0,0 +1,85 @@
+cdl_configuration eCos {
+ package CYGPKG_IO_FRAMEBUF ;
+};
+
+cdl_component CYGPKG_DEVS_FRAMEBUF_SYNTH_FB0 {
+ user_value 1
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB0_WIDTH {
+ user_value 320
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB0_HEIGHT {
+ user_value 240
+};
+
+cdl_option CYGDAT_DEVS_FRAMEBUF_SYNTH_FB0_FORMAT {
+ user_value 32BPP_TRUE_0888
+};
+
+cdl_component CYGPKG_DEVS_FRAMEBUF_SYNTH_FB1 {
+ user_value 1
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB1_WIDTH {
+ user_value 320
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB1_HEIGHT {
+ user_value 240
+};
+
+cdl_option CYGDAT_DEVS_FRAMEBUF_SYNTH_FB1_FORMAT {
+ user_value 16BPP_TRUE_555
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB1_PAGE_FLIPPING {
+ user_value 1 2
+};
+
+cdl_component CYGPKG_DEVS_FRAMEBUF_SYNTH_FB2 {
+ user_value 1
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB2_WIDTH {
+ user_value 320
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB2_HEIGHT {
+ user_value 240
+};
+
+cdl_option CYGDAT_DEVS_FRAMEBUF_SYNTH_FB2_FORMAT {
+ user_value 16BPP_TRUE_565
+};
+
+cdl_component CYGIMP_DEVS_FRAMEBUF_SYNTH_FB2_VIEWPORT {
+ user_value 1
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB2_VIEWPORT_WIDTH {
+ user_value 160
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB2_VIEWPORT_HEIGHT {
+ user_value 120
+};
+
+cdl_component CYGPKG_DEVS_FRAMEBUF_SYNTH_FB3 {
+ user_value 1
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB3_WIDTH {
+ user_value 320
+};
+
+cdl_option CYGNUM_DEVS_FRAMEBUF_SYNTH_FB3_HEIGHT {
+ user_value 240
+};
+
+cdl_option CYGDAT_DEVS_FRAMEBUF_SYNTH_FB3_FORMAT {
+ user_value 8BPP_PAL888
+};
+
+
diff --git a/ecos/packages/devs/framebuf/synth/current/misc/example.tdf b/ecos/packages/devs/framebuf/synth/current/misc/example.tdf
new file mode 100644
index 0000000..5cae70a
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/misc/example.tdf
@@ -0,0 +1,42 @@
+# An example framebuffer create function. This is for use with the
+# synthetic target framebuffer example program which uses four
+# devices:
+#
+# fb0: 320x240 32bpp true 0888
+# fb1: 320x240 16bpp true 555 with two pages
+# fb2: 320x240 16bpp true 565 with a viewport of 160x120
+# fb3: 320x240 8bpp pal 888
+#
+# These are all created in a single toplevel .synth_framebufs, one above the other,
+# with labels in between.
+proc my_framebuf_create_frame { fb_id magnification depth little_endian width height viewport_width viewport_height stride number_pages format } {
+ if { ![winfo exists .synth_framebufs] } {
+ toplevel .synth_framebufs
+ wm title .synth_framebufs "Synthetic target framebuffers"
+ wm protocol .synth_framebufs WM_DELETE_WINDOW {}
+ wm geometry .synth_framebufs +1000+0
+
+ label .synth_framebufs.fb0_label -text "FB0 320x240 32bpp true 0888"
+ frame .synth_framebufs.fb0 -container 1 -height 240 -width 320
+ label .synth_framebufs.fb1_label -text "FB1 320x240 16bpp true 0555 two pages"
+ frame .synth_framebufs.fb1 -container 1 -height 240 -width 320
+ label .synth_framebufs.fb2_label -text "FB2 320x240 16bpp true 0565\nviewport 160x120 magnified *2"
+ frame .synth_framebufs.fb2 -container 1 -height 240 -width 320
+ label .synth_framebufs.fb3_label -text "FB3 320x240 8bpp paletted 888"
+ frame .synth_framebufs.fb3 -container 1 -height 240 -width 320
+ pack .synth_framebufs.fb0_label -side top -expand 1 -anchor w -fill x
+ pack .synth_framebufs.fb0 -side top -expand 0 -anchor w
+ pack .synth_framebufs.fb1_label -side top -expand 1 -anchor w -fill x
+ pack .synth_framebufs.fb1 -side top -expand 0 -anchor w
+ pack .synth_framebufs.fb2_label -side top -expand 1 -anchor w -fill x
+ pack .synth_framebufs.fb2 -side top -expand 0 -anchor w
+ pack .synth_framebufs.fb3_label -side top -expand 1 -anchor w -fill x
+ pack .synth_framebufs.fb3 -side top -expand 0 -anchor w
+ }
+ return .synth_framebufs.fb$fb_id
+}
+
+synth_device framebuf {
+ fb2_magnification 2
+ create_frame_proc my_framebuf_create_frame
+}
diff --git a/ecos/packages/devs/framebuf/synth/current/src/gen_synthfb.tcl b/ecos/packages/devs/framebuf/synth/current/src/gen_synthfb.tcl
new file mode 100644
index 0000000..e297b4b
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/src/gen_synthfb.tcl
@@ -0,0 +1,349 @@
+#!/usr/bin/env tclsh
+
+#===============================================================================
+#
+# gen_synthfb.tcl
+#
+# Generate header files for all enabled synthetic target framebuffer devices.
+#
+#===============================================================================
+# ####ECOSGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2008 Free Software Foundation, Inc.
+#
+# eCos is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 or (at your option) any later
+# version.
+#
+# eCos is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with eCos; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered by
+# the GNU General Public License. However the source code for this file
+# must still be made available in accordance with section (3) of the GNU
+# General Public License v2.
+#
+# This exception does not invalidate any other reasons why a work based
+# on this file might be covered by the GNU General Public License.
+# -------------------------------------------
+# ####ECOSGPLCOPYRIGHTEND####
+#===============================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Date: 2005-10-28
+#
+# This script is invoked via a custom make rule to generate files
+# <cyg/io/framebufs/synth_fb.h> and synth_fbs.c
+#
+#####DESCRIPTIONEND####
+#===============================================================================
+
+proc do_it { prefix } {
+ set pkgconf_file [file join $prefix "include/pkgconf/devs_framebuf_synth.h"]
+ if { ! [file exists $pkgconf_file] } {
+ puts stderr "gen_synthfb.tcl: missing configuration header $pkgconf_file"
+ exit 1
+ }
+ set fd [open $pkgconf_file "r"]
+ set data [read $fd]
+ close $fd
+
+ array set defines [list]
+ foreach line [split $data "\n"] {
+ if { [regexp -- {^\#define[[:space:]]*([a-zA-Z_][a-zA-Z0-9_]*)[[:space:]]+([^[:space:]]+)$} $line junk symbol value] } {
+ set defines($symbol) $value
+ }
+ }
+
+ set data \
+ "/*
+ * File <cyg/io/framebufs/synth_fb.h>
+ *
+ * This is a generated file - do not edit!
+ * It should not be \#include'd directly. Instead use <cyg/io/framebuf.h>
+ */
+
+#include <cyg/io/framebuf.inl>
+
+"
+
+ for { set fb 0 } { $fb < 4 } { incr fb } {
+ if { ! [info exists defines(CYGPKG_DEVS_FRAMEBUF_SYNTH_FB[set fb])] } {
+ continue
+ }
+
+ set width $defines(CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set fb]_WIDTH)
+ set height $defines(CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set fb]_HEIGHT)
+ set flags0 "(CYG_FB_FLAGS0_LINEAR_FRAMEBUFFER | \\\n CYG_FB_FLAGS0_DOUBLE_BUFFER | \\\n"
+ if { [info exists defines(CYGIMP_DEVS_FRAMEBUF_SYNTH_FB[set fb]_VIEWPORT) ] } {
+ set viewport_width $defines(CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set fb]_VIEWPORT_WIDTH)
+ set viewport_height $defines(CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set fb]_VIEWPORT_HEIGHT)
+ append flags0 " CYG_FB_FLAGS0_VIEWPORT | \\\n"
+ } else {
+ set viewport_width $width
+ set viewport_height $height
+ }
+ if { [info exists defines(CYGNUM_DEVS_FRAMEBUF_SYNTH_FB[set fb]_PAGE_FLIPPING)] } {
+ append flags0 " CYG_FB_FLAGS0_PAGE_FLIPPING | \\\n"
+ }
+ set paletted 1
+ switch -- $defines(CYGDAT_DEVS_FRAMEBUF_SYNTH_FB[set fb]_FORMAT) {
+ 1BPP_BE_PAL888 {
+ set format "CYG_FB_FORMAT_1BPP_PAL888"
+ set suffix "1BE"
+ set depth 1
+ set stride [expr ($width + 7) >> 3]
+ }
+ 1BPP_LE_PAL888 {
+ append flags0 " CYG_FB_FLAGS0_LE | \\\n"
+ set format "CYG_FB_FORMAT_1BPP_PAL888"
+ set suffix "1LE"
+ set depth 1
+ set stride [expr ($width + 7) >> 3]
+ }
+ 2BPP_BE_PAL888 {
+ set format "CYG_FB_FORMAT_2BPP_PAL888"
+ set suffix "2BE"
+ set depth 2
+ set stride [expr ($width + 3) >> 2]
+ }
+ 2BPP_LE_PAL888 {
+ append flags0 " CYG_FB_FLAGS0_LE | \\\n"
+ set format "CYG_FB_FORMAT_2BPP_PAL888"
+ set suffix "2LE"
+ set depth 2
+ set stride [expr ($width + 3) >> 2]
+ }
+ 4BPP_BE_PAL888 {
+ set format "CYG_FB_FORMAT_4BPP_PAL888"
+ set suffix "4BE"
+ set depth 4
+ set stride [expr ($width + 1) >> 1]
+ }
+ 4BPP_LE_PAL888 {
+ append flags0 " CYG_FB_FLAGS0_LE | \\\n"
+ set format "CYG_FB_FORMAT_4BPP_PAL888"
+ set suffix "4LE"
+ set depth 4
+ set stride [expr ($width + 1) >> 1]
+ }
+ 8BPP_PAL888 {
+ set format "CYG_FB_FORMAT_8BPP_PAL888"
+ set suffix "8"
+ set depth 8
+ set stride $width
+ }
+ 8BPP_TRUE_332 {
+ set format "CYG_FB_FORMAT_8BPP_TRUE_332"
+ set suffix "8"
+ set paletted 0
+ set make_colour_fn "cyg_fb_dev_make_colour_8bpp_true_332"
+ set break_colour_fn "cyg_fb_dev_break_colour_8bpp_true_332"
+ set make_colour_macro "CYG_FB_MAKE_COLOUR_8BPP_TRUE_332"
+ set break_colour_macro "CYG_FB_BREAK_COLOUR_8BPP_TRUE_332"
+ set depth 8
+ set stride $width
+ }
+ 16BPP_TRUE_565 {
+ set format "CYG_FB_FORMAT_16BPP_TRUE_565"
+ set suffix "16"
+ set paletted 0
+ set make_colour_fn "cyg_fb_dev_make_colour_16bpp_true_565"
+ set break_colour_fn "cyg_fb_dev_break_colour_16bpp_true_565"
+ set make_colour_macro "CYG_FB_MAKE_COLOUR_16BPP_TRUE_565"
+ set break_colour_macro "CYG_FB_BREAK_COLOUR_16BPP_TRUE_565"
+ set depth 16
+ set stride [expr $width * 2]
+ }
+ 16BPP_TRUE_555 {
+ set format "CYG_FB_FORMAT_16BPP_TRUE_555"
+ set suffix "16"
+ set paletted 0
+ set make_colour_fn "cyg_fb_dev_make_colour_16bpp_true_555"
+ set break_colour_fn "cyg_fb_dev_break_colour_16bpp_true_555"
+ set make_colour_macro "CYG_FB_MAKE_COLOUR_16BPP_TRUE_555"
+ set break_colour_macro "CYG_FB_BREAK_COLOUR_16BPP_TRUE_555"
+ set depth 16
+ set stride [expr $width * 2]
+ }
+ 32BPP_TRUE_0888 {
+ set format "CYG_FB_FORMAT_32BPP_TRUE_0888"
+ set suffix "32"
+ set paletted 0
+ set make_colour_fn "cyg_fb_dev_make_colour_32bpp_true_0888"
+ set break_colour_fn "cyg_fb_dev_break_colour_32bpp_true_0888"
+ set make_colour_macro "CYG_FB_MAKE_COLOUR_32BPP_TRUE_0888"
+ set break_colour_macro "CYG_FB_BREAK_COLOUR_32BPP_TRUE_0888"
+ set depth 32
+ set stride [expr $width * 4]
+ }
+ }
+ if { $paletted } {
+ append flags0 " CYG_FB_FLAGS0_PALETTE | \\\n CYG_FB_FLAGS0_WRITEABLE_PALETTE | \\\n"
+ set write_palette_fn "cyg_synth_fb_write_palette"
+ set read_palette_fn "cyg_synth_fb_read_palette"
+ set make_colour_fn "cyg_fb_nop_make_colour"
+ set break_colour_fn "cyg_fb_nop_break_colour"
+ } else {
+ append flags0 " CYG_FB_FLAGS0_TRUE_COLOUR | \\\n"
+ set write_palette_fn "cyg_fb_nop_write_palette"
+ set read_palette_fn "cyg_fb_nop_read_palette"
+ }
+ append flags0 " CYG_FB_FLAGS0_BLANK)"
+
+ # The framebuffer parameters
+ append data \
+ "
+extern cyg_fb cyg_synth_fb[set fb];
+extern cyg_uint8* cyg_synth_fb[set fb]_base;
+#define CYG_FB_fb[set fb]_STRUCT cyg_synth_fb[set fb]
+#define CYG_FB_fb[set fb]_DEPTH $depth
+#define CYG_FB_fb[set fb]_FORMAT $format
+#define CYG_FB_fb[set fb]_WIDTH $width
+#define CYG_FB_fb[set fb]_HEIGHT $height
+#define CYG_FB_fb[set fb]_VIEWPORT_WIDTH $viewport_width
+#define CYG_FB_fb[set fb]_VIEWPORT_HEIGHT $viewport_height
+#define CYG_FB_fb[set fb]_BASE cyg_synth_fb[set fb]_base
+#define CYG_FB_fb[set fb]_STRIDE $stride
+#define CYG_FB_fb[set fb]_FLAGS0 $flags0
+#define CYG_FB_fb[set fb]_FLAGS1 0
+#define CYG_FB_fb[set fb]_FLAGS2 0
+#define CYG_FB_fb[set fb]_FLAGS3 0
+"
+
+ # These macros are not part of the usual framebuffer set, but are
+ # useful because of the configurable nature of the synthetic target
+ append data \
+ "
+#define CYG_FB_fb[set fb]_SUFFIX $suffix
+#define CYG_FB_fb[set fb]_READ_PALETTE_FN $read_palette_fn
+#define CYG_FB_fb[set fb]_WRITE_PALETTE_FN $write_palette_fn
+#define CYG_FB_fb[set fb]_MAKE_COLOUR_FN $make_colour_fn
+#define CYG_FB_fb[set fb]_BREAK_COLOUR_FN $break_colour_fn
+"
+ # And the macro API, all done in terms of the linear framebuffer functions.
+ append data \
+ "
+#define CYG_FB_fb[set fb]_PIXELx_VAR( _fb_, _id_) CYG_FB_PIXELx_VAR_[set suffix]( _fb_, _id_)
+#define CYG_FB_fb[set fb]_PIXELx_SET( _fb_, _id_, _x_, _y_) \\
+ CYG_MACRO_START \\
+ CYG_FB_PIXELx_SET_[set suffix]( _fb_, _id_, CYG_FB_fb[set fb]_BASE, CYG_FB_fb[set fb]_STRIDE, _x_, _y_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_PIXELx_GET( _fb_, _id_, _x_, _y_) \\
+ CYG_MACRO_START \\
+ CYG_FB_PIXELx_GET_[set suffix]( _fb_, _id_, CYG_FB_fb[set fb]_BASE, CYG_FB_fb[set fb]_STRIDE, _x_, _y_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_PIXELx_ADDX( _fb_, _id_, _incr_) \\
+ CYG_MACRO_START \\
+ CYG_FB_PIXELx_ADDX_[set suffix]( _fb_, _id_, CYG_FB_fb[set fb]_STRIDE, _incr_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_PIXELx_ADDY( _fb_, _id_, _incr_) \\
+ CYG_MACRO_START \\
+ CYG_FB_PIXELx_ADDY_[set suffix]( _fb_, _id_, CYG_FB_fb[set fb]_STRIDE, _incr_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_PIXELx_WRITE(_fb_, _id_, _colour_) \\
+ CYG_MACRO_START \\
+ CYG_FB_PIXELx_WRITE_[set suffix](_fb_, _id_, _colour_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_PIXELx_READ( _fb_, _id_) \\
+ ({ CYG_FB_PIXELx_READ_[set suffix]( _fb_, _id_); })
+#define CYG_FB_fb[set fb]_PIXELx_FLUSHABS( _fb_, _id_, _x0_, _y0_, _width_, _height_) \\
+ CYG_MACRO_START \\
+ CYG_FB_PIXELx_FLUSHABS_[set suffix](_fb_, _id_, _x0_, _y0_, _width_, _height_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_PIXELx_FLUSHREL( _fb_, _id_, _x0_, _y0_, _dx_, _dy_) \\
+ CYG_MACRO_START \\
+ CYG_FB_PIXELx_FLUSHREL_[set suffix](_fb_, _id_, _x0_, _y0_, _dx_, _dy_); \\
+ CYG_MACRO_END
+
+#define CYG_FB_fb[set fb]_WRITE_PIXEL(_x_, _y_, _colour_) \\
+ CYG_MACRO_START \\
+ cyg_fb_linear_write_pixel_[set suffix]_inl(CYG_FB_fb[set fb]_BASE, CYG_FB_fb[set fb]_STRIDE, \\
+ _x_, _y_, _colour_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_READ_PIXEL(_x_, _y_) \\
+ ({ cyg_fb_linear_read_pixel_[set suffix]_inl(CYG_FB_fb[set fb]_BASE, CYG_FB_fb[set fb]_STRIDE, _x_, _y_); })
+#define CYG_FB_fb[set fb]_WRITE_HLINE(_x_, _y_, _len_, _colour_) \\
+ CYG_MACRO_START \\
+ cyg_fb_linear_write_hline_[set suffix]_inl(CYG_FB_fb[set fb]_BASE, CYG_FB_fb[set fb]_STRIDE, \\
+ _x_, _y_, _len_, _colour_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_WRITE_VLINE(_x_, _y_, _len_, _colour_) \\
+ CYG_MACRO_START \\
+ cyg_fb_linear_write_vline_[set suffix]_inl(CYG_FB_fb[set fb]_BASE, CYG_FB_fb[set fb]_STRIDE, \\
+ _x_, _y_, _len_, _colour_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_FILL_BLOCK(_x_, _y_, _width_, _height_, _colour_) \\
+ CYG_MACRO_START \\
+ cyg_fb_linear_fill_block_[set suffix]_inl(CYG_FB_fb[set fb]_BASE, CYG_FB_fb[set fb]_STRIDE, \\
+ _x_, _y_, _width_, _height_, _colour_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_WRITE_BLOCK(_x_, _y_, _width_, _height_, _data_, _offset_, _data_stride_) \\
+ CYG_MACRO_START \\
+ cyg_fb_linear_write_block_[set suffix]_inl(CYG_FB_fb[set fb]_BASE, CYG_FB_fb[set fb]_STRIDE, \\
+ _x_, _y_, _width_, _height_, _data_, _offset_, _data_stride_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_READ_BLOCK(_x_, _y_, _width_, _height_, _data_, _offset_, _data_stride_) \\
+ CYG_MACRO_START \\
+ cyg_fb_linear_read_block_[set suffix]_inl(CYG_FB_fb[set fb]_BASE, CYG_FB_fb[set fb]_STRIDE, \\
+ _x_, _y_, _width_, _height_, _data_, _offset_, _data_stride_); \\
+ CYG_MACRO_END
+#define CYG_FB_fb[set fb]_MOVE_BLOCK(_x_, _y_, _width_, _height_, _new_x_, _new_y_) \\
+ CYG_MACRO_START \\
+ cyg_fb_linear_move_block_[set suffix]_inl(CYG_FB_fb[set fb]_BASE, CYG_FB_fb[set fb]_STRIDE, \\
+ _x_, _y_, _width_, _height_, _new_x_, _new_y_); \\
+ CYG_MACRO_END
+"
+ if { !$paletted } {
+ append data \
+ "
+#define CYG_FB_fb[set fb]_MAKE_COLOUR(_r_, _g_, _b_) \\
+ ({ [set make_colour_macro](_r_, _g_, _b_); })
+#define CYG_FB_fb[set fb]_BREAK_COLOUR(_colour_, _r_, _g_, _b_) \\
+ CYG_MACRO_START \\
+ [set break_colour_macro](_colour_, _r_, _g_, _b_); \\
+ CYG_MACRO_END
+"
+ }
+ }
+
+ set old_data ""
+ set framebuf_file [file join $prefix "include/cyg/io/framebufs/synth_fb.h"]
+ if { [file exists $framebuf_file] && [file readable $framebuf_file] } {
+ set fd [open $framebuf_file "r"]
+ set old_data [read $fd]
+ close $fd
+ }
+ if { ! [string equal $old_data $data] } {
+ if { ! [info exists [file dirname $framebuf_file]] } {
+ file mkdir [file dirname $framebuf_file]
+ }
+ set fd [open $framebuf_file "w"]
+ puts -nonewline $fd $data
+ close $fd
+ }
+}
+
+if { 0 == $::argc } {
+ puts stderr "gen_synthfb.tcl: missing argument for install directory"
+ exit 1
+}
+if { [catch { do_it [lindex $::argv 0] } msg] } {
+ puts stderr "gen_synthfb.tcl: internal error"
+ puts stderr " $msg"
+ exit 1
+}
+exit 0
+
diff --git a/ecos/packages/devs/framebuf/synth/current/src/protocol.h b/ecos/packages/devs/framebuf/synth/current/src/protocol.h
new file mode 100644
index 0000000..7fb6969
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/src/protocol.h
@@ -0,0 +1,126 @@
+//==========================================================================
+//
+// protocol.h
+//
+// Data common to host and target.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//###DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2005-10-28
+//
+//###DESCRIPTIONEND####
+//========================================================================
+
+// These requests are sent by eCos to the I/O auxiliary and the
+// framebuf.tcl script.
+//
+// Protocol version number
+#define SYNTH_FB_PROTOCOL_VERSION 0x01
+
+// Initialize, getting back various file names.
+#define SYNTH_FB_INIT 0x01
+// Abort, failed to open the file names
+#define SYNTH_FB_ABORT 0x02
+// Switch a device back on.
+#define SYNTH_FB_ON 0x03
+// Or off
+#define SYNTH_FB_OFF 0x04
+
+// These requests are sent by eCos to the host-side framebuf program
+// to indicate what has changed.
+//
+// All connected
+#define SYNTH_FB_OK 0x01
+// A double buffer synch.
+#define SYNTH_FB_SYNC 0x02
+// Palette change, redraw the lot
+#define SYNTH_FB_WRITE_PALETTE 0x03
+// Blank or unblank the screen
+#define SYNTH_FB_BLANK 0x04
+// Move the viewport
+#define SYNTH_FB_VIEWPORT 0x05
+// Page flipping
+#define SYNTH_FB_PAGE_FLIP 0x06
+
+// These requests go from the framebuf.tcl script to the framebuf
+// program.
+typedef struct synth_fb_auxiliary_request {
+ unsigned int command;
+ unsigned int arg1;
+ unsigned int arg2;
+} synth_fb_auxiliary_request;
+
+// This is sent when the frame becomes visible. It is followed
+// by a 32-bit windows id.
+#define SYNTH_FB_AUX_MAPPED 0x01
+// ON, processed by auxiliary and then passed on to framebuf
+#define SYNTH_FB_AUX_ON 0x02
+// OFF, processed by auxiliary and then passed on to framebuf
+#define SYNTH_FB_AUX_OFF 0x03
+// Refresh, sent by the auxiliary a second after mapping.
+#define SYNTH_FB_AUX_REDRAW 0x04
+
+// This data structure is in the shared memory region.
+typedef struct synth_fb_data {
+ // Do we have a connection to a host-side framebuf program to do
+ // the drawing?
+ int connected;
+ // Named fifo between framebuf and the synthetic target.
+ int fifo_to_framebuf;
+ int fifo_from_framebuf;
+ // The device id for the auxiliary
+ int devid;
+ // The bounding box for syncs.
+ int sync_x0;
+ int sync_y0;
+ int sync_x1;
+ int sync_y1;
+ // Is the display on?
+ int display_on;
+ // Current blank state
+ int blank_on;
+ // Current viewport position, top left
+ int viewport_x;
+ int viewport_y;
+ // Current page for page flipping
+ int page_visible;
+ int page_drawable;
+ // The palette, if used.
+ unsigned char palette[3 * 256];
+ // The framebuffer data follows.
+ unsigned int framebuf[1];
+} synth_fb_data;
diff --git a/ecos/packages/devs/framebuf/synth/current/src/synthfb.c b/ecos/packages/devs/framebuf/synth/current/src/synthfb.c
new file mode 100644
index 0000000..80a27ef
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/src/synthfb.c
@@ -0,0 +1,682 @@
+//==========================================================================
+//
+// synthfb.c
+//
+// Provide one or more framebuffer devices for the synthetic target.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//###DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2005-10-28
+//
+//###DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/devs_framebuf_synth.h>
+#include <pkgconf/io_framebuf.h>
+#include <cyg/io/framebuf.h>
+#include <errno.h>
+#include <string.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_io.h>
+#include "protocol.h"
+
+// Set the DEBUG_LEVEL to 0 for no debugging, 2 for maximum debugging.
+#define DEBUG_LEVEL 0
+#define DEBUG(_level_, _str_, ...) \
+ CYG_MACRO_START \
+ if (_level_ <= DEBUG_LEVEL) { \
+ diag_printf( _str_, ## __VA_ARGS__); \
+ } \
+ CYG_MACRO_END
+
+// Achieving high performance graphics operations in the synthetic
+// target is difficult. Theoretically it might be possible to access
+// the Linux framebuffer directly using MIT-SHM or DGA. However there
+// is no practical way to handle the relevant parts of the X prococol,
+// e.g. expose events. We also don't want to go via the
+// general-purpose xchgmsg() functionality and a Tcl script, those
+// are not appropriate for high performance.
+//
+// Instead if the I/O auxiliary is running a framebuffer device is
+// instantiated, and the framebuf.tcl script will start a program
+// framebuf. That program will create a shared memory region which
+// then gets mapped into the synthetic target's address space. The
+// shared memory region holds a synth_fb_data structure followed by
+// the framebuffer data. If there are multiple framebuffer devices
+// then there will be multiple invocations of the framebuf program.
+//
+// The framebuf program needs to respond to requests from several
+// different sources. The X server may send events like expose.
+// The synthetic target application can send synchronization requests,
+// palette updates, and so on. The X events will come via a socket,
+// and the requests from framebuf.tcl can come via a pipe. select()
+// will serve for this. Several mechanisms can be used for the
+// communication between the synthetic target application and framebuf
+// including shared memory semaphores and reliable signals. To fit in
+// neatly with the select() a named fifo is used.
+//
+// So assuming a framebuf program is running fb_op() writes a single
+// byte to the fifo, then waits for framebuf to complete the
+// operation. That wait also uses a named fifo. This keeps everything
+// synchronous, and avoids some portability problems between
+// Linux on various architectures.
+static void
+fb_op(cyg_fb* fb, int command)
+{
+ synth_fb_data* fb_data = (synth_fb_data*) fb->fb_driver2;
+ DEBUG(2, "target synthfb: fb_op %d\n", command);
+ if (fb_data->connected) {
+ cyg_uint8 data[1];
+ int rc;
+
+ data[0] = (cyg_uint8)command;
+ do {
+ rc = cyg_hal_sys_write(fb_data->fifo_to_framebuf, (const void*) data, 1);
+ } while (-CYG_HAL_SYS_EINTR == rc);
+ do {
+ rc = cyg_hal_sys_read(fb_data->fifo_from_framebuf, (void*) data, 1);
+ } while (-CYG_HAL_SYS_EINTR == rc);
+ if (rc < 0) {
+ diag_printf("Internal error: unexpected result %d when receiving response from the framebuf program.\n", rc);
+ diag_printf(" : disabling framebuffer device fb%d.\n", fb->fb_driver0);
+ fb_data->connected = 0;
+ }
+ }
+ DEBUG(2, "target synthfb: fb_op %d done\n", command);
+}
+
+// Create a framebuffer device. This gets called from a C++
+// static constructor, to ensure that all the framebuffer
+// windows are created early on during initialization before
+// the host-side ecosynth support performs any cleanups.
+void
+_cyg_synth_fb_instantiate(struct cyg_fb* fb)
+{
+ synth_fb_data* local_fb_data = (synth_fb_data*) fb->fb_driver2;
+ synth_fb_data* shared_fb_data;
+ char device_data[512];
+ char fb_name[4];
+ char* fb_format = 0;
+ char* ptr;
+ char* filename;
+ int fd;
+ int len;
+ int reply;
+ cyg_uint8* fb_base;
+ DEBUG(1, "target synth_fb_instantiate\n");
+
+ if (!synth_auxiliary_running) {
+ diag_printf("cyg_synth_fb_instantiate(): no I/O auxiliary, sticking with in-memory framebuffer\n");
+ return;
+ }
+
+ diag_sprintf(fb_name, "fb%d", fb->fb_driver0);
+ switch(fb->fb_format) {
+ // Only bother with the formats used by gensynth_fb.tcl
+ case CYG_FB_FORMAT_1BPP_PAL888:
+ {
+ static const cyg_uint8 fb_1bpp_palette[2 * 3] = {
+ 0x00, 0x00, 0x00, // colour 0 == black
+ 0xFF, 0xFF, 0xFF // colour 1 == white
+ };
+ fb_format = "1BPP_PAL888";
+ memcpy(local_fb_data->palette, fb_1bpp_palette, sizeof(fb_1bpp_palette));
+ break;
+ }
+ case CYG_FB_FORMAT_2BPP_PAL888:
+ {
+ static const cyg_uint8 fb_2bpp_palette[4 * 3] = {
+ 0x00, 0x00, 0x00, // colour 0 == black
+ 0x54, 0x54, 0x54, // dark grey
+ 0xA8, 0xA8, 0xA8, // light grey
+ 0xFF, 0xFF, 0xFF // colour 3 == white
+ } ;
+ fb_format = "2BPP_PAL888";
+ memcpy(local_fb_data->palette, fb_2bpp_palette, sizeof(fb_2bpp_palette));
+ break;
+ }
+ case CYG_FB_FORMAT_4BPP_PAL888:
+ fb_format = "4BPP_PAL888";
+ memcpy(local_fb_data->palette, cyg_fb_palette_ega, 16 * 3);
+ break;
+ case CYG_FB_FORMAT_8BPP_PAL888:
+ fb_format = "8BPP_PAL888";
+ memcpy(local_fb_data->palette, cyg_fb_palette_vga, 256 * 3);
+ break;
+ case CYG_FB_FORMAT_8BPP_TRUE_332:
+ fb_format = "8BPP_TRUE_332";
+ break;
+ case CYG_FB_FORMAT_16BPP_TRUE_565:
+ fb_format = "16BPP_TRUE_565";
+ break;
+ case CYG_FB_FORMAT_16BPP_TRUE_555:
+ fb_format = "16BPP_TRUE_555";
+ break;
+ case CYG_FB_FORMAT_32BPP_TRUE_0888:
+ fb_format = "32BPP_TRUE_0888";
+ break;
+ }
+
+ diag_sprintf(device_data, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%s",
+ SYNTH_FB_PROTOCOL_VERSION,
+ fb->fb_driver0, /* id 0-3 */
+ fb->fb_depth,
+ fb->fb_flags0 & CYG_FB_FLAGS0_LE,
+ fb->fb_width, fb->fb_height,
+#ifdef CYGHWR_IO_FRAMEBUF_FUNCTIONALITY_VIEWPORT
+ fb->fb_viewport_width, fb->fb_viewport_height,
+#else
+ fb->fb_width, fb->fb_height,
+#endif
+ fb->fb_stride,
+ fb->fb_driver1, /* number of pages */
+ fb_format);
+
+ local_fb_data->devid = synth_auxiliary_instantiate("devs/framebuf/synth", SYNTH_MAKESTRING(CYGPKG_DEVS_FRAMEBUF_SYNTH),
+ "framebuf", fb_name, device_data);
+ if (local_fb_data->devid < 0) {
+ // The I/O auxiliary should have reported a suitable error.
+ // Just stick with an in-memory device.
+ diag_printf("cyg_synth_fb_instantiate(): failed to instantiate device, sticking with in-memory framebuffer\n");
+ return;
+ } else {
+ DEBUG(1, "target synth_auxiliary_instantiate(), host-side framebuf utility running\n");
+ // At this point the framebuf.tcl script has run, the window has
+ // been created, the framebuf program has been started, it will
+ // have created the shared memory region and the two fifos,
+ // passed the names back up to framebuf.tcl, and everything should
+ // be running. This xchgmsg() retrieves the file names from
+ // framebuf.tcl.
+ synth_auxiliary_xchgmsg(local_fb_data->devid, SYNTH_FB_INIT, 0, 0, 0, 0, &reply, (unsigned char*)device_data, &len, 512);
+ // First filename is the shared memory region.
+ filename = device_data;
+ for (ptr = device_data; *ptr != ';'; ptr++)
+ ;
+ *ptr++ = '\0';
+ DEBUG(1, "target : Opening shared memory region %s\n", filename);
+ fd = cyg_hal_sys_open(filename, CYG_HAL_SYS_O_RDWR, 0);
+ if (fd < 0) {
+ synth_auxiliary_xchgmsg(local_fb_data->devid, SYNTH_FB_ABORT, 0, 0, 0, 0, 0, 0, 0, 0);
+ return;
+ }
+ shared_fb_data = (synth_fb_data*)cyg_hal_sys_mmap(0,
+ sizeof(synth_fb_data) + (fb->fb_height * fb->fb_stride * fb->fb_driver1),
+ CYG_HAL_SYS_PROT_READ | CYG_HAL_SYS_PROT_WRITE,
+ CYG_HAL_SYS_MAP_SHARED,
+ fd,
+ 0
+ );
+ if (shared_fb_data <= 0) {
+ synth_auxiliary_xchgmsg(local_fb_data->devid, SYNTH_FB_ABORT, 0, 0, 0, 0, 0, 0, 0, 0);
+ cyg_hal_sys_close(fd);
+ return;
+ }
+ DEBUG(1, "target: mmap()'d shared memory region -> %p\n", shared_fb_data);
+ shared_fb_data->devid = local_fb_data->devid;
+
+ // Next filename is the fifo to the framebuf program.
+ filename = ptr;
+ for (ptr = device_data; *ptr != ';'; ptr++)
+ ;
+ *ptr++ = '\0';
+ DEBUG(1, "target: Opening fifo to framebuf %s\n", filename);
+ shared_fb_data->fifo_to_framebuf = cyg_hal_sys_open(filename, CYG_HAL_SYS_O_WRONLY, 0);
+ if (shared_fb_data->fifo_to_framebuf < 0) {
+ synth_auxiliary_xchgmsg(shared_fb_data->devid, SYNTH_FB_ABORT, 0, 0, 0, 0, 0, 0, 0, 0);
+ cyg_hal_sys_close(fd);
+ return;
+ }
+ // And finally the fifo from the framebuf program.
+ filename = ptr;
+ for (ptr = device_data; *ptr != ';'; ptr++)
+ ;
+ *ptr = '\0';
+ DEBUG(1, "target: Opening fifo from framebuf %s\n", filename);
+ shared_fb_data->fifo_from_framebuf = cyg_hal_sys_open(filename, CYG_HAL_SYS_O_RDONLY, 0);
+ if (shared_fb_data->fifo_from_framebuf < 0) {
+ synth_auxiliary_xchgmsg(shared_fb_data->devid, SYNTH_FB_ABORT, 0, 0, 0, 0, 0, 0, 0, 0);
+ cyg_hal_sys_close(fd);
+ cyg_hal_sys_close(shared_fb_data->fifo_to_framebuf);
+ return;
+ }
+
+ // We have a shared memory region and the two files. Copy
+ // all existing fb_data contents (e.g. the palettes) and
+ // the framebuffer contents to the shared memory region.
+ // The MUST_BE_ON flag is not set for synthetic target
+ // framebuffers so there may already be contents.
+ fb_base = (cyg_uint8*)fb->fb_base;
+ fb_base -= (fb->fb_height * fb->fb_stride * shared_fb_data->page_drawable);
+ memcpy(&(shared_fb_data->palette[0]), &(local_fb_data->palette[0]), 3 * 256);
+ memcpy(&(shared_fb_data->framebuf[0]), fb_base, fb->fb_height * fb->fb_stride * fb->fb_driver1);
+ shared_fb_data->connected = 1;
+ fb->fb_driver2 = (CYG_ADDRWORD)shared_fb_data;
+
+ fb_base = (cyg_uint8*)&(shared_fb_data->framebuf[0]);
+ fb_base += (fb->fb_height * fb->fb_stride * shared_fb_data->page_drawable);
+ fb->fb_base = fb_base;
+ *(cyg_uint8**)fb->fb_driver3 = fb_base;
+
+ DEBUG(1, "target: Fully instantiated, fb_data %p, blank_on %d, display_on %d\n",
+ shared_fb_data, shared_fb_data->blank_on, shared_fb_data->display_on);
+ DEBUG(1, "target: devid %d, t2h %d, h2t %d\n",
+ shared_fb_data->devid, shared_fb_data->fifo_to_framebuf, shared_fb_data->fifo_from_framebuf);
+ // Finally tell the framebuf program everything is ready.
+ fb_op(fb, SYNTH_FB_OK);
+ DEBUG(1, "target: Sent SYNTH_FB_OK\n");
+ }
+}
+
+
+// Switch on a framebuffer device. This may get called multiple
+// times, e.g. when switching between different screen modes.
+// It just involves sending a message to the auxiliary.
+static int
+cyg_synth_fb_on(struct cyg_fb* fb)
+{
+ synth_fb_data* fb_data = (synth_fb_data*) fb->fb_driver2;
+ if (fb_data->connected) {
+ synth_auxiliary_xchgmsg(fb_data->devid, SYNTH_FB_ON, 0, 0, 0, 0, 0, 0, 0, 0);
+ }
+
+ return 0;
+}
+
+static int
+cyg_synth_fb_off(struct cyg_fb* fb)
+{
+ synth_fb_data* fb_data = (synth_fb_data*) fb->fb_driver2;
+ if (fb_data->connected) {
+ synth_auxiliary_xchgmsg(fb_data->devid, SYNTH_FB_OFF, 0, 0, 0, 0, 0, 0, 0, 0);
+ }
+ return 0;
+}
+
+static int
+cyg_synth_fb_ioctl(struct cyg_fb* fb, cyg_ucount16 key, void* data, size_t* len)
+{
+ synth_fb_data* fb_data = (synth_fb_data*) fb->fb_driver2;
+ int result = ENOSYS;
+
+ switch(key) {
+ case CYG_FB_IOCTL_VIEWPORT_GET_POSITION:
+ DEBUG(1, "cyg_synth_fb_ioctl: viewport_get_position\n");
+ if (fb->fb_flags0 & CYG_FB_FLAGS0_VIEWPORT) {
+ cyg_fb_ioctl_viewport* viewport = (cyg_fb_ioctl_viewport*)data;
+ CYG_ASSERT(*len == sizeof(cyg_fb_ioctl_viewport), "data argument should be a cyg_fb_ioctl_viewport structure");
+ viewport->fbvp_x = fb_data->viewport_x;
+ viewport->fbvp_y = fb_data->viewport_y;
+ result = 0;
+ DEBUG(1, " : current viewport x %d, y %d\n", fb_data->viewport_x, fb_data->viewport_y);
+ } else {
+ DEBUG(1, " : framebuffer does not support a viewport\n");
+ }
+ break;
+ case CYG_FB_IOCTL_VIEWPORT_SET_POSITION:
+ DEBUG(1, "cyg_synth_fb_ioctl: viewport_set_position\n");
+ if (fb->fb_flags0 & CYG_FB_FLAGS0_VIEWPORT) {
+ cyg_fb_ioctl_viewport* viewport = (cyg_fb_ioctl_viewport*)data;
+ CYG_ASSERT(*len == sizeof(cyg_fb_ioctl_viewport), "data argument should be a cyg_fb_ioctl_viewport structure");
+ CYG_ASSERT(((viewport->fbvp_x + fb->fb_viewport_width) <= fb->fb_width) &&
+ ((viewport->fbvp_y + fb->fb_viewport_height) <= fb->fb_height),
+ "viewport should be within framebuffer dimensions");
+ DEBUG(1, " : setting viewport from x %d, y %d to x %d, y %d\n",
+ fb_data->viewport_x, fb_data->viewport_y, (int) viewport->fbvp_x, (int) viewport->fbvp_y);
+ if ((fb_data->viewport_x != (int)viewport->fbvp_x) || (fb_data->viewport_y != (int)viewport->fbvp_y)) {
+ fb_data->viewport_x = (int)viewport->fbvp_x;
+ fb_data->viewport_y = (int)viewport->fbvp_y;
+ fb_op(fb, SYNTH_FB_VIEWPORT);
+ }
+ result = 0;
+ } else {
+ DEBUG(1, " : framebuffer does not support a viewport\n");
+ }
+ break;
+ case CYG_FB_IOCTL_PAGE_FLIPPING_GET_PAGES:
+ DEBUG(1, "cyg_synth_fb_ioctl: page_flipping_get_pages\n");
+ if (fb->fb_flags0 & CYG_FB_FLAGS0_PAGE_FLIPPING) {
+ cyg_fb_ioctl_page_flip* page_flip = (cyg_fb_ioctl_page_flip*)data;
+ CYG_ASSERT(*len == sizeof(cyg_fb_ioctl_page_flip), "data argument should be a cyg_fb_ioctl_page_flip structure");
+ page_flip->fbpf_number_pages = fb->fb_driver1;
+ page_flip->fbpf_visible_page = fb_data->page_visible;
+ page_flip->fbpf_drawable_page = fb_data->page_drawable;
+ result = 0;
+ DEBUG(1, " : number_pages %d, visible page %d, drawable page %d\n",
+ fb->fb_driver1, fb_data->page_visible, fb_data->page_drawable);
+ } else {
+ DEBUG(1, " : framebuffer does not support page flipping\n");
+ }
+ break;
+ case CYG_FB_IOCTL_PAGE_FLIPPING_SET_PAGES:
+ DEBUG(1, "cyg_synth_fb_ioctl: page_flipping_set_pages\n");
+ if (fb->fb_flags0 & CYG_FB_FLAGS0_PAGE_FLIPPING) {
+ cyg_fb_ioctl_page_flip* page_flip = (cyg_fb_ioctl_page_flip*)data;
+ cyg_uint8* fb_base;
+
+ CYG_ASSERT(*len == sizeof(cyg_fb_ioctl_page_flip), "data argument should be a cyg_fb_ioctl_page_flip structure");
+ CYG_ASSERT((page_flip->fbpf_visible_page < fb->driver1) &&
+ (page_flip->fbpf_drawable_page < fb->driver1),
+ "framebuffer does not have that many pages");
+ DEBUG(1, " : drawable page was %d, now %d, visible page was %d, now %d\n",
+ fb_data->page_drawable, (int)page_flip->fbpf_drawable_page,
+ fb_data->page_visible, (int)page_flip->fbpf_visible_page);
+ fb_base = (cyg_uint8*)fb->fb_base;
+ fb_base -= (fb->fb_height * fb->fb_stride * fb_data->page_drawable);
+ fb_data->page_drawable = page_flip->fbpf_drawable_page;
+ fb_base += (fb->fb_height * fb->fb_stride * fb_data->page_drawable);
+ fb->fb_base = fb_base;
+ *(cyg_uint8**)fb->fb_driver3 = fb_base;
+ if (fb_data->page_visible != (int)page_flip->fbpf_visible_page) {
+ fb_data->page_visible = (int)page_flip->fbpf_visible_page;
+ fb_op(fb, SYNTH_FB_PAGE_FLIP);
+ }
+ result = 0;
+ } else {
+ DEBUG(1, " : framebuffer does not support page flipping\n");
+ }
+ break;
+ case CYG_FB_IOCTL_BLANK_GET:
+ {
+ cyg_fb_ioctl_blank* blank = (cyg_fb_ioctl_blank*)data;
+ DEBUG(1, "cyg_synth_fb_ioctl: blank_get, current on state %d\n", fb_data->blank_on);
+ CYG_ASSERT(*len == sizeof(cyg_fb_ioctl_blank), "data argument should be a cyg_fb_ioctl_blank structure");
+ blank->fbbl_on = fb_data->blank_on;
+ result = 0;
+ }
+ break;
+ case CYG_FB_IOCTL_BLANK_SET:
+ {
+ cyg_fb_ioctl_blank* blank = (cyg_fb_ioctl_blank*)data;
+ CYG_ASSERT(*len == sizeof(cyg_fb_ioctl_blank), "data argument should be a cyg_fb_ioctl_blank structure");
+ DEBUG(1, "cyg_synth_fb_ioctl: blank_set, on was %d, now %d\n", fb_data->blank_on, blank->fbbl_on);
+ if (blank->fbbl_on != fb_data->blank_on) {
+ fb_data->blank_on = blank->fbbl_on;
+ fb_op(fb, SYNTH_FB_BLANK);
+ }
+ result = 0;
+ }
+ break;
+ default:
+ result = ENOSYS;
+ break;
+ }
+ return result;
+}
+
+void
+cyg_synth_fb_synch(struct cyg_fb* fb, cyg_ucount16 when)
+{
+ // FIXME: update synch_x0/y0/x1/y1 once the generic framebuffer
+ // code actually maintains a bounding box.
+ fb_op(fb, SYNTH_FB_SYNC);
+}
+
+#ifdef CYGHWR_DEVS_FRAMEBUF_SYNTH_FUNCTIONALITY_PALETTED
+// The palette is held in the synth_fb_data structure.
+static void
+cyg_synth_fb_read_palette(struct cyg_fb* fb, cyg_ucount32 first, cyg_ucount32 count, void* dest)
+{
+ synth_fb_data* fb_data = (synth_fb_data*) fb->fb_driver2;
+ CYG_ASSERT(fb->fb_flags0 & CYG_FB_FLAGS0_PALETTE, "reading palette of non-paletted display");
+ CYG_ASSERT((first + count) <= (0x01 << fb->fb_depth), "palette size exceeded");
+
+ memcpy(dest, &(fb_data->palette[3 * first]), 3 * count);
+}
+
+static void
+cyg_synth_fb_write_palette(struct cyg_fb* fb, cyg_ucount32 first, cyg_ucount32 count, const void* source, cyg_ucount16 when)
+{
+ synth_fb_data* fb_data = (synth_fb_data*) fb->fb_driver2;
+ CYG_ASSERT(fb->fb_flags0 & CYG_FB_FLAGS0_PALETTE, "reading palette of non-paletted display");
+ CYG_ASSERT((first + count) <= (0x01 << fb->fb_depth), "palette size exceeded");
+
+ DEBUG(1, "write_palette: fb %p, first %d, count %d, source %p\n", fb, first, count, source);
+ memcpy(&(fb_data->palette[3 * first]), source, 3 * count);
+ fb_op(fb, SYNTH_FB_WRITE_PALETTE);
+ CYG_UNUSED_PARAM(cyg_ucount16, when);
+}
+#endif
+
+#define LINEAR1(_fn_, _suffix_) cyg_fb_linear_ ## _fn_ ## _ ## _suffix_
+#define LINEAR( _fn_, _suffix_) LINEAR1(_fn_, _suffix_)
+
+#ifdef CYGPKG_DEVS_FRAMEBUF_SYNTH_FB0
+# ifdef CYGNUM_DEVS_FRAMEBUF_SYNTH_FB0_PAGE_FLIPPING
+# define FB0_PAGES CYGNUM_DEVS_FRAMEBUF_SYNTH_FB0_PAGE_FLIPPING
+# else
+# define FB0_PAGES 1
+#endif
+
+// A default area of memory for the framebuffer, if the auxiliary is not
+// running.
+static cyg_uint8 cyg_synth_fb0_default_base[CYG_FB_fb0_HEIGHT * CYG_FB_fb0_STRIDE * FB0_PAGES];
+
+// Pointer to framebuffer memory. This defaults to a statically
+// allocated memory but will switch to a shared memory region if
+// the auxiliary is running. It may also change if page flipping
+// is enabled.
+cyg_uint8* cyg_synth_fb0_base = cyg_synth_fb0_default_base;
+
+// Driver-specific data needed for interacting with the auxiliary.
+static synth_fb_data cyg_synth_fb0_data;
+
+CYG_FB_FRAMEBUFFER(CYG_FB_fb0_STRUCT,
+ CYG_FB_fb0_DEPTH,
+ CYG_FB_fb0_FORMAT,
+ CYG_FB_fb0_WIDTH,
+ CYG_FB_fb0_HEIGHT,
+ CYG_FB_fb0_VIEWPORT_WIDTH,
+ CYG_FB_fb0_VIEWPORT_HEIGHT,
+ cyg_synth_fb0_default_base,
+ CYG_FB_fb0_STRIDE,
+ CYG_FB_fb0_FLAGS0,
+ CYG_FB_fb0_FLAGS1,
+ CYG_FB_fb0_FLAGS2,
+ CYG_FB_fb0_FLAGS3,
+ (CYG_ADDRWORD) 0, // id, 0 - 3
+ (CYG_ADDRWORD) FB0_PAGES,
+ (CYG_ADDRWORD) &cyg_synth_fb0_data,
+ (CYG_ADDRWORD) &cyg_synth_fb0_base,
+ &cyg_synth_fb_on,
+ &cyg_synth_fb_off,
+ &cyg_synth_fb_ioctl,
+ &cyg_synth_fb_synch,
+ &CYG_FB_fb0_READ_PALETTE_FN,
+ &CYG_FB_fb0_WRITE_PALETTE_FN,
+ &CYG_FB_fb0_MAKE_COLOUR_FN,
+ &CYG_FB_fb0_BREAK_COLOUR_FN,
+ LINEAR(write_pixel, CYG_FB_fb0_SUFFIX),
+ LINEAR(read_pixel, CYG_FB_fb0_SUFFIX),
+ LINEAR(write_hline, CYG_FB_fb0_SUFFIX),
+ LINEAR(write_vline, CYG_FB_fb0_SUFFIX),
+ LINEAR(fill_block, CYG_FB_fb0_SUFFIX),
+ LINEAR(write_block, CYG_FB_fb0_SUFFIX),
+ LINEAR(read_block, CYG_FB_fb0_SUFFIX),
+ LINEAR(move_block, CYG_FB_fb0_SUFFIX),
+ 0, 0, 0, 0 // Spare0 -> spare3
+ );
+
+#endif
+
+#ifdef CYGPKG_DEVS_FRAMEBUF_SYNTH_FB1
+
+# ifdef CYGNUM_DEVS_FRAMEBUF_SYNTH_FB1_PAGE_FLIPPING
+# define FB1_PAGES CYGNUM_DEVS_FRAMEBUF_SYNTH_FB1_PAGE_FLIPPING
+# else
+# define FB1_PAGES 1
+#endif
+static cyg_uint8 cyg_synth_fb1_default_base[CYG_FB_fb1_HEIGHT * CYG_FB_fb1_STRIDE * FB1_PAGES];
+cyg_uint8* cyg_synth_fb1_base = cyg_synth_fb1_default_base;
+static synth_fb_data cyg_synth_fb1_data;
+
+CYG_FB_FRAMEBUFFER(CYG_FB_fb1_STRUCT,
+ CYG_FB_fb1_DEPTH,
+ CYG_FB_fb1_FORMAT,
+ CYG_FB_fb1_WIDTH,
+ CYG_FB_fb1_HEIGHT,
+ CYG_FB_fb1_VIEWPORT_WIDTH,
+ CYG_FB_fb1_VIEWPORT_HEIGHT,
+ cyg_synth_fb1_default_base,
+ CYG_FB_fb1_STRIDE,
+ CYG_FB_fb1_FLAGS0,
+ CYG_FB_fb1_FLAGS1,
+ CYG_FB_fb1_FLAGS2,
+ CYG_FB_fb1_FLAGS3,
+ (CYG_ADDRWORD) 1, // id, 0 - 3
+ (CYG_ADDRWORD) FB1_PAGES,
+ (CYG_ADDRWORD) &cyg_synth_fb1_data,
+ (CYG_ADDRWORD) &cyg_synth_fb1_base,
+ &cyg_synth_fb_on,
+ &cyg_synth_fb_off,
+ &cyg_synth_fb_ioctl,
+ &cyg_synth_fb_synch,
+ &CYG_FB_fb1_READ_PALETTE_FN,
+ &CYG_FB_fb1_WRITE_PALETTE_FN,
+ &CYG_FB_fb1_MAKE_COLOUR_FN,
+ &CYG_FB_fb1_BREAK_COLOUR_FN,
+ LINEAR(write_pixel, CYG_FB_fb1_SUFFIX),
+ LINEAR(read_pixel, CYG_FB_fb1_SUFFIX),
+ LINEAR(write_hline, CYG_FB_fb1_SUFFIX),
+ LINEAR(write_vline, CYG_FB_fb1_SUFFIX),
+ LINEAR(fill_block, CYG_FB_fb1_SUFFIX),
+ LINEAR(write_block, CYG_FB_fb1_SUFFIX),
+ LINEAR(read_block, CYG_FB_fb1_SUFFIX),
+ LINEAR(move_block, CYG_FB_fb1_SUFFIX),
+ 0, 0, 0, 0 // Spare0 -> spare3
+ );
+
+#endif
+
+#ifdef CYGPKG_DEVS_FRAMEBUF_SYNTH_FB2
+
+# ifdef CYGNUM_DEVS_FRAMEBUF_SYNTH_FB2_PAGE_FLIPPING
+# define FB2_PAGES CYGNUM_DEVS_FRAMEBUF_SYNTH_FB2_PAGE_FLIPPING
+# else
+# define FB2_PAGES 1
+#endif
+static cyg_uint8 cyg_synth_fb2_default_base[CYG_FB_fb2_HEIGHT * CYG_FB_fb2_STRIDE * FB2_PAGES];
+cyg_uint8* cyg_synth_fb2_base = cyg_synth_fb2_default_base;
+static synth_fb_data cyg_synth_fb2_data;
+
+CYG_FB_FRAMEBUFFER(CYG_FB_fb2_STRUCT,
+ CYG_FB_fb2_DEPTH,
+ CYG_FB_fb2_FORMAT,
+ CYG_FB_fb2_WIDTH,
+ CYG_FB_fb2_HEIGHT,
+ CYG_FB_fb2_VIEWPORT_WIDTH,
+ CYG_FB_fb2_VIEWPORT_HEIGHT,
+ cyg_synth_fb2_default_base,
+ CYG_FB_fb2_STRIDE,
+ CYG_FB_fb2_FLAGS0,
+ CYG_FB_fb2_FLAGS1,
+ CYG_FB_fb2_FLAGS2,
+ CYG_FB_fb2_FLAGS3,
+ (CYG_ADDRWORD) 2, // id, 0 - 3
+ (CYG_ADDRWORD) FB2_PAGES,
+ (CYG_ADDRWORD) &cyg_synth_fb2_data,
+ (CYG_ADDRWORD) &cyg_synth_fb2_base,
+ &cyg_synth_fb_on,
+ &cyg_synth_fb_off,
+ &cyg_synth_fb_ioctl,
+ &cyg_synth_fb_synch,
+ &CYG_FB_fb2_READ_PALETTE_FN,
+ &CYG_FB_fb2_WRITE_PALETTE_FN,
+ &CYG_FB_fb2_MAKE_COLOUR_FN,
+ &CYG_FB_fb2_BREAK_COLOUR_FN,
+ LINEAR(write_pixel, CYG_FB_fb2_SUFFIX),
+ LINEAR(read_pixel, CYG_FB_fb2_SUFFIX),
+ LINEAR(write_hline, CYG_FB_fb2_SUFFIX),
+ LINEAR(write_vline, CYG_FB_fb2_SUFFIX),
+ LINEAR(fill_block, CYG_FB_fb2_SUFFIX),
+ LINEAR(write_block, CYG_FB_fb2_SUFFIX),
+ LINEAR(read_block, CYG_FB_fb2_SUFFIX),
+ LINEAR(move_block, CYG_FB_fb2_SUFFIX),
+ 0, 0, 0, 0 // Spare0 -> spare3
+ );
+
+#endif
+
+#ifdef CYGPKG_DEVS_FRAMEBUF_SYNTH_FB3
+
+# ifdef CYGNUM_DEVS_FRAMEBUF_SYNTH_FB3_PAGE_FLIPPING
+# define FB3_PAGES CYGNUM_DEVS_FRAMEBUF_SYNTH_FB3_PAGE_FLIPPING
+# else
+# define FB3_PAGES 1
+#endif
+static cyg_uint8 cyg_synth_fb3_default_base[CYG_FB_fb3_HEIGHT * CYG_FB_fb3_STRIDE * FB3_PAGES];
+cyg_uint8* cyg_synth_fb3_base = cyg_synth_fb3_default_base;
+static synth_fb_data cyg_synth_fb3_data;
+
+CYG_FB_FRAMEBUFFER(CYG_FB_fb3_STRUCT,
+ CYG_FB_fb3_DEPTH,
+ CYG_FB_fb3_FORMAT,
+ CYG_FB_fb3_WIDTH,
+ CYG_FB_fb3_HEIGHT,
+ CYG_FB_fb3_VIEWPORT_WIDTH,
+ CYG_FB_fb3_VIEWPORT_HEIGHT,
+ cyg_synth_fb3_default_base,
+ CYG_FB_fb3_STRIDE,
+ CYG_FB_fb3_FLAGS0,
+ CYG_FB_fb3_FLAGS1,
+ CYG_FB_fb3_FLAGS2,
+ CYG_FB_fb3_FLAGS3,
+ (CYG_ADDRWORD) 3, // id, 0 - 3
+ (CYG_ADDRWORD) FB3_PAGES,
+ (CYG_ADDRWORD) &cyg_synth_fb3_data,
+ (CYG_ADDRWORD) &cyg_synth_fb3_base,
+ &cyg_synth_fb_on,
+ &cyg_synth_fb_off,
+ &cyg_synth_fb_ioctl,
+ &cyg_synth_fb_synch,
+ &CYG_FB_fb3_READ_PALETTE_FN,
+ &CYG_FB_fb3_WRITE_PALETTE_FN,
+ &CYG_FB_fb3_MAKE_COLOUR_FN,
+ &CYG_FB_fb3_BREAK_COLOUR_FN,
+ LINEAR(write_pixel, CYG_FB_fb3_SUFFIX),
+ LINEAR(read_pixel, CYG_FB_fb3_SUFFIX),
+ LINEAR(write_hline, CYG_FB_fb3_SUFFIX),
+ LINEAR(write_vline, CYG_FB_fb3_SUFFIX),
+ LINEAR(fill_block, CYG_FB_fb3_SUFFIX),
+ LINEAR(write_block, CYG_FB_fb3_SUFFIX),
+ LINEAR(read_block, CYG_FB_fb3_SUFFIX),
+ LINEAR(move_block, CYG_FB_fb3_SUFFIX),
+ 0, 0, 0, 0 // Spare0 -> spare3
+ );
+
+#endif
diff --git a/ecos/packages/devs/framebuf/synth/current/src/synthfb_init.cxx b/ecos/packages/devs/framebuf/synth/current/src/synthfb_init.cxx
new file mode 100644
index 0000000..eeb9ce8
--- /dev/null
+++ b/ecos/packages/devs/framebuf/synth/current/src/synthfb_init.cxx
@@ -0,0 +1,73 @@
+//==========================================================================
+//
+// synthfb_init.cxx
+//
+// Instantiate one or more framebuffer devices for the synthetic target.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//###DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2007-02-0
+//
+//###DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/devs_framebuf_synth.h>
+#include <cyg/io/framebuf.h>
+
+extern "C" void _cyg_synth_fb_instantiate(struct cyg_fb*);
+
+class _synth_fb_init {
+
+ public:
+ _synth_fb_init(void)
+ {
+#ifdef CYGPKG_DEVS_FRAMEBUF_SYNTH_FB0
+ _cyg_synth_fb_instantiate(&cyg_synth_fb0);
+#endif
+#ifdef CYGPKG_DEVS_FRAMEBUF_SYNTH_FB1
+ _cyg_synth_fb_instantiate(&cyg_synth_fb1);
+#endif
+#ifdef CYGPKG_DEVS_FRAMEBUF_SYNTH_FB2
+ _cyg_synth_fb_instantiate(&cyg_synth_fb2);
+#endif
+#ifdef CYGPKG_DEVS_FRAMEBUF_SYNTH_FB3
+ _cyg_synth_fb_instantiate(&cyg_synth_fb3);
+#endif
+ }
+};
+
+static _synth_fb_init _synth_fb_init_object CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_DEV_CHAR);
diff --git a/ecos/packages/devs/i2c/arm/lpc2xxx/current/ChangeLog b/ecos/packages/devs/i2c/arm/lpc2xxx/current/ChangeLog
new file mode 100644
index 0000000..b0a29e6
--- /dev/null
+++ b/ecos/packages/devs/i2c/arm/lpc2xxx/current/ChangeLog
@@ -0,0 +1,40 @@
+2008-09-16 Uwe Kindler <uwe_kindler@web.de>
+
+ * src/i2c_lpc2xxx.c: Implemented support for multiple I2C busses
+ Call DSR only if there is something to signal. Removed
+ declaration of I2C bus via CYG_I2C_BUS() macro - this belongs in
+ the platform HAL.
+
+ * include/i2c_lpc2xxx.h: New file with macro definition of macro
+ CYG_LPC2XXX_I2C_BUS() for I2C bus declaration by platform HAL
+
+ * cdl/i2c_lpc2xxx.cdl: Added CYGHWR_DEVS_I2C_ARM_LPC2XXX_MULTIPLE_BUSES
+ configuration option to support multiple I2C busses
+
+2007-07-12 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+
+ * lpc2xxx: driver for on-chip I2C unit
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/i2c/arm/lpc2xxx/current/cdl/i2c_lpc2xxx.cdl b/ecos/packages/devs/i2c/arm/lpc2xxx/current/cdl/i2c_lpc2xxx.cdl
new file mode 100644
index 0000000..faff590
--- /dev/null
+++ b/ecos/packages/devs/i2c/arm/lpc2xxx/current/cdl/i2c_lpc2xxx.cdl
@@ -0,0 +1,96 @@
+# ====================================================================
+#
+# i2c_lpc2xxx.cdl
+#
+# eCos LPC2xxx I2C configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors: Uwe Kindler <uwe_kindler@web.de>
+# Date: 2007-07-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_I2C_ARM_LPC2XXX {
+ display "I2C driver for LPC2xxx family of ARM controllers"
+
+ parent CYGPKG_IO_I2C
+ active_if CYGPKG_IO_I2C
+ active_if CYGPKG_HAL_ARM_LPC2XXX || CYGPKG_HAL_ARM_LPC24XX
+
+ description "
+ This package provides a generic I2C device driver for the on-chip
+ I2C peripherals in LPX2xxx processors."
+
+ include_dir cyg/io
+ compile i2c_lpc2xxx.c
+
+ cdl_option CYGHWR_DEVS_I2C_ARM_LPC2XXX_MULTIPLE_BUSES {
+ display "Target hardware may have multiple I2C buses"
+ flavor bool
+ default_value 0
+ description "
+ The LPC2xxx I2C driver can support multiple I2C bus devices. By
+ default the driver assumes only a single device is present and will
+ optimize for that case, using constant definitions provided by the
+ platform HAL rather than per-device structure fields. If the hardware
+ has multiple I2C bus devices, or if a singleton bus is instantiated
+ by some other package and hence the platform HAL cannot provide the
+ necessary definitions, then this option should be enabled."
+ }
+
+ cdl_option CYGPKG_DEVS_I2C_ARM_LPC2XXX_DEBUG_LEVEL {
+ display "Driver debug output level"
+ flavor data
+ legal_values {0 1}
+ default_value 0
+ description "
+ This option specifies the level of debug data output by
+ the LPC2XXX I2C device driver. A value of 0 signifies
+ no debug data output; 1 signifies normal debug data
+ output. The generic eCos I2C driver functions do not return any
+ error information if a I2C transfer failed. If this option is
+ 1 then the driver prints the status flags if a transfer failed
+ or was aborted. It prints the status flags in case of a missing
+ data or address acknowledge, in case of lost arbitration and in
+ case of a bus error. A missing acknowledge does not realy indicate
+ an error and may be part of a normal I2C communication. Therefore
+ this option should only be >0 for debug reasons."
+ }
+}
diff --git a/ecos/packages/devs/i2c/arm/lpc2xxx/current/include/i2c_lpc2xxx.h b/ecos/packages/devs/i2c/arm/lpc2xxx/current/include/i2c_lpc2xxx.h
new file mode 100644
index 0000000..7a942ba
--- /dev/null
+++ b/ecos/packages/devs/i2c/arm/lpc2xxx/current/include/i2c_lpc2xxx.h
@@ -0,0 +1,143 @@
+#ifndef CYGONCE_I2C_LPC2XXX_H
+#define CYGONCE_I2C_LPC2XXX_H
+//==========================================================================
+//
+// devs/i2c/arm/lpc2xxx/current/src/i2c_lpc2xxx.h
+//
+// I2C driver for NXP LPC2xxx ARM processors
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors: Uwe Kindler <uwe_kindler@web.de>
+// Date: 2008-09-11
+// Description: I2C driver for LPC2xxx
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/devs_i2c_arm_lpc2xxx.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+
+
+//==========================================================================
+// Single I2C bus sepecififc data
+//==========================================================================
+typedef struct cyg_lpc2xxx_i2c_extra {
+#ifdef CYGHWR_DEVS_I2C_ARM_LPC2XXX_MULTIPLE_BUSES
+ // Put statically initialized fields first.
+ cyg_uint32 i2c_base; // Per-bus h/w details
+ cyg_vector_t i2c_isrvec;
+ int i2c_isrpri;
+ cyg_uint32 i2c_pclk; // peripheral clock of
+ cyg_uint32 i2c_bus_freq;// I2C bus frequency (e.g. 100 kHz, 400 kHz)
+#endif // CYGHWR_DEVS_I2C_ARM_LPC2XXX_MULTIPLE_BUSES
+
+ cyg_uint8 i2c_addr;
+ cyg_uint32 i2c_count;
+ const cyg_uint8* i2c_txbuf;
+ cyg_uint8* i2c_rxbuf;
+ cyg_bool i2c_rxnak;
+
+ cyg_uint32 i2c_flag;
+ cyg_uint32 i2c_delay;
+
+ cyg_drv_mutex_t i2c_lock; // For synchronizing between DSR and foreground
+ cyg_drv_cond_t i2c_wait;
+ cyg_handle_t i2c_interrupt_handle;// For initializing the interrupt
+ cyg_interrupt i2c_interrupt_data;
+} cyg_lpc2xxx_i2c_extra;
+
+
+//==========================================================================
+// I2C driver interface
+//==========================================================================
+externC void cyg_lpc2xxx_i2c_init(struct cyg_i2c_bus*);
+externC cyg_uint32 cyg_lpc2xxx_i2c_tx(const cyg_i2c_device*,
+ cyg_bool, const cyg_uint8*,
+ cyg_uint32, cyg_bool);
+externC cyg_uint32 cyg_lpc2xxx_i2c_rx(const cyg_i2c_device*,
+ cyg_bool, cyg_uint8*,
+ cyg_uint32, cyg_bool, cyg_bool);
+externC void cyg_lpc2xxx_i2c_stop(const cyg_i2c_device*);
+
+//==========================================================================
+// I2C bus declaration macros
+//=========================================================================
+#ifdef CYGHWR_DEVS_I2C_ARM_LPC2XXX_MULTIPLE_BUSES
+# define CYG_LPC2XXX_I2C_BUS(_name_, _init_fn_, _base_, _isr_vec_, _isr_pri_, \
+ _pclk_, _i2c_bus_freq_) \
+ static cyg_lpc2xxx_i2c_extra _name_ ## _extra = { \
+ i2c_base : _base_, \
+ i2c_isrvec : _isr_vec_, \
+ i2c_isrpri : _isr_pri_, \
+ i2c_pclk : _pclk_, \
+ i2c_bus_freq : _i2c_bus_freq_, \
+ i2c_count : 0, \
+ i2c_txbuf : NULL, \
+ i2c_rxbuf : NULL, \
+ i2c_flag : 0 \
+ } ; \
+ CYG_I2C_BUS(_name_, \
+ _init_fn_, \
+ &cyg_lpc2xxx_i2c_tx, \
+ &cyg_lpc2xxx_i2c_rx, \
+ &cyg_lpc2xxx_i2c_stop, \
+ (void*) & ( _name_ ## _extra)) ;
+
+#else // !CYGHWR_DEVS_I2C_ARM_LPC2XXX_MULTIPLE_BUSES
+# define CYG_LPC2XXX_I2C_BUS(_name_, _init_fn_, _base_, _isr_vec_, _isr_pri_, \
+ _pclk_, _i2c_bus_freq_) \
+ static cyg_lpc2xxx_i2c_extra _name_ ## _extra = { \
+ i2c_count : 0, \
+ i2c_txbuf : NULL, \
+ i2c_rxbuf : NULL, \
+ i2c_flag : 0 \
+ } ; \
+ CYG_I2C_BUS(_name_, \
+ _init_fn_, \
+ cyg_lpc2xxx_i2c_tx, \
+ cyg_lpc2xxx_i2c_rx, \
+ cyg_lpc2xxx_i2c_stop, \
+ (void*) & ( _name_ ## _extra)) ;
+#endif // CYGHWR_DEVS_I2C_ARM_LPC2XXX_MULTIPLE_BUSES
+
+//-----------------------------------------------------------------------------
+#endif // #endif CYGONCE_I2C_LPC2XXX_H
diff --git a/ecos/packages/devs/i2c/arm/lpc2xxx/current/src/i2c_lpc2xxx.c b/ecos/packages/devs/i2c/arm/lpc2xxx/current/src/i2c_lpc2xxx.c
new file mode 100644
index 0000000..fff6a3a
--- /dev/null
+++ b/ecos/packages/devs/i2c/arm/lpc2xxx/current/src/i2c_lpc2xxx.c
@@ -0,0 +1,491 @@
+//==========================================================================
+//
+// i2c_lpc2xxx.c
+//
+// I2C driver for LPC2xxx
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors: Uwe Kindler <uwe_kindler@web.de>
+// Date: 2007-07-12
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/devs_i2c_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/i2c.h>
+#include <cyg/io/i2c_lpc2xxx.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+//
+// According to the Users Manual the LPC2xxx I2C module is very
+// similar to the I2C module of the Philips 8xC552/556 controllers. I
+// guess it is used in other Philips/NXP controllers, too. Using these
+// macros should make it easier to split off the common parts of the
+// driver once it's necessary.
+//
+// Optimize for the case of a single bus device, while still allowing
+// multiple devices.
+//
+#ifndef CYGHWR_DEVS_I2C_ARM_LPC2XXX_MULTIPLE_BUSES
+# define I2C_BASE(_extra_) (cyg_uint8*)HAL_LPC2XXX_I2C_SINGLETON_BASE
+# define I2C_ISRVEC(_extra_) HAL_LPC2XXX_I2C_SINGLETON_ISRVEC
+# define I2C_ISRPRI(_extra_) HAL_LPC2XXX_I2C_SINGLETON_ISRPRI
+# define I2C_CLK(_extra_) HAL_LPC2XXX_I2C_SINGLETON_CLK
+# define I2C_BUS_FREQ(_extra_) HAL_LPC2XXX_I2C_SINGLETON_BUS_FREQ
+#else
+# define I2C_BASE(_extra_) ((_extra_)->i2c_base)
+# define I2C_ISRVEC(_extra_) ((_extra_)->i2c_isrvec)
+# define I2C_ISRPRI(_extra_) ((_extra_)->i2c_isrpri)
+# define I2C_CLK(_extra_) ((_extra_)->i2c_pclk)
+# define I2C_BUS_FREQ(_extra_) ((_extra_)->i2c_bus_freq)
+#endif // CYGHWR_DEVS_I2C_ARM_LPC2XXX_MULTIPLE_BUSES
+
+#define I2C_XFER 8
+
+#define I2C_CONSET(_extra_) (I2C_BASE(_extra_) + 0x0000)
+#define I2C_CON(_extra_) I2C_CONSET(_extra_)
+#define I2C_STAT(_extra_) (I2C_BASE(_extra_) + 0x0004)
+#define I2C_DAT(_extra_) (I2C_BASE(_extra_) + 0x0008)
+#define I2C_ADR(_extra_) (I2C_BASE(_extra_) + 0x000C)
+#define I2C_SCLH(_extra_) (I2C_BASE(_extra_) + 0x0010)
+#define I2C_SCLL(_extra_) (I2C_BASE(_extra_) + 0x0014)
+#define I2C_CONCLR(_extra_) (I2C_BASE(_extra_) + 0x0018)
+
+#define I2C_R8(r, x) HAL_READ_UINT8 ((r), (x))
+#define I2C_W8(r, x) HAL_WRITE_UINT8 ((r), (x))
+#define I2C_R16(r, x) HAL_READ_UINT16 ((r), (x))
+#define I2C_W16(r, x) HAL_WRITE_UINT16((r), (x))
+
+// Special case for setting/clearing bits in I2C_CON
+#define SET_CON(_extra_, x) I2C_W8(I2C_CONSET(_extra_), (x))
+#define CLR_CON(_extra_, x) I2C_W8(I2C_CONCLR(_extra_), (x))
+
+// I2C_CONSET register bits
+#define CON_AA (1<<2)
+#define CON_SI (1<<3)
+#define CON_STO (1<<4)
+#define CON_STA (1<<5)
+#define CON_EN (1<<6)
+
+
+#define I2C_FLAG_FINISH 1 // transfer finished
+#define I2C_FLAG_ACT 2 // bus still active, no STOP condition send
+#define I2C_FLAG_ERROR (1<<31) // one of the following errors occured:
+#define I2C_FLAG_ADDR (1<<30) // - address was not ACKed
+#define I2C_FLAG_DATA (1<<29) // - data was not ACKed
+#define I2C_FLAG_LOST (1<<28) // - bus arbitration was lost
+#define I2C_FLAG_BUF (1<<27) // - no buffer for reading or writing
+#define I2C_FLAG_UNK (1<<26) // - unknown I2C status
+#define I2C_FLAG_BUS (1<<25) // - bus error
+
+#if CYGPKG_DEVS_I2C_ARM_LPC2XXX_DEBUG_LEVEL > 0
+ #define debug1_printf(args...) diag_printf(args)
+#else
+ #define debug1_printf(args...)
+#endif
+#if CYGPKG_DEVS_I2C_ARM_LPC2XXX_DEBUG_LEVEL > 1
+ #define debug2_printf(args...) diag_printf(args)
+#else
+ #define debug2_printf(args...)
+#endif
+
+//==========================================================================
+// The ISR does the actual work. It is not that much work to justify
+// putting it in the DSR, and it is also not clear whether this would
+// even work. If an error occurs we try to leave the bus in the same
+// state as we would if there was no error.
+//==========================================================================
+static cyg_uint32 lpc2xxx_i2c_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ cyg_lpc2xxx_i2c_extra* extra = (cyg_lpc2xxx_i2c_extra*)data;
+ cyg_uint8 status;
+
+ I2C_R8(I2C_STAT(extra), status);
+ switch(status)
+ {
+ case 0x00: // bus error, stop transfer
+ SET_CON(extra, CON_STO);
+ extra->i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_BUS;
+ break;
+
+ case 0x08: // START sent, send Addr+R/W
+ case 0x10: // ReSTART sent, send Addr+R/W
+ CLR_CON(extra, CON_STA);
+ I2C_W8(I2C_DAT(extra), extra->i2c_addr);
+ break;
+
+ case 0x18: // Addr ACKed, send data
+ if(extra->i2c_txbuf == NULL)
+ {
+ extra->i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_BUF;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+ I2C_W8(I2C_DAT(extra), *extra->i2c_txbuf);
+ extra->i2c_txbuf++;
+ break;
+
+ case 0x28: // Data ACKed, send more
+ extra->i2c_count--;
+ if(extra->i2c_count == 0)
+ {
+ extra->i2c_flag = I2C_FLAG_FINISH;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+ I2C_W8(I2C_DAT(extra), *extra->i2c_txbuf);
+ extra->i2c_txbuf++;
+ break;
+
+ case 0x50: // Data ACKed, receive more
+ case 0x58: // Data not ACKed, end reception
+ if(extra->i2c_rxbuf == NULL)
+ {
+ extra->i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_BUF;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+
+ I2C_R8(I2C_DAT(extra), *extra->i2c_rxbuf);
+ extra->i2c_rxbuf++;
+ extra->i2c_count--;
+ // fall through
+
+ case 0x40: // Addr ACKed, receive data
+ if(status == 0x58 || extra->i2c_count == 0)
+ {
+ extra->i2c_flag = I2C_FLAG_FINISH;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+
+ if((extra->i2c_count == 1) && extra->i2c_rxnak)
+ {
+ CLR_CON(extra, CON_AA);
+ }
+ else
+ {
+ SET_CON(extra, CON_AA);
+ }
+ break;
+
+ case 0x20: // Addr not ACKed
+ case 0x48: // Addr not ACKed
+ SET_CON(extra, CON_STO); // tranfer failed - force stop
+ extra->i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_ADDR;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ break;
+
+ case 0x30: // Data not ACKed
+ SET_CON(extra, CON_STO); // tranfer failed - force stop
+ extra->i2c_count++;
+ extra->i2c_txbuf--;
+ extra->i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_DATA;
+ cyg_drv_interrupt_mask_intunsafe(vec);
+ cyg_drv_interrupt_acknowledge(vec);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ break;
+
+ case 0x38: // Arbitration lost
+ extra->i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_LOST;
+ break;
+
+ default: // lots of unused states
+ extra->i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_UNK;
+ break;
+ } // switch(status)
+
+ CLR_CON(extra, CON_SI);
+ cyg_drv_interrupt_acknowledge(vec);
+
+ //
+ // We need to call the DSR only if there is really something to signal,
+ // that means only if extra->i2c_flag != 0
+ //
+ if (extra->i2c_flag)
+ {
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+ else
+ {
+ return CYG_ISR_HANDLED;
+ }
+}
+
+
+//==========================================================================
+// DSR signals data
+//==========================================================================
+static void
+lpc2xxx_i2c_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_lpc2xxx_i2c_extra* extra = (cyg_lpc2xxx_i2c_extra*)data;
+ if(extra->i2c_flag)
+ {
+ cyg_drv_cond_signal(&extra->i2c_wait);
+ }
+}
+
+
+//==========================================================================
+// Initialize driver & hardware state
+//==========================================================================
+void cyg_lpc2xxx_i2c_init(struct cyg_i2c_bus *bus)
+{
+ cyg_lpc2xxx_i2c_extra* extra = (cyg_lpc2xxx_i2c_extra*)bus->i2c_extra;
+ cyg_uint16 duty_cycle;
+
+ cyg_drv_mutex_init(&extra->i2c_lock);
+ cyg_drv_cond_init(&extra->i2c_wait, &extra->i2c_lock);
+ cyg_drv_interrupt_create(I2C_ISRVEC(extra),
+ I2C_ISRPRI(extra),
+ (cyg_addrword_t) extra,
+ &lpc2xxx_i2c_isr,
+ &lpc2xxx_i2c_dsr,
+ &(extra->i2c_interrupt_handle),
+ &(extra->i2c_interrupt_data));
+ cyg_drv_interrupt_attach(extra->i2c_interrupt_handle);
+
+
+ CLR_CON(extra, CON_EN | CON_STA | CON_SI | CON_AA);
+ HAL_WRITE_UINT8(I2C_ADR(extra), 0);
+
+ //
+ // Setup I2C bus frequency
+ //
+ duty_cycle = (I2C_CLK(extra) / I2C_BUS_FREQ(extra)) / 2;
+ HAL_WRITE_UINT16(I2C_SCLL(extra), duty_cycle);
+ HAL_WRITE_UINT16(I2C_SCLH(extra), duty_cycle);
+
+ SET_CON(extra, CON_EN);
+}
+
+
+//==========================================================================
+// transmit a buffer to a device
+//==========================================================================
+cyg_uint32 cyg_lpc2xxx_i2c_tx(const cyg_i2c_device *dev,
+ cyg_bool send_start,
+ const cyg_uint8 *tx_data,
+ cyg_uint32 count,
+ cyg_bool send_stop)
+{
+ cyg_lpc2xxx_i2c_extra* extra =
+ (cyg_lpc2xxx_i2c_extra*)dev->i2c_bus->i2c_extra;
+ extra->i2c_addr = dev->i2c_address << 1;
+ extra->i2c_count = count;
+ extra->i2c_txbuf = tx_data;
+
+ //
+ // for a repeated start the SI bit has to be reset
+ // if we continue a previous transfer, load the next byte
+ //
+ if(send_start)
+ {
+ SET_CON(extra, CON_STA);
+ if (I2C_FLAG_ACT == extra->i2c_flag)
+ {
+ CLR_CON(extra, CON_SI);
+ }
+ }
+ else
+ {
+ HAL_WRITE_UINT8(I2C_DAT(extra), *(extra->i2c_txbuf));
+ extra->i2c_txbuf++;
+ CLR_CON(extra, CON_SI);
+ }
+
+ extra->i2c_flag = 0;
+
+ //
+ // the isr will do most of the work, and the dsr will signal when an
+ // error occured or the transfer finished
+ //
+ cyg_drv_mutex_lock(&extra->i2c_lock);
+ cyg_drv_dsr_lock();
+ cyg_drv_interrupt_unmask(I2C_ISRVEC(extra));
+ while(!(extra->i2c_flag & (I2C_FLAG_FINISH | I2C_FLAG_ERROR)))
+ {
+ cyg_drv_cond_wait(&extra->i2c_wait);
+ }
+ cyg_drv_interrupt_mask(I2C_ISRVEC(extra));
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&extra->i2c_lock);
+
+ // too bad we have no way to tell the caller
+ if(extra->i2c_flag & I2C_FLAG_ERROR)
+ {
+ debug1_printf("I2C TX error flag: %x\n", extra->i2c_flag);
+ extra->i2c_flag = 0;
+ }
+ else
+ {
+ if(send_stop)
+ {
+ SET_CON(extra, CON_STO);
+ CLR_CON(extra, CON_SI | CON_STA);
+ extra->i2c_flag = 0;
+ }
+ else
+ {
+ extra->i2c_flag = I2C_FLAG_ACT;
+ }
+ }
+
+ count -= extra->i2c_count;
+
+ extra->i2c_addr = 0;
+ extra->i2c_count = 0;
+ extra->i2c_txbuf = NULL;
+
+ return count;
+}
+
+
+//==========================================================================
+// receive into a buffer from a device
+//==========================================================================
+cyg_uint32 cyg_lpc2xxx_i2c_rx(const cyg_i2c_device *dev,
+ cyg_bool send_start,
+ cyg_uint8 *rx_data,
+ cyg_uint32 count,
+ cyg_bool send_nak,
+ cyg_bool send_stop)
+{
+ cyg_lpc2xxx_i2c_extra* extra =
+ (cyg_lpc2xxx_i2c_extra*)dev->i2c_bus->i2c_extra;
+ extra->i2c_addr = (dev->i2c_address << 1) | 0x01;
+ extra->i2c_count = count;
+ extra->i2c_rxbuf = rx_data;
+ extra->i2c_rxnak = send_nak;
+
+ //
+ // for a repeated start the SI bit has to be reset
+ // if we continue a previous transfer, start reception
+ //
+ if(send_start)
+ {
+ SET_CON(extra, CON_STA);
+ if (I2C_FLAG_ACT == extra->i2c_flag)
+ {
+ CLR_CON(extra, CON_SI);
+ }
+ }
+
+ extra->i2c_flag = 0;
+
+ //
+ // the isr will do most of the work, and the dsr will signal when an
+ // error occurred or the transfer finished
+ //
+ cyg_drv_mutex_lock(&extra->i2c_lock);
+ cyg_drv_dsr_lock();
+ cyg_drv_interrupt_unmask(I2C_ISRVEC(extra));
+ while(!(extra->i2c_flag & (I2C_FLAG_FINISH | I2C_FLAG_ERROR)))
+ {
+ cyg_drv_cond_wait(&extra->i2c_wait);
+ }
+ cyg_drv_interrupt_mask(I2C_ISRVEC(extra));
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&extra->i2c_lock);
+
+ // too bad we have no way to tell the caller
+ if (extra->i2c_flag & I2C_FLAG_ERROR)
+ {
+ diag_printf("I2C RX error flag: %x\n", extra->i2c_flag);
+ extra->i2c_flag = 0;
+ }
+ else
+ {
+ if(send_stop)
+ {
+ SET_CON(extra, CON_STO);
+ CLR_CON(extra, CON_SI | CON_STA);
+ extra->i2c_flag = 0;
+ }
+ else
+ {
+ extra->i2c_flag = I2C_FLAG_ACT;
+ }
+ }
+
+ count -= extra->i2c_count;
+
+ extra->i2c_addr = 0;
+ extra->i2c_count = 0;
+ extra->i2c_rxbuf = NULL;
+
+ return count;
+}
+
+
+//==========================================================================
+// generate a STOP
+//==========================================================================
+void cyg_lpc2xxx_i2c_stop(const cyg_i2c_device *dev)
+{
+ cyg_lpc2xxx_i2c_extra* extra =
+ (cyg_lpc2xxx_i2c_extra*)dev->i2c_bus->i2c_extra;
+ extra = extra; // avoid compiler warning in case of singleton
+ SET_CON(extra, CON_STO);
+ extra->i2c_flag = 0;
+ extra->i2c_count = 0;
+}
+
+//---------------------------------------------------------------------------
+// eof i2c_lpc2xxx.c
diff --git a/ecos/packages/devs/i2c/cortexm/a2fxxx/current/ChangeLog b/ecos/packages/devs/i2c/cortexm/a2fxxx/current/ChangeLog
new file mode 100644
index 0000000..738696c
--- /dev/null
+++ b/ecos/packages/devs/i2c/cortexm/a2fxxx/current/ChangeLog
@@ -0,0 +1,31 @@
+2011-04-01 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * cdl/i2c_a2fxxx.cdl:
+ * include/i2c_a2fxxx.h:
+ * src/i2c_a2fxxx.c:
+ New package -- Smartfusion Cortex-M3 I2C driver package.
+ [Bugzilla 1001291]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/i2c/cortexm/a2fxxx/current/cdl/i2c_a2fxxx.cdl b/ecos/packages/devs/i2c/cortexm/a2fxxx/current/cdl/i2c_a2fxxx.cdl
new file mode 100644
index 0000000..05ec5a4
--- /dev/null
+++ b/ecos/packages/devs/i2c/cortexm/a2fxxx/current/cdl/i2c_a2fxxx.cdl
@@ -0,0 +1,113 @@
+# ====================================================================
+#
+# i2c_a2fxxx.cdl
+#
+# eCos Smartfusion Cortex-M3 I2C configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ccoutand
+# Contributors:
+# Date: 2011-01-18
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_I2C_CORTEXM_A2FXXX {
+ display "Actel Smartfusion I2C driver"
+ parent CYGPKG_IO_I2C
+ active_if CYGPKG_IO_I2C
+ active_if CYGPKG_HAL_CORTEXM_A2FXXX
+ include_dir cyg/io
+ description "
+ This package provides a generic I2C device driver for the on-chip
+ I2C modules in Smartfusion Cortex-M3 microcontroller."
+
+ compile -library=libextras.a i2c_a2fxxx.c
+
+ cdl_option CYGNUM_HAL_CORTEXM_A2FXXX_I2C_CLK_DIV {
+ display "I2C channel clock divider"
+ flavor data
+ default_value { 256 }
+ legal_values { 8 60 120 160 192 960 224 256 960}
+ description "
+ Set the I2C clock divider."
+ }
+
+ cdl_option CYGDBG_DEVS_I2C_CORTEXM_A2FXXX_TRACE {
+ display "Display status messages during I2C operations"
+ flavor bool
+ default_value 0
+ description "
+ Selecting this option will cause the I2C driver to print status
+ messages as various I2C operations are undertaken."
+ }
+
+ cdl_component CYGPKG_DEVS_I2C_CORTEXM_A2FXXX_OPTIONS {
+ display "I2C driver build options"
+ flavor none
+ active_if { CYGINT_DEVS_I2C_CORTEXM_A2FXXX_BUS_DEVICES > 0 }
+ description "
+ Package specific build options including control over
+ compiler flags used only in building the Smartfusion Cortex-M3
+ I2C bus driver."
+
+ cdl_option CYGPKG_DEVS_I2C_CORTEXM_A2FXXX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Smartfusion Cortex-M3 I2C bus driver. These
+ flags are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_I2C_CORTEXM_A2FXXX_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Smartfusion Cortex-M3 I2C bus driver. These
+ flags are removed from the set of global flags if
+ present."
+ }
+ }
+}
+
+# EOF i2c_a2fxxx.cdl
diff --git a/ecos/packages/devs/i2c/cortexm/a2fxxx/current/include/i2c_a2fxxx.h b/ecos/packages/devs/i2c/cortexm/a2fxxx/current/include/i2c_a2fxxx.h
new file mode 100644
index 0000000..9aa027a
--- /dev/null
+++ b/ecos/packages/devs/i2c/cortexm/a2fxxx/current/include/i2c_a2fxxx.h
@@ -0,0 +1,128 @@
+//==========================================================================
+//
+// i2c_a2fxxx.h
+//
+// I2C driver for Smartfusion Cortex M3 microcontroller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Contributors:
+// Date: 2011-01-18
+// Original: Bart Veer
+// I2C driver for motorola coldfire processor
+// Description: I2C driver for Smartfusion Cortex M3 microcontroller
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#ifndef CYGONCE_I2C_A2FXXX_H
+# define CYGONCE_I2C_A2FXXX_H
+
+# include <pkgconf/devs_i2c_cortexm_a2fxxx.h>
+# include <cyg/infra/cyg_type.h>
+# include <cyg/hal/drv_api.h>
+
+typedef enum a2fxxx_i2c_xfer_mode {
+ A2FXXX_I2C_XFER_MODE_INVALID = 0x00,
+ A2FXXX_I2C_XFER_MODE_TX = 0x01,
+ A2FXXX_I2C_XFER_MODE_RX = 0x02
+} a2fxxx_i2c_xfer_mode;
+
+typedef struct a2fxxx_i2c_extra {
+ cyg_uint32 i2c_base; // I2C base address
+ cyg_uint32 i2c_base_bb; // I2C base address (Bit-band)
+ cyg_uint32 i2c_periph; // I2C peripheral bit mask
+ cyg_uint8 i2c_owner; // We have bus ownership
+ cyg_uint8 i2c_lost_arb; // Error condition leading to loss of
+ // bus ownership
+ cyg_uint8 i2c_send_nack; // As per rx send_nack argument
+ cyg_uint8 i2c_got_nack; // The last tx resulted in a nack
+ cyg_uint8 i2c_completed; // Set by DSR, checked by thread
+
+ union {
+ const cyg_uint8 *i2c_tx_data;
+ cyg_uint8 *i2c_rx_data;
+ } i2c_data; // The current buffer for rx or tx
+ cyg_uint32 i2c_count; // Number of bytes left in buffer
+ a2fxxx_i2c_xfer_mode i2c_mode; // TX, RX, ...
+
+ cyg_bool send_stop;
+ cyg_bool send_start;
+ cyg_uint8 slave_addr;
+ cyg_drv_mutex_t i2c_lock; // For synchronizing between DSR and
+ // foreground
+ cyg_drv_cond_t i2c_wait;
+ // For initializing the interrupt
+ cyg_handle_t i2c_interrupt_handle;
+ cyg_interrupt i2c_interrupt_data;
+ cyg_uint32 i2c_isr_id;
+ cyg_uint32 i2c_isr_pri;
+ cyg_uint32 i2c_isr_mask;
+} a2fxxx_i2c_extra;
+
+externC void a2fxxx_i2c_init(struct cyg_i2c_bus *);
+externC cyg_uint32 a2fxxx_i2c_tx(const cyg_i2c_device *, cyg_bool,
+ const cyg_uint8 *, cyg_uint32, cyg_bool);
+externC cyg_uint32 a2fxxx_i2c_rx(const cyg_i2c_device *, cyg_bool,
+ cyg_uint8 *, cyg_uint32, cyg_bool, cyg_bool);
+externC void a2fxxx_i2c_stop(const cyg_i2c_device *);
+
+# define CYG_A2FXXX_I2C_BUS( \
+ _name_, \
+ _init_fn_, \
+ _base_, \
+ _base_bb_, \
+ _periph_, \
+ _isr_vec_, \
+ _isr_pri_) \
+ static a2fxxx_i2c_extra _name_ ## _extra = { \
+ .i2c_base = _base_, \
+ .i2c_base_bb = _base_bb_, \
+ .i2c_periph = _periph_, \
+ .i2c_isr_id = _isr_vec_, \
+ .i2c_isr_pri = _isr_pri_ \
+ }; \
+ CYG_I2C_BUS(_name_, \
+ _init_fn_, \
+ a2fxxx_i2c_tx, \
+ a2fxxx_i2c_rx, \
+ a2fxxx_i2c_stop, \
+ (void*) & ( _name_ ## _extra)) ;
+
+#endif // CYGONCE_I2C_A2FXXX_H
+
+// -------------------------------------------------------------------------
+// EOF i2c_a2fxxx.h
diff --git a/ecos/packages/devs/i2c/cortexm/a2fxxx/current/src/i2c_a2fxxx.c b/ecos/packages/devs/i2c/cortexm/a2fxxx/current/src/i2c_a2fxxx.c
new file mode 100644
index 0000000..239bb09
--- /dev/null
+++ b/ecos/packages/devs/i2c/cortexm/a2fxxx/current/src/i2c_a2fxxx.c
@@ -0,0 +1,450 @@
+//==========================================================================
+//
+// i2c_a2fxxx.c
+//
+// I2C driver for Smartfusion Cortex M3 microcontroller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Contributors:
+// Date: 2011-01-18
+// Original: Uwe Kindler, Bart Veer
+// I2C driver for motorola coldfire processor
+// Description: I2C driver for Smartfusion Cortex M3 microcontroller
+// The RX part of the driver has not been tested.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/i2c.h>
+#include <cyg/io/i2c_a2fxxx.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+#ifdef CYGDBG_DEVS_I2C_CORTEXM_A2FXXX_TRACE
+# define I2C_TRACE(args...) diag_printf(args)
+#else
+# define I2C_TRACE(args...)
+#endif
+
+#define I2C_DAT(_base_) (_base_ + CYGHWR_HAL_A2FXXX_I2C_DATA)
+#define I2C_ADR(_base_) (_base_ + CYGHWR_HAL_A2FXXX_I2C_ADDR)
+#define I2C_SR(_base_) (_base_ + CYGHWR_HAL_A2FXXX_I2C_STATUS)
+#define I2C_CR(_base_) (_base_ + CYGHWR_HAL_A2FXXX_I2C_CTRL)
+#define I2C_FREQ(_base_) (_base_ + CYGHWR_HAL_A2FXXX_I2C_FREQ)
+#define I2C_SMBUS(_base_) (_base_ + CYGHWR_HAL_A2FXXX_I2C_SMBUS)
+#define I2C_GLITCH(_base_) (_base_ + CYGHWR_HAL_A2FXXX_I2C_GLITCH)
+
+// Bit-band definition
+#define I2C_CR_CR0(_base_) (_base_ + ( CYGHWR_HAL_A2FXXX_I2C_CTRL << 5 ) + \
+ ( 0*sizeof(cyg_uint32) ) )
+#define I2C_CR_CR1(_base_) (_base_ + ( CYGHWR_HAL_A2FXXX_I2C_CTRL << 5 ) + \
+ ( 1*sizeof(cyg_uint32) ) )
+#define I2C_CR_AA(_base_) (_base_ + ( CYGHWR_HAL_A2FXXX_I2C_CTRL << 5 ) + \
+ ( 2*sizeof(cyg_uint32) ) )
+#define I2C_CR_SI(_base_) (_base_ + ( CYGHWR_HAL_A2FXXX_I2C_CTRL << 5 ) + \
+ ( 3*sizeof(cyg_uint32) ) )
+#define I2C_CR_STO(_base_) (_base_ + ( CYGHWR_HAL_A2FXXX_I2C_CTRL << 5 ) + \
+ ( 4*sizeof(cyg_uint32) ) )
+#define I2C_CR_STA(_base_) (_base_ + ( CYGHWR_HAL_A2FXXX_I2C_CTRL << 5 ) + \
+ ( 5*sizeof(cyg_uint32) ) )
+#define I2C_CR_ENS1(_base_) (_base_ + ( CYGHWR_HAL_A2FXXX_I2C_CTRL << 5 ) + \
+ ( 6*sizeof(cyg_uint32) ) )
+#define I2C_CR_CR2(_base_) (_base_ + ( CYGHWR_HAL_A2FXXX_I2C_CTRL << 5 ) + \
+ ( 7*sizeof(cyg_uint32) ) )
+
+#define I2C_MTX_STATE(x) CYGHWR_HAL_A2FXXX_I2C_STATUS_MTX_##x
+#define I2C_MRX_STATE(x) CYGHWR_HAL_A2FXXX_I2C_STATUS_MRX_##x
+
+// Divider coefficient
+static const unsigned int i2c_div[] = {
+ 256,
+ 224,
+ 192,
+ 160,
+ 960,
+ 120,
+ 60,
+ 8,
+ 0
+};
+
+static cyg_uint32
+a2fxxx_i2c_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ a2fxxx_i2c_extra *extra = (a2fxxx_i2c_extra *) data;
+ cyg_uint32 result = CYG_ISR_HANDLED;
+ cyg_uint32 sr,
+ dr;
+ cyg_uint8 tx_data = *extra->i2c_data.i2c_tx_data;
+ cyg_uint32 cr = 0;
+
+ // Read the current status of the I2C
+ HAL_READ_UINT32(I2C_SR(extra->i2c_base), sr);
+ HAL_READ_UINT32(I2C_CR(extra->i2c_base), cr);
+
+ // What to do next depends on the current transfer mode.
+ if (A2FXXX_I2C_XFER_MODE_TX == extra->i2c_mode) {
+ I2C_TRACE("I2C: TX IRQ handling -> 0x%x\n", sr);
+ switch (sr) {
+ // Start/Repeated start, write the slave address and clear the
+ // START and SI bits
+ case I2C_MTX_STATE(START):
+ case I2C_MTX_STATE(REPEAT_START):
+ HAL_WRITE_UINT32(I2C_DAT(extra->i2c_base), extra->slave_addr);
+ cr &= ~CYGHWR_HAL_A2FXXX_I2C_CTRL_STA;
+ cr &= ~CYGHWR_HAL_A2FXXX_I2C_CTRL_SI;
+ break;
+ // ACK is received for the address or data, keep sending
+ // START and SI bits
+ case I2C_MTX_STATE(ADDR_ACK):
+ case I2C_MTX_STATE(DATA_ACK):
+ if (0 == extra->i2c_count) {
+ if (extra->send_stop) {
+ cr |= CYGHWR_HAL_A2FXXX_I2C_CTRL_STO;
+ cr &= ~CYGHWR_HAL_A2FXXX_I2C_CTRL_SI;
+ } else {
+ // For repeated start, we must disable interrupt
+ extra->i2c_isr_mask = true;
+ }
+ // No more bytes to send.
+ result |= CYG_ISR_CALL_DSR;
+ } else {
+ // Send byte
+ HAL_WRITE_UINT32(I2C_DAT(extra->i2c_base),
+ (cyg_uint32)tx_data);
+ extra->i2c_data.i2c_tx_data += 1;
+ extra->i2c_count -= 1;
+ cr &= ~CYGHWR_HAL_A2FXXX_I2C_CTRL_SI;
+ }
+ break;
+ case I2C_MTX_STATE(ARBLOST):
+ case I2C_MTX_STATE(DATA_NACK):
+ // Lost the bus, abort the transfer. count has already been
+ // decremented. Assume the byte did not actually arrive.
+ extra->i2c_count += 1;
+ case I2C_MTX_STATE(ADDR_NACK):
+ // For all error type, clear interrupt and send stop bit
+ cr |= CYGHWR_HAL_A2FXXX_I2C_CTRL_STO;
+ cr &= ~CYGHWR_HAL_A2FXXX_I2C_CTRL_SI;
+ extra->i2c_got_nack = 1;
+ result |= CYG_ISR_CALL_DSR;
+ break;
+ default:
+ HAL_INTERRUPT_ACKNOWLEDGE(extra->i2c_isr_id);
+ return result;
+ }
+ } else if (A2FXXX_I2C_XFER_MODE_RX == extra->i2c_mode) {
+ I2C_TRACE("I2C: RX IRQ handling -> 0x%x\n", sr);
+ cr &= ~CYGHWR_HAL_A2FXXX_I2C_CTRL_AA;
+ switch (sr) {
+ // Start/Repeated start, write the slave address and clear the
+ // START and SI bits
+ case I2C_MRX_STATE(START):
+ case I2C_MRX_STATE(REPEAT_START):
+ HAL_WRITE_UINT32(I2C_DAT(extra->i2c_base), extra->slave_addr);
+ cr &= ~CYGHWR_HAL_A2FXXX_I2C_CTRL_STA;
+ cr &= ~CYGHWR_HAL_A2FXXX_I2C_CTRL_SI;
+ break;
+ // ACK is received for the address
+ case I2C_MRX_STATE(ADDR_ACK):
+ if (extra->i2c_count > 1) {
+ cr |= CYGHWR_HAL_A2FXXX_I2C_CTRL_AA;
+ }
+ cr &= ~CYGHWR_HAL_A2FXXX_I2C_CTRL_SI;
+ break;
+ // Receive data
+ case I2C_MRX_STATE(DATA_ACK):
+ case I2C_MRX_STATE(DATA_NACK):
+ cr &= ~CYGHWR_HAL_A2FXXX_I2C_CTRL_SI;
+ if (extra->i2c_count > 2) {
+ cr |= CYGHWR_HAL_A2FXXX_I2C_CTRL_AA;
+ }
+ if (1 == extra->i2c_count) {
+ if (extra->send_stop) {
+ cr |= CYGHWR_HAL_A2FXXX_I2C_CTRL_STO;
+ } else {
+ // For repeated start, we must disable interrupt
+ cr |= CYGHWR_HAL_A2FXXX_I2C_CTRL_SI;
+ extra->i2c_isr_mask = true;
+ }
+ // Received the last byte.
+ result |= CYG_ISR_CALL_DSR;
+ }
+ HAL_READ_UINT32(I2C_DAT(extra->i2c_base), dr);
+ *(extra->i2c_data.i2c_rx_data) = (cyg_uint8)dr;
+ extra->i2c_data.i2c_rx_data += 1;
+ extra->i2c_count -= 1;
+ break;
+ case I2C_MRX_STATE(ARBLOST):
+ case I2C_MRX_STATE(ADDR_NACK):
+ // Lost the bus? Maybe a spurious stop
+ cr |= CYGHWR_HAL_A2FXXX_I2C_CTRL_STO;
+ result |= CYG_ISR_CALL_DSR;
+ break;
+ default:
+ HAL_INTERRUPT_ACKNOWLEDGE(extra->i2c_isr_id);
+ return result;
+ }
+ } else {
+ // Invalid state? Some kind of spurious interrupt?
+ // Just ignore it.
+ I2C_TRACE("I2C spurious interrupt\n");
+ }
+
+ HAL_WRITE_UINT32(I2C_CR(extra->i2c_base), cr);
+
+ HAL_INTERRUPT_ACKNOWLEDGE(extra->i2c_isr_id);
+
+ if (extra->i2c_isr_mask)
+ HAL_INTERRUPT_MASK(extra->i2c_isr_id);
+
+ return result;
+}
+
+
+static void
+a2fxxx_i2c_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ a2fxxx_i2c_extra *extra = (a2fxxx_i2c_extra *) data;
+ extra->i2c_completed = 1;
+ cyg_drv_cond_signal(&(extra->i2c_wait));
+}
+
+
+// A transfer has been started. Wait for completion
+static inline void
+a2fxxx_i2c_doit(a2fxxx_i2c_extra * extra)
+{
+ cyg_drv_mutex_lock(&(extra->i2c_lock));
+ cyg_drv_dsr_lock();
+ while (!extra->i2c_completed) {
+ cyg_drv_cond_wait(&(extra->i2c_wait));
+ }
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&(extra->i2c_lock));
+}
+
+
+static inline void
+a2fxxx_i2c_stopit(a2fxxx_i2c_extra * extra)
+{
+ extra->i2c_lost_arb = 0;
+ extra->i2c_owner = 0;
+ extra->i2c_mode = A2FXXX_I2C_XFER_MODE_INVALID;
+}
+
+
+void
+a2fxxx_i2c_stop(const cyg_i2c_device * dev)
+{
+ a2fxxx_i2c_extra *extra = (a2fxxx_i2c_extra *) dev->i2c_bus->i2c_extra;
+ a2fxxx_i2c_stopit(extra);
+}
+
+
+cyg_uint32
+a2fxxx_i2c_tx(const cyg_i2c_device * dev, cyg_bool send_start,
+ const cyg_uint8 *tx_data, cyg_uint32 count, cyg_bool send_stop)
+{
+ a2fxxx_i2c_extra *extra = (a2fxxx_i2c_extra *) dev->i2c_bus->i2c_extra;
+ extra->send_stop = send_stop;
+ extra->send_start = send_start;
+ extra->i2c_count = count;
+ extra->slave_addr = ((dev->i2c_address << 1) | 0x00);
+ cyg_uint32 si = 0;
+
+ if (!extra->i2c_lost_arb) {
+ extra->i2c_completed = 0;
+ extra->i2c_mode = A2FXXX_I2C_XFER_MODE_TX;
+
+ if (send_start || !extra->i2c_got_nack) {
+ I2C_TRACE
+ ("I2C: TX to %2x, data %2x, count: %4d, START flag: %s, STOP flag: %s\n",
+ dev->i2c_address, *tx_data, count,
+ (send_start == true) ? "true" : "false",
+ (send_stop == true) ? "true" : "false");
+ extra->i2c_data.i2c_tx_data = tx_data;
+ HAL_READ_UINT32(I2C_CR_SI(extra->i2c_base_bb), si);
+ // Set start bit
+ HAL_WRITE_UINT32(I2C_CR_STA(extra->i2c_base_bb),
+ CYGHWR_HAL_A2FXXX_BITSET);
+ // For repeated start, we need to clear the interrupt
+ if (si != 0) {
+ HAL_WRITE_UINT32(I2C_CR_SI(extra->i2c_base_bb),
+ CYGHWR_HAL_A2FXXX_BITCLEAR);
+ HAL_INTERRUPT_ACKNOWLEDGE(extra->i2c_isr_id);
+ }
+ // For repeated start, we need to un-mask the interrupt
+ if (extra->i2c_isr_mask) {
+ extra->i2c_isr_mask = false;
+ HAL_INTERRUPT_UNMASK(extra->i2c_isr_id);
+ }
+ a2fxxx_i2c_doit(extra);
+ }
+
+ }
+ if (send_stop) {
+ I2C_TRACE("I2C: TX send stop\n");
+ a2fxxx_i2c_stopit(extra);
+ }
+
+ I2C_TRACE("I2C: TX count %d\n", extra->i2c_count);
+
+ // tx() should return the number of bytes actually transmitted.
+ // ISR() increments extra->count after a failure, which leads to
+ // an edge condition when send_start and there is no acknowledgment
+ // of the address byte.
+ if (extra->i2c_count > count) {
+ return 0;
+ }
+
+ return count - extra->i2c_count;
+}
+
+
+cyg_uint32
+a2fxxx_i2c_rx(const cyg_i2c_device * dev, cyg_bool send_start,
+ cyg_uint8 *rx_data, cyg_uint32 count, cyg_bool send_nack,
+ cyg_bool send_stop)
+{
+ a2fxxx_i2c_extra *extra = (a2fxxx_i2c_extra *) dev->i2c_bus->i2c_extra;
+ extra->i2c_send_nack = send_nack;
+ extra->i2c_count = count;
+ extra->send_stop = send_stop;
+ extra->send_start = send_start;
+ extra->slave_addr = ((dev->i2c_address << 1) | 0x01);
+ cyg_uint32 si = 0;
+
+ if (!extra->i2c_lost_arb) {
+ extra->i2c_completed = 0;
+ extra->i2c_data.i2c_rx_data = rx_data;
+ extra->i2c_mode = A2FXXX_I2C_XFER_MODE_RX;
+ I2C_TRACE
+ ("I2C: RX to %2x, count: %4d, START flag: %s, STOP flag: %s\n",
+ dev->i2c_address, count, (send_start == true) ? "true" : "false",
+ (send_stop == true) ? "true" : "false");
+ HAL_READ_UINT32(I2C_CR_SI(extra->i2c_base_bb), si);
+ // Set start bit
+ HAL_WRITE_UINT32(I2C_CR_STA(extra->i2c_base_bb),
+ CYGHWR_HAL_A2FXXX_BITSET);
+ // For repeated start, we need to clear the interrupt
+ if (si != 0) {
+ HAL_WRITE_UINT32(I2C_CR_SI(extra->i2c_base_bb),
+ CYGHWR_HAL_A2FXXX_BITCLEAR);
+ HAL_INTERRUPT_ACKNOWLEDGE(extra->i2c_isr_id);
+ }
+ // For repeated start, we need to un-mask the interrupt
+ if (extra->i2c_isr_mask) {
+ extra->i2c_isr_mask = false;
+ HAL_INTERRUPT_UNMASK(extra->i2c_isr_id);
+ }
+ a2fxxx_i2c_doit(extra);
+ }
+
+ if (send_stop) {
+ I2C_TRACE("I2C: RX send stop\n");
+ a2fxxx_i2c_stopit(extra);
+ }
+
+ return count - extra->i2c_count;
+}
+
+
+// ----------------------------------------------------------------------------
+// The functions needed for all I2C devices.
+
+void
+a2fxxx_i2c_init(struct cyg_i2c_bus *bus)
+{
+ a2fxxx_i2c_extra *extra = (a2fxxx_i2c_extra *) bus->i2c_extra;
+ cyg_uint8 div = 0;
+#ifdef CYGDBG_DEVS_I2C_CORTEXM_A2FXXX_TRACE
+ cyg_uint32 i2c_freq =
+ ((hal_a2fxxx_i2c_clock(extra->i2c_base) /
+ CYGNUM_HAL_CORTEXM_A2FXXX_I2C_CLK_DIV));
+#endif
+
+ while ((i2c_div[div] != CYGNUM_HAL_CORTEXM_A2FXXX_I2C_CLK_DIV) &&
+ i2c_div[div] != 0) {
+ div++;
+ }
+
+ I2C_TRACE("\nI2C INIT, divider: %d(%d), frequency: %d\n", i2c_div[div],
+ div, i2c_freq);
+
+ cyg_drv_mutex_init(&extra->i2c_lock);
+ cyg_drv_cond_init(&extra->i2c_wait, &extra->i2c_lock);
+ cyg_drv_interrupt_create(extra->i2c_isr_id,
+ extra->i2c_isr_pri,
+ (cyg_addrword_t)extra,
+ &a2fxxx_i2c_isr,
+ &a2fxxx_i2c_dsr,
+ &(extra->i2c_interrupt_handle),
+ &(extra->i2c_interrupt_data));
+ cyg_drv_interrupt_attach(extra->i2c_interrupt_handle);
+
+ // Enable I2C peripheral
+ CYGHWR_HAL_A2FXXX_PERIPH_RELEASE(extra->i2c_periph);
+
+ // Set I2C bus speed
+ HAL_WRITE_UINT32(I2C_CR_ENS1(extra->i2c_base_bb),
+ CYGHWR_HAL_A2FXXX_BITSET);
+
+ HAL_WRITE_UINT32(I2C_CR_CR0(extra->i2c_base_bb),
+ ((div & 0x1) ? CYGHWR_HAL_A2FXXX_BITSET :
+ CYGHWR_HAL_A2FXXX_BITCLEAR));
+ HAL_WRITE_UINT32(I2C_CR_CR1(extra->i2c_base_bb),
+ ((div & 0x2) ? CYGHWR_HAL_A2FXXX_BITSET :
+ CYGHWR_HAL_A2FXXX_BITCLEAR));
+ HAL_WRITE_UINT32(I2C_CR_CR2(extra->i2c_base_bb),
+ ((div & 0x4) ? CYGHWR_HAL_A2FXXX_BITSET :
+ CYGHWR_HAL_A2FXXX_BITCLEAR));
+
+ // Interrupts can now be safely unmasked
+ HAL_INTERRUPT_UNMASK(extra->i2c_isr_id);
+}
+
+//---------------------------------------------------------------------------
+// EOF i2c_a2fxxx.c
diff --git a/ecos/packages/devs/i2c/cortexm/lm3s/current/ChangeLog b/ecos/packages/devs/i2c/cortexm/lm3s/current/ChangeLog
new file mode 100644
index 0000000..121e57e
--- /dev/null
+++ b/ecos/packages/devs/i2c/cortexm/lm3s/current/ChangeLog
@@ -0,0 +1,30 @@
+2011-01-18 Christophe Coutand <ccoutand@stmi.com>
+
+ * cdl/i2c_lm3s.cdl:
+ * include/i2c_lm3s.h:
+ * src/i2c_lm3s.c:
+ New package -- Stellaris Cortex M3 I2C driver package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/i2c/cortexm/lm3s/current/cdl/i2c_lm3s.cdl b/ecos/packages/devs/i2c/cortexm/lm3s/current/cdl/i2c_lm3s.cdl
new file mode 100644
index 0000000..6084920
--- /dev/null
+++ b/ecos/packages/devs/i2c/cortexm/lm3s/current/cdl/i2c_lm3s.cdl
@@ -0,0 +1,113 @@
+# ====================================================================
+#
+# i2c_lm3s.cdl
+#
+# eCos Stellaris Cortex M3 I2C configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ccoutand
+# Contributors:
+# Date: 2011-01-18
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_I2C_CORTEXM_LM3S {
+ display "I2C driver for Stellaris Cortex M3 microcontroller family"
+ parent CYGPKG_IO_I2C
+ active_if CYGPKG_IO_I2C
+ active_if CYGPKG_HAL_CORTEXM_LM3S
+ include_dir cyg/io
+ description "
+ This package provides a generic I2C device driver for the on-chip
+ I2C modules in Stellaris Cortex M3 microcontroller."
+
+ compile -library=libextras.a i2c_lm3s.c
+
+ cdl_option CYGNUM_HAL_CORTEXM_LM3S_I2C_CLK_SPEED {
+ display "I2C channel clock"
+ flavor data
+ default_value { 100000 }
+ legal_values { 100000 400000 }
+ description "
+ Set the I2C clock speed. Slow mode (100KHz) or fast mode
+ (400KHz)"
+ }
+
+ cdl_option CYGPKG_DEVS_I2C_CORTEXM_LM3S_TRACE {
+ display "I2C trace"
+ flavor bool
+ default_value 0
+ description "
+ Enable I2C transaction trace. Select to debug the driver."
+ }
+
+ cdl_component CYGPKG_DEVS_I2C_CORTEXM_LM3S_OPTIONS {
+ display "I2C driver build options"
+ flavor none
+ active_if { CYGINT_DEVS_I2C_CORTEXM_LM3S_BUS_DEVICES > 0 }
+ description "
+ Package specific build options including control over
+ compiler flags used only in building the Stellaris Cortex M3
+ I2C bus driver."
+
+ cdl_option CYGPKG_DEVS_I2C_CORTEXM_LM3S_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Stellaris Cortex M3 I2C bus driver. These
+ flags are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_I2C_CORTEXM_LM3S_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Stellaris Cortex M3 I2C bus driver. These
+ flags are removed from the set of global flags if
+ present."
+ }
+ }
+}
+
+# EOF i2c_lm3s.cdl
diff --git a/ecos/packages/devs/i2c/cortexm/lm3s/current/include/i2c_lm3s.h b/ecos/packages/devs/i2c/cortexm/lm3s/current/include/i2c_lm3s.h
new file mode 100644
index 0000000..d969427
--- /dev/null
+++ b/ecos/packages/devs/i2c/cortexm/lm3s/current/include/i2c_lm3s.h
@@ -0,0 +1,124 @@
+//==========================================================================
+//
+// i2c_lm3s8xx.h
+//
+// I2C driver for Stellaris Cortex M3 microcontroller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Contributors:
+// Date: 2011-01-18
+// Original: Bart Veer
+// I2C driver for motorola coldfire processor
+// Description: I2C driver for Stellaris Cortex M3 microcontroller
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#ifndef CYGONCE_I2C_LM3S_H
+#define CYGONCE_I2C_LM3S_H
+
+#include <pkgconf/devs_i2c_cortexm_lm3s.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+
+typedef enum lm3s_i2c_xfer_mode {
+ LM3S_I2C_XFER_MODE_INVALID = 0x00,
+ LM3S_I2C_XFER_MODE_TX = 0x01,
+ LM3S_I2C_XFER_MODE_RX = 0x02
+} lm3s_i2c_xfer_mode;
+
+typedef struct lm3s_i2c_extra {
+ cyg_uint32 i2c_base; // I2C base address
+ cyg_uint32 i2c_periph; // I2C peripheral bit mask
+ cyg_uint8 i2c_owner; // We have bus ownership
+ cyg_uint8 i2c_lost_arb; // Error condition leading to loss of
+ // bus ownership
+ cyg_uint8 i2c_send_nack; // As per rx send_nack argument
+ cyg_uint8 i2c_got_nack; // The last tx resulted in a nack
+ cyg_uint8 i2c_completed; // Set by DSR, checked by thread
+
+ union {
+ const cyg_uint8 *i2c_tx_data;
+ cyg_uint8 *i2c_rx_data;
+ } i2c_data; // The current buffer for rx or tx
+ cyg_uint32 i2c_count; // Number of bytes left in buffer
+ lm3s_i2c_xfer_mode i2c_mode; // TX, RX, ...
+
+ cyg_bool send_stop;
+ cyg_bool send_start;
+ cyg_drv_mutex_t i2c_lock; // For synchronizing between DSR and
+ // foreground
+ cyg_drv_cond_t i2c_wait;
+ // For initializing the interrupt
+ cyg_handle_t i2c_interrupt_handle;
+ cyg_interrupt i2c_interrupt_data;
+ cyg_uint32 i2c_isr_id;
+ cyg_uint32 i2c_isr_pri;
+} lm3s_i2c_extra;
+
+externC void lm3s_i2c_init(struct cyg_i2c_bus *);
+externC cyg_uint32 lm3s_i2c_tx(const cyg_i2c_device *, cyg_bool,
+ const cyg_uint8 *, cyg_uint32, cyg_bool);
+externC cyg_uint32 lm3s_i2c_rx(const cyg_i2c_device *, cyg_bool, cyg_uint8 *,
+ cyg_uint32, cyg_bool, cyg_bool);
+externC void lm3s_i2c_stop(const cyg_i2c_device *);
+
+#define CYG_LM3S_I2C_BUS( \
+ _name_, \
+ _init_fn_, \
+ _base_, \
+ _periph_, \
+ _isr_vec_, \
+ _isr_pri_, \
+ _fdr_) \
+ static lm3s_i2c_extra _name_ ## _extra = { \
+ .i2c_base = _base_, \
+ .i2c_periph = _periph_, \
+ .i2c_isr_id = _isr_vec_, \
+ .i2c_isr_pri= _isr_pri_ \
+ }; \
+ CYG_I2C_BUS(_name_, \
+ _init_fn_, \
+ lm3s_i2c_tx, \
+ lm3s_i2c_rx, \
+ lm3s_i2c_stop, \
+ (void*) & ( _name_ ## _extra)) ;
+
+#endif // CYGONCE_I2C_LM3S_H
+
+// -------------------------------------------------------------------------
+// EOF i2c_lm3s.h
diff --git a/ecos/packages/devs/i2c/cortexm/lm3s/current/src/i2c_lm3s.c b/ecos/packages/devs/i2c/cortexm/lm3s/current/src/i2c_lm3s.c
new file mode 100644
index 0000000..c084bf2
--- /dev/null
+++ b/ecos/packages/devs/i2c/cortexm/lm3s/current/src/i2c_lm3s.c
@@ -0,0 +1,389 @@
+//==========================================================================
+//
+// i2c_lm3s.c
+//
+// I2C driver for Stellaris Cortex M3 microcontroller
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Contributors:
+// Date: 2011-01-18
+// Original: Uwe Kindler, Bart Veer
+// I2C driver for motorola coldfire processor
+// Description: I2C driver for Stellaris Cortex M3 microcontroller
+// The RX part of the driver has not been tested.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/i2c.h>
+#include <cyg/io/i2c_lm3s.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+#ifdef CYGPKG_DEVS_I2C_CORTEXM_LM3S_TRACE
+# define I2C_TRACE(args...) diag_printf(args)
+#else
+# define I2C_TRACE(args...)
+#endif
+
+#define I2C_DAT(_extra_) (_extra_ + CYGHWR_HAL_LM3S_I2C_MDR)
+#define I2C_ADR(_extra_) (_extra_ + CYGHWR_HAL_LM3S_I2C_MSA)
+#define I2C_SR(_extra_) (_extra_ + CYGHWR_HAL_LM3S_I2C_MCS)
+#define I2C_CR(_extra_) (_extra_ + CYGHWR_HAL_LM3S_I2C_MCS)
+#define I2C_MCR(_extra_) (_extra_ + CYGHWR_HAL_LM3S_I2C_MCR)
+#define I2C_MTPR(_extra_) (_extra_ + CYGHWR_HAL_LM3S_I2C_MTPR)
+#define I2C_MCR(_extra_) (_extra_ + CYGHWR_HAL_LM3S_I2C_MCR)
+#define I2C_IMR(_extra_) (_extra_ + CYGHWR_HAL_LM3S_I2C_MIMR)
+#define I2C_ICR(_extra_) (_extra_ + CYGHWR_HAL_LM3S_I2C_MICR)
+
+#define WAIT_BUS_READY( __sr__, __extra__ ) \
+{ \
+ if (!__extra__->i2c_owner) { \
+ __extra__->i2c_got_nack = 0; \
+ __extra__->i2c_owner = 1; \
+ HAL_READ_UINT32(I2C_SR(__extra__->i2c_base), __sr__); \
+ while (__sr__ & CYGHWR_HAL_LM3S_I2C_MCS_BUSBSY) { \
+ HAL_READ_UINT32(I2C_SR(__extra__->i2c_base),__sr__); \
+ } \
+ } \
+}
+
+
+static cyg_uint32
+lm3s_i2c_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ lm3s_i2c_extra *extra = (lm3s_i2c_extra *) data;
+ cyg_uint32 sr,
+ dr;
+ cyg_uint32 result = CYG_ISR_HANDLED;
+ cyg_uint32 reg = CYGHWR_HAL_LM3S_I2C_MCS_RUN;
+ cyg_uint8 tx_data = *extra->i2c_data.i2c_tx_data;
+
+ // Read the current status, then clear the interrupt
+ HAL_READ_UINT32(I2C_SR(extra->i2c_base), sr);
+ HAL_WRITE_UINT32(I2C_ICR(extra->i2c_base), 1);
+
+ // What to do next depends on the current transfer mode.
+ if (LM3S_I2C_XFER_MODE_TX == extra->i2c_mode) {
+ I2C_TRACE("I2C: TX IRQ handling\n");
+ if (sr & CYGHWR_HAL_LM3S_I2C_MCS_ERR) {
+ // Lost the bus, abort the transfer. count has already been
+ // decremented. Assume the byte did not actually arrive.
+ extra->i2c_count += 1;
+ // Arbitration lost, stop
+ if (sr & CYGHWR_HAL_LM3S_I2C_MCS_ARBLST) {
+ reg = CYGHWR_HAL_LM3S_I2C_MCS_STOP;
+ HAL_WRITE_UINT32(I2C_CR(extra->i2c_base), reg);
+ }
+ // This byte has been sent but the device cannot accept
+ // any more. The nack must be remembered. Otherwise if
+ // we got a nack for the last byte in a tx then the
+ // calling code will think the entire tx succeeded,
+ // and there will be problems if the next call is
+ // another tx without a repeated start.
+ if ((sr & CYGHWR_HAL_LM3S_I2C_MCS_ADRACK) |
+ (sr & CYGHWR_HAL_LM3S_I2C_MCS_DATACK)) {
+ extra->i2c_got_nack = 1;
+ }
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ I2C_TRACE("I2C TX, bus arbitration error\n");
+ } else if (0 == extra->i2c_count) {
+ // No more bytes to send.
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else {
+ // Send byte
+ HAL_WRITE_UINT32(I2C_DAT(extra->i2c_base), (cyg_uint32)tx_data);
+ extra->i2c_data.i2c_tx_data += 1;
+ extra->i2c_count -= 1;
+ // Last byte
+ if ((0 == extra->i2c_count) && extra->send_stop) {
+ reg |= CYGHWR_HAL_LM3S_I2C_MCS_STOP;
+ }
+ HAL_WRITE_UINT32(I2C_CR(extra->i2c_base), reg);
+ }
+ } else if (LM3S_I2C_XFER_MODE_RX == extra->i2c_mode) {
+ I2C_TRACE("I2C: RX IRQ handling\n");
+ if (sr & CYGHWR_HAL_LM3S_I2C_MCS_ERR) {
+ // Lost the bus? Maybe a spurious stop
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else {
+ if (2 == extra->i2c_count) {
+ // Received one, one more to go,
+ // and that one should be nacked.
+ if (!extra->i2c_send_nack) {
+ reg |= CYGHWR_HAL_LM3S_I2C_MCS_ACK;
+ }
+ if (extra->send_stop) {
+ reg |= CYGHWR_HAL_LM3S_I2C_MCS_STOP;
+ }
+ HAL_WRITE_UINT32(I2C_CR(extra->i2c_base), reg);
+ } else if (1 == extra->i2c_count) {
+ // Received the last byte.
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+ HAL_READ_UINT32(I2C_DAT(extra->i2c_base), dr);
+ *(extra->i2c_data.i2c_rx_data) = (cyg_uint8)dr;
+ extra->i2c_data.i2c_rx_data += 1;
+ extra->i2c_count -= 1;
+ }
+ } else {
+ // Invalid state? Some kind of spurious interrupt?
+ // Just ignore it.
+ I2C_TRACE("I2C spurious interrupt\n");
+ }
+
+ HAL_INTERRUPT_ACKNOWLEDGE(extra->i2c_isr_id);
+
+ return result;
+}
+
+
+static void
+lm3s_i2c_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ lm3s_i2c_extra *extra = (lm3s_i2c_extra *) data;
+ extra->i2c_completed = 1;
+ cyg_drv_cond_signal(&(extra->i2c_wait));
+}
+
+
+// A transfer has been started. Wait for completion
+static inline void
+lm3s_i2c_doit(lm3s_i2c_extra * extra)
+{
+ cyg_drv_mutex_lock(&(extra->i2c_lock));
+ cyg_drv_dsr_lock();
+ while (!extra->i2c_completed) {
+ cyg_drv_cond_wait(&(extra->i2c_wait));
+ }
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&(extra->i2c_lock));
+}
+
+
+static inline void
+lm3s_i2c_stopit(lm3s_i2c_extra * extra)
+{
+ extra->i2c_lost_arb = 0;
+ extra->i2c_owner = 0;
+ extra->i2c_mode = LM3S_I2C_XFER_MODE_INVALID;
+}
+
+
+void
+lm3s_i2c_stop(const cyg_i2c_device * dev)
+{
+ lm3s_i2c_extra *extra = (lm3s_i2c_extra *) dev->i2c_bus->i2c_extra;
+ lm3s_i2c_stopit(extra);
+}
+
+
+static cyg_bool
+lm3s_i2c_handle_xfer(lm3s_i2c_extra * extra, int address)
+{
+ cyg_uint32 sr;
+ cyg_uint8 data = *extra->i2c_data.i2c_tx_data;
+ cyg_uint32 reg = CYGHWR_HAL_LM3S_I2C_MCS_RUN;
+
+ // Nothing to send or receive
+ if (extra->i2c_count == 0)
+ return 0;
+
+ // Take the bus ownership
+ WAIT_BUS_READY(sr, extra);
+
+ // This can be a start or repeated start
+ if (extra->send_start) {
+ reg |= CYGHWR_HAL_LM3S_I2C_MCS_START;
+ HAL_WRITE_UINT32(I2C_ADR(extra->i2c_base), address);
+ }
+ // TX transfer
+ if (extra->i2c_mode == LM3S_I2C_XFER_MODE_TX) {
+ extra->i2c_data.i2c_tx_data += 1;
+ extra->i2c_count -= 1;
+ HAL_WRITE_UINT32(I2C_DAT(extra->i2c_base), (cyg_uint32)data);
+
+ // Single byte transfer
+ if (extra->send_stop && (extra->i2c_count == 0)) {
+ reg |= CYGHWR_HAL_LM3S_I2C_MCS_STOP;
+ }
+ } else {
+ // Single byte transfer, set the STOP bit
+ if (extra->send_stop && (extra->i2c_count == 1)) {
+ reg |= CYGHWR_HAL_LM3S_I2C_MCS_STOP;
+ }
+ // Do not ACK last byte per user request
+ if (!extra->i2c_send_nack || !(extra->i2c_count == 1)) {
+ reg |= CYGHWR_HAL_LM3S_I2C_MCS_ACK;
+ }
+ }
+
+ HAL_WRITE_UINT32(I2C_CR(extra->i2c_base), reg);
+
+ return 1;
+}
+
+
+cyg_uint32
+lm3s_i2c_tx(const cyg_i2c_device * dev, cyg_bool send_start,
+ const cyg_uint8 *tx_data, cyg_uint32 count, cyg_bool send_stop)
+{
+ lm3s_i2c_extra *extra = (lm3s_i2c_extra *) dev->i2c_bus->i2c_extra;
+ extra->send_stop = send_stop;
+ extra->send_start = send_start;
+ extra->i2c_count = count;
+
+ if (!extra->i2c_lost_arb) {
+ extra->i2c_completed = 0;
+ extra->i2c_mode = LM3S_I2C_XFER_MODE_TX;
+
+ if (send_start || !extra->i2c_got_nack) {
+ I2C_TRACE
+ ("I2C: TX to %2x, data %2x, count: %4d, START flag: %s\n",
+ dev->i2c_address, *tx_data, count,
+ (send_start == true) ? "true" : "false");
+ extra->i2c_data.i2c_tx_data = tx_data;
+ if (!lm3s_i2c_handle_xfer(extra, (dev->i2c_address << 1) | 0x00)) {
+ return 0;
+ }
+ lm3s_i2c_doit(extra);
+ }
+
+ }
+ if (send_stop) {
+ I2C_TRACE("I2C: TX send stop\n");
+ lm3s_i2c_stopit(extra);
+ }
+
+ I2C_TRACE("I2C: TX count %d\n", extra->i2c_count);
+
+ // tx() should return the number of bytes actually transmitted.
+ // ISR() increments extra->count after a failure, which leads to
+ // an edge condition when send_start and there is no acknowledgment
+ // of the address byte.
+ if (extra->i2c_count > count) {
+ return 0;
+ }
+
+ return count - extra->i2c_count;
+}
+
+
+cyg_uint32
+lm3s_i2c_rx(const cyg_i2c_device * dev, cyg_bool send_start,
+ cyg_uint8 *rx_data, cyg_uint32 count, cyg_bool send_nack,
+ cyg_bool send_stop)
+{
+ lm3s_i2c_extra *extra = (lm3s_i2c_extra *) dev->i2c_bus->i2c_extra;
+ extra->i2c_count = count;
+ extra->i2c_send_nack = send_nack;
+ extra->send_stop = send_stop;
+ extra->send_start = send_start;
+
+ if (!extra->i2c_lost_arb) {
+ extra->i2c_completed = 0;
+ extra->i2c_data.i2c_rx_data = rx_data;
+ extra->i2c_mode = LM3S_I2C_XFER_MODE_RX;
+ I2C_TRACE("I2C: RX to %2x, count: %4d, START flag: %s\n",
+ dev->i2c_address, count,
+ (send_start == true) ? "true" : "false");
+ if (!lm3s_i2c_handle_xfer(extra, (dev->i2c_address << 1) | 0x01)) {
+ return 0;
+ }
+ lm3s_i2c_doit(extra);
+ }
+
+ if (send_stop) {
+ I2C_TRACE("I2C: RX send stop\n");
+ lm3s_i2c_stopit(extra);
+ }
+
+ return count - extra->i2c_count;
+}
+
+
+// ----------------------------------------------------------------------------
+// The functions needed for all I2C devices.
+
+void
+lm3s_i2c_init(struct cyg_i2c_bus *bus)
+{
+ lm3s_i2c_extra *extra = (lm3s_i2c_extra *) bus->i2c_extra;
+ cyg_uint32 tpr =
+ ((hal_lm3s_i2c_clock() /
+ (20 * CYGNUM_HAL_CORTEXM_LM3S_I2C_CLK_SPEED)) - 1);
+
+ I2C_TRACE("I2C INIT, TPR register: %d\n", tpr);
+
+ cyg_drv_mutex_init(&extra->i2c_lock);
+ cyg_drv_cond_init(&extra->i2c_wait, &extra->i2c_lock);
+ cyg_drv_interrupt_create(extra->i2c_isr_id,
+ extra->i2c_isr_pri,
+ (cyg_addrword_t)extra,
+ &lm3s_i2c_isr,
+ &lm3s_i2c_dsr,
+ &(extra->i2c_interrupt_handle),
+ &(extra->i2c_interrupt_data));
+ cyg_drv_interrupt_attach(extra->i2c_interrupt_handle);
+
+ // Enable I2C peripheral, it is left to the variant/platform HAL to
+ // configure the SDA and SCL IOs.
+ CYGHWR_HAL_LM3S_PERIPH_SET(extra->i2c_periph, 1);
+
+ // Enable Master mode
+ HAL_WRITE_UINT32(I2C_MCR(extra->i2c_base), CYGHWR_HAL_LM3S_I2C_MCR_MFE);
+
+ // Set I2C bus speed
+ HAL_WRITE_UINT32(I2C_MTPR(extra->i2c_base), tpr);
+
+ // Enable Interrupt
+ HAL_WRITE_UINT32(I2C_IMR(extra->i2c_base), 1);
+
+ // Interrupts can now be safely unmasked
+ HAL_INTERRUPT_UNMASK(extra->i2c_isr_id);
+}
+
+//---------------------------------------------------------------------------
+// EOF i2c_lm3s.c
diff --git a/ecos/packages/devs/i2c/freescale/i2c/current/ChangeLog b/ecos/packages/devs/i2c/freescale/i2c/current/ChangeLog
new file mode 100644
index 0000000..94efe46
--- /dev/null
+++ b/ecos/packages/devs/i2c/freescale/i2c/current/ChangeLog
@@ -0,0 +1,39 @@
+2013-04-30 Ilija Kocho <ilijak@siva.com.mk>
+
+ * src/i2c_freescale.cdl: Add requirement of CYGPKG_KERNEL.
+ [ Bugzilla 1001397 ]
+
+2011-11-20 Tomas Frydrych <tomas@sleepfive.com>
+2013-03-21 Mike Jones <mike@proclivis.com>
+
+ * cdl/i2c_freescale.cdl:
+ * include/i2c_freescale.h:
+ * src/i2c_freescale.c:
+ Tomas: New package -- Freescale I2C driver package. [Bugzilla 1001397]
+ Mike: Made adjustments to state machine behavior to prevent race conditions
+ that led to lockup. Debugged data rate code provided by Ilija Kocho.
+ Fully tested with large PMBus application and verified clock rates.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/i2c/freescale/i2c/current/cdl/i2c_freescale.cdl b/ecos/packages/devs/i2c/freescale/i2c/current/cdl/i2c_freescale.cdl
new file mode 100644
index 0000000..e05052b
--- /dev/null
+++ b/ecos/packages/devs/i2c/freescale/i2c/current/cdl/i2c_freescale.cdl
@@ -0,0 +1,183 @@
+# ====================================================================
+#
+# i2c_freescale.cdl
+#
+# eCos Freescale Kinetis and ColdFire+ I2C configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Tomas Frydrych
+# Contributors:
+# Date: 2011-11-20
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_interface CYGINT_IO_FREESCALE_I2C_BUS {
+ display "Number of I2C buses"
+}
+
+cdl_package CYGPKG_DEVS_I2C_FREESCALE_I2C {
+ display "Freescale I2C driver"
+ parent CYGPKG_IO_I2C
+ requires CYGPKG_IO_I2C
+ active_if CYGPKG_KERNEL
+ requires CYGPKG_HAL_CORTEXM_KINETIS
+ include_dir cyg/io
+ description "
+ This package provides a generic I2C device driver for the on-chip
+ I2C modules in Freescale Kinetis and ColdFire+ chips."
+
+ compile -library=libextras.a i2c_freescale.c
+
+ for { set ::bus 0 } { $::bus < 2 } { incr ::bus } {
+
+ cdl_interface CYGINT_IO_FREESCALE_I2C[set ::bus] {
+ display "I2C bus [set ::bus] is present"
+ }
+
+ cdl_component CYGHWR_DEVS_FREESCALE_I2C[set ::bus] {
+ display "I2C bus [set ::bus]"
+ flavor bool
+ description "Enable I2C bus [set ::bus]"
+ requires CYGPKG_DEVS_I2C_FREESCALE_I2C
+ active_if CYGINT_IO_FREESCALE_I2C[set ::bus]
+ implements CYGINT_IO_FREESCALE_I2C_BUS
+ default_value 0
+
+ cdl_component CYGNUM_DEVS_FREESCALE_I2C[set ::bus]_CLOCK {
+ display "Default I2C bus frequency"
+ flavor data
+ description "
+ The default frequency setting for I2C[set ::bus].
+ If bit 31 is set then the least significant byte contains
+ pre-calculeted frequency divider register setting.
+ Otherwise other bits contain frequency setpoint in \[Hz\]."
+
+ requires (CYGNUM_DEVS_FREESCALE_I2C[set ::bus]_CLOCK > 0 && \
+ CYGNUM_DEVS_FREESCALE_I2C[set ::bus]_CLOCK <= 268435455) || \
+ (CYGNUM_DEVS_FREESCALE_I2C[set ::bus]_CLOCK >= 0x80000000 && \
+ CYGNUM_DEVS_FREESCALE_I2C[set ::bus]_CLOCK <= 0x800000FF)
+
+ default_value 100000
+
+ cdl_option CYGNUM_DEVS_FREESCALE_I2C[set ::bus]_CLOCK_FIT {
+ display "Fit"
+ flavor data
+ legal_values 1 2 3
+ default_value 1
+ description "
+ For a given clock frequency there are several divider
+ register that fit. This option is hints on which fit to end lookup"
+ }
+
+ cdl_option CYGNUM_DEVS_FREESCALE_I2C[set ::bus]_CLOCK_AGR {
+ display "Aggressive clocking"
+ flavor data
+ legal_values 0 1
+ default_value 0
+ description "
+ If the setpoint bus frequency is not available, then if
+ this option is 1 the closest available frequency is
+ picked even if it overclocks. If 0 the closest available
+ frequency frequency not higher than setpoint is picked."
+ }
+ }
+
+ cdl_component CYGOPT_DEVS_FREESCALE_I2C[set ::bus]_C2 {
+ display "C2 register options"
+ flavor data
+ calculated 0x0 | \
+ CYGOPT_DEVS_FREESCALE_I2C[set ::bus]_C2_HDRS << 5
+
+ cdl_option CYGOPT_DEVS_FREESCALE_I2C[set ::bus]_C2_HDRS {
+ display "High drive select"
+ flavor bool
+ no_define
+ default_value 0
+ }
+ }
+
+ cdl_option CYGNUM_DEVS_FREESCALE_I2C[set ::bus]_FLT {
+ display "Glitch filter"
+ flavor data
+ default_value 0
+ legal_values { 0 to 31 }
+ }
+ }
+ }
+
+ cdl_option CYGPKG_DEVS_I2C_FREESCALE_I2C_TRACE {
+ display "I2C trace"
+ flavor bool
+ default_value 0
+ description "
+ Enable I2C transaction trace. Select to debug the driver."
+ }
+
+ cdl_component CYGPKG_DEVS_I2C_FREESCALE_I2C_OPTIONS {
+ display "I2C driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building the Freescale I2C bus driver."
+
+ cdl_option CYGPKG_DEVS_I2C_FREESCALE_I2C_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Freescale I2C bus driver. These
+ flags are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_I2C_FREESCALE_I2C_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Freescale I2C bus driver. These
+ flags are removed from the set of global flags if
+ present."
+ }
+ }
+}
+
+# EOF i2c_freescale.cdl
diff --git a/ecos/packages/devs/i2c/freescale/i2c/current/include/i2c_freescale.h b/ecos/packages/devs/i2c/freescale/i2c/current/include/i2c_freescale.h
new file mode 100644
index 0000000..6c575f3
--- /dev/null
+++ b/ecos/packages/devs/i2c/freescale/i2c/current/include/i2c_freescale.h
@@ -0,0 +1,254 @@
+//==========================================================================
+//
+// i2c_freescale.h
+//
+// I2C driver for Freescale Kinetis and ColdFire+ microcontrollers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Tomas Frydrych <tomas@sleepfive.com>
+// Contributors:
+// Date: 2011-11-20
+// Original: ccoutand
+// I2C driver for Stellaris Cortex M3 microcontroller
+// Description: I2C driver for Freescale Kinetis and ColdFire+
+// microcontrollers
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#ifndef CYGONCE_I2C_FREESCALE_H
+#define CYGONCE_I2C_FREESCALE_H
+
+#include <pkgconf/devs_i2c_freescale_i2c.h>
+#include <cyg/io/i2c.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+
+//---------------------------------------------------------------------------
+// i2c memory structure
+typedef volatile struct freescale_i2c_s {
+ cyg_uint8 a1;
+ cyg_uint8 f;
+ cyg_uint8 c1;
+ cyg_uint8 s;
+ cyg_uint8 d;
+ cyg_uint8 c2;
+ cyg_uint8 flt;
+ cyg_uint8 ra;
+ cyg_uint8 smb;
+ cyg_uint8 a2;
+ cyg_uint8 slth;
+ cyg_uint8 sltl;
+} freescale_i2c_t;
+
+// I2C register base pointers
+#define FREESCALE_I2C_P(__base) ((freescale_i2c_t*)(__base))
+
+// Modes
+// Master write
+#define FREESCALE_I2C_MODE_MW 0x0u
+// Master read
+#define FREESCALE_I2C_MODE_MR 0x1u
+
+// Bit Fields
+#define FREESCALE_I2C_A1_AD_M 0xFEu
+#define FREESCALE_I2C_A1_AD_S 1
+// adress register from address and mode
+#define FREESCALE_I2C_A1_AD(__a, __m) \
+ ((((cyg_uint8)(((cyg_uint8)(__a))<<FREESCALE_I2C_A1_AD_S)) & \
+ FREESCALE_I2C_A1_AD_M)|(__m & 0x1u))
+
+#define FREESCALE_I2C_F_ICR_M 0x3Fu
+#define FREESCALE_I2C_F_ICR_S 0
+#define FREESCALE_I2C_F_ICR(x) \
+ (((cyg_uint8)(((cyg_uint8)(x))<<FREESCALE_I2C_F_ICR_S)) & \
+ FREESCALE_I2C_F_ICR_M)
+#define FREESCALE_I2C_F_MULT_M 0xC0u
+#define FREESCALE_I2C_F_MULT_S 6
+#define FREESCALE_I2C_F_MULT(x) \
+ (((cyg_uint8)(((cyg_uint8)(x))<<FREESCALE_I2C_F_MULT_S)) & \
+ FREESCALE_I2C_F_MULT_M)
+#define FREESCALE_I2C_F(__mult, __icr) \
+ (FREESCALE_I2C_F_MULT (__mult) | \
+ FREESCALE_I2C_F_ICR (__icr))
+
+#define FREESCALE_I2C_C1_DMAEN_M 0x1u
+#define FREESCALE_I2C_C1_WUEN_M 0x2u
+#define FREESCALE_I2C_C1_RSTA_M 0x4u
+#define FREESCALE_I2C_C1_TXAK_M 0x8u
+#define FREESCALE_I2C_C1_TX_M 0x10u
+#define FREESCALE_I2C_C1_MST_M 0x20u
+#define FREESCALE_I2C_C1_IICIE_M 0x40u
+#define FREESCALE_I2C_C1_IICEN_M 0x80u
+
+#define FREESCALE_I2C_S_RXAK_M 0x1u
+#define FREESCALE_I2C_S_IICIF_M 0x2u
+#define FREESCALE_I2C_S_SRW_M 0x4u
+#define FREESCALE_I2C_S_RAM_M 0x8u
+#define FREESCALE_I2C_S_ARBL_M 0x10u
+#define FREESCALE_I2C_S_BUSY_M 0x20u
+#define FREESCALE_I2C_S_IAAS_M 0x40u
+#define FREESCALE_I2C_S_TCF_M 0x80u
+
+#define FREESCALE_I2C_C2_AD_M 0x7u
+#define FREESCALE_I2C_C2_AD_S 0
+#define FREESCALE_I2C_C2_AD(x) \
+ (((cyg_uint8)(((cyg_uint8)(x))<<FREESCALE_I2C_C2_AD_S)) & \
+ FREESCALE_I2C_C2_AD_M)
+#define FREESCALE_I2C_C2_RMEN_M 0x8u
+#define FREESCALE_I2C_C2_SBRC_M 0x10u
+#define FREESCALE_I2C_C2_HDRS_M 0x20u
+#define FREESCALE_I2C_C2_ADEXT_M 0x40u
+#define FREESCALE_I2C_C2_GCAEN_M 0x80u
+
+#define FREESCALE_I2C_FLT_FLT_M 0x1Fu
+#define FREESCALE_I2C_FLT_FLT_S 0
+#define FREESCALE_I2C_FLT_FLT(x) \
+ (((cyg_uint8)(((cyg_uint8)(x))<<FREESCALE_I2C_FLT_FLT_S)) & \
+ FREESCALE_I2C_FLT_FLT_M)
+
+#define FREESCALE_I2C_RA_RAD_M 0xFEu
+#define FREESCALE_I2C_RA_RAD_S 1
+#define FREESCALE_I2C_RA_RAD(x) \
+ (((cyg_uint8)(((cyg_uint8)(x))<<FREESCALE_I2C_RA_RAD_S)) & \
+ FREESCALE_I2C_RA_RAD_M)
+
+#define FREESCALE_I2C_SMB_SHTF2IE_M 0x1u
+#define FREESCALE_I2C_SMB_SHTF2_M 0x2u
+#define FREESCALE_I2C_SMB_SHTF1_M 0x4u
+#define FREESCALE_I2C_SMB_SLTF_M 0x8u
+#define FREESCALE_I2C_SMB_TCKSEL_M 0x10u
+#define FREESCALE_I2C_SMB_SIICAEN_M 0x20u
+#define FREESCALE_I2C_SMB_ALERTEN_M 0x40u
+#define FREESCALE_I2C_SMB_FACK_M 0x80u
+
+#define FREESCALE_I2C_A2_SAD_M 0xFEu
+#define FREESCALE_I2C_A2_SAD_S 1
+#define FREESCALE_I2C_A2_SAD(x) \
+ (((cyg_uint8)(((cyg_uint8)(x))<<FREESCALE_I2C_A2_SAD_S)) & \
+ FREESCALE_I2C_A2_SAD_M)
+
+#define FREESCALE_I2C_SLTH_SSLT_M 0xFFu
+#define FREESCALE_I2C_SLTH_SSLT_S 0
+#define FREESCALE_I2C_SLTH_SSLT(x) \
+ (((cyg_uint8)(((cyg_uint8)(x))<<FREESCALE_I2C_SLTH_SSLT_S)) & \
+ FREESCALE_I2C_SLTH_SSLT_M)
+
+#define FREESCALE_I2C_SLTL_SSLT_M 0xFFu
+#define FREESCALE_I2C_SLTL_SSLT_S 0
+#define FREESCALE_I2C_SLTL_SSLT(x) \
+ (((cyg_uint8)(((cyg_uint8)(x))<<FREESCALE_I2C_SLTL_SSLT_S)) & \
+ FREESCALE_I2C_SLTL_SSLT_M)
+
+#define FREESCALE_I2C_DELAY_F_CACHED_S 31
+#define FREESCALE_I2C_DELAY_FIT_S 29
+#define FREESCALE_I2C_DELAY_AGR_S 28
+
+#define FREESCALE_I2C_DELAY_F_IS_CACHED_M BIT_(FREESCALE_I2C_DELAY_F_CACHED_S)
+#define FREESCALE_I2C_DELAY_F_CACHE_M 0xFF
+#define FREESCALE_I2C_DELAY_M 0x0FFFFFFF
+
+#define FREESCALE_I2C_DELAY_CFG(__delay, __fit, __agr) \
+ ((__delay) + (((__fit) & 0x3) << FREESCALE_I2C_DELAY_FIT_S) + \
+ (((__agr) & 0x1) << FREESCALE_I2C_DELAY_AGR_S))
+
+#define FREEDCALE_I2C_DELAY_IS_AGRESIVE(__delay) \
+ ((__delay) & (1 << FREESCALE_I2C_DELAY_AGR_S))
+
+typedef enum freescale_i2c_xfer_mode {
+ FREESCALE_I2C_XFER_MODE_INVALID = 0x00,
+ FREESCALE_I2C_XFER_MODE_TX = 0x01,
+ FREESCALE_I2C_XFER_MODE_RX = 0x02
+} freescale_i2c_xfer_mode;
+
+// Resources borrowed from HAL
+typedef struct freescale_i2c_extra_hal_s {
+ cyg_uint32 pin_sda; // Data pin
+ cyg_uint32 pin_scl; // Clock pin
+ cyg_uint32 clock; // Clock gate
+} freescale_i2c_extra_hal_t;
+
+/*
+ * Extra data for the i2c bus
+ */
+typedef struct freescale_i2c_extra {
+ cyg_uint32 i2c_base; // I2C base address
+ cyg_uint32 i2c_delay;
+ cyg_uint8 i2c_bus_number; // bus number
+ cyg_uint8 i2c_owner; // We have bus ownership
+ cyg_uint8 i2c_lost_arb; // Error condition leading to loss of
+ // bus ownership
+ cyg_uint8 i2c_send_nack; // As per rx send_nack argument
+ cyg_uint8 i2c_got_nack; // The last tx resulted in a nack
+ cyg_uint8 i2c_completed; // Set by DSR, checked by thread
+
+ cyg_uint8 c2_cfg; // C2 register default settings
+ cyg_uint8 flt_cfg; // Glitch filter setting
+
+ union {
+ const cyg_uint8 *i2c_tx_data;
+ cyg_uint8 *i2c_rx_data;
+ } i2c_data; // The current buffer for rx or tx
+ cyg_uint32 i2c_count; // Number of bytes left in buffer
+
+ freescale_i2c_xfer_mode i2c_mode; // TX, RX, ...
+
+ cyg_bool send_stop;
+ cyg_bool send_start;
+ cyg_drv_mutex_t i2c_lock; // For synchronizing between DSR and
+ // foreground
+ cyg_drv_cond_t i2c_wait;
+ // For initializing the interrupt
+ cyg_handle_t i2c_interrupt_handle;
+ cyg_interrupt i2c_interrupt_data;
+ cyg_uint32 i2c_isr_id;
+ cyg_uint32 i2c_isr_pri;
+ const freescale_i2c_extra_hal_t *hal_p; // Resources borrowed from HAL
+} freescale_i2c_extra;
+
+externC void freescale_i2c_init(struct cyg_i2c_bus *);
+externC cyg_uint32 freescale_i2c_tx(cyg_i2c_device *, cyg_bool,
+ const cyg_uint8 *, cyg_uint32, cyg_bool);
+externC cyg_uint32 freescale_i2c_rx(cyg_i2c_device *,
+ cyg_bool, cyg_uint8 *, cyg_uint32,
+ cyg_bool, cyg_bool);
+externC void freescale_i2c_stop(const cyg_i2c_device *);
+externC void freescale_i2c_set_frequency (cyg_i2c_device * dev,
+ cyg_uint8 premul);
+
+#endif // CYGONCE_I2C_FREESCALE_H
+// -------------------------------------------------------------------------
+// EOF i2c_freescale.h
diff --git a/ecos/packages/devs/i2c/freescale/i2c/current/include/i2c_freescale_buses.inl b/ecos/packages/devs/i2c/freescale/i2c/current/include/i2c_freescale_buses.inl
new file mode 100644
index 0000000..3ffc26d
--- /dev/null
+++ b/ecos/packages/devs/i2c/freescale/i2c/current/include/i2c_freescale_buses.inl
@@ -0,0 +1,108 @@
+#ifndef CYGONCE_I2C_FREESCALE_BUSES_INL
+#define CYGONCE_I2C_FREESCALE_BUSES_INL
+//==========================================================================
+//
+// i2c_freescale_buses.inl
+//
+// Freescale I2C bus instances
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ilijak
+// Contributors:
+// Date: 2011-11-20
+// Description: Freescale I2C bus instances
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// I2C bus definition macros
+// HAL should provide following macros per _bus_:
+// -I2C controller base address
+// CYGADDR_IO_I2C_FREESCALE_I2C<_bus_>_BASE
+// -Interrupt vector number and priority
+// CYGNUM_DEVS_INTERRUPT_I2C<_bus_>
+// CYGNUM_DEVS_FREESCALE_I2C<_bus_>_IRQ_PRIORITY
+// -I2C pin configuration:
+// CYGHWR_IO_I2C_FREESCALE_I2C<_bus_>_PIN_SDA
+// CYGHWR_IO_I2C_FREESCALE_I2C<_bus_>_PIN_SCL
+// -Clock gating
+// CYGHWR_IO_FREESCALE_I2C<_bus_>_CLK
+
+#define CYG_FREESCALE_I2C_BUS(_bus_) \
+static const freescale_i2c_extra_hal_t cyg_i2c ## _bus_ ## _extra_hal = { \
+ .pin_sda = CYGHWR_IO_I2C_FREESCALE_I2C ## _bus_ ## _PIN_SDA, \
+ .pin_scl = CYGHWR_IO_I2C_FREESCALE_I2C ## _bus_ ## _PIN_SCL, \
+ .clock = CYGHWR_IO_FREESCALE_I2C ## _bus_ ## _CLK \
+}; \
+ \
+static freescale_i2c_extra cyg_i2c ## _bus_ ## _bus_extra = { \
+ .i2c_base = CYGADDR_IO_I2C_FREESCALE_I2C ## _bus_ ## _BASE, \
+ .i2c_bus_number = _bus_, \
+ .i2c_delay = CYGNUM_DEVS_FREESCALE_I2C ## _bus_ ## _CLOCK & 0x80000000 ? \
+ CYGNUM_DEVS_FREESCALE_I2C ## _bus_ ## _CLOCK : \
+ FREESCALE_I2C_DELAY_CFG(1000000000 / \
+ CYGNUM_DEVS_FREESCALE_I2C ## _bus_ ## _CLOCK, \
+ CYGNUM_DEVS_FREESCALE_I2C ## _bus_ ## _CLOCK_FIT - 1, \
+ CYGNUM_DEVS_FREESCALE_I2C ## _bus_ ## _CLOCK_AGR), \
+ .i2c_isr_id = CYGNUM_HAL_INTERRUPT_I2C ## _bus_, \
+ .i2c_isr_pri = CYGNUM_DEVS_FREESCALE_I2C ## _bus_ ## _IRQ_PRIORITY, \
+ .c2_cfg = CYGOPT_DEVS_FREESCALE_I2C ## _bus_ ## _C2, \
+ .flt_cfg = CYGNUM_DEVS_FREESCALE_I2C ## _bus_ ## _FLT, \
+ .hal_p = &(cyg_i2c ## _bus_ ## _extra_hal) \
+}; \
+ \
+CYG_I2C_BUS(cyg_i2c ## _bus_ ## _bus, \
+ freescale_i2c_init, \
+ freescale_i2c_tx, \
+ freescale_i2c_rx, \
+ freescale_i2c_stop, \
+ (void*) & (cyg_i2c ## _bus_ ## _bus_extra)) ;
+
+#endif // CYGONCE_I2C_FREESCALE_BUSES_INL
+
+//-----------------------------------------------------------------------------
+// I2C bus instances
+//
+#ifdef CYGHWR_DEVS_FREESCALE_I2C0
+CYG_FREESCALE_I2C_BUS(0);
+#endif
+
+#ifdef CYGHWR_DEVS_FREESCALE_I2C1
+CYG_FREESCALE_I2C_BUS(1);
+#endif
+// -------------------------------------------------------------------------
+// EOF i2c_freescale_buses.inl
diff --git a/ecos/packages/devs/i2c/freescale/i2c/current/src/i2c_freescale.c b/ecos/packages/devs/i2c/freescale/i2c/current/src/i2c_freescale.c
new file mode 100644
index 0000000..79538e6
--- /dev/null
+++ b/ecos/packages/devs/i2c/freescale/i2c/current/src/i2c_freescale.c
@@ -0,0 +1,839 @@
+//==========================================================================
+//
+// i2c_freescale.c
+//
+// I2C driver for Freescale Kinetis and ColdFire+ microcontrollers
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Tomas Frydrych <tomas@sleepfive.com>
+// Contributors: Mike Jones <mike@proclivis.com>
+// Ilija Kocho <ilijak@siva.com.mk>
+// Date: 2011-11-20
+// Original: ccoutand
+// I2C driver for Stellaris Cortex M3 microcontroller
+// Description: Driver for Freescale I2C controller
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#define CYGBLD_I2C_DEVICE_CONST
+#include <cyg/io/i2c.h>
+#include <cyg/io/i2c_freescale.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/kernel/kapi.h>
+
+#ifdef CYGPKG_DEVS_I2C_FREESCALE_I2C_TRACE
+# define I2C_TRACE(args...) diag_printf(args)
+#else
+# define I2C_TRACE(args...)
+#endif
+
+#ifndef CYGNUM_DEV_I2C_SPIN_PRIO
+#define CYGNUM_DEV_I2C_SPIN_PRIO (CYGNUM_KERNEL_SCHED_PRIORITIES - 2)
+#endif
+
+#ifndef CYGNUM_DEV_I2C_SPIN_TIMEOUT
+#define CYGNUM_DEV_I2C_SPIN_TIMEOUT 30
+#endif
+
+#define CYGOPT_FREESCALE_I2C_FREQ_FAST_EXIT 0
+
+#define I2C_STOP(__i2c) \
+CYG_MACRO_START \
+ __i2c->c1 &= ~FREESCALE_I2C_C1_MST_M; \
+ __i2c->c1 &= ~FREESCALE_I2C_C1_TX_M; \
+CYG_MACRO_END
+
+#define I2C_START(__i2c) \
+CYG_MACRO_START \
+ __i2c->c1 |= FREESCALE_I2C_C1_TX_M; \
+ __i2c->c1 |= FREESCALE_I2C_C1_MST_M; \
+CYG_MACRO_END
+
+#define I2C_REPEAT_START(__i2c) \
+CYG_MACRO_START \
+ __i2c->c1 |= FREESCALE_I2C_C1_RSTA_M; \
+CYG_MACRO_END
+
+
+#define I2C_CLEAR(__i2c, __mask) \
+CYG_MACRO_START \
+ __i2c->s |= __mask; \
+CYG_MACRO_END
+
+// Clock rate calculator
+
+#define I2C_DEBUG_CLOCK 0
+
+#define I2C_CLOCK_NORM 1000
+#define I2C_CLOCK_NORMLL 1000LL
+
+// dev_i2c_freescale_freq_table[] entries and
+// dev_i2c_freescale_frequency_entry_t (typedef of cyg_uint16 or cyg_uint32)
+// type are provided be provided by HAL
+static const dev_i2c_freescale_frequency_entry_t dev_i2c_freescale_freq_table[]
+ = { CYGHWR_IO_FREESCALE_I2C_FREQUENCY_TABLE };
+static const cyg_uint32 dev_i2c_freescale_freq_table_size =
+ sizeof(dev_i2c_freescale_freq_table) /
+ sizeof(dev_i2c_freescale_freq_table[0]);
+
+// Frequency divider setting calculator
+// Calculate F register setting. The input parameter period_sp is encodded:
+// If most significant bit (31) is 1, than the least significant byte contains
+// explicit F refister value. If most significant bit (31) is 0 then:
+// - bits 27-0: clock period in [ns];
+// - bits 30,29: fit (see CDL)
+// - bit 28:
+// 1) aggressive look up - closest matching period
+// 0) consrvative look up - closest matching period not shorter than setpoint
+
+static cyg_uint8
+freescale_i2c_freq_div_calc(cyg_uint32 period_sp)
+{
+ cyg_uint32 sys_clk_per;
+ cyg_uint32 period, the_period = 0xffffffff, agr;
+ cyg_uint32 mult, the_mult = 4;
+ cyg_int32 icr_i, the_icr_i = dev_i2c_freescale_freq_table_size - 1;
+ cyg_uint16 icr;
+ cyg_uint8 i2cf = 0xff;
+
+ cyg_uint32 fit;
+
+#if I2C_DEBUG_CLOCK
+ I2C_TRACE("Period setpont: 0x%08x\n", period_sp);
+#endif
+ // Extract period and fit
+ fit = period_sp >> FREESCALE_I2C_DELAY_FIT_S;
+ agr = FREEDCALE_I2C_DELAY_IS_AGRESIVE(period_sp);
+ period_sp &= FREESCALE_I2C_DELAY_M;
+ sys_clk_per = ((1000000000 * I2C_CLOCK_NORMLL) / CYGHWR_IO_I2C_FREESCALE_I2C_CLOCK);
+ period_sp *= I2C_CLOCK_NORM;
+
+#if I2C_DEBUG_CLOCK
+ I2C_TRACE("Period %d.%d[ns] [0x%08x] fit %d agr 0x%08x\n", period_sp/I2C_CLOCK_NORM,
+ period_sp%I2C_CLOCK_NORM, period_sp, fit, agr);
+#endif
+
+ for(mult = 4; mult > 0; mult /= 2) {
+
+#if I2C_DEBUG_CLOCK >= 3
+ I2C_TRACE("mult = %d icr_n=%d\n", mult, dev_i2c_freescale_freq_table_size);
+#endif
+
+ for(icr_i = dev_i2c_freescale_freq_table_size - 1; icr_i >= 0; icr_i--) {
+ icr = dev_i2c_freescale_freq_table[icr_i];
+ period = sys_clk_per * (icr * mult);
+
+#if I2C_DEBUG_CLOCK >= 3
+ I2C_TRACE("sys_clk_per=%d the_mult = %d icr[0x%02x]=%d, period = %d.%d (sp = %d.%d)\n",
+ sys_clk_per, the_mult, icr_i, icr,
+ period/I2C_CLOCK_NORM, period%I2C_CLOCK_NORM,
+ period_sp/I2C_CLOCK_NORM, period_sp%I2C_CLOCK_NORM);
+#endif
+
+ if (period == period_sp) {
+
+ I2C_TRACE ("FreqDiv EQ: [0x%02x] the_mult = %d, icr[0x%02x] = %d\n",
+ i2cf, the_mult, the_icr_i, dev_i2c_freescale_freq_table[the_icr_i]);
+
+ return FREESCALE_I2C_F(mult / 2, icr_i);
+ } else if (period < period_sp) {
+ if(0 == fit) {
+ if(agr && ((period_sp - period) < period - the_period )) {
+ the_mult = mult;
+ the_icr_i = icr_i;
+ the_period = period;
+ }
+ i2cf = FREESCALE_I2C_F(the_mult / 2, the_icr_i);
+
+#ifdef CYGPKG_DEVS_I2C_FREESCALE_I2C_TRACE
+ I2C_TRACE ("FreqDiv LT: [0x%02x] the_mult = %d, icr[0x%02x] = %d\n",
+ i2cf, the_mult, the_icr_i, dev_i2c_freescale_freq_table[the_icr_i]);
+ icr = dev_i2c_freescale_freq_table[the_icr_i];
+ period = (sys_clk_per * (icr * the_mult));
+ I2C_TRACE (" Actual: period = %d.%d[ns], frequency = %d[Hz]\n",
+ period/I2C_CLOCK_NORM, period%I2C_CLOCK_NORM,
+ (cyg_uint32)((1000000000 * I2C_CLOCK_NORMLL) / period));
+#endif
+
+ return i2cf;
+ break;
+ } else {
+
+#if I2C_DEBUG_CLOCK >= 1
+ icr = dev_i2c_freescale_freq_table[the_icr_i];
+ period = (sys_clk_per * (icr * mult));
+
+ I2C_TRACE (" Fits left %d: period = %d.%d[ns], frequency = %d[Hz]\n",
+ fit, period/I2C_CLOCK_NORM, period%I2C_CLOCK_NORM,
+ (cyg_uint32)((1000000000 * I2C_CLOCK_NORMLL) / period));
+#endif
+
+ fit --;
+ break;
+ }
+ } else { // period > period_sp
+ the_period = period;
+ the_mult = mult;
+ the_icr_i = icr_i;
+ i2cf = FREESCALE_I2C_F(mult / 2, the_icr_i);
+
+#if I2C_DEBUG_CLOCK >= 2
+ I2C_TRACE ("FreqDiv FIT %d: [0x%02x] the_mult = %d, icr[0x%02x] = %d\n", 3-fit,
+ i2cf, the_mult, the_icr_i, dev_i2c_freescale_freq_table[the_icr_i]);
+#endif
+
+ }
+ }
+ }
+
+ I2C_TRACE ("FreqDiv EX: [0x%02x] the_mult = %d, icr[0x%02x] = %d\n",
+ i2cf, the_mult, the_icr_i, dev_i2c_freescale_freq_table[the_icr_i]);
+
+#ifdef CYGPKG_DEVS_I2C_FREESCALE_I2C_TRACE
+ icr = dev_i2c_freescale_freq_table[the_icr_i];
+ period = (sys_clk_per * (icr * the_mult));
+ I2C_TRACE (" Actual: period = %d[ns], frequency = %d[Hz]\n",
+ period, (cyg_uint32)((1000000000 * I2C_CLOCK_NORMLL) / period));
+#endif
+
+ return i2cf;
+}
+
+// Set frequency divider.
+// If frequency divider setting is cached simply return the value else
+// calculate one by means of freescale_i2c_freq_div_calc() and cache it.
+
+static inline cyg_uint8
+freescale_i2c_freq_div(cyg_uint32 *period_p)
+{
+ cyg_uint32 period;
+ cyg_uint8 freq;
+
+ if((period = *period_p) & FREESCALE_I2C_DELAY_F_IS_CACHED_M) {
+#if I2C_DEBUG_CLOCK
+ I2C_TRACE("Cached/pre-calculated divider setting: 0x%08x\n", period);
+#endif
+ freq = period & FREESCALE_I2C_DELAY_F_CACHE_M;
+ } else {
+ freq = freescale_i2c_freq_div_calc(period);
+ *period_p = freq | FREESCALE_I2C_DELAY_F_IS_CACHED_M;
+ }
+ return freq;
+}
+
+// Wait untill the bus is free or timeout expires
+// This function performes busy-wait In order to prevent blocking
+// other processes it lowers thread priority prior to entering the spin loop.
+// After the spin loop the original thread priority is restored.
+
+static bool
+wait_bus_ready(freescale_i2c_extra* extra)
+{
+ freescale_i2c_t *i2c_s;
+ bool bus_ready;
+ cyg_priority_t i2c_prio;
+ cyg_tick_count_t time;
+ cyg_handle_t i2c_thread;
+#ifdef CYGPKG_DEVS_I2C_FREESCALE_I2C_TRACE
+ cyg_priority_t i2c_cur_prio;
+ cyg_uint8 __sr;
+
+#endif
+
+ if (!extra->i2c_owner) {
+ I2C_TRACE ("I2C bus ready: 0:\n");
+ i2c_s = FREESCALE_I2C_P (extra->i2c_base);
+ if((
+#ifdef CYGPKG_DEVS_I2C_FREESCALE_I2C_TRACE
+ __sr =
+#endif
+ i2c_s->s) & FREESCALE_I2C_S_BUSY_M)
+ {
+ bus_ready = false;
+ // Decrease priority before busy-waiting.
+ i2c_thread = cyg_thread_self();
+ i2c_prio = cyg_thread_get_priority(i2c_thread);
+#ifdef CYGPKG_DEVS_I2C_FREESCALE_I2C_TRACE
+ i2c_cur_prio = cyg_thread_get_current_priority(i2c_thread);
+#endif
+ I2C_TRACE ("I2C bus ready: 1: priority %d, current priority %d\n",
+ i2c_prio, i2c_cur_prio);
+ // FIXME: What about current thread priority?
+ I2C_TRACE ("I2C bus ready: 2: sr 0x%02x, cr 0x%02x\n", __sr, i2c_s->c1);
+
+ cyg_thread_set_priority(i2c_thread, CYGNUM_DEV_I2C_SPIN_PRIO);
+
+ I2C_TRACE ("I2C bus ready: 3: priority %d, current priority %d\n",
+ cyg_thread_get_priority(i2c_thread),
+ cyg_thread_get_current_priority(i2c_thread));
+ for (time = cyg_current_time();
+ (cyg_current_time() - time) < CYGNUM_DEV_I2C_SPIN_TIMEOUT;)
+ {
+ if(!(i2c_s->s & FREESCALE_I2C_S_BUSY_M)) {
+ bus_ready = true;
+ break;
+ }
+ }
+ cyg_thread_set_priority(i2c_thread, i2c_prio);
+
+ I2C_TRACE ("I2C bus ready: 4: priority %d, current priority %d\n",
+ cyg_thread_get_priority(i2c_thread),
+ cyg_thread_get_current_priority(i2c_thread));
+ } else {
+ bus_ready = true;
+ }
+ if(bus_ready) {
+ extra->i2c_got_nack = 0;
+ extra->i2c_owner = 1;
+ }
+ } else {
+ bus_ready = true;
+ }
+
+ I2C_TRACE ("I2C bus ready: Z bus_ready = %d\n", bus_ready);
+
+ return bus_ready;
+}
+
+// Interrupt service routine
+static cyg_uint32
+freescale_i2c_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ freescale_i2c_extra *extra = (freescale_i2c_extra *) data;
+ freescale_i2c_t *i2c_s = FREESCALE_I2C_P (extra->i2c_base);
+ cyg_uint8 sr;
+ cyg_uint32 result = CYG_ISR_HANDLED;
+ cyg_uint8 tx_data = *extra->i2c_data.i2c_tx_data;
+
+ I2C_TRACE ("I2C ISR\n");
+
+ // Read current status
+ sr = i2c_s->s;
+
+ // clear interrupt
+ i2c_s->s |= FREESCALE_I2C_S_IICIF_M;
+
+ if (FREESCALE_I2C_XFER_MODE_TX == extra->i2c_mode) {
+ I2C_TRACE("I2C: TX IRQ handling, sr 0x%02x\n", sr);
+
+ // check for error conditions
+ if (sr & FREESCALE_I2C_S_ARBL_M) {
+ /*
+ * Arbitration lost
+ *
+ * Lost the bus, abort the transfer. count has already been
+ * decremented. Assume the byte did not actually arrive.
+ */
+ extra->i2c_count += 1;
+
+ I2C_STOP(i2c_s);
+ I2C_CLEAR(i2c_s, FREESCALE_I2C_S_ARBL_M);
+
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ I2C_TRACE("I2C: TX, bus arbitration error\n");
+ } else if (sr & FREESCALE_I2C_S_RXAK_M) {
+ /*
+ * NACK
+ * Transfer failed. Handled upon exit from the dsr.
+ */
+ extra->i2c_got_nack = 1;
+ I2C_STOP(i2c_s);
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ I2C_TRACE("I2C: TX, got NACK\n");
+ } else if (0 == extra->i2c_count) {
+ // No more bytes to send.
+ I2C_TRACE("I2C: TX, no more bytes\n");
+
+ // Last byte
+ if ((0 == extra->i2c_count) && extra->send_stop)
+ I2C_STOP(i2c_s);
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else {
+ // Send byte
+ I2C_TRACE("I2C: TX, sending 0x%02x\n", tx_data);
+ i2c_s->d = tx_data;
+ extra->i2c_data.i2c_tx_data += 1;
+ extra->i2c_count -= 1;
+
+ }
+ } else if (FREESCALE_I2C_XFER_MODE_RX == extra->i2c_mode) {
+ I2C_TRACE("I2C: RX IRQ handling, sr 0x%02x\n", sr);
+
+ /*
+ * check the actual bus mode, RX transaction starts with initial TX
+ * to transmit the slave address.
+ */
+ if (i2c_s->c1 & FREESCALE_I2C_C1_TX_M) {
+ /*
+ * In TX mode, should be getting an acknowledgement of the slave
+ * address write
+ */
+ if (sr & FREESCALE_I2C_S_ARBL_M) {
+ // Arbitration lost, stop
+ I2C_STOP(i2c_s);
+ I2C_CLEAR(i2c_s, FREESCALE_I2C_S_ARBL_M);
+
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ I2C_TRACE("I2C: RX, initial bus arbitration error\n");
+ } else if (sr & FREESCALE_I2C_S_RXAK_M) {
+ // nack
+ extra->i2c_got_nack = 1;
+ I2C_STOP(i2c_s);
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ I2C_TRACE("I2C: RX, got initial NACK\n");
+ } else {
+ /*
+ * The slave address was transmitted successfully, now switch
+ * the bus to RX
+ */
+ volatile cyg_uint8 dummy_read __attribute__((unused));
+
+ I2C_TRACE("I2C: RX, switching bus to RX\n");
+ i2c_s->c1 &= ~FREESCALE_I2C_C1_TX_M;
+
+ // ACK if more bytes
+ if (extra->i2c_count != 1)
+ i2c_s->c1 &= ~FREESCALE_I2C_C1_TXAK_M;
+ // NACK if asked to
+ else if (extra->i2c_send_nack)
+ i2c_s->c1 |= FREESCALE_I2C_C1_TXAK_M;
+ // ACK if last btye but not asked to NACK,
+ // meaning there will be another read
+ else
+ i2c_s->c1 &= ~FREESCALE_I2C_C1_TXAK_M;
+
+ // do a dummy read to get things going
+ dummy_read = i2c_s->d;
+ }
+ }
+ /*
+ * Already in RX mode ...
+ */
+ else if (sr & FREESCALE_I2C_S_ARBL_M) {
+ // Lost the bus? Maybe a spurious stop
+ I2C_CLEAR(i2c_s, FREESCALE_I2C_S_ARBL_M);
+ I2C_TRACE("I2C: RX, bus arbitration error\n");
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else {
+ I2C_TRACE("I2C: RX, got some data, count %d\n", extra->i2c_count);
+ if (2 == extra->i2c_count) {
+ // One more byte to go, and it should be NACKed.
+ I2C_TRACE("I2C: RX, penultimate byte\n");
+ if (extra->i2c_send_nack)
+ i2c_s->c1 |= FREESCALE_I2C_C1_TXAK_M;
+ } else if (1 == extra->i2c_count) {
+ // Received the last byte.
+ I2C_TRACE("I2C: RX, last byte\n");
+
+ if (extra->send_stop)
+ I2C_STOP(i2c_s);
+
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else if (0 == extra->i2c_count) {
+ /*
+ * Data beyond last byte ... this should never happen, but see
+ * the comment in freescale_i2c_handle_xfer()
+ */
+ CYG_FAIL("I2C: RX sender sending data beyond last byte\n");
+
+ // Forcefully stop the bus and quit
+ I2C_STOP(i2c_s);
+
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+
+ HAL_INTERRUPT_ACKNOWLEDGE (extra->i2c_isr_id);
+
+ return result;
+ }
+
+ // extract data
+ *(extra->i2c_data.i2c_rx_data) = i2c_s->d;
+ I2C_TRACE("I2C: RX, data: 0x%02x\n",
+ *(extra->i2c_data.i2c_rx_data));
+
+ extra->i2c_data.i2c_rx_data += 1;
+ extra->i2c_count -= 1;
+ }
+ } else {
+ /*
+ * Invalid state? Some kind of spurious interrupt? Ignore it.
+ */
+ I2C_TRACE("I2C spurious interrupt\n");
+ }
+
+ HAL_INTERRUPT_ACKNOWLEDGE (extra->i2c_isr_id);
+
+ return result;
+}
+
+// Deferred interrupt service routine
+static void
+freescale_i2c_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ freescale_i2c_extra *extra = (freescale_i2c_extra *) data;
+
+ I2C_TRACE ("I2C DSR -- finishing off\n");
+
+ extra->i2c_completed = 1;
+ cyg_drv_cond_signal(&(extra->i2c_wait));
+}
+
+// A transfer has been started. Wait for completion
+static inline void
+freescale_i2c_doit(freescale_i2c_extra * extra)
+{
+ cyg_drv_mutex_lock(&(extra->i2c_lock));
+ cyg_drv_dsr_lock();
+
+ while (!extra->i2c_completed) {
+ I2C_TRACE ("Waiting ...\n");
+ cyg_drv_cond_wait(&(extra->i2c_wait));
+ }
+
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&(extra->i2c_lock));
+}
+
+static inline void
+freescale_i2c_stopit(freescale_i2c_extra * extra)
+{
+ extra->i2c_lost_arb = 0;
+ extra->i2c_owner = 0;
+ extra->i2c_mode = FREESCALE_I2C_XFER_MODE_INVALID;
+}
+
+void
+freescale_i2c_stop(const cyg_i2c_device * dev)
+{
+ freescale_i2c_extra *extra = (freescale_i2c_extra *) dev->i2c_bus->i2c_extra;
+ freescale_i2c_t *i2c_s = FREESCALE_I2C_P (extra->i2c_base);
+
+ I2C_STOP(i2c_s);
+
+ freescale_i2c_stopit(extra);
+}
+
+static cyg_bool
+freescale_i2c_handle_xfer(cyg_i2c_device * dev, int address)
+{
+ freescale_i2c_extra *extra = (freescale_i2c_extra *) dev->i2c_bus->i2c_extra;
+ cyg_uint8 data = *extra->i2c_data.i2c_tx_data;
+ freescale_i2c_t *i2c_s = FREESCALE_I2C_P (extra->i2c_base);
+ cyg_uint8 freq;
+
+ // Nothing to do
+ if (extra->i2c_count == 0)
+ return false;
+
+ // Take the bus ownership
+ if(!wait_bus_ready (extra))
+ return false;
+
+ // set the bus frequency
+ freq = freescale_i2c_freq_div(dev->i2c_delay ?
+ &dev->i2c_delay :
+ &extra->i2c_delay);
+
+ i2c_s->f = freq;
+ I2C_TRACE("Set f = 0x%02x\n", i2c_s->f);
+
+ if (extra->send_start) {
+ I2C_TRACE ("Doing start: restart: %s\n",
+ i2c_s->c1 & FREESCALE_I2C_C1_MST_M ? "yes" : "no");
+
+ /*
+ * If we are the current master, use repeat start
+ */
+ if (i2c_s->c1 & FREESCALE_I2C_C1_MST_M) {
+ I2C_REPEAT_START(i2c_s);
+ } else {
+#if 0
+ i2c_s->c1 &= ~0x3fu;
+#endif
+ I2C_START(i2c_s);
+ }
+
+ I2C_TRACE ("STATUS: sr 0x%02x, cr 0x%02x\n", i2c_s->s, i2c_s->c1);
+
+ /*
+ * Write the address out and wait for interrupt
+ */
+ I2C_TRACE ("Address: %d [0x%x]\n", address, address);
+ i2c_s->d = address;
+ return true;
+ } else if (extra->i2c_mode == FREESCALE_I2C_XFER_MODE_TX) {
+ // TX transfer without a start
+ I2C_TRACE ("TX transfer without start\n");
+
+ extra->i2c_data.i2c_tx_data += 1;
+ extra->i2c_count -= 1;
+ i2c_s->d = data;
+
+ // Single byte transfer
+ if (extra->send_stop && (extra->i2c_count == 0))
+ I2C_STOP(i2c_s);
+ } else {
+ // RX transfer without a start
+#if 0
+ /*
+ * This is how it would be done in theory; in practice, because the
+ * actual reading is IRQ driven, we are stuck in the isr handler until
+ * such time the sender will stop sending data, but since the sender
+ * will continue sending data until it receives the stop signal from us,
+ * if someone makes an RX call with the 'don't send stop' flag, the
+ * incoming data stream will never stop (until there is an error).
+ *
+ * And since we can never allow an RX call with the 'don't send stop'
+ * flag, we can never do send without explicit start either.
+ */
+ I2C_TRACE ("RX transfer without start\n");
+ // Single byte transfer, set the STOP bit
+ if (extra->send_stop && (extra->i2c_count == 1))
+ I2C_STOP(i2c_s);
+
+ // Do not ACK last byte per user request
+ if (!extra->i2c_send_nack && (extra->i2c_count == 1)) {
+ I2C_TRACE ("RX: NACK for last byte in single byte transfer\n");
+ i2c_s->c1 |= FREESCALE_I2C_C1_TXAK_M;
+ }
+#else
+ CYG_FAIL( "I2C driver does not support piecemeal RX\n" );
+#endif
+ }
+
+ return true;
+}
+
+cyg_uint32
+freescale_i2c_tx(cyg_i2c_device * dev, cyg_bool send_start,
+ const cyg_uint8 *tx_data, cyg_uint32 count, cyg_bool send_stop)
+{
+ freescale_i2c_extra *extra = (freescale_i2c_extra *) dev->i2c_bus->i2c_extra;
+ extra->send_stop = send_stop;
+ extra->send_start = send_start;
+ extra->i2c_count = count;
+
+ if (!extra->i2c_lost_arb) {
+ extra->i2c_completed = 0;
+ extra->i2c_mode = FREESCALE_I2C_XFER_MODE_TX;
+
+ if (send_start || !extra->i2c_got_nack) {
+ I2C_TRACE
+ ("I2C: TX to %2x, data %2x, count: %4d, START flag: %s\n",
+ dev->i2c_address, *tx_data, count,
+ (send_start == true) ? "true" : "false");
+ extra->i2c_data.i2c_tx_data = tx_data;
+ if (!freescale_i2c_handle_xfer (dev, FREESCALE_I2C_A1_AD (dev->i2c_address,
+ FREESCALE_I2C_MODE_MW))
+ )
+ {
+ return 0;
+ }
+
+ /*
+ * Now block till we are done
+ */
+ freescale_i2c_doit(extra);
+ }
+
+ }
+
+ if (send_stop) {
+ I2C_TRACE("I2C: TX send stop\n");
+ freescale_i2c_stopit(extra);
+ }
+
+ I2C_TRACE("I2C: TX count %d\n", extra->i2c_count);
+
+ /*
+ * tx() should return the number of bytes actually transmitted.
+ * ISR() increments extra->count after a failure, which leads to
+ * an edge condition when send_start and there is no acknowledgment
+ * of the address byte.
+ */
+ if (extra->i2c_count > count)
+ return 0;
+
+ return count - extra->i2c_count;
+}
+
+cyg_uint32
+freescale_i2c_rx(cyg_i2c_device * dev, cyg_bool send_start,
+ cyg_uint8 *rx_data, cyg_uint32 count, cyg_bool send_nack,
+ cyg_bool send_stop)
+{
+ freescale_i2c_extra *extra = (freescale_i2c_extra *) dev->i2c_bus->i2c_extra;
+
+ /*
+ * see comments in freescale_i2c_handle_xfer() as to why this assert.
+ */
+ CYG_ASSERT( send_start && send_stop,
+ "I2C driver does not support piecemeal RX, i.e., the "
+ "send_start and send_stop parameters must always be set to "
+ "true\n");
+
+ extra->i2c_count = count;
+ extra->i2c_send_nack = send_nack;
+ extra->send_stop = send_stop;
+ extra->send_start = send_start;
+
+ if (!extra->i2c_lost_arb) {
+ extra->i2c_completed = 0;
+ extra->i2c_data.i2c_rx_data = rx_data;
+ extra->i2c_mode = FREESCALE_I2C_XFER_MODE_RX;
+ I2C_TRACE("I2C: RX to %2x, count: %4d, START flag: %s\n",
+ dev->i2c_address, count,
+ (send_start == true) ? "true" : "false");
+
+ if (!freescale_i2c_handle_xfer (dev, FREESCALE_I2C_A1_AD (dev->i2c_address,
+ FREESCALE_I2C_MODE_MR))
+ )
+ {
+ return 0;
+ }
+
+ /*
+ * Now block till we are done
+ */
+ freescale_i2c_doit(extra);
+ }
+
+ if (send_stop) {
+ I2C_TRACE("I2C: RX send stop\n");
+ freescale_i2c_stopit(extra);
+ }
+
+ return count - extra->i2c_count;
+}
+
+// ----------------------------------------------------------------------------
+// The functions needed for all I2C devices.
+
+void
+freescale_i2c_init(struct cyg_i2c_bus *bus)
+{
+ freescale_i2c_extra *extra = (freescale_i2c_extra *) bus->i2c_extra;
+ freescale_i2c_t *i2c_s = FREESCALE_I2C_P (extra->i2c_base);
+ cyg_uint32 freq;
+
+ I2C_TRACE("I2C INIT0 bus base 0x%08x Pins: 0x%08x, 0x%08x Clock 0x%08x\n",
+ extra->i2c_base, extra->hal_p->pin_sda, extra->hal_p->pin_scl,
+ extra->hal_p->clock);
+
+ // Bring clock to the sevice
+ CYGHWR_IO_CLOCK_ENABLE(extra->hal_p->clock);
+ // setup SDA/SCL pins, the I2C driver to take care of the rest.
+ CYGHWR_IO_FREESCALE_I2C_PIN(extra->hal_p->pin_sda);
+ CYGHWR_IO_FREESCALE_I2C_PIN(extra->hal_p->pin_scl);
+
+ cyg_drv_mutex_init(&extra->i2c_lock);
+ cyg_drv_cond_init(&extra->i2c_wait, &extra->i2c_lock);
+ cyg_drv_interrupt_create(extra->i2c_isr_id,
+ extra->i2c_isr_pri,
+ (cyg_addrword_t)extra,
+ &freescale_i2c_isr,
+ &freescale_i2c_dsr,
+ &(extra->i2c_interrupt_handle),
+ &(extra->i2c_interrupt_data));
+ cyg_drv_interrupt_attach(extra->i2c_interrupt_handle);
+
+ if (!extra->i2c_owner) {
+#ifdef CYGPKG_DEVS_I2C_FREESCALE_I2C_TRACE
+ cyg_uint8 cr;
+#endif
+ cyg_uint8 sr;
+
+ extra->i2c_got_nack = 0;
+ extra->i2c_owner = 1;
+ sr = i2c_s->s;
+#ifdef CYGPKG_DEVS_I2C_FREESCALE_I2C_TRACE
+ cr = i2c_s->c1;
+#endif
+
+ I2C_TRACE ("BUS: INIT sr 0x%02x, cr 0x%02x\n", sr, cr);
+
+ while (sr & FREESCALE_I2C_S_BUSY_M) {
+ sr = i2c_s->s;
+ }
+ }
+
+#if 1
+ i2c_s->c2 = extra->c2_cfg; // some options set in CDL
+ i2c_s->flt = extra->flt_cfg; // glitch filter
+#endif
+
+ /*
+ * bus speed: set the frequency divider
+ *
+ * The bus can run up to clock/20, but can only achieve full loads
+ * under 100kHz
+ */
+ I2C_TRACE("I2C INIT1: extra->i2c_delay = %d\n", extra->i2c_delay);
+
+ freq = freescale_i2c_freq_div(&extra->i2c_delay);
+
+ I2C_TRACE("I2C INIT2: -> extra->i2c_delay = 0x%08x\n", extra->i2c_delay);
+
+ i2c_s->f = freq;
+
+ /*
+ * Signal start -- selects master mode
+ * Enable I2C
+ * Enable Interrupt
+ */
+ i2c_s->c1 |= (FREESCALE_I2C_C1_IICEN_M | FREESCALE_I2C_C1_IICIE_M);
+
+ // Interrupts can now be safely unmasked
+ HAL_INTERRUPT_UNMASK(extra->i2c_isr_id);
+}
+
+//-----------------------------------------------------------------------------
+// Bus instances.
+
+#include <cyg/io/i2c_freescale_buses.inl>
+
+//---------------------------------------------------------------------------
+// EOF i2c_freescale.c
diff --git a/ecos/packages/devs/i2c/m68k/mcf52xx/current/ChangeLog b/ecos/packages/devs/i2c/m68k/mcf52xx/current/ChangeLog
new file mode 100644
index 0000000..958e5ab
--- /dev/null
+++ b/ecos/packages/devs/i2c/m68k/mcf52xx/current/ChangeLog
@@ -0,0 +1,45 @@
+2009-02-09 Bart Veer <bartv@ecoscentric.com>
+
+ * src/i2c_mcf52xx.c (mcf52xx_i2c_isr): handle RXAK error
+ condition, reported by Rainer Arndt.
+
+ * src/i2c_mcf52xx.c (cyg_mcf52xx_i2c_tx): remove spurious
+ diag_printf().
+
+2008-12-30 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/i2c_mcf52xx.cdl: Reference per-package documentation.
+
+2006-02-28 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/mcf52xx_i2c.sgml, include/i2c_mcf52xx.h: new files
+
+ * src/i2c_mcf52xx.c, cdl/i2c_mcf52xx.cdl: various clean-ups
+
+2005-10-23 Uwe Kindler <uwe_kindler@web.de>
+
+ * mcf52xx I2C driver package created
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/i2c/m68k/mcf52xx/current/cdl/i2c_mcf52xx.cdl b/ecos/packages/devs/i2c/m68k/mcf52xx/current/cdl/i2c_mcf52xx.cdl
new file mode 100644
index 0000000..e581020
--- /dev/null
+++ b/ecos/packages/devs/i2c/m68k/mcf52xx/current/cdl/i2c_mcf52xx.cdl
@@ -0,0 +1,111 @@
+# ====================================================================
+#
+# i2c_mcf52xx.cdl
+#
+# eCos MCF52xx I2C configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Contributors: Bart Veer
+# Date: 2005-10-23
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+
+cdl_package CYGPKG_DEVS_I2C_MCF52xx {
+ display "I2C driver for coldfire MCF52xx family"
+ doc ref/devs-i2c-m68k-mcf52xx-part.html
+
+ parent CYGPKG_IO_I2C
+ active_if CYGPKG_IO_I2C
+ active_if CYGPKG_HAL_M68K_MCF52xx
+
+ description "
+ This package provides a generic I2C device driver for the on-chip
+ I2C modules in MCF52xx ColdFire processors."
+
+ include_dir cyg/io
+ compile i2c_mcf52xx.c
+
+ cdl_option CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES {
+ display "Target hardware may have multiple MCF52xx I2C buses"
+ flavor bool
+ default_value 0
+ description "
+ The MCF52xx I2C driver can support multiple I2C bus devices, but
+ typically the coldfire processor only provides a single device. By
+ default the driver assumes only a single device is present and will
+ optimize for that case, using constant definitions provided by the
+ platform HAL rather than per-device structure fields. If the hardware
+ has multiple I2C bus devices, or if a singleton bus is instantiated
+ by some other package and hence the platform HAL cannot provide the
+ necessary definitions, then this option should be enabled."
+ }
+
+ cdl_component CYGPKG_DEVS_I2C_MCF52xx_OPTIONS {
+ display "I2C driver build options"
+ flavor none
+ active_if { CYGINT_DEVS_I2C_MCF52xx_BUS_DEVICES > 0 }
+ description "
+ Package specific build options including control over
+ compiler flags used only in building the MCF52xx I2C
+ bus driver."
+
+ cdl_option CYGPKG_DEVS_I2C_MCF52xx_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the MCF52xx I2C bus driver. These flags are
+ used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_I2C_MCF52xx_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the MCF52xx I2C bus driver. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+}
diff --git a/ecos/packages/devs/i2c/m68k/mcf52xx/current/doc/mcf52xx_i2c.sgml b/ecos/packages/devs/i2c/m68k/mcf52xx/current/doc/mcf52xx_i2c.sgml
new file mode 100644
index 0000000..bd67c46
--- /dev/null
+++ b/ecos/packages/devs/i2c/m68k/mcf52xx/current/doc/mcf52xx_i2c.sgml
@@ -0,0 +1,277 @@
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- mcf52xx_i2c.sgml -->
+<!-- -->
+<!-- Documentation for the mcf52xx I2C bus driver -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2006 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2006/02/19 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-i2c-m68k-mcf52xx-part"><title>Motorola MCF52xx ColdFire I<superscript>2</superscript>C Bus Driver</title>
+
+<refentry id="devs-i2c-m68k-mcf52xx">
+ <refmeta>
+ <refentrytitle>Motorola MCF52xx Coldfire I<superscript>2</superscript>C Bus Driver</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname><varname>CYGPKG_DEVS_I2C_MCF52xx</varname></refname>
+ <refpurpose>eCos Support for the Motorola Coldfire I<superscript>2</superscript>C Bus</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="devs-i2c-m68k-mcf52xx-description"><title>Description</title>
+ <para>
+Several processors in the Motorola ColdFire family come with one or
+more on-chip I<superscript>2</superscript>C bus devices. This package
+provides an eCos I<superscript>2</superscript>C bus driver. It was
+originally developed on an MCF5280 but should work with any ColdFire
+processor that uses a compatible bus device. The driver implements the
+functionality defined by the generic I<superscript>2</superscript>C
+package <varname>CYGPKG_IO_I2C</varname>.
+ </para>
+ <caution><para>
+The hardware does not support DMA or fifos, so usually a transfer will
+involve an interrupt for every byte transferred. Since the
+I<superscript>2</superscript>C bus typically runs at 100KHz large
+transfers will consume much of the available cpu time.
+ </para></caution>
+ <para>
+This package does not provide any <structname>cyg_i2c_bus</structname>
+structures. The number of I<superscript>2</superscript>C buses varies
+between ColdFire processors. If multiple buses are available then
+exactly which one(s) are in use on a given hardware platform depends
+entirely on that platform. The desired I<superscript>2</superscript>C
+bus speed also depends on the platform, and there may be other issues
+such as how the processor pins should be set up. Hence it is left to
+other code, usually the platform HAL, to instantiate the bus
+structure(s). This driver package supplies the necessary functions and
+utility macros. Similarly this package does not provide any
+<structname>cyg_i2c_device</structname> structures. Which
+I<superscript>2</superscript>C devices are hooked up to which
+I<superscript>2</superscript>C bus is entirely a characteristic of the
+hardware platform, so again it is up to the platform HAL to
+instantiate the necessary structures.
+ </para>
+ <para>
+The driver will operate in interrupt-driven mode if interrupts are
+enabled when a transfer is initiated. Otherwise it will operate in
+polled mode. This allows the driver to be used in a variety of
+configurations including inside RedBoot.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-i2c-m68k-mcf52xx-config"><title>Configuration Options</title>
+ <para>
+The I<superscript>2</superscript>C bus driver package should be loaded
+automatically when selecting a target containing a suitable ColdFire
+processor, and it should never be necessary to load the package
+explicitly. If the application does not use any of the
+I<superscript>2</superscript>C functionality, directly or indirectly,
+then all the I<superscript>2</superscript>C code should be removed at
+link-time and the application does not suffer any overheads.
+ </para>
+ <para>
+By default the driver assumes a single I<superscript>2</superscript>C
+bus and optimizes for that case. For example options like the ISR
+vector and priority are handled by compile-time
+<literal>#define</literal>'s in the platform HAL's exported header
+files rather than by per-bus structure fields. This helps to reduce
+both code and data overheads. If the driver should support multiple
+I<superscript>2</superscript>C buses then
+<varname>CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES</varname> should be
+enabled. Typically this will be done by the platform HAL using a CDL
+<property>requires</property> property. If bus instantiation happens
+outside the platform HAL and hence the HAL's header files do not
+provide the appropriate definitions, then this configuration option
+should also be defined.
+ </para>
+ <para>
+The only other configuration options in this package provide control
+over the compiler flags used to build the driver code.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-i2c-m68k-mcf52xx-bus-devices"><title>Defining the Bus and Devices</title>
+ <para>
+For most hardware targets the platform HAL will instantiate the
+<structname>cyg_i2c_bus</structname> and
+<structname>cyg_i2c_device</structname> structures, and it will also
+initialize the hardware so that the
+I<superscript>2</superscript>C-related pins are connected
+appropriately. Some development boards have no
+I<superscript>2</superscript>C devices, but the
+I<superscript>2</superscript>C bus signals are accessible via an
+expansion connector and I<superscript>2</superscript>C devices can be
+put on a daughter board. In such cases it may be necessary for the
+application to instantiate both the bus and all the device structures.
+Alternatively the platform HAL may provide a configuration option to
+enable just the bus, with the devices still left to application code.
+ </para>
+ <para>
+To facilitate bus instantiation the header file <filename
+class="headerfile">cyg/io/i2c_mcf52xx.h</filename> provides a utility
+macro <function>CYG_MCF52xx_I2C_BUS</function>. This takes six
+parameters:
+ </para>
+ <orderedlist>
+ <listitem><para>
+The name of the bus, for example
+<varname>hal_dnp5280_i2c_bus</varname>. This name will be used when
+instantiating the I<superscript>2</superscript>C devices.
+ </para></listitem>
+ <listitem><para>
+An initialization function. If no platform-specific initialization is
+needed then this can be the <function>cyg_mcf52xx_i2c_init</function>
+function exported by this driver. Otherwise it can be a
+platform-specific function which, for example, sets up the relevant
+pins appropriately and then chains into
+<function>cyg_mcf52xx_i2c_init</function>.
+ </para></listitem>
+ <listitem><para>
+The base address of the I<superscript>2</superscript>C bus. For
+example on an MCF5282 with the IPSBAR set to its usual value of
+0x40000000, the I<superscript>2</superscript>C bus is at location
+0x40000300.
+ </para></listitem>
+ <listitem><para>
+The interrupt vector, for example
+<varname>CYGNUM_HAL_ISR_I2C_IIF</varname> on an MCF5282.
+ </para></listitem>
+ <listitem><para>
+The interrupt priority. Typically this will be a configurable option
+within the platform HAL.
+ </para></listitem>
+ <listitem><para>
+A value for the I<superscript>2</superscript>C bus's I2FDR register.
+That register controls the bus speed. Typical bus speeds are 100KHz
+and 400KHz, depending on the capabilities of the attached devices.
+There is no simple relationship between the system clock speed, the
+desired bus speed, and the FDR register. Although the driver could
+determine the FDR setting using a lookup table and appropriate code,
+it is better to determine the correct value once during the porting
+process and avoid unnecessary run-time overheads.
+ </para></listitem>
+ </orderedlist>
+ <para>
+For the common case where only a single I<superscript>2</superscript>C
+bus should be supported
+(<varname>CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES</varname> is
+disabled), the last four parameters should be provided by preprocessor
+<literal>#define</literal>'s, typically in <filename
+class="headerfile">cyg/hal/plf_io.h</filename> which gets
+<literal>#include</literal>'d automatically via
+<filename>cyg/hal/hal_io.h</filename>. This header can also define the
+<varname>HAL_I2C_EXPORTED_DEVICES</varname> macro as per the generic
+I<superscript>2</superscript>C package:
+ </para>
+ <programlisting width=72>
+#include &lt;pkgconf/hal_m68k_dnp5280.h&gt;
+&hellip;
+#ifdef CYGHWR_HAL_M68K_DNP5280_I2C
+#define HAL_MCF52xx_I2C_SINGLETON_BASE (HAL_MCF52xx_MBAR+HAL_MCF5282_I2C0_BASE)
+#define HAL_MCF52xx_I2C_SINGLETON_ISRVEC CYGNUM_HAL_ISR_I2C_IIF
+#define HAL_MCF52xx_I2C_SINGLETON_ISRPRI CYGNUM_HAL_M68K_DNP5280_I2C_ISRPRI
+#define HAL_MCF52xx_I2C_SINGLETON_FDR CYGNUM_HAL_M68K_DNP5280_I2C_FDR
+
+#define HAL_I2C_EXPORTED_DEVICES \
+ extern cyg_i2c_bus hal_dnp5280_i2c_bus;
+#endif
+ </programlisting>
+ <para>
+On this particular platform the I<superscript>2</superscript>C bus is
+only accessible on an expansion connector so the support is
+conditional on a configuration option
+<varname>CYGHWR_HAL_M68K_DNP5280_I2C</varname>. The interrupt priority
+and I2FDR values are also controlled by configuration options. On
+other platforms the I<superscript>2</superscript>C support may not be
+conditional and the priority and/or FDR values may be hard-wired.
+ </para>
+ <para>
+The I<superscript>2</superscript>C bus instantiation should happen in
+an ordinary C or C++ file, typically in the platform HAL. The
+corresponding object file should go into
+<filename>libtarget.a</filename> and the file should only contain
+I<superscript>2</superscript>C-related code to get the maximum benefit
+of linker garbage collection.
+ </para>
+ <programlisting width=72>
+#include &lt;cyg/infra/cyg_type.h&gt;
+#include &lt;cyg/hal/hal_io.h&gt;
+#include &lt;cyg/io/i2c.h&gt;
+#include &lt;cyg/io/i2c_mcf52xx.h&gt;
+
+static void
+dnp5280_i2c_init(struct cyg_i2c_bus* bus)
+{
+ cyg_uint16 paspar;
+ // Reset GPIO pins PAS0/1 to their alternative SCL/SDA settings
+ HAL_READ_UINT16(HAL_MCF5282_IPSBAR + HAL_MCF5282_GPIO_PASPAR, paspar);
+ paspar &amp;= ~(HAL_MCF5282_GPIO_PASPAR_A0_MASK | HAL_MCF5282_GPIO_PASPAR_A1_MASK);
+ paspar |= (HAL_MCF5282_GPIO_PASPAR_A0_SCL | HAL_MCF5282_GPIO_PASPAR_A1_SDA);
+ HAL_WRITE_UINT16(HAL_MCF5282_IPSBAR + HAL_MCF5282_GPIO_PASPAR, paspar);
+
+ // And leave the driver to take care of the rest.
+ cyg_mcf52xx_i2c_init(bus);
+}
+
+CYG_MCF52xx_I2C_BUS(hal_dnp5280_i2c_bus,
+ &amp;dnp5280_i2c_init,
+ HAL_MCF52xx_I2C_SINGLETON_BASE,
+ HAL_MCF52xx_I2C_SINGLETON_ISRVEC,
+ HAL_MCF52xx_I2C_SINGLETON_ISRPRI,
+ HAL_MCF52xx_I2C_SINGLETON_FDR);
+
+ </programlisting>
+ <para>
+Obviously if <varname>CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES</varname>
+is enabled then the singleton macros may not be defined and the
+appropriate numbers should be used directly. This example uses a
+custom initialization function which sets up the relevant pins and
+then chains into the I<superscript>2</superscript>C drivers'
+<function>cyg_mcf52xx_i2c_init</function> function. If the platform
+HAL has already set up the pins correctly then
+<function>cyg_mcf52xx_i2c_init</function> could be used directly in
+the bus instantiation, saving a small amount of code for the custom
+initialization function.
+ </para>
+ <para>
+I<superscript>2</superscript>C device structures can be instantiated
+in the usual way, for example:
+ </para>
+ <programlisting width=72>
+CYG_I2C_DEVICE(cyg_i2c_wallclock_ds1307,
+ &amp;hal_dnp5280_i2c_bus,
+ 0x68,
+ 0x00,
+ CYG_I2C_DEFAULT_DELAY);
+ </programlisting>
+ </refsect1>
+
+</refentry>
+</part>
diff --git a/ecos/packages/devs/i2c/m68k/mcf52xx/current/include/i2c_mcf52xx.h b/ecos/packages/devs/i2c/m68k/mcf52xx/current/include/i2c_mcf52xx.h
new file mode 100644
index 0000000..d756612
--- /dev/null
+++ b/ecos/packages/devs/i2c/m68k/mcf52xx/current/include/i2c_mcf52xx.h
@@ -0,0 +1,119 @@
+//==========================================================================
+//
+// devs/i2c/m68k/mcf52xx/current/src/i2c_mcf52xx.h
+//
+// I2C driver for Motorola coldfire processors
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bart Veer
+// Contributors:
+// Date: 2005-11-20
+// Description: I2C driver for motorola coldfire processor
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/devs_i2c_mcf52xx.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+
+typedef enum cyg_mcf52xx_i2c_xfer_mode {
+ CYG_MCF52xx_I2C_XFER_MODE_INVALID = 0x00,
+ CYG_MCF52xx_I2C_XFER_MODE_TX = 0x01,
+ CYG_MCF52xx_I2C_XFER_MODE_RX = 0x02,
+ CYG_MCF52xx_I2C_XFER_MODE_STARTRX = 0x03
+} cyg_mcf52xx_i2c_xfer_mode;
+
+typedef struct cyg_mcf52xx_i2c_extra {
+#ifdef CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES
+ // Put statically initialized fields first.
+ cyg_uint8* i2c_base; // Per-bus h/w details
+ cyg_vector_t i2c_isrvec;
+ int i2c_isrpri;
+ int i2c_fdr;
+#endif
+
+ cyg_uint8 i2c_owner; // We have bus ownership
+ cyg_uint8 i2c_lost_arb; // Error condition leading to loss of bus ownership
+ cyg_uint8 i2c_send_nack; // As per rx send_nack argument
+ cyg_uint8 i2c_got_nack; // The last tx resulted in a nack
+ cyg_uint8 i2c_completed; // Set by DSR, checked by thread
+
+ union {
+ const cyg_uint8* i2c_tx_data;
+ cyg_uint8* i2c_rx_data;
+ } i2c_data; // The current buffer for rx or tx
+ cyg_uint32 i2c_count; // Number of bytes left in buffer
+ cyg_mcf52xx_i2c_xfer_mode i2c_mode; // TX, RX, ...
+
+
+ cyg_drv_mutex_t i2c_lock; // For synchronizing between DSR and foreground
+ cyg_drv_cond_t i2c_wait;
+ cyg_handle_t i2c_interrupt_handle; // For initializing the interrupt
+ cyg_interrupt i2c_interrupt_data;
+} cyg_mcf52xx_i2c_extra;
+
+externC void cyg_mcf52xx_i2c_init(struct cyg_i2c_bus*);
+externC cyg_uint32 cyg_mcf52xx_i2c_tx(const cyg_i2c_device*, cyg_bool, const cyg_uint8*, cyg_uint32, cyg_bool);
+externC cyg_uint32 cyg_mcf52xx_i2c_rx(const cyg_i2c_device*, cyg_bool, cyg_uint8*, cyg_uint32, cyg_bool, cyg_bool);
+externC void cyg_mcf52xx_i2c_stop(const cyg_i2c_device*);
+
+#ifdef CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES
+# define CYG_MCF52xx_I2C_BUS(_name_, _init_fn_, _base_, _isr_vec_, _isr_pri_, _fdr_) \
+ static cyg_mcf52xx_i2c_extra _name_ ## _extra = { \
+ _base_, \
+ _isr_vec_, \
+ _isr_pri_, \
+ _fdr_ \
+ } ; \
+ CYG_I2C_BUS(_name_, \
+ _init_fn_, \
+ &cyg_mcf52xx_i2c_tx, \
+ &cyg_mcf52xx_i2c_rx, \
+ &cyg_mcf52xx_i2c_stop, \
+ (void*) & ( _name_ ## _extra)) ;
+
+#else
+# define CYG_MCF52xx_I2C_BUS(_name_, _init_fn_, _base_, _isr_vec_, _isr_pri_, _fdr_) \
+ static cyg_mcf52xx_i2c_extra _name_ ## _extra; \
+ CYG_I2C_BUS(_name_, \
+ _init_fn_, \
+ cyg_mcf52xx_i2c_tx, \
+ cyg_mcf52xx_i2c_rx, \
+ cyg_mcf52xx_i2c_stop, \
+ (void*) & ( _name_ ## _extra)) ;
+#endif
+
diff --git a/ecos/packages/devs/i2c/m68k/mcf52xx/current/src/i2c_mcf52xx.c b/ecos/packages/devs/i2c/m68k/mcf52xx/current/src/i2c_mcf52xx.c
new file mode 100644
index 0000000..dddc6de
--- /dev/null
+++ b/ecos/packages/devs/i2c/m68k/mcf52xx/current/src/i2c_mcf52xx.c
@@ -0,0 +1,452 @@
+//==========================================================================
+//
+// devs/i2c/m68k/mcf52xx/current/src/i2c_mcf52xx.c
+//
+// I2C driver for Motorola coldfire processors
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler, Bart Veer
+// Contributors:
+// Date: 2005-10-23
+// Description: I2C driver for motorola coldfire processor
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_i2c_mcf52xx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/i2c.h>
+#include <cyg/io/i2c_mcf52xx.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+// Optimize for the case of a single bus device, while still allowing
+// multiple devices.
+#ifndef CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES
+# define I2C_BASE(_extra_) (cyg_uint8*)HAL_MCF52xx_I2C_SINGLETON_BASE
+# define I2C_ISRVEC(_extra_) HAL_MCF52xx_I2C_SINGLETON_ISRVEC
+# define I2C_ISRPRI(_extra_) HAL_MCF52xx_I2C_SINGLETON_ISRPRI
+# define I2C_FDR(_extra_) HAL_MCF52xx_I2C_SINGLETON_FDR
+#else
+# define I2C_BASE(_extra_) ((_extra_)->i2c_base)
+# define I2C_ISRVEC(_extra_) ((_extra_)->i2c_isrvec)
+# define I2C_ISRPRI(_extra_) ((_extra_)->i2c_isrpri)
+# define I2C_FDR(_extra_) ((_extra_)->i2c_fdr)
+#endif
+
+// If building for a singleton but the macros are no defined, assume
+// the I2C support is conditional on a disabled platform HAL
+// configuration option. This handles the common case of an I2C bus
+// accessed only via an expansion connector.
+#if defined(CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES) || defined(HAL_MCF52xx_I2C_SINGLETON_BASE)
+
+// ----------------------------------------------------------------------------
+// Interrupt handling and polling
+//
+// The MCF52xx I2C bus device does not have a fifo or any kind of DMA
+// capability, so can generate interrupts at a very high rate: ~10K
+// interrupts per second if the bus is running at the standard 100KHz,
+// or 50K for a high-speed 400KHz bus. To keep the cpu load down to
+// something vaguely reasonable as much work as possible has to be
+// done in the ISR, with the DSR used only for completion.
+static cyg_uint32
+mcf52xx_i2c_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)data;
+ cyg_uint8 sr, dr;
+ cyg_uint8* base = I2C_BASE(extra);
+ cyg_uint32 result = CYG_ISR_HANDLED;
+
+ // Read the current status, then clear the interrupt and
+ // arbitration-lost flags. No later code will look at the
+ // SR register again.
+ HAL_READ_UINT8( base + HAL_MCF52xx_I2C_SR_OFF, sr);
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, 0x00);
+
+ // What to do next depends on the current transfer mode.
+ if (CYG_MCF52xx_I2C_XFER_MODE_TX == extra->i2c_mode) {
+ // We are in a transmit, or sending the address byte just
+ // before a transmit.
+ if (sr & HAL_MCF52xx_I2C_SR_IAL) {
+ // Lost the bus, abort the transfer. count has already been
+ // decremented. Assume the byte did not actually arrive.
+ extra->i2c_count += 1;
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else if (sr & HAL_MCF52xx_I2C_SR_RXAK) {
+ // This byte has been sent but the device cannot accept
+ // any more. The nack must be remembered. Otherwise if
+ // we got a nack for the last byte in a tx then the
+ // calling code will think the entire tx succeeded,
+ // and there will be problems if the next call is
+ // another tx without a repeated start.
+ extra->i2c_got_nack = 1;
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else if (0 == extra->i2c_count) {
+ // No more bytes to send.
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, *(extra->i2c_data.i2c_tx_data));
+ extra->i2c_data.i2c_tx_data += 1;
+ extra->i2c_count -= 1;
+ }
+ } else if (CYG_MCF52xx_I2C_XFER_MODE_RX == extra->i2c_mode) {
+ if (sr & HAL_MCF52xx_I2C_SR_IAL) {
+ // Lost the bus? Maybe a spurious stop
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else {
+ if (extra->i2c_send_nack && (2 == extra->i2c_count)) {
+ // Received one, one more to go, and that one should be nacked.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA |
+ HAL_MCF52xx_I2C_CR_TXAK);
+ } else if (1 == extra->i2c_count) {
+ // Received the last byte. The docs say to send a stop,
+ // but there may be another transaction_rx() call. We
+ // cannot just read DR again, that would trigger another
+ // read. So instead switch to transmit mode for now,
+ // which should cause the h/w to wait until a byte is
+ // written to DR.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA |
+ HAL_MCF52xx_I2C_CR_MTX);
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ }
+
+ HAL_READ_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, dr);
+ *(extra->i2c_data.i2c_rx_data) = dr;
+ extra->i2c_data.i2c_rx_data += 1;
+ extra->i2c_count -= 1;
+ }
+ } else if (CYG_MCF52xx_I2C_XFER_MODE_STARTRX == extra->i2c_mode) {
+ // Start followed by RX. The address byte has been sent, we
+ // need to switch to receiving.
+ if (sr & (HAL_MCF52xx_I2C_SR_IAL | HAL_MCF52xx_I2C_SR_RXAK)) {
+ // Looks like no device acknowledged the address.
+ result = CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+ } else {
+ extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_RX;
+ if (extra->i2c_send_nack && (1 == extra->i2c_count)) {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA |
+ HAL_MCF52xx_I2C_CR_TXAK);
+ } else {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA);
+ }
+ // This dummy read causes the next rx to start
+ HAL_READ_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, dr);
+ }
+ } else {
+ // Invalid state? Some kind of spurious interrupt? Just ignore
+ // it.
+ CYG_FAIL("I2C spurious interrupt");
+ }
+
+ // NOTE: this will acknowledge the interrupt even in polled mode.
+ // Probably harmless. Using I2C_ISRVEC rather than the vec arg
+ // means a constant number for the singleton case, which may
+ // allow the HAL to optimize the acknowledge away completely.
+ HAL_INTERRUPT_ACKNOWLEDGE(I2C_ISRVEC(extra));
+ return result;
+}
+
+static void
+mcf52xx_i2c_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)data;
+ extra->i2c_completed = 1;
+ cyg_drv_cond_signal(&(extra->i2c_wait));
+}
+
+// A transfer has been started. Wait for completion, allowing for both
+// polled and interrupt-driven mode.
+static inline void
+mcf52xx_i2c_doit(cyg_mcf52xx_i2c_extra* extra)
+{
+ cyg_uint8* base = I2C_BASE(extra);
+ int ints_state;
+ int sr;
+
+ HAL_QUERY_INTERRUPTS(ints_state);
+ if (((ints_state >> 8) & 0x07) > CYGNUM_HAL_INTERRUPT_DEFAULT_IPL_LEVEL) {
+ // Interrupts are currently disabled. We'll have to poll.
+ for ( ; ; ) {
+ HAL_READ_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, sr);
+ if (sr & HAL_MCF52xx_I2C_SR_IIF) {
+ if (CYG_ISR_CALL_DSR & mcf52xx_i2c_isr(I2C_ISRVEC(extra), (cyg_addrword_t)extra)) {
+ break;
+ }
+ }
+ }
+ } else {
+ cyg_drv_mutex_lock(&(extra->i2c_lock));
+ cyg_drv_dsr_lock();
+ while (! extra->i2c_completed) {
+ cyg_drv_cond_wait(&(extra->i2c_wait));
+ }
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&(extra->i2c_lock));
+ }
+}
+
+static cyg_bool
+mcf52xx_i2c_send_start(cyg_mcf52xx_i2c_extra* extra, int address)
+{
+ cyg_uint8* base = I2C_BASE(extra);
+ cyg_uint8 sr;
+
+ // This may be a repeated start or the beginning of a transaction.
+ // If the former then we still own the bus.
+ if (!extra->i2c_owner) {
+ // The bus is currently in slave mode. See if another master
+ // currently owns the bus and if so fail immediately. It is up
+ // to higher level code to decide when to retry. Alternatively
+ // if the bus has somehow got stuck in busy mode it is again
+ // up to higher level code to sort things out.
+ HAL_READ_UINT8(I2C_BASE(extra) + HAL_MCF52xx_I2C_SR_OFF, sr);
+ if (sr & HAL_MCF52xx_I2C_SR_IBB) {
+ return 0;
+ }
+
+ // Now we can put the bus into master mode
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA | // This implicitly generates the start
+ HAL_MCF52xx_I2C_CR_MTX); // The address byte needs to be transmitted.
+ extra->i2c_owner = 1;
+ } else {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA | // Already set so no start generated by this
+ HAL_MCF52xx_I2C_CR_MTX |
+ HAL_MCF52xx_I2C_CR_RSTA); // Repeated start
+ }
+
+ // Any previous nack is no longer relevant. If the device cannot accept
+ // more data it will nack the address.
+ extra->i2c_got_nack = 0;
+ // Now send the address. The rest of the transfer is handled by the
+ // interrupt/polling code.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, address);
+ return 1;
+}
+
+static inline void
+mcf52xx_i2c_stopit(cyg_mcf52xx_i2c_extra* extra)
+{
+ // If we still own the bus this releases it (by clearing MSTA) and
+ // generating a stop. If we have lost arbitration then this write
+ // has no effect (other than disabling interrupts). Either way the
+ // bus should end up in a consistent state.
+ HAL_WRITE_UINT8(I2C_BASE(extra) + HAL_MCF52xx_I2C_CR_OFF, HAL_MCF52xx_I2C_CR_IEN);
+ extra->i2c_lost_arb = 0;
+ extra->i2c_owner = 0;
+ extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_INVALID;
+}
+
+// ----------------------------------------------------------------------------
+// The functions needed for all I2C devices.
+
+void
+cyg_mcf52xx_i2c_init(struct cyg_i2c_bus* bus)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)bus->i2c_extra;
+ cyg_uint8 reg;
+ cyg_uint8* base = I2C_BASE(extra);
+
+ cyg_drv_mutex_init(&extra->i2c_lock);
+ cyg_drv_cond_init(&extra->i2c_wait, &extra->i2c_lock);
+ cyg_drv_interrupt_create(I2C_ISRVEC(extra),
+ I2C_ISRPRI(extra),
+ (cyg_addrword_t) extra,
+ &mcf52xx_i2c_isr,
+ &mcf52xx_i2c_dsr,
+ &(extra->i2c_interrupt_handle),
+ &(extra->i2c_interrupt_data));
+ cyg_drv_interrupt_attach(extra->i2c_interrupt_handle);
+
+ // Before unmasking the interrupt sort out the hardware.
+ //
+ // The bus frequency is set by the platform HAL or user, since
+ // it depends on what mixture of devices are present on the bus.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_FDR_OFF, I2C_FDR(extra));
+ // The device will operate in slave mode when idle. If there is
+ // another bus master then the coldfire might accidentally accept
+ // requests intended for another device. Address 0 is installed
+ // as the slave address. This is the General Call address, used
+ // for broadcasting. It might be better to use another address
+ // like an Hs-mode one, but conflicts are still possible.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_ADR_OFF, 0x0);
+ // Enable the I2C device but do not start any transfers and
+ // leave interrupts disabled.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, HAL_MCF52xx_I2C_CR_IEN);
+
+ // As per the documentation, if IBB is set then issue a stop. It
+ // is not really clear this is the right thing to do in
+ // multimaster setups, if another master happens to start a
+ // transfer at this exact time. Presumably it solves more problems
+ // than it might cause.
+ HAL_READ_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, reg);
+ if (reg & HAL_MCF52xx_I2C_SR_IBB) {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, 0x0000);
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, 0x00A0);
+ HAL_READ_UINT8( base + HAL_MCF52xx_I2C_DR_OFF, reg);
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, 0x0000);
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, 0x0000);
+
+ // Don't forget to reenable the device.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF, HAL_MCF52xx_I2C_CR_IEN);
+ }
+
+ // Clear any pending conditions including interrupts.
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_SR_OFF, 0);
+
+ // Interrupts can now be safely unmasked
+ HAL_INTERRUPT_UNMASK(I2C_ISRVEC(extra));
+}
+
+cyg_uint32
+cyg_mcf52xx_i2c_tx(const cyg_i2c_device* dev, cyg_bool send_start, const cyg_uint8* tx_data, cyg_uint32 count, cyg_bool send_stop)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)dev->i2c_bus->i2c_extra;
+
+ extra->i2c_count = count;
+ if (! extra->i2c_lost_arb) {
+ extra->i2c_completed = 0;
+ extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_TX;
+
+ if (send_start) {
+ extra->i2c_data.i2c_tx_data = tx_data;
+ if (! mcf52xx_i2c_send_start(extra, (dev->i2c_address << 1) | 0x00)) {
+ return 0;
+ }
+ mcf52xx_i2c_doit(extra);
+ } else if ( !extra->i2c_got_nack) {
+ // We are in the middle of a transaction and not
+ // generating a repeated start, so the device must already
+ // be set up for writes.
+ extra->i2c_data.i2c_tx_data = &(tx_data[1]);
+ extra->i2c_count = count - 1;
+ HAL_WRITE_UINT8(I2C_BASE(extra) + HAL_MCF52xx_I2C_DR_OFF, *tx_data);
+ mcf52xx_i2c_doit(extra);
+ }
+ }
+ if (send_stop) {
+ mcf52xx_i2c_stopit(extra);
+ }
+
+ // tx() should return the number of bytes actually transmitted.
+ // ISR() increments extra->count after a failure, which leads to
+ // an edge condition when send_start and there is no acknowledgment
+ // of the address byte.
+ if (extra->i2c_count > count) {
+ return 0;
+ }
+ return count - extra->i2c_count;
+}
+
+cyg_uint32
+cyg_mcf52xx_i2c_rx(const cyg_i2c_device* dev, cyg_bool send_start, cyg_uint8* rx_data, cyg_uint32 count, cyg_bool send_nack, cyg_bool send_stop)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)dev->i2c_bus->i2c_extra;
+ cyg_uint8* base = I2C_BASE(extra);
+ cyg_uint8 discard;
+
+ extra->i2c_count = count;
+ extra->i2c_send_nack = send_nack;
+
+ if (! extra->i2c_lost_arb) {
+ extra->i2c_completed = 0;
+ extra->i2c_data.i2c_rx_data = rx_data;
+ if (send_start) {
+ extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_STARTRX;
+ if (! mcf52xx_i2c_send_start(extra, (dev->i2c_address << 1) | 0x01) ) {
+ return 0;
+ }
+ } else {
+ // In the middle of a transaction. The previous transfer
+ // will have left the device in tx mode.
+ extra->i2c_mode = CYG_MCF52xx_I2C_XFER_MODE_RX;
+ if (send_nack && (1 == count)) {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA |
+ HAL_MCF52xx_I2C_CR_TXAK);
+ } else {
+ HAL_WRITE_UINT8(base + HAL_MCF52xx_I2C_CR_OFF,
+ HAL_MCF52xx_I2C_CR_IEN |
+ HAL_MCF52xx_I2C_CR_IIEN |
+ HAL_MCF52xx_I2C_CR_MSTA);
+ }
+ // So reading the data register here should get the device
+ // reading the next byte.
+ HAL_READ_UINT8(base + HAL_MCF52xx_I2C_DR_OFF, discard);
+ }
+ mcf52xx_i2c_doit(extra);
+ }
+ if (send_stop) {
+ mcf52xx_i2c_stopit(extra);
+ }
+ return count - extra->i2c_count;
+}
+
+void
+cyg_mcf52xx_i2c_stop(const cyg_i2c_device* dev)
+{
+ cyg_mcf52xx_i2c_extra* extra = (cyg_mcf52xx_i2c_extra*)dev->i2c_bus->i2c_extra;
+ mcf52xx_i2c_stopit(extra);
+}
+
+#endif // defined(CYGHWR_DEVS_I2C_MCF52xx_MULTIPLE_BUSES) || defined(HAL_MCF52xx_I2C_SINGLETON_BASE)
+//---------------------------------------------------------------------------
+// EOF i2c_mcf52xx.c
diff --git a/ecos/packages/devs/kbd/arm/aaed2000/current/ChangeLog b/ecos/packages/devs/kbd/arm/aaed2000/current/ChangeLog
new file mode 100644
index 0000000..047fed0
--- /dev/null
+++ b/ecos/packages/devs/kbd/arm/aaed2000/current/ChangeLog
@@ -0,0 +1,28 @@
+2002-03-10 Gary Thomas <gthomas@redhat.com>
+
+ * src/aaed2000_kbd.c:
+ * cdl/kbd_aaed2000.cdl: New file(s). Keyboard driver for AAED2000.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/kbd/arm/aaed2000/current/cdl/kbd_aaed2000.cdl b/ecos/packages/devs/kbd/arm/aaed2000/current/cdl/kbd_aaed2000.cdl
new file mode 100644
index 0000000..5d14823
--- /dev/null
+++ b/ecos/packages/devs/kbd/arm/aaed2000/current/cdl/kbd_aaed2000.cdl
@@ -0,0 +1,99 @@
+#==========================================================================
+#
+# kbd_aaed2000.cdl
+#
+# eCos configuration data for the Agilent AAED2000 keyboard
+#
+#==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas
+# Date: 2002-03-11
+# Purpose:
+# Description: Keyboard driver for Agilent AAED2000
+#
+#####DESCRIPTIONEND####
+#
+#==========================================================================
+
+cdl_package CYGPKG_DEVS_KBD_AAED2000 {
+ display "Keypad driver for AAED2000"
+ include_dir cyg/io
+
+ active_if CYGPKG_IO_FILEIO
+ requires CYGPKG_IO
+ requires CYGFUN_KERNEL_API_C
+ requires CYGPKG_HAL_ARM_ARM9_AAED2000
+ active_if !CYGSEM_AAED2000_LCD_COMM
+
+ compile -library=libextras.a aaed2000_kbd.c
+
+ description "Keyboard driver for the AAED2000"
+
+ cdl_component CYGPKG_DEVS_KBD_AAED2000_OPTIONS {
+ display "options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_KBD_AAED2000_CFLAGS {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the keypad driver package. These flags
+ are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGDAT_DEVS_KBD_AAED2000_NAME {
+ display "Device name for the keyboard driver"
+ flavor data
+ default_value {"\"/dev/kbd\""}
+ description " This option specifies the name of the keypad device"
+ }
+
+ cdl_option CYGNUM_DEVS_KBD_AAED2000_EVENT_BUFFER_SIZE {
+ display "Number of events the driver can buffer"
+ flavor data
+ default_value { 32 }
+ description "
+ This option defines the size of the keypad device internal
+ buffer. The cyg_io_read() function will return as many of these
+ as there is space for in the buffer passed."
+ }
+ }
+}
diff --git a/ecos/packages/devs/kbd/arm/aaed2000/current/src/aaed2000_kbd.c b/ecos/packages/devs/kbd/arm/aaed2000/current/src/aaed2000_kbd.c
new file mode 100644
index 0000000..8127ff2
--- /dev/null
+++ b/ecos/packages/devs/kbd/arm/aaed2000/current/src/aaed2000_kbd.c
@@ -0,0 +1,245 @@
+//==========================================================================
+//
+// aaed2000_kbd.c
+//
+// Keyboard driver for the Agilent AAED2000
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2002-03-11
+// Purpose:
+// Description: Keyboardd driver for Agilent AAED2000
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <pkgconf/devs_kbd_aaed2000.h>
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/aaed2000.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <cyg/fileio/fileio.h> // For select() functionality
+static cyg_selinfo kbd_select_info;
+static cyg_bool kbd_select_active;
+
+#include <cyg/io/devtab.h>
+
+// Functions in this module
+
+static Cyg_ErrNo kbd_read(cyg_io_handle_t handle,
+ void *buffer,
+ cyg_uint32 *len);
+static cyg_bool kbd_select(cyg_io_handle_t handle,
+ cyg_uint32 which,
+ cyg_addrword_t info);
+static Cyg_ErrNo kbd_set_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ const void *buffer,
+ cyg_uint32 *len);
+static Cyg_ErrNo kbd_get_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ void *buffer,
+ cyg_uint32 *len);
+static bool kbd_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo kbd_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *st,
+ const char *name);
+
+CHAR_DEVIO_TABLE(aaed2000_kbd_handlers,
+ NULL, // Unsupported write() function
+ kbd_read,
+ kbd_select,
+ kbd_get_config,
+ kbd_set_config);
+
+CHAR_DEVTAB_ENTRY(aaed2000_kbd_device,
+ CYGDAT_DEVS_KBD_AAED2000_NAME,
+ NULL, // Base device name
+ &aaed2000_kbd_handlers,
+ kbd_init,
+ kbd_lookup,
+ NULL); // Private data pointer
+
+#define MAX_EVENTS CYGNUM_DEVS_KBD_AAED2000_EVENT_BUFFER_SIZE
+static int num_events;
+static int _event_put, _event_get;
+static unsigned char _events[MAX_EVENTS];
+
+static bool _is_open = false;
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+static char kbd_scan_stack[STACK_SIZE];
+static cyg_thread kbd_scan_thread_data;
+static cyg_handle_t kbd_scan_thread_handle;
+#define SCAN_FREQ 20 // Hz
+//#define SCAN_FREQ 5 // Hz
+#define SCAN_DELAY ((1000/SCAN_FREQ)/10)
+
+static void
+kbd_scan(cyg_addrword_t param)
+{
+ unsigned char ch;
+ unsigned char *ev;
+
+ diag_printf("Keyboard scan\n");
+ while (true) {
+ cyg_thread_delay(SCAN_DELAY);
+ if (aaed2000_KeyboardTest()) {
+ ch = aaed2000_KeyboardGetc();
+ if (num_events < MAX_EVENTS) {
+ num_events++;
+ ev = &_events[_event_put++];
+ if (_event_put == MAX_EVENTS) {
+ _event_put = 0;
+ }
+ *ev = ch;
+ if (kbd_select_active) {
+ kbd_select_active = false;
+ cyg_selwakeup(&kbd_select_info);
+ }
+ }
+ }
+ }
+}
+
+static Cyg_ErrNo
+kbd_read(cyg_io_handle_t handle,
+ void *buffer,
+ cyg_uint32 *len)
+{
+ unsigned char *ev;
+ int tot = *len;
+ unsigned char *bp = (unsigned char *)buffer;
+
+ cyg_scheduler_lock(); // Prevent interaction with DSR code
+ while (tot >= sizeof(*ev)) {
+ if (num_events > 0) {
+ ev = &_events[_event_get++];
+ if (_event_get == MAX_EVENTS) {
+ _event_get = 0;
+ }
+ memcpy(bp, ev, sizeof(*ev));
+ bp += sizeof(*ev);
+ tot -= sizeof(*ev);
+ num_events--;
+ } else {
+ break; // No more events
+ }
+ }
+ cyg_scheduler_unlock(); // Allow DSRs again
+ diag_dump_buf(buffer, tot);
+ *len -= tot;
+ return ENOERR;
+}
+
+static cyg_bool
+kbd_select(cyg_io_handle_t handle,
+ cyg_uint32 which,
+ cyg_addrword_t info)
+{
+ if (which == CYG_FREAD) {
+ cyg_scheduler_lock(); // Prevent interaction with DSR code
+ if (num_events > 0) {
+ cyg_scheduler_unlock(); // Reallow interaction with DSR code
+ return true;
+ }
+ if (!kbd_select_active) {
+ kbd_select_active = true;
+ cyg_selrecord(info, &kbd_select_info);
+ }
+ cyg_scheduler_unlock(); // Reallow interaction with DSR code
+ }
+ return false;
+}
+
+static Cyg_ErrNo
+kbd_set_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ const void *buffer,
+ cyg_uint32 *len)
+{
+ return EINVAL;
+}
+
+static Cyg_ErrNo
+kbd_get_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ void *buffer,
+ cyg_uint32 *len)
+{
+ return EINVAL;
+}
+
+static bool
+kbd_init(struct cyg_devtab_entry *tab)
+{
+ cyg_selinit(&kbd_select_info);
+ return true;
+}
+
+static Cyg_ErrNo
+kbd_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *st,
+ const char *name)
+{
+ if (!_is_open) {
+ _is_open = true;
+ cyg_thread_create(1, // Priority
+ kbd_scan, // entry
+ 0, // entry parameter
+ "Keyboard scan", // Name
+ &kbd_scan_stack[0], // Stack
+ STACK_SIZE, // Size
+ &kbd_scan_thread_handle, // Handle
+ &kbd_scan_thread_data // Thread data structure
+ );
+ cyg_thread_resume(kbd_scan_thread_handle); // Start it
+ }
+ return ENOERR;
+}
+
+
+
diff --git a/ecos/packages/devs/kbd/arm/ipaq/current/ChangeLog b/ecos/packages/devs/kbd/arm/ipaq/current/ChangeLog
new file mode 100644
index 0000000..aebd5c8
--- /dev/null
+++ b/ecos/packages/devs/kbd/arm/ipaq/current/ChangeLog
@@ -0,0 +1,36 @@
+2001-08-29 Kenichi Nakamura <nakamura@redhat.com>
+
+ * cdl/kbd_ipaq.cdl: Modified dependency on file I/O package.
+
+2001-04-24 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/kbd_ipaq.cdl: Add dependency on file I/O package.
+
+2001-03-15 Gary Thomas <gthomas@redhat.com>
+
+ * src/ipaq_kbd.c:
+ * cdl/kbd_ipaq.cdl: New file(s) - keypad driver for iPAQ.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/kbd/arm/ipaq/current/cdl/kbd_ipaq.cdl b/ecos/packages/devs/kbd/arm/ipaq/current/cdl/kbd_ipaq.cdl
new file mode 100644
index 0000000..3856fec
--- /dev/null
+++ b/ecos/packages/devs/kbd/arm/ipaq/current/cdl/kbd_ipaq.cdl
@@ -0,0 +1,99 @@
+#==========================================================================
+#
+# kbd_ipaq.cdl
+#
+# eCos configuration data for the Compaq iPAQ keypad/buttons
+#
+#==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas
+# Date: 2001-03-15
+# Purpose:
+# Description: Kbdscreen drivers for Compaq iPAQ
+#
+#####DESCRIPTIONEND####
+#
+#==========================================================================
+
+cdl_package CYGPKG_DEVS_KBD_IPAQ {
+ display "Keypad driver for iPAQ"
+ include_dir cyg/io
+
+ active_if CYGPKG_IO_FILEIO
+ requires CYGPKG_IO
+ requires CYGFUN_KERNEL_API_C
+ requires CYGPKG_HAL_ARM_SA11X0_IPAQ
+ active_if !CYGSEM_IPAQ_LCD_COMM
+
+ compile -library=libextras.a ipaq_kbd.c
+
+ description "Keypad driver for the iPAQ using the Atmel micro-controller"
+
+ cdl_component CYGPKG_DEVS_KBD_IPAQ_OPTIONS {
+ display "options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_KBD_IPAQ_CFLAGS {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the keypad driver package. These flags
+ are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGDAT_DEVS_KBD_IPAQ_NAME {
+ display "Device name for the keypad driver"
+ flavor data
+ default_value {"\"/dev/kbd\""}
+ description " This option specifies the name of the keypad device"
+ }
+
+ cdl_option CYGNUM_DEVS_KBD_IPAQ_EVENT_BUFFER_SIZE {
+ display "Number of events the driver can buffer"
+ flavor data
+ default_value { 32 }
+ description "
+ This option defines the size of the keypad device internal
+ buffer. The cyg_io_read() function will return as many of these
+ as there is space for in the buffer passed."
+ }
+ }
+}
diff --git a/ecos/packages/devs/kbd/arm/ipaq/current/src/ipaq_kbd.c b/ecos/packages/devs/kbd/arm/ipaq/current/src/ipaq_kbd.c
new file mode 100644
index 0000000..a34f0d1
--- /dev/null
+++ b/ecos/packages/devs/kbd/arm/ipaq/current/src/ipaq_kbd.c
@@ -0,0 +1,224 @@
+//==========================================================================
+//
+// ipaq_kbd.c
+//
+// Keypad driver for the Compaq iPAQ
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2001-03-15
+// Purpose:
+// Description: Keypad driver for Compaq IPAQ
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <pkgconf/devs_kbd_ipaq.h>
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_sa11x0.h>
+#include <cyg/hal/ipaq.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <cyg/fileio/fileio.h> // For select() functionality
+static cyg_selinfo kbd_select_info;
+static cyg_bool kbd_select_active;
+
+#include <cyg/io/devtab.h>
+#include <cyg/hal/atmel_support.h>
+
+// Functions in this module
+
+static Cyg_ErrNo kbd_read(cyg_io_handle_t handle,
+ void *buffer,
+ cyg_uint32 *len);
+static cyg_bool kbd_select(cyg_io_handle_t handle,
+ cyg_uint32 which,
+ cyg_addrword_t info);
+static Cyg_ErrNo kbd_set_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ const void *buffer,
+ cyg_uint32 *len);
+static Cyg_ErrNo kbd_get_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ void *buffer,
+ cyg_uint32 *len);
+static bool kbd_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo kbd_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *st,
+ const char *name);
+
+CHAR_DEVIO_TABLE(ipaq_kbd_handlers,
+ NULL, // Unsupported write() function
+ kbd_read,
+ kbd_select,
+ kbd_get_config,
+ kbd_set_config);
+
+CHAR_DEVTAB_ENTRY(ipaq_kbd_device,
+ CYGDAT_DEVS_KBD_IPAQ_NAME,
+ NULL, // Base device name
+ &ipaq_kbd_handlers,
+ kbd_init,
+ kbd_lookup,
+ NULL); // Private data pointer
+
+#define MAX_EVENTS CYGNUM_DEVS_KBD_IPAQ_EVENT_BUFFER_SIZE
+static int num_events;
+static int _event_put, _event_get;
+static unsigned char _events[MAX_EVENTS];
+
+static bool _is_open = false;
+
+//
+// Note: this routine is called from the Atmel processing DSR
+//
+static void
+kbd_handler(atmel_pkt *pkt)
+{
+ unsigned char *dp = pkt->data;
+ unsigned char *ev;
+
+// diag_printf("KBD = %x\n", dp[1]);
+ if (num_events < MAX_EVENTS) {
+ num_events++;
+ ev = &_events[_event_put++];
+ if (_event_put == MAX_EVENTS) {
+ _event_put = 0;
+ }
+ *ev = dp[1];
+ if (kbd_select_active) {
+ kbd_select_active = false;
+ cyg_selwakeup(&kbd_select_info);
+ }
+ }
+}
+
+static Cyg_ErrNo
+kbd_read(cyg_io_handle_t handle,
+ void *buffer,
+ cyg_uint32 *len)
+{
+ unsigned char *ev;
+ int tot = *len;
+ unsigned char *bp = (unsigned char *)buffer;
+
+ cyg_scheduler_lock(); // Prevent interaction with DSR code
+ while (tot >= sizeof(*ev)) {
+ if (num_events > 0) {
+ ev = &_events[_event_get++];
+ if (_event_get == MAX_EVENTS) {
+ _event_get = 0;
+ }
+ memcpy(bp, ev, sizeof(*ev));
+ bp += sizeof(*ev);
+ tot -= sizeof(*ev);
+ num_events--;
+ } else {
+ break; // No more events
+ }
+ }
+ cyg_scheduler_unlock(); // Allow DSRs again
+ *len -= tot;
+ return ENOERR;
+}
+
+static cyg_bool
+kbd_select(cyg_io_handle_t handle,
+ cyg_uint32 which,
+ cyg_addrword_t info)
+{
+ if (which == CYG_FREAD) {
+ cyg_scheduler_lock(); // Prevent interaction with DSR code
+ if (num_events > 0) {
+ cyg_scheduler_unlock(); // Reallow interaction with DSR code
+ return true;
+ }
+ if (!kbd_select_active) {
+ kbd_select_active = true;
+ cyg_selrecord(info, &kbd_select_info);
+ }
+ cyg_scheduler_unlock(); // Reallow interaction with DSR code
+ }
+ return false;
+}
+
+static Cyg_ErrNo
+kbd_set_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ const void *buffer,
+ cyg_uint32 *len)
+{
+ return EINVAL;
+}
+
+static Cyg_ErrNo
+kbd_get_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ void *buffer,
+ cyg_uint32 *len)
+{
+ return EINVAL;
+}
+
+static bool
+kbd_init(struct cyg_devtab_entry *tab)
+{
+ cyg_selinit(&kbd_select_info);
+ return true;
+}
+
+static Cyg_ErrNo
+kbd_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *st,
+ const char *name)
+{
+ if (!_is_open) {
+ _is_open = true;
+ atmel_register(ATMEL_CMD_KEYBD, kbd_handler);
+ atmel_interrupt_mode(true);
+ }
+ return ENOERR;
+}
diff --git a/ecos/packages/devs/pcmcia/arm/assabet/current/ChangeLog b/ecos/packages/devs/pcmcia/arm/assabet/current/ChangeLog
new file mode 100644
index 0000000..bfa3590
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/assabet/current/ChangeLog
@@ -0,0 +1,62 @@
+2001-07-13 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_pcmcia.c (cf_hwr_change_state): Check for VERS_1
+ field instead of MANID since some cards don't seem to have that one.
+ Suggested by I-Jui Sung <ijsung@csie.nctu.edu.tw>.
+
+2000-09-17 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_pcmcia.c: Change interrupt functions to have same
+ calling convention as DSR.
+
+2000-09-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_pcmcia.c: Fix build problem when built for eCos.
+
+2000-08-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_pcmcia.c (cf_irq_dsr): Support [shared] network
+ debug situation where "IF" functions need to see device interrupts.
+ This is used to detect ^C over the connection. This also requires
+ additional care when setting up the bus initially.
+
+2000-08-24 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_pcmcia.c: Add hardware function to clear interrupts.
+
+2000-07-16 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_pcmcia.c: Remove dependency in generic I/O package.
+
+2000-07-15 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_pcmcia.c: Support new slot-oriented interrupts.
+
+2000-07-14 Gary Thomas <gthomas@redhat.com>
+
+ * src/assabet_pcmcia.c: Support running in non-kernel (stand-alone)
+ environments.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/pcmcia/arm/assabet/current/cdl/pcmcia_assabet.cdl b/ecos/packages/devs/pcmcia/arm/assabet/current/cdl/pcmcia_assabet.cdl
new file mode 100644
index 0000000..8cd493d
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/assabet/current/cdl/pcmcia_assabet.cdl
@@ -0,0 +1,65 @@
+# ====================================================================
+#
+# pcmcia_assabet.cdl
+#
+# PCMCIA (Compact Flash) - Hardware support on Assabet
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_PCMCIA_ASSABET {
+ display "SA11x0/Assabet PCMCIA support"
+
+ parent CYGPKG_IO_PCMCIA
+ active_if CYGPKG_IO_PCMCIA
+ active_if CYGPKG_HAL_ARM_SA11X0_ASSABET
+
+ implements CYGHWR_IO_PCMCIA_DEVICE
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "PCMCIA (Compact Flash) device support for SA11x0/Assabet"
+ compile assabet_pcmcia.c
+}
+
diff --git a/ecos/packages/devs/pcmcia/arm/assabet/current/src/assabet_pcmcia.c b/ecos/packages/devs/pcmcia/arm/assabet/current/src/assabet_pcmcia.c
new file mode 100644
index 0000000..307f532
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/assabet/current/src/assabet_pcmcia.c
@@ -0,0 +1,271 @@
+//==========================================================================
+//
+// devs/pcmcia/assabet/assabet_pcmcia.c
+//
+// PCMCIA support (Card Services)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-06
+// Purpose: PCMCIA support
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/io_pcmcia.h>
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_arch.h> // Register state info
+#include <cyg/hal/hal_intr.h> // HAL interrupt macros
+#include <cyg/hal/drv_api.h>
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h> // Configuration header
+#include <cyg/kernel/kapi.h>
+#endif
+#include <cyg/hal/hal_if.h>
+
+#include <cyg/io/pcmcia.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_sa11x0.h> // Board definitions
+#include <cyg/hal/assabet.h>
+
+#ifdef CYGPKG_KERNEL
+static cyg_interrupt cf_detect_interrupt;
+static cyg_handle_t cf_detect_interrupt_handle;
+static cyg_interrupt cf_irq_interrupt;
+static cyg_handle_t cf_irq_interrupt_handle;
+
+// This ISR is called when a CompactFlash board is inserted
+static int
+cf_detect_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_interrupt_mask(SA1110_CF_DETECT);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+// This DSR handles the board insertion
+static void
+cf_detect_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ struct cf_slot *slot = (struct cf_slot *)data;
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ slot->state = CF_SLOT_STATE_Inserted;
+ } else {
+ slot->state = CF_SLOT_STATE_Removed; // Implies powered up, etc.
+ }
+ cyg_interrupt_acknowledge(SA1110_CF_DETECT);
+ cyg_interrupt_unmask(SA1110_CF_DETECT);
+}
+
+// This ISR is called when the card interrupt occurs
+static int
+cf_irq_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_drv_interrupt_mask(SA1110_CF_IRQ);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+// This DSR handles the card interrupt
+static void
+cf_irq_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct cf_slot *slot = (struct cf_slot *)data;
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+ cyg_bool was_ctrlc_int;
+#endif
+
+ // Clear interrupt [edge indication]
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+ was_ctrlc_int = HAL_CTRLC_CHECK(vector, data);
+ if (!was_ctrlc_int) // Fall through and run normal code
+#endif
+ // Process interrupt
+ (slot->irq_handler.handler)(vector, count, slot->irq_handler.param);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
+}
+#endif
+
+//
+// Fill in the details of a PCMCIA slot and initialize the device
+//
+void
+cf_hwr_init(struct cf_slot *slot)
+{
+ static int int_init = 0;
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ if (!int_init) {
+ int_init = 1;
+#ifdef CYGPKG_KERNEL
+ // Set up interrupts
+ cyg_drv_interrupt_create(SA1110_CF_DETECT,
+ 99, // Priority - what goes here?
+ (cyg_addrword_t) slot, // Data item passed to interrupt handler
+ (cyg_ISR_t *)cf_detect_isr,
+ (cyg_DSR_t *)cf_detect_dsr,
+ &cf_detect_interrupt_handle,
+ &cf_detect_interrupt);
+ cyg_drv_interrupt_attach(cf_detect_interrupt_handle);
+ cyg_drv_interrupt_configure(SA1110_CF_DETECT, true, true); // Detect either edge
+ cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
+ cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
+ cyg_drv_interrupt_create(SA1110_CF_IRQ,
+ 99, // Priority - what goes here?
+ (cyg_addrword_t) slot, // Data item passed to interrupt handler
+ (cyg_ISR_t *)cf_irq_isr,
+ (cyg_DSR_t *)cf_irq_dsr,
+ &cf_irq_interrupt_handle,
+ &cf_irq_interrupt);
+ cyg_drv_interrupt_attach(cf_irq_interrupt_handle);
+ cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
+#endif
+ cyg_drv_interrupt_configure(SA1110_CF_IRQ, false, false); // Falling edge
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+ }
+ slot->attr = (unsigned char *)0x38000000;
+ slot->attr_length = 0x200;
+ slot->io = (unsigned char *)0x30000000;
+ slot->io_length = 0x04000000;
+ slot->mem = (unsigned char *)0x3C000000;
+ slot->mem_length = 0x04000000;
+ slot->int_num = SA1110_CF_IRQ;
+#ifdef CYG_HAL_STARTUP_ROM
+ // Disable CF bus & power (idle/off)
+ assabet_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_OFF |
+ SA1110_BCR_CF_RESET_DISABLE |
+ SA1110_BCR_CF_BUS_OFF);
+#endif
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ if ((_assabet_BCR & SA1110_BCR_CF_POWER) == SA1110_BCR_CF_POWER_ON) {
+ // Assume that the ROM environment has turned the bus on
+ slot->state = CF_SLOT_STATE_Ready;
+ } else {
+ slot->state = CF_SLOT_STATE_Inserted;
+ }
+ } else {
+ slot->state = CF_SLOT_STATE_Empty;
+ }
+}
+
+void
+cf_hwr_poll(struct cf_slot *slot)
+{
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ slot->state = CF_SLOT_STATE_Inserted;
+ } else {
+ slot->state = CF_SLOT_STATE_Empty;
+ }
+}
+
+static void
+do_delay(int ticks)
+{
+#ifdef CYGPKG_KERNEL
+ cyg_thread_delay(ticks);
+#else
+ CYGACC_CALL_IF_DELAY_US(10000*ticks);
+#endif
+}
+
+//
+// Transition the card/slot to a new state
+// note: currently only supports transitions to Ready, Empty
+//
+bool
+cf_hwr_change_state(struct cf_slot *slot, int new_state)
+{
+ int i, ptr, len;
+ unsigned char buf[256];
+
+ if (new_state == CF_SLOT_STATE_Ready) {
+ if (slot->state == CF_SLOT_STATE_Inserted) {
+ assabet_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_ON |
+ SA1110_BCR_CF_RESET_DISABLE |
+ SA1110_BCR_CF_BUS_OFF);
+ do_delay(30); // At least 300 ms
+ slot->state = CF_SLOT_STATE_Powered;
+ assabet_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_ON |
+ SA1110_BCR_CF_RESET_ENABLE |
+ SA1110_BCR_CF_BUS_ON);
+ do_delay(1); // At least 10 us
+ slot->state = CF_SLOT_STATE_Reset;
+ assabet_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_ON |
+ SA1110_BCR_CF_RESET_DISABLE |
+ SA1110_BCR_CF_BUS_ON);
+ do_delay(5); // At least 20 ms
+ // Wait until the card is ready to talk
+ for (i = 0; i < 10; i++) {
+ ptr = 0;
+ if (cf_get_CIS(slot, CF_CISTPL_VERS_1, buf, &len, &ptr)) {
+ slot->state = CF_SLOT_STATE_Ready;
+ break;
+ }
+ do_delay(10);
+ }
+ }
+ }
+}
+
+//
+// Acknowledge interrupt (used in non-kernel environments)
+//
+void
+cf_hwr_clear_interrupt(struct cf_slot *slot)
+{
+ // Clear interrupt [edge indication]
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+}
diff --git a/ecos/packages/devs/pcmcia/arm/cerf/current/ChangeLog b/ecos/packages/devs/pcmcia/arm/cerf/current/ChangeLog
new file mode 100644
index 0000000..23cf9d3
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/cerf/current/ChangeLog
@@ -0,0 +1,28 @@
+2002-02-04 Gary Thomas <gthomas@redhat.com>
+
+ * src/cerf_pcmcia.c:
+ * cdl/pcmcia_cerf.cdl: New file(s) - port to Intrinsyc CerfCube.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/pcmcia/arm/cerf/current/cdl/pcmcia_cerf.cdl b/ecos/packages/devs/pcmcia/arm/cerf/current/cdl/pcmcia_cerf.cdl
new file mode 100644
index 0000000..b8afa2f
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/cerf/current/cdl/pcmcia_cerf.cdl
@@ -0,0 +1,65 @@
+# ====================================================================
+#
+# pcmcia_cerf.cdl
+#
+# PCMCIA (Compact Flash) - Hardware support on Intrinsyc Cerf
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_PCMCIA_CERF {
+ display "SA11x0/Cerf PCMCIA support"
+
+ parent CYGPKG_IO_PCMCIA
+ active_if CYGPKG_IO_PCMCIA
+ active_if CYGPKG_HAL_ARM_SA11X0_CERF
+
+ implements CYGHWR_IO_PCMCIA_DEVICE
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "PCMCIA (Compact Flash) device support for SA11x0/Cerf"
+ compile cerf_pcmcia.c
+}
+
diff --git a/ecos/packages/devs/pcmcia/arm/cerf/current/src/cerf_pcmcia.c b/ecos/packages/devs/pcmcia/arm/cerf/current/src/cerf_pcmcia.c
new file mode 100644
index 0000000..7478678
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/cerf/current/src/cerf_pcmcia.c
@@ -0,0 +1,271 @@
+//==========================================================================
+//
+// devs/pcmcia/cerf/cerf_pcmcia.c
+//
+// PCMCIA support (Card Services)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-06
+// Purpose: PCMCIA support
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/io_pcmcia.h>
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_arch.h> // Register state info
+#include <cyg/hal/hal_intr.h> // HAL interrupt macros
+#include <cyg/hal/drv_api.h>
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h> // Configuration header
+#include <cyg/kernel/kapi.h>
+#endif
+#include <cyg/hal/hal_if.h>
+
+#include <cyg/io/pcmcia.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_sa11x0.h> // Board definitions
+#include <cyg/hal/cerf.h>
+
+#ifdef CYGPKG_KERNEL
+static cyg_interrupt cf_detect_interrupt;
+static cyg_handle_t cf_detect_interrupt_handle;
+static cyg_interrupt cf_irq_interrupt;
+static cyg_handle_t cf_irq_interrupt_handle;
+
+// This ISR is called when a CompactFlash board is inserted
+static int
+cf_detect_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_interrupt_mask(SA1110_CF_DETECT);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+// This DSR handles the board insertion
+static void
+cf_detect_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ struct cf_slot *slot = (struct cf_slot *)data;
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ slot->state = CF_SLOT_STATE_Inserted;
+ } else {
+ slot->state = CF_SLOT_STATE_Removed; // Implies powered up, etc.
+ }
+ cyg_interrupt_acknowledge(SA1110_CF_DETECT);
+ cyg_interrupt_unmask(SA1110_CF_DETECT);
+}
+
+// This ISR is called when the card interrupt occurs
+static int
+cf_irq_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_drv_interrupt_mask(SA1110_CF_IRQ);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+// This DSR handles the card interrupt
+static void
+cf_irq_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct cf_slot *slot = (struct cf_slot *)data;
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+ cyg_bool was_ctrlc_int;
+#endif
+
+ // Clear interrupt [edge indication]
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+ was_ctrlc_int = HAL_CTRLC_CHECK(vector, data);
+ if (!was_ctrlc_int) // Fall through and run normal code
+#endif
+ // Process interrupt
+ (slot->irq_handler.handler)(vector, count, slot->irq_handler.param);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
+}
+#endif
+
+//
+// Fill in the details of a PCMCIA slot and initialize the device
+//
+void
+cf_hwr_init(struct cf_slot *slot)
+{
+ static int int_init = 0;
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ if (!int_init) {
+ int_init = 1;
+#ifdef CYGPKG_KERNEL
+ // Set up interrupts
+ cyg_drv_interrupt_create(SA1110_CF_DETECT,
+ 99, // Priority - what goes here?
+ (cyg_addrword_t) slot, // Data item passed to interrupt handler
+ (cyg_ISR_t *)cf_detect_isr,
+ (cyg_DSR_t *)cf_detect_dsr,
+ &cf_detect_interrupt_handle,
+ &cf_detect_interrupt);
+ cyg_drv_interrupt_attach(cf_detect_interrupt_handle);
+ cyg_drv_interrupt_configure(SA1110_CF_DETECT, true, true); // Detect either edge
+ cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
+ cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
+ cyg_drv_interrupt_create(SA1110_CF_IRQ,
+ 99, // Priority - what goes here?
+ (cyg_addrword_t) slot, // Data item passed to interrupt handler
+ (cyg_ISR_t *)cf_irq_isr,
+ (cyg_DSR_t *)cf_irq_dsr,
+ &cf_irq_interrupt_handle,
+ &cf_irq_interrupt);
+ cyg_drv_interrupt_attach(cf_irq_interrupt_handle);
+ cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
+#endif
+ cyg_drv_interrupt_configure(SA1110_CF_IRQ, false, false); // Falling edge
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+ }
+ slot->attr = (unsigned char *)0x38000000;
+ slot->attr_length = 0x200;
+ slot->io = (unsigned char *)0x30000000;
+ slot->io_length = 0x04000000;
+ slot->mem = (unsigned char *)0x3C000000;
+ slot->mem_length = 0x04000000;
+ slot->int_num = SA1110_CF_IRQ;
+#ifdef CYG_HAL_STARTUP_ROM
+ // Disable CF bus & power (idle/off)
+ cerf_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_OFF |
+ SA1110_BCR_CF_RESET_DISABLE |
+ SA1110_BCR_CF_BUS_OFF);
+#endif
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ if ((_cerf_BCR & SA1110_BCR_CF_POWER) == SA1110_BCR_CF_POWER_ON) {
+ // Assume that the ROM environment has turned the bus on
+ slot->state = CF_SLOT_STATE_Ready;
+ } else {
+ slot->state = CF_SLOT_STATE_Inserted;
+ }
+ } else {
+ slot->state = CF_SLOT_STATE_Empty;
+ }
+}
+
+void
+cf_hwr_poll(struct cf_slot *slot)
+{
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ slot->state = CF_SLOT_STATE_Inserted;
+ } else {
+ slot->state = CF_SLOT_STATE_Empty;
+ }
+}
+
+static void
+do_delay(int ticks)
+{
+#ifdef CYGPKG_KERNEL
+ cyg_thread_delay(ticks);
+#else
+ CYGACC_CALL_IF_DELAY_US(10000*ticks);
+#endif
+}
+
+//
+// Transition the card/slot to a new state
+// note: currently only supports transitions to Ready, Empty
+//
+bool
+cf_hwr_change_state(struct cf_slot *slot, int new_state)
+{
+ int i, ptr, len;
+ unsigned char buf[256];
+
+ if (new_state == CF_SLOT_STATE_Ready) {
+ if (slot->state == CF_SLOT_STATE_Inserted) {
+ cerf_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_ON |
+ SA1110_BCR_CF_RESET_DISABLE |
+ SA1110_BCR_CF_BUS_OFF);
+ do_delay(30); // At least 300 ms
+ slot->state = CF_SLOT_STATE_Powered;
+ cerf_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_ON |
+ SA1110_BCR_CF_RESET_ENABLE |
+ SA1110_BCR_CF_BUS_ON);
+ do_delay(1); // At least 10 us
+ slot->state = CF_SLOT_STATE_Reset;
+ cerf_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_ON |
+ SA1110_BCR_CF_RESET_DISABLE |
+ SA1110_BCR_CF_BUS_ON);
+ do_delay(5); // At least 20 ms
+ // Wait until the card is ready to talk
+ for (i = 0; i < 10; i++) {
+ ptr = 0;
+ if (cf_get_CIS(slot, CF_CISTPL_VERS_1, buf, &len, &ptr)) {
+ slot->state = CF_SLOT_STATE_Ready;
+ break;
+ }
+ do_delay(10);
+ }
+ }
+ }
+}
+
+//
+// Acknowledge interrupt (used in non-kernel environments)
+//
+void
+cf_hwr_clear_interrupt(struct cf_slot *slot)
+{
+ // Clear interrupt [edge indication]
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+}
diff --git a/ecos/packages/devs/pcmcia/arm/cerfpda/current/ChangeLog b/ecos/packages/devs/pcmcia/arm/cerfpda/current/ChangeLog
new file mode 100644
index 0000000..95a88b4
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/cerfpda/current/ChangeLog
@@ -0,0 +1,28 @@
+2002-02-04 Gary Thomas <gthomas@redhat.com>
+
+ * src/cerfpda_pcmcia.c:
+ * cdl/pcmcia_cerfpda.cdl: New file(s) - port to Intrinsyc CerfPDA.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/pcmcia/arm/cerfpda/current/cdl/pcmcia_cerfpda.cdl b/ecos/packages/devs/pcmcia/arm/cerfpda/current/cdl/pcmcia_cerfpda.cdl
new file mode 100644
index 0000000..9d1658a
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/cerfpda/current/cdl/pcmcia_cerfpda.cdl
@@ -0,0 +1,65 @@
+# ====================================================================
+#
+# pcmcia_cerfpda.cdl
+#
+# PCMCIA (Compact Flash) - Hardware support on Intrinsyc CerfPDA
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Date: 2000-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_PCMCIA_CERFPDA {
+ display "SA11x0/Cerfpda PCMCIA support"
+
+ parent CYGPKG_IO_PCMCIA
+ active_if CYGPKG_IO_PCMCIA
+ active_if CYGPKG_HAL_ARM_SA11X0_CERFPDA
+
+ implements CYGHWR_IO_PCMCIA_DEVICE
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "PCMCIA (Compact Flash) device support for SA11x0/Cerfpda"
+ compile cerfpda_pcmcia.c
+}
+
diff --git a/ecos/packages/devs/pcmcia/arm/cerfpda/current/src/cerfpda_pcmcia.c b/ecos/packages/devs/pcmcia/arm/cerfpda/current/src/cerfpda_pcmcia.c
new file mode 100644
index 0000000..1f78117
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/cerfpda/current/src/cerfpda_pcmcia.c
@@ -0,0 +1,271 @@
+//==========================================================================
+//
+// devs/pcmcia/cerfpda/cerfpda_pcmcia.c
+//
+// PCMCIA support (Card Services)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-07-06
+// Purpose: PCMCIA support
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/io_pcmcia.h>
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_arch.h> // Register state info
+#include <cyg/hal/hal_intr.h> // HAL interrupt macros
+#include <cyg/hal/drv_api.h>
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h> // Configuration header
+#include <cyg/kernel/kapi.h>
+#endif
+#include <cyg/hal/hal_if.h>
+
+#include <cyg/io/pcmcia.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_sa11x0.h> // Board definitions
+#include <cyg/hal/cerfpda.h>
+
+#ifdef CYGPKG_KERNEL
+static cyg_interrupt cf_detect_interrupt;
+static cyg_handle_t cf_detect_interrupt_handle;
+static cyg_interrupt cf_irq_interrupt;
+static cyg_handle_t cf_irq_interrupt_handle;
+
+// This ISR is called when a CompactFlash board is inserted
+static int
+cf_detect_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_interrupt_mask(SA1110_CF_DETECT);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+// This DSR handles the board insertion
+static void
+cf_detect_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ struct cf_slot *slot = (struct cf_slot *)data;
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ slot->state = CF_SLOT_STATE_Inserted;
+ } else {
+ slot->state = CF_SLOT_STATE_Removed; // Implies powered up, etc.
+ }
+ cyg_interrupt_acknowledge(SA1110_CF_DETECT);
+ cyg_interrupt_unmask(SA1110_CF_DETECT);
+}
+
+// This ISR is called when the card interrupt occurs
+static int
+cf_irq_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_drv_interrupt_mask(SA1110_CF_IRQ);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+// This DSR handles the card interrupt
+static void
+cf_irq_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct cf_slot *slot = (struct cf_slot *)data;
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+ cyg_bool was_ctrlc_int;
+#endif
+
+ // Clear interrupt [edge indication]
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+ was_ctrlc_int = HAL_CTRLC_CHECK(vector, data);
+ if (!was_ctrlc_int) // Fall through and run normal code
+#endif
+ // Process interrupt
+ (slot->irq_handler.handler)(vector, count, slot->irq_handler.param);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
+}
+#endif
+
+//
+// Fill in the details of a PCMCIA slot and initialize the device
+//
+void
+cf_hwr_init(struct cf_slot *slot)
+{
+ static int int_init = 0;
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ if (!int_init) {
+ int_init = 1;
+#ifdef CYGPKG_KERNEL
+ // Set up interrupts
+ cyg_drv_interrupt_create(SA1110_CF_DETECT,
+ 99, // Priority - what goes here?
+ (cyg_addrword_t) slot, // Data item passed to interrupt handler
+ (cyg_ISR_t *)cf_detect_isr,
+ (cyg_DSR_t *)cf_detect_dsr,
+ &cf_detect_interrupt_handle,
+ &cf_detect_interrupt);
+ cyg_drv_interrupt_attach(cf_detect_interrupt_handle);
+ cyg_drv_interrupt_configure(SA1110_CF_DETECT, true, true); // Detect either edge
+ cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
+ cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
+ cyg_drv_interrupt_create(SA1110_CF_IRQ,
+ 99, // Priority - what goes here?
+ (cyg_addrword_t) slot, // Data item passed to interrupt handler
+ (cyg_ISR_t *)cf_irq_isr,
+ (cyg_DSR_t *)cf_irq_dsr,
+ &cf_irq_interrupt_handle,
+ &cf_irq_interrupt);
+ cyg_drv_interrupt_attach(cf_irq_interrupt_handle);
+ cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
+#endif
+ cyg_drv_interrupt_configure(SA1110_CF_IRQ, false, false); // Falling edge
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+ }
+ slot->attr = (unsigned char *)0x38000000;
+ slot->attr_length = 0x200;
+ slot->io = (unsigned char *)0x30000000;
+ slot->io_length = 0x04000000;
+ slot->mem = (unsigned char *)0x3C000000;
+ slot->mem_length = 0x04000000;
+ slot->int_num = SA1110_CF_IRQ;
+#ifdef CYG_HAL_STARTUP_ROM
+ // Disable CF bus & power (idle/off)
+ cerfpda_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_OFF |
+ SA1110_BCR_CF_RESET_DISABLE |
+ SA1110_BCR_CF_BUS_OFF);
+#endif
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ if ((_cerfpda_BCR & SA1110_BCR_CF_POWER) == SA1110_BCR_CF_POWER_ON) {
+ // Assume that the ROM environment has turned the bus on
+ slot->state = CF_SLOT_STATE_Ready;
+ } else {
+ slot->state = CF_SLOT_STATE_Inserted;
+ }
+ } else {
+ slot->state = CF_SLOT_STATE_Empty;
+ }
+}
+
+void
+cf_hwr_poll(struct cf_slot *slot)
+{
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ slot->state = CF_SLOT_STATE_Inserted;
+ } else {
+ slot->state = CF_SLOT_STATE_Empty;
+ }
+}
+
+static void
+do_delay(int ticks)
+{
+#ifdef CYGPKG_KERNEL
+ cyg_thread_delay(ticks);
+#else
+ CYGACC_CALL_IF_DELAY_US(10000*ticks);
+#endif
+}
+
+//
+// Transition the card/slot to a new state
+// note: currently only supports transitions to Ready, Empty
+//
+bool
+cf_hwr_change_state(struct cf_slot *slot, int new_state)
+{
+ int i, ptr, len;
+ unsigned char buf[256];
+
+ if (new_state == CF_SLOT_STATE_Ready) {
+ if (slot->state == CF_SLOT_STATE_Inserted) {
+ cerfpda_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_ON |
+ SA1110_BCR_CF_RESET_DISABLE |
+ SA1110_BCR_CF_BUS_OFF);
+ do_delay(30); // At least 300 ms
+ slot->state = CF_SLOT_STATE_Powered;
+ cerfpda_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_ON |
+ SA1110_BCR_CF_RESET_ENABLE |
+ SA1110_BCR_CF_BUS_ON);
+ do_delay(1); // At least 10 us
+ slot->state = CF_SLOT_STATE_Reset;
+ cerfpda_BCR(SA1110_BCR_CF_POWER |
+ SA1110_BCR_CF_RESET |
+ SA1110_BCR_CF_BUS,
+ SA1110_BCR_CF_POWER_ON |
+ SA1110_BCR_CF_RESET_DISABLE |
+ SA1110_BCR_CF_BUS_ON);
+ do_delay(5); // At least 20 ms
+ // Wait until the card is ready to talk
+ for (i = 0; i < 10; i++) {
+ ptr = 0;
+ if (cf_get_CIS(slot, CF_CISTPL_VERS_1, buf, &len, &ptr)) {
+ slot->state = CF_SLOT_STATE_Ready;
+ break;
+ }
+ do_delay(10);
+ }
+ }
+ }
+}
+
+//
+// Acknowledge interrupt (used in non-kernel environments)
+//
+void
+cf_hwr_clear_interrupt(struct cf_slot *slot)
+{
+ // Clear interrupt [edge indication]
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+}
diff --git a/ecos/packages/devs/pcmcia/arm/ipaq/current/ChangeLog b/ecos/packages/devs/pcmcia/arm/ipaq/current/ChangeLog
new file mode 100644
index 0000000..45644a6
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/ipaq/current/ChangeLog
@@ -0,0 +1,52 @@
+2002-09-20 Gary Thomas <gthomas@ecoscentric.com>
+
+ * src/ipaq_pcmcia.c: Additional setup required for Compaq dual
+ PCMCIA sleeve. Add card reset which is necessary for some older cards.
+
+2002-04-12 Gary Thomas <gthomas@redhat.com>
+
+ * src/ipaq_pcmcia.c: Clean up warnings.
+
+2001-07-13 Gary Thomas <gthomas@redhat.com>
+
+ * src/ipaq_pcmcia.c (cf_hwr_change_state): Use VERS_1 instead of
+ MANID since some cards don't seem to support that.
+
+2001-03-14 Gary Thomas <gthomas@redhat.com>
+
+ * src/ipaq_pcmcia.c (cf_hwr_init): Leave GPIO/timing setup to HAL code.
+
+2001-03-01 Gary Thomas <gthomas@redhat.com>
+
+ * src/ipaq_pcmcia.c (cf_hwr_init): Remove [illegal] delay which caused
+ this code to be unreliable when run in non-ROM mode.
+
+2001-02-24 Gary Thomas <gthomas@redhat.com>
+
+ * src/ipaq_pcmcia.c:
+ * cdl/pcmcia_ipaq.cdl: New file(s) - initial import of
+ iPAQ support, contributed by Richard Panton, 3G Labs.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/pcmcia/arm/ipaq/current/cdl/pcmcia_ipaq.cdl b/ecos/packages/devs/pcmcia/arm/ipaq/current/cdl/pcmcia_ipaq.cdl
new file mode 100644
index 0000000..ca5404d
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/ipaq/current/cdl/pcmcia_ipaq.cdl
@@ -0,0 +1,65 @@
+# ====================================================================
+#
+# pcmcia_ipaq.cdl
+#
+# PCMCIA (Compact Flash) - Hardware support on iPAQ
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors:
+# Richard Panton <richard.panton@3glab.com>
+# Date: 2001-02-24
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_PCMCIA_IPAQ {
+ display "SA11x0/iPaq PCMCIA support"
+
+ parent CYGPKG_IO_PCMCIA
+ active_if CYGPKG_IO_PCMCIA
+ active_if CYGPKG_HAL_ARM_SA11X0_IPAQ
+
+ implements CYGHWR_IO_PCMCIA_DEVICE
+
+ include_dir .
+ include_files ; # none _exported_ whatsoever
+ description "PCMCIA (Compact Flash) device support for SA11x0/iPAQ"
+ compile ipaq_pcmcia.c
+}
diff --git a/ecos/packages/devs/pcmcia/arm/ipaq/current/src/ipaq_pcmcia.c b/ecos/packages/devs/pcmcia/arm/ipaq/current/src/ipaq_pcmcia.c
new file mode 100644
index 0000000..5d3e000
--- /dev/null
+++ b/ecos/packages/devs/pcmcia/arm/ipaq/current/src/ipaq_pcmcia.c
@@ -0,0 +1,269 @@
+//==========================================================================
+//
+// devs/pcmcia/ipaq/ipaq_pcmcia.c
+//
+// PCMCIA support (Card Services)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// richard.panton@3glab.com
+// Date: 2001-02-24
+// Purpose: PCMCIA support
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/io_pcmcia.h>
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_arch.h> // Register state info
+#include <cyg/hal/hal_intr.h> // HAL interrupt macros
+#include <cyg/hal/drv_api.h>
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h> // Configuration header
+#include <cyg/kernel/kapi.h>
+#endif
+#include <cyg/hal/hal_if.h>
+
+#include <cyg/io/pcmcia.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_sa11x0.h> // Board definitions
+#include <cyg/hal/ipaq.h>
+
+#ifdef CYGPKG_KERNEL
+static cyg_interrupt cf_detect_interrupt;
+static cyg_handle_t cf_detect_interrupt_handle;
+static cyg_interrupt cf_irq_interrupt;
+static cyg_handle_t cf_irq_interrupt_handle;
+
+// This ISR is called when a CompactFlash board is inserted
+static int
+cf_detect_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_drv_interrupt_mask(SA1110_CF_DETECT);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+// This DSR handles the board insertion
+static void
+cf_detect_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ struct cf_slot *slot = (struct cf_slot *)data;
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ slot->state = CF_SLOT_STATE_Inserted;
+ } else {
+ slot->state = CF_SLOT_STATE_Removed; // Implies powered up, etc.
+ }
+ cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
+ cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
+}
+
+// This ISR is called when the card interrupt occurs
+static int
+cf_irq_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
+{
+ cyg_drv_interrupt_mask(SA1110_CF_IRQ);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
+}
+
+// This DSR handles the card interrupt
+static void
+cf_irq_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ struct cf_slot *slot = (struct cf_slot *)data;
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+ cyg_bool was_ctrlc_int;
+#endif
+
+ // Clear interrupt [edge indication]
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+ was_ctrlc_int = HAL_CTRLC_CHECK(vector, data);
+ if (!was_ctrlc_int) // Fall through and run normal code
+#endif
+ // Process interrupt
+ (slot->irq_handler.handler)(vector, count, slot->irq_handler.param);
+ // Allow interrupts to happen again
+ cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
+}
+#endif
+
+static void
+do_delay(int ticks)
+{
+#ifdef CYGPKG_KERNEL
+ cyg_thread_delay(ticks);
+#else
+ CYGACC_CALL_IF_DELAY_US(10000*ticks);
+#endif
+}
+
+//
+// Fill in the details of a PCMCIA slot and initialize the device
+//
+void
+cf_hwr_init(struct cf_slot *slot)
+{
+ static int int_init = 0;
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+
+ if (!int_init) {
+ int_init = 1;
+#ifdef CYGPKG_KERNEL
+ // Set up interrupts
+ cyg_drv_interrupt_create(SA1110_CF_DETECT,
+ 99, // Priority - what goes here?
+ (cyg_addrword_t) slot, // Data item passed to interrupt handler
+ (cyg_ISR_t *)cf_detect_isr,
+ (cyg_DSR_t *)cf_detect_dsr,
+ &cf_detect_interrupt_handle,
+ &cf_detect_interrupt);
+ cyg_drv_interrupt_attach(cf_detect_interrupt_handle);
+ cyg_drv_interrupt_configure(SA1110_CF_DETECT, true, true); // Detect either edge
+ cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
+ cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
+
+ cyg_drv_interrupt_create(SA1110_CF_IRQ,
+ 99, // Priority - what goes here?
+ (cyg_addrword_t) slot, // Data item passed to interrupt handler
+ (cyg_ISR_t *)cf_irq_isr,
+ (cyg_DSR_t *)cf_irq_dsr,
+ &cf_irq_interrupt_handle,
+ &cf_irq_interrupt);
+ cyg_drv_interrupt_attach(cf_irq_interrupt_handle);
+ cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
+ cyg_drv_interrupt_configure(SA1110_CF_IRQ, false, false); // Falling edge
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+#endif
+ }
+ slot->attr = (unsigned char *)0x28000000;
+ slot->attr_length = 0x200;
+ slot->io = (unsigned char *)0x20000000;
+ slot->io_length = 0x04000000;
+ slot->mem = (unsigned char *)0x2C000000;
+ slot->mem_length = 0x04000000;
+ slot->int_num = SA1110_CF_IRQ;
+#ifdef CYG_HAL_STARTUP_ROM
+ // Disable CF bus & power (idle/off)
+ ipaq_EGPIO( SA1110_EIO_OPT_PWR | SA1110_EIO_OPT | SA1110_EIO_CF_RESET,
+ SA1110_EIO_OPT_PWR_ON | SA1110_EIO_OPT_ON | SA1110_EIO_CF_RESET_ENABLE );
+#endif
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ if ((_ipaq_EGPIO & SA1110_EIO_OPT_PWR) == SA1110_EIO_OPT_PWR_ON) {
+ // Assume that the ROM environment has turned the bus on
+ slot->state = CF_SLOT_STATE_Ready;
+ } else {
+ slot->state = CF_SLOT_STATE_Inserted;
+ }
+ } else {
+ slot->state = CF_SLOT_STATE_Empty;
+ }
+}
+
+void
+cf_hwr_poll(struct cf_slot *slot)
+{
+ unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
+ if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
+ slot->state = CF_SLOT_STATE_Inserted;
+ } else {
+ slot->state = CF_SLOT_STATE_Empty;
+ }
+}
+
+//
+// Transition the card/slot to a new state
+// note: currently only supports transitions to Ready, Empty
+//
+void
+cf_hwr_change_state(struct cf_slot *slot, int new_state)
+{
+ int i, ptr, len;
+ unsigned char buf[256];
+
+ if (new_state == CF_SLOT_STATE_Ready) {
+ if (slot->state == CF_SLOT_STATE_Inserted) {
+ ipaq_EGPIO( SA1110_EIO_OPT_PWR | SA1110_EIO_OPT | SA1110_EIO_CF_RESET,
+ SA1110_EIO_OPT_PWR_ON | SA1110_EIO_OPT_ON | SA1110_EIO_CF_RESET_DISABLE);
+ do_delay(30); // At least 300 ms
+ slot->state = CF_SLOT_STATE_Powered;
+ ipaq_EGPIO( SA1110_EIO_CF_RESET, SA1110_EIO_CF_RESET_ENABLE);
+ *(volatile unsigned short *)IPAQ_CF_CTRL = IPAQ_CF_CTRL_V5_DISABLE |
+ IPAQ_CF_CTRL_V3_ENABLE |
+ IPAQ_CF_CTRL_RESET_ENABLE |
+ IPAQ_CF_CTRL_APOE_ENABLE |
+ IPAQ_CF_CTRL_SOE_ENABLE;
+ do_delay(1); // At least 10 us
+ slot->state = CF_SLOT_STATE_Reset;
+ ipaq_EGPIO( SA1110_EIO_CF_RESET, SA1110_EIO_CF_RESET_DISABLE);
+ do_delay(5); // At least 20 ms
+ // This is necessary for the two slot sleeve and doesn't seem to
+ // hurt on the single slot versions. Note: only 3.3V is ever used!
+ *(volatile unsigned short *)IPAQ_CF_CTRL = IPAQ_CF_CTRL_V5_DISABLE |
+ IPAQ_CF_CTRL_V3_ENABLE |
+ IPAQ_CF_CTRL_RESET_DISABLE |
+ IPAQ_CF_CTRL_APOE_ENABLE |
+ IPAQ_CF_CTRL_SOE_ENABLE;
+ do_delay(5); // At least 20 ms
+ // Wait until the card is ready to talk
+ for (i = 0; i < 10; i++) {
+ ptr = 0;
+ if (cf_get_CIS(slot, CF_CISTPL_VERS_1, buf, &len, &ptr)) {
+ slot->state = CF_SLOT_STATE_Ready;
+ break;
+ }
+ do_delay(10);
+ }
+ }
+ }
+}
+
+//
+// Acknowledge interrupt (used in non-kernel environments)
+//
+void
+cf_hwr_clear_interrupt(struct cf_slot *slot)
+{
+ // Clear interrupt [edge indication]
+ cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
+}
diff --git a/ecos/packages/devs/serial/arm/aaed2000/current/ChangeLog b/ecos/packages/devs/serial/arm/aaed2000/current/ChangeLog
new file mode 100644
index 0000000..b313235
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aaed2000/current/ChangeLog
@@ -0,0 +1,41 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_aaed2000.cdl: Remove irrelevant doc link.
+
+2001-11-14 Jesper Skov <jskov@redhat.com>
+
+ * src/aaed2000_serial.c (aaed2000_serial_DSR): Reworked a little
+ to fill/empty FIFO.
+
+2001-11-13 Jesper Skov <jskov@redhat.com>
+
+ * src/aaed2000_serial.c: Removed ser1 structures. Fix reader. Make
+ DSR loop to empty FIFO.
+
+2001-11-12 Jesper Skov <jskov@redhat.com>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/aaed2000/current/cdl/ser_arm_aaed2000.cdl b/ecos/packages/devs/serial/arm/aaed2000/current/cdl/ser_arm_aaed2000.cdl
new file mode 100644
index 0000000..97d8faf
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aaed2000/current/cdl/ser_arm_aaed2000.cdl
@@ -0,0 +1,159 @@
+# ====================================================================
+#
+# ser_arm_aaed2000.cdl
+#
+# eCos serial Agilent/AAED2000 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-11-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_AAED2000 {
+ display "ARM AAED2000 serial device driver"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_ARM9_AAED2000
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ Agilent AAED2000."
+
+ compile -library=libextras.a aaed2000_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_aaed2000.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AAED2000_SERIAL0 {
+ display "Agilent AAED2000-1 serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the Agilent AAED2000."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_AAED2000_SERIAL0_NAME {
+ display "Device name for the Agilent AAED2000-1 serial port driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option sets the name of the serial device for the Agilent AAED2000."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AAED2000_SERIAL0_BAUD {
+ display "Baud rate for the Agilent AAED2000 serial port driver"
+ flavor data
+ legal_values { 1200 2400 3600 4800 7200 9600 14400 19200 38400 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the Agilent AAED2000."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AAED2000_SERIAL0_BUFSIZE {
+ display "Buffer size for the Agilent AAED2000 serial port driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the Agilent AAED2000 serial driver."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AAED2000_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_AAED2000_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_AAED2000_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AAED2000_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_AAED2000_SERIAL0
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_AAED2000_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"aaed2000\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_arm_aaed2000.cdl
diff --git a/ecos/packages/devs/serial/arm/aaed2000/current/src/aaed2000_serial.c b/ecos/packages/devs/serial/arm/aaed2000/current/src/aaed2000_serial.c
new file mode 100644
index 0000000..477e463
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aaed2000/current/src/aaed2000_serial.c
@@ -0,0 +1,338 @@
+//==========================================================================
+//
+// io/serial/arm/aaed2000_serial.c
+//
+// Agilent AAED2000 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, jskov
+// Contributors:gthomas, jskov
+// Date: 2001-11-12
+// Purpose: AAED2000 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h> // interrupt
+#include <cyg/hal/hal_io.h> // register base
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#include "aaed2000_serial.h"
+
+typedef struct aaed2000_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} aaed2000_serial_info;
+
+static bool aaed2000_serial_init(struct cyg_devtab_entry *tab);
+static bool aaed2000_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo aaed2000_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char aaed2000_serial_getc(serial_channel *chan);
+static Cyg_ErrNo aaed2000_serial_set_config(serial_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void aaed2000_serial_start_xmit(serial_channel *chan);
+static void aaed2000_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 aaed2000_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void aaed2000_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(aaed2000_serial_funs,
+ aaed2000_serial_putc,
+ aaed2000_serial_getc,
+ aaed2000_serial_set_config,
+ aaed2000_serial_start_xmit,
+ aaed2000_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AAED2000_SERIAL0
+static aaed2000_serial_info aaed2000_serial_info0 = {0x80000800,
+ CYGNUM_HAL_INTERRUPT_UART3INTR};
+#if CYGNUM_IO_SERIAL_ARM_AAED2000_SERIAL0_BUFSIZE > 0
+static unsigned char aaed2000_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_AAED2000_SERIAL0_BUFSIZE];
+static unsigned char aaed2000_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_AAED2000_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(aaed2000_serial_channel0,
+ aaed2000_serial_funs,
+ aaed2000_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AAED2000_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &aaed2000_serial_out_buf0[0], sizeof(aaed2000_serial_out_buf0),
+ &aaed2000_serial_in_buf0[0], sizeof(aaed2000_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(aaed2000_serial_channel0,
+ aaed2000_serial_funs,
+ aaed2000_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AAED2000_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(aaed2000_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_AAED2000_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ aaed2000_serial_init,
+ aaed2000_serial_lookup, // Serial driver may need initializing
+ &aaed2000_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_AAED2000_SERIAL0
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+aaed2000_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ aaed2000_serial_info *aaed2000_chan = (aaed2000_serial_info *)chan->dev_priv;
+ CYG_ADDRWORD base = aaed2000_chan->base;
+ unsigned short baud_divisor = select_baud[new_config->baud];
+ cyg_uint32 _lcr, _intm;
+ if (baud_divisor == 0) return false;
+
+ // Register writes don't take effect till the UART is enabled.
+ HAL_WRITE_UINT32(base+AAEC_UART_CTRL, AAEC_UART_CTRL_ENAB);
+
+ // Disable port interrupts while changing hardware
+ HAL_READ_UINT32(base+AAEC_UART_INTM, _intm);
+ HAL_WRITE_UINT32(base+AAEC_UART_INTM, 0);
+
+ _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ HAL_WRITE_UINT32(base+AAEC_UART_BAUD, baud_divisor);
+ if (init) {
+ _lcr |= AAEC_UART_LCR_FIFO; // Enable FIFO
+ if (chan->out_cbuf.len != 0) {
+ _intm = AAEC_UART_INT_RIS|AAEC_UART_INT_RTIS;
+ } else {
+ _intm = 0;
+ }
+ }
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+
+ // Set line control and (re)enable interrupts
+ HAL_WRITE_UINT32(base+AAEC_UART_LCR, _lcr);
+ HAL_WRITE_UINT32(base+AAEC_UART_INTM, _intm);
+
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+aaed2000_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ aaed2000_serial_info *aaed2000_chan = (aaed2000_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("AAED2000 SERIAL init - dev: 0x%08x.%d\n",
+ aaed2000_chan->base, aaed2000_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(aaed2000_chan->int_num,
+ 1, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ aaed2000_serial_ISR,
+ aaed2000_serial_DSR,
+ &aaed2000_chan->serial_interrupt_handle,
+ &aaed2000_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(aaed2000_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(aaed2000_chan->int_num);
+ }
+ aaed2000_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+aaed2000_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+aaed2000_serial_putc(serial_channel *chan, unsigned char c)
+{
+ aaed2000_serial_info *aaed2000_chan = (aaed2000_serial_info *)chan->dev_priv;
+ CYG_ADDRWORD base = aaed2000_chan->base;
+ cyg_uint32 _status;
+
+ HAL_READ_UINT32(base+AAEC_UART_STATUS, _status);
+ if (_status & AAEC_UART_STATUS_TxFF) {
+ // No space
+ return false;
+ } else {
+ // Transmit buffer is empty
+ HAL_WRITE_UINT32(base+AAEC_UART_DATA, (cyg_uint32)c);
+ return true;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+aaed2000_serial_getc(serial_channel *chan)
+{
+ aaed2000_serial_info *aaed2000_chan = (aaed2000_serial_info *)chan->dev_priv;
+ CYG_ADDRWORD base = aaed2000_chan->base;
+ cyg_uint32 _status;
+ cyg_uint32 _c;
+
+ do {
+ HAL_READ_UINT32(base+AAEC_UART_STATUS, _status);
+ } while (_status & AAEC_UART_STATUS_RxFE);
+
+ HAL_READ_UINT32(base+AAEC_UART_DATA, _c);
+ return (unsigned char)_c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+aaed2000_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != aaed2000_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+aaed2000_serial_start_xmit(serial_channel *chan)
+{
+ aaed2000_serial_info *aaed2000_chan = (aaed2000_serial_info *)chan->dev_priv;
+ CYG_ADDRWORD base = aaed2000_chan->base;
+ cyg_uint32 _intm;
+
+ HAL_READ_UINT32(base+AAEC_UART_INTM, _intm);
+ _intm |= AAEC_UART_INT_TIS;
+ HAL_WRITE_UINT32(base+AAEC_UART_INTM, _intm);
+}
+
+// Disable the transmitter on the device
+static void
+aaed2000_serial_stop_xmit(serial_channel *chan)
+{
+ aaed2000_serial_info *aaed2000_chan = (aaed2000_serial_info *)chan->dev_priv;
+ CYG_ADDRWORD base = aaed2000_chan->base;
+ cyg_uint32 _intm;
+
+ HAL_READ_UINT32(base+AAEC_UART_INTM, _intm);
+ _intm &= ~AAEC_UART_INT_TIS;
+ HAL_WRITE_UINT32(base+AAEC_UART_INTM, _intm);
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+aaed2000_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ aaed2000_serial_info *aaed2000_chan = (aaed2000_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(aaed2000_chan->int_num);
+ cyg_drv_interrupt_acknowledge(aaed2000_chan->int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+aaed2000_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ aaed2000_serial_info *aaed2000_chan = (aaed2000_serial_info *)chan->dev_priv;
+ CYG_ADDRWORD base = aaed2000_chan->base;
+ cyg_uint32 _intres, _c;
+
+ HAL_READ_UINT32(base+AAEC_UART_INTRES, _intres);
+ _intres &= (AAEC_UART_INT_TIS | AAEC_UART_INT_RIS | AAEC_UART_INT_RTIS);
+ while (_intres) {
+
+ // Empty Rx FIFO
+ if (_intres & (AAEC_UART_INT_RIS|AAEC_UART_INT_RTIS)) {
+ HAL_READ_UINT32(base+AAEC_UART_DATA, _c);
+ (chan->callbacks->rcv_char)(chan, (unsigned char)_c);
+ }
+
+ // Fill into Tx FIFO. xmt_char will mask the interrupt when it
+ // runs out of chars, so doing this in a loop is OK.
+ if (_intres & AAEC_UART_INT_TIS) {
+ (chan->callbacks->xmt_char)(chan);
+ }
+
+ HAL_READ_UINT32(base+AAEC_UART_INTRES, _intres);
+ _intres &= (AAEC_UART_INT_TIS | AAEC_UART_INT_RIS | AAEC_UART_INT_RTIS);
+ }
+
+ cyg_drv_interrupt_unmask(aaed2000_chan->int_num);
+}
diff --git a/ecos/packages/devs/serial/arm/aaed2000/current/src/aaed2000_serial.h b/ecos/packages/devs/serial/arm/aaed2000/current/src/aaed2000_serial.h
new file mode 100644
index 0000000..32a7eb4
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aaed2000/current/src/aaed2000_serial.h
@@ -0,0 +1,105 @@
+#ifndef CYGONCE_ARM_AAED2000_SERIAL_H
+#define CYGONCE_ARM_AAED2000_SERIAL_H
+
+// ====================================================================
+//
+// aaed2000_serial.h
+//
+// Device I/O - Description of Agilent AAED2000 serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas, jskov
+// Contributors:gthomas, jskov
+// Date: 2001-11-12
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+static unsigned char select_word_length[] = {
+ AAEC_UART_LCR_WL5, // 5 bits / word (char)
+ AAEC_UART_LCR_WL6,
+ AAEC_UART_LCR_WL7,
+ AAEC_UART_LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ 0, // 1 stop bit
+ AAEC_UART_LCR_S2, // 1.5 stop bit (I think)
+ AAEC_UART_LCR_S2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ 0, // No parity
+ AAEC_UART_LCR_PEN|AAEC_UART_LCR_EP, // Even parity
+ AAEC_UART_LCR_PEN, // Odd parity
+ 0, // Mark parity
+ 0, // Space parity
+};
+
+// Baud rate values, based on 7.3728MHz clock
+// #define BAUD_RATE(_n_) ((7372800/((_n_)*16))-1)
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0x23ff, // 50
+ 0x17ff, // 75
+ 0x105c, // 110
+ 0x0d60, // 134.5
+ 0x0bff, // 150
+ 0x08ff, // 200
+ 0x05ff, // 300
+ 0x02ff, // 600
+ 0x017f, // 1200
+ 0x00ff, // 1800
+ 0x00bf, // 2400
+ 0x007f, // 3600
+ 0x005f, // 4800
+ 0x003f, // 7200
+ 0x002f, // 9600
+ 0x001f, // 14400
+ 0x0017, // 19200
+ 0x000b, // 38400
+ 0x0007, // 57600
+ 0x0003, // 115200
+ 0x0001, // 230400
+};
+
+#endif // CYGONCE_ARM_AAED2000_SERIAL_H
diff --git a/ecos/packages/devs/serial/arm/aeb/current/ChangeLog b/ecos/packages/devs/serial/arm/aeb/current/ChangeLog
new file mode 100644
index 0000000..6f9b108
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aeb/current/ChangeLog
@@ -0,0 +1,1190 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_aeb.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_arm_aeb.cdl:
+ Fix 234000->230400 typo.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_arm_aeb.cdl: Moved testing parameters here.
+
+2000-09-06 Gary Thomas <gthomas@redhat.com>
+
+ * src/aeb_serial.h: Define baud rates for 57600 & 115200.
+ Note: these are untested at this time.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/aeb_serial.c (aeb_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_arm_aeb.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/aeb/current/cdl/ser_arm_aeb.cdl b/ecos/packages/devs/serial/arm/aeb/current/cdl/ser_arm_aeb.cdl
new file mode 100644
index 0000000..1c4a2f8
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aeb/current/cdl/ser_arm_aeb.cdl
@@ -0,0 +1,210 @@
+# ====================================================================
+#
+# ser_arm_aeb.cdl
+#
+# eCos serial ARM/AEB configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_AEB {
+ display "ARM AEB-1 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_AEB
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ ARM AEB-1."
+
+ compile -library=libextras.a aeb_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_aeb.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_ARM_AEB_SERIAL0 {
+ display "ARM AEB-1 serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the ARM AEB-1
+ port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_AEB_SERIAL0_NAME {
+ display "Device name for the ARM AEB-1 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option sets the name of the serial device for the ARM
+ AEB-1 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BAUD {
+ display "Baud rate for the ARM AEB-1 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ ARM AEB-1 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE {
+ display "Buffer size for the ARM AEB-1 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the ARM AEB-1 port 0."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1 {
+ display "ARM AEB-1 serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the ARM
+ AEB-1 port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_AEB_SERIAL1_NAME {
+ display "Device name for the ARM AEB-1 serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for the
+ ARM AEB-1 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BAUD {
+ display "Baud rate for the ARM AEB-1 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ ARM AEB-1 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE {
+ display "Buffer size for the ARM AEB-1 serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ARM AEB-1 port 1."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AEB_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_AEB_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_AEB_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AEB_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_38400
+ implements CYGINT_IO_SERIAL_TEST_SKIP_57600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_AEB_SERIAL1_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"armaeb\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+
+# EOF ser_arm_aeb.cdl
diff --git a/ecos/packages/devs/serial/arm/aeb/current/src/aeb_serial.c b/ecos/packages/devs/serial/arm/aeb/current/src/aeb_serial.c
new file mode 100644
index 0000000..761e456
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aeb/current/src/aeb_serial.c
@@ -0,0 +1,344 @@
+//==========================================================================
+//
+// io/serial/arm/aeb_serial.c
+//
+// ARM AEB-1 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-02-04
+// Purpose: AEB-1 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AEB
+
+#include "aeb_serial.h"
+
+typedef struct aeb_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} aeb_serial_info;
+
+static bool aeb_serial_init(struct cyg_devtab_entry *tab);
+static bool aeb_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo aeb_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char aeb_serial_getc(serial_channel *chan);
+static Cyg_ErrNo aeb_serial_set_config(serial_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void aeb_serial_start_xmit(serial_channel *chan);
+static void aeb_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 aeb_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void aeb_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(aeb_serial_funs,
+ aeb_serial_putc,
+ aeb_serial_getc,
+ aeb_serial_set_config,
+ aeb_serial_start_xmit,
+ aeb_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AEB_SERIAL0
+static aeb_serial_info aeb_serial_info0 = {0xFFFF0000,
+ CYGNUM_HAL_INTERRUPT_UART0};
+#if CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE > 0
+static unsigned char aeb_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE];
+static unsigned char aeb_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(aeb_serial_channel0,
+ aeb_serial_funs,
+ aeb_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &aeb_serial_out_buf0[0], sizeof(aeb_serial_out_buf0),
+ &aeb_serial_in_buf0[0], sizeof(aeb_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(aeb_serial_channel0,
+ aeb_serial_funs,
+ aeb_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(aeb_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_AEB_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ aeb_serial_init,
+ aeb_serial_lookup, // Serial driver may need initializing
+ &aeb_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_AEB_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1
+static aeb_serial_info aeb_serial_info1 = {0xFFFF0400,
+ CYGNUM_HAL_INTERRUPT_UART1};
+#if CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE > 0
+static unsigned char aeb_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE];
+static unsigned char aeb_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(aeb_serial_channel1,
+ aeb_serial_funs,
+ aeb_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &aeb_serial_out_buf1[0], sizeof(aeb_serial_out_buf1),
+ &aeb_serial_in_buf1[0], sizeof(aeb_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(aeb_serial_channel1,
+ aeb_serial_funs,
+ aeb_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(aeb_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_AEB_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ aeb_serial_init,
+ aeb_serial_lookup, // Serial driver may need initializing
+ &aeb_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+aeb_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base;
+ unsigned short baud_divisor = select_baud[new_config->baud];
+ unsigned char _lcr, _ier;
+ if (baud_divisor == 0) return false;
+ _ier = port->REG_IER;
+ port->REG_IER = 0; // Disable port interrupts while changing hardware
+ _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ port->REG_LCR = _lcr;
+ port->REG_LCR |= LCR_DL;
+ port->REG_MDL = baud_divisor >> 8;
+ port->REG_LDL = baud_divisor & 0xFF;
+ port->REG_LCR &= ~LCR_DL;
+ if (init) {
+ port->REG_FCR = 0x07; // Enable and clear FIFO
+ if (chan->out_cbuf.len != 0) {
+ port->REG_IER = IER_RCV;
+ } else {
+ port->REG_IER = 0;
+ }
+ port->REG_MCR = MCR_INT|MCR_DTR|MCR_RTS; // Master interrupt enable
+ } else {
+ port->REG_IER = _ier;
+ }
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+aeb_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("AEB SERIAL init - dev: %x.%d\n", aeb_chan->base, aeb_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(aeb_chan->int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ aeb_serial_ISR,
+ aeb_serial_DSR,
+ &aeb_chan->serial_interrupt_handle,
+ &aeb_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(aeb_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(aeb_chan->int_num);
+ }
+ aeb_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+aeb_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+aeb_serial_putc(serial_channel *chan, unsigned char c)
+{
+ aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base;
+ if (port->REG_LSR & LSR_THE) {
+// Transmit buffer is empty
+ port->REG_THR = c;
+ return true;
+ } else {
+// No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+aeb_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base;
+ while ((port->REG_LSR & LSR_RSR) == 0) ; // Wait for char
+ c = port->REG_RHR;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+aeb_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != aeb_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+aeb_serial_start_xmit(serial_channel *chan)
+{
+ aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base;
+ port->REG_IER |= IER_XMT; // Enable xmit interrupt
+}
+
+// Disable the transmitter on the device
+static void
+aeb_serial_stop_xmit(serial_channel *chan)
+{
+ aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base;
+ port->REG_IER &= ~IER_XMT; // Disable xmit interrupt
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+aeb_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(aeb_chan->int_num);
+ cyg_drv_interrupt_acknowledge(aeb_chan->int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+aeb_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base;
+ unsigned char isr;
+ isr = port->REG_ISR & 0x0E;
+ if (isr == ISR_Tx) {
+ (chan->callbacks->xmt_char)(chan);
+ } else if (isr == ISR_Rx) {
+ (chan->callbacks->rcv_char)(chan, port->REG_RHR);
+ }
+ cyg_drv_interrupt_unmask(aeb_chan->int_num);
+}
+#endif
diff --git a/ecos/packages/devs/serial/arm/aeb/current/src/aeb_serial.h b/ecos/packages/devs/serial/arm/aeb/current/src/aeb_serial.h
new file mode 100644
index 0000000..e436d39
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aeb/current/src/aeb_serial.h
@@ -0,0 +1,162 @@
+#ifndef CYGONCE_ARM_AEB_SERIAL_H
+#define CYGONCE_ARM_AEB_SERIAL_H
+
+// ====================================================================
+//
+// aeb_serial.h
+//
+// Device I/O - Description of ARM AEB-1 serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-02-04
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports on ARM AEB-1
+
+struct serial_port {
+ unsigned char _byte[32];
+};
+
+#define REG(n) _byte[n*4]
+
+// Receive control registers
+#define REG_RHR REG(0) // Receive holding register
+#define REG_ISR REG(2) // Interrupt status register
+#define REG_LSR REG(5) // Line status register
+#define REG_MSR REG(6) // Modem status register
+#define REG_SCR REG(7) // Scratch register
+
+// Transmit control registers
+#define REG_THR REG(0) // Transmit holding register
+#define REG_IER REG(1) // Interrupt enable register
+#define REG_FCR REG(2) // FIFO control register
+#define REG_LCR REG(3) // Line control register
+#define REG_MCR REG(4) // Modem control register
+#define REG_LDL REG(0) // LSB of baud rate
+#define REG_MDL REG(1) // MSB of baud rate
+
+// Interrupt Enable Register
+#define IER_RCV 0x01
+#define IER_XMT 0x02
+#define IER_LS 0x04
+#define IER_MS 0x08
+
+// Line Control Register
+#define LCR_WL5 0x00 // Word length
+#define LCR_WL6 0x01
+#define LCR_WL7 0x02
+#define LCR_WL8 0x03
+#define LCR_SB1 0x00 // Number of stop bits
+#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words
+#define LCR_SB2 0x04
+#define LCR_PN 0x00 // Parity mode - none
+#define LCR_PE 0x0C // Parity mode - even
+#define LCR_PO 0x08 // Parity mode - odd
+#define LCR_PM 0x28 // Forced "mark" parity
+#define LCR_PS 0x38 // Forced "space" parity
+#define LCR_DL 0x80 // Enable baud rate latch
+
+// Line Status Register
+#define LSR_RSR 0x01
+#define LSR_THE 0x20
+
+// Modem Control Register
+#define MCR_DTR 0x01
+#define MCR_RTS 0x02
+#define MCR_INT 0x08 // Enable interrupts
+
+// Interrupt status register
+#define ISR_Tx 0x02
+#define ISR_Rx 0x04
+
+static unsigned char select_word_length[] = {
+ LCR_WL5, // 5 bits / word (char)
+ LCR_WL6,
+ LCR_WL7,
+ LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ LCR_SB1, // 1 stop bit
+ LCR_SB1_5, // 1.5 stop bit
+ LCR_SB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ LCR_PN, // No parity
+ LCR_PE, // Even parity
+ LCR_PO, // Odd parity
+ LCR_PM, // Mark parity
+ LCR_PS, // Space parity
+};
+
+// Baud rate values, based on raw 24MHz clock
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 10000*3, // 50
+ 6667*3, // 75
+ 4545*3, // 110
+ 3717*3, // 134.5
+ 3333*3, // 150
+ 0, // 200
+ 1667*3, // 300
+ 833*3, // 600
+ 417*3, // 1200
+ 277*3, // 1800
+ 208*3, // 2400
+ 139*3, // 3600
+ 104*3, // 4800
+ 69*3, // 7200
+ 52*3, // 9600
+ (69*3)/2, // 14400
+ 26*3, // 19200
+ 13*3, // 38400
+ 26, // 57600
+ 13, // 115200
+ 0, // 230400
+};
+
+#endif // CYGONCE_ARM_AEB_SERIAL_H
diff --git a/ecos/packages/devs/serial/arm/aim711/current/ChangeLog b/ecos/packages/devs/serial/arm/aim711/current/ChangeLog
new file mode 100755
index 0000000..785a5a7
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aim711/current/ChangeLog
@@ -0,0 +1,36 @@
+2004-09-09 John Dallaway <jld@ecoscentric.com>
+
+ * cdl/ser_arm_aim711.cdl: Implement CYGPKG_IO_SERIAL_ARM_AIM711_S3C4510 and
+ CYGPKG_IO_SERIAL_ARM_AIM711_16X5X as CDL components rather than packages.
+ [ patch from Roland Cassebohm ]
+
+ * cdl/ser_arm_aim711_16x5x.cdl, cdl/ser_arm_aim711_s3c4510.cdl: Remove obsolete
+ files.
+
+2003-10-30 Roland Cassebohm <roland.cassebohm@visionsystems.de>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/aim711/current/cdl/ser_arm_aim711.cdl b/ecos/packages/devs/serial/arm/aim711/current/cdl/ser_arm_aim711.cdl
new file mode 100755
index 0000000..75b5968
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aim711/current/cdl/ser_arm_aim711.cdl
@@ -0,0 +1,297 @@
+# ====================================================================
+#
+# ser_arm_aim711.cdl
+#
+# eCos serial ARM Industrial Module AIM 711 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Lars.Lindqvist@combitechsystems.com, rcassebohm
+# Contributors: jlarmour, rcassebohm
+# Date: 2004-09-09
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_AIM711 {
+ display "ARM Industrial Module AIM 711 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_AIM711
+
+ include_dir cyg/io
+ description "
+ This package contains serial device drivers for the
+ ARM Industrial Module AIM 711."
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#ifndef CYGDAT_IO_SERIAL_DEVICE_HEADER"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_aim711.h>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/ser_arm_aim711_16x5x.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_arm_aim711.h>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_ARM_S3C4510_INL <cyg/io/ser_arm_aim711_s3c4510.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_ARM_S3C4510_CFG <pkgconf/io_serial_arm_aim711.h>"
+ puts $::cdl_system_header "#endif"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include <pkgconf/io_serial_arm_s3c4510.h>";
+ puts $::cdl_header "#include <pkgconf/io_serial_generic_16x5x.h>";
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AIM711_16X5X {
+ display "ARM Industrial Module AIM 711 16x5x serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_AIM711
+ default_value 1
+
+ requires CYGPKG_ERROR
+ description "
+ This package contains serial device drivers for the
+ ARM Industrial Module AIM 711 for the 16550 serial
+ interface on board."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0 {
+ display "AIM 711 16X5X serial port 0 driver (COM1)"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the AIM 711 16X5X
+ port 0, which is COM1 on the AIM 711."
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0_NAME {
+ display "Device name for the AIM 711 16X5X serial port 0 driver (COM1)"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option sets the name of the serial device for the AIM 711
+ 16X5X port 0 (COM1)."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0_BAUD {
+ display "Baud rate for the AIM 711 16X5X serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ AIM 711 16X5X port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0_BUFSIZE {
+ display "Buffer size for the AIM 711 16X5X serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the AIM 711 16X5X port 0."
+ }
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AIM711_S3C4510 {
+ display "ARM Industrial Module AIM 711 S3C4510 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_AIM711
+ default_value 1
+
+ requires CYGPKG_ERROR
+ description "
+ This package contains serial device drivers for the
+ ARM Industrial Module AIM 711 for the internal serial
+ interface of the S3C4510."
+
+ # FIXME: This really belongs in the SERIAL_ARM_S3C4510 package
+ cdl_interface CYGINT_IO_SERIAL_ARM_S3C4510_REQUIRED {
+ display "Generic s3c4510 serial driver required"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0 {
+ display "AIM 711 S3C4510 serial port 0 driver (service adapter)"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the AIM 711 S3C4510
+ port 0, which is on the AIM 711 the port on the service adapter."
+
+ implements CYGINT_IO_SERIAL_ARM_S3C4510_REQUIRED
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0_NAME {
+ display "Device name for the AIM 711 S3C4510 serial port 0 driver (service adapter)"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option sets the name of the serial device for the AIM 711
+ S3C4510 port 0 (service adapter)."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0_BAUD {
+ display "Baud rate for the AIM 711 S3C4510 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ AIM 711 S3C4510 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0_BUFSIZE {
+ display "Buffer size for the AIM 711 S3C4510 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the AIM 711 S3C4510 port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1 {
+ display "AIM 711 S3C4510 serial port 1 driver (COM2)"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the AIM 711
+ S3C4510 port 1, which is the COM2 on the AIM 711."
+
+ implements CYGINT_IO_SERIAL_ARM_S3C4510_REQUIRED
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1_NAME {
+ display "Device name for the AIM 711 S3C4510 serial port 1 driver (COM2)"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the name of serial device for the
+ AIM 711 S3C4510 port 1 (COM2)."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1_BAUD {
+ display "Baud rate for the AIM 711 S3C4510 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ AIM 711 S3C4510 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1_BUFSIZE {
+ display "Buffer size for the AIM 711 S3C4510 serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the AIM 711 S3C4510 port 1."
+ }
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AIM711_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_AIM711_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_AIM711_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AIM711_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"arm16x5x\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty2\""
+ }
+ }
+}
+
+# EOF ser_arm_aim711.cdl
diff --git a/ecos/packages/devs/serial/arm/aim711/current/include/ser_arm_aim711_16x5x.inl b/ecos/packages/devs/serial/arm/aim711/current/include/ser_arm_aim711_16x5x.inl
new file mode 100755
index 0000000..8768981
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aim711/current/include/ser_arm_aim711_16x5x.inl
@@ -0,0 +1,124 @@
+//==========================================================================
+//
+// ser_arm_aim711_16x5x.inl
+//
+// ARM Industrial Module AIM 711 Serial I/O Interface Module
+// (interrupt driven) for use with 16x5x driver.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2001-06-08
+// Purpose: Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification, based on raw 7.3728 MHz clock
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 9216, // 50
+ 6144, // 75
+ 4189, // 110
+ 3426, // 134.5
+ 3072, // 150
+ 2304, // 200
+ 1537, // 300
+ 768, // 600
+ 384, // 1200
+ 256, // 1800
+ 192, // 2400
+ 128, // 3600
+ 96, // 4800
+ 64, // 7200
+ 48, // 9600
+ 32, // 14400
+ 24, // 19200
+ 12, // 38400
+ 8, // 57600
+ 4, // 115200
+ 2, // 230400
+ 1, // 460800
+};
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0
+static pc_serial_info aim711_16x5x_serial_info0 = {0x7fd0008,
+ CYGNUM_HAL_INTERRUPT_EXT0};
+#if CYGNUM_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0_BUFSIZE > 0
+static unsigned char aim711_16x5x_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0_BUFSIZE];
+static unsigned char aim711_16x5x_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(aim711_16x5x_serial_channel0,
+ pc_serial_funs,
+ aim711_16x5x_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &aim711_16x5x_serial_out_buf0[0], sizeof(aim711_16x5x_serial_out_buf0),
+ &aim711_16x5x_serial_in_buf0[0], sizeof(aim711_16x5x_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(aim711_16x5x_serial_channel0,
+ pc_serial_funs,
+ aim711_16x5x_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(aim711_16x5x_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &aim711_16x5x_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_AIM711_16X5X_SERIAL0
+
+// EOF ser_arm_aim711_16x5x.inl
diff --git a/ecos/packages/devs/serial/arm/aim711/current/include/ser_arm_aim711_s3c4510.inl b/ecos/packages/devs/serial/arm/aim711/current/include/ser_arm_aim711_s3c4510.inl
new file mode 100755
index 0000000..024bfb0
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/aim711/current/include/ser_arm_aim711_s3c4510.inl
@@ -0,0 +1,140 @@
+// ====================================================================
+//
+// ser_arm_aim711_s3c4510.inl
+//
+// ARM Industrial Module AIM 711 Serial I/O Interface Module
+// (interrupt driven) for use with s3c4510 driver.
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Lars.Lindqvist@combitechsystems.com
+// Contributors: jlarmour
+// Date: 2001-10-19
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+#include <pkgconf/hal.h> // Value CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED needed
+#include <cyg/hal/hal_intr.h>
+
+#define CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED CYGNUM_HAL_CPUCLOCK
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0
+static s3c4510_serial_info s3c4510_serial_info0 = {0x07FFd000,
+ CYGNUM_HAL_INTERRUPT_UART0_TX,
+ CYGNUM_HAL_INTERRUPT_UART0_RX};
+#if CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0_BUFSIZE > 0
+static unsigned char s3c4510_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0_BUFSIZE];
+static unsigned char s3c4510_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(s3c4510_serial_channel0,
+ s3c4510_serial_funs,
+ s3c4510_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &s3c4510_serial_out_buf0[0], sizeof(s3c4510_serial_out_buf0),
+ &s3c4510_serial_in_buf0[0], sizeof(s3c4510_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(s3c4510_serial_channel0,
+ s3c4510_serial_funs,
+ s3c4510_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(s3c4510_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ s3c4510_serial_init,
+ s3c4510_serial_lookup, // Serial driver may need initializing
+ &s3c4510_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1
+static s3c4510_serial_info s3c4510_serial_info1 = {0x07FFe000,
+ CYGNUM_HAL_INTERRUPT_UART1_TX,
+ CYGNUM_HAL_INTERRUPT_UART1_RX};
+#if CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1_BUFSIZE > 0
+static unsigned char s3c4510_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1_BUFSIZE];
+static unsigned char s3c4510_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(s3c4510_serial_channel1,
+ s3c4510_serial_funs,
+ s3c4510_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &s3c4510_serial_out_buf1[0], sizeof(s3c4510_serial_out_buf1),
+ &s3c4510_serial_in_buf1[0], sizeof(s3c4510_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(s3c4510_serial_channel1,
+ s3c4510_serial_funs,
+ s3c4510_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(s3c4510_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ s3c4510_serial_init,
+ s3c4510_serial_lookup, // Serial driver may need initializing
+ &s3c4510_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_AIM711_S3C4510_SERIAL1
+
+// EOF ser_arm_aim711_s3c4510.inl
diff --git a/ecos/packages/devs/serial/arm/at91/current/ChangeLog b/ecos/packages/devs/serial/arm/at91/current/ChangeLog
new file mode 100644
index 0000000..3528435
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/at91/current/ChangeLog
@@ -0,0 +1,102 @@
+2007-06-01 Jim Seymour <jim@cipher.com>
+
+ * src/at91_serial.c (at91_serial_DSR): Remove CYG_FAIL if receive
+ buffer fills up; eliminate compiler warning when setting "end"
+ pointer.
+
+2006-03-05 Oliver Munz <munz@speag.ch>
+
+ * src/at91_serial.c (at91_serial_ISR): Only call the DSR if there
+ is work to do.
+
+2006-02-28 Andrew Lunn <andrew.lunn@ascom.ch>
+ Oliver Munz <munz@speag.ch>
+
+ * src/at91_serial.c (at91_serial_config_port): Enable the DMA
+ if the control register exists.
+
+2006-02-19 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/at91_serial.c (at91_serial_lookup): Enable the peripheral
+ clock at lookup time to keep the power usage low.
+
+2004-11-10 Sebastian Block <sebastianblock@gmx.net>
+
+ * src/at91_serial.c: Added third port
+
+2004-01-26 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/at91_serial.c (at91_serial_getc_polled)
+ * src/ay91_serial.c (at91_serial_putc_polled):
+ Only define these functions if polled IO is configured so
+ avoiding compiler warnings.
+
+2004-01-16 Thomas Koeller <thomas.koeller@baslerweb.com>
+
+ * src/at91_serial.c: If both a transmitter and a receiver
+ interrupt arrive at the same time, process the receiver
+ interrupt first.
+
+2003-11-21 Thomas Koeller <thomas.koeller@baslerweb.com>
+
+ * src/at91_serial.c: Fix endless loop that would occur if
+ high-level driver was not ready to accept data received.
+
+2003-11-07 Thomas Koeller <thomas.koeller@baslerweb.com>
+
+ * src/at91_serial.c:
+ * cdl/ser_arm_at91.cdl: Major rewrite to achieve reliable
+ operation at higher baud rates.
+
+2003-10-16 Nick Garnett <nickg@balti.calivar.com>
+
+ * src/at91_serial.c (at91_serial_config_port): Added update of
+ channel configuration, which was missing.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_at91.cdl: Remove irrelevant doc link.
+
+2001-09-20 Jesper Skov <jskov@redhat.com>
+
+ * src/at91_serial.c (at91_serial_init): Use valid interrupt priority.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_arm_at91.cdl:
+ Fix 234000->230400 typo.
+
+2001-08-14 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/at91_serial.c (at91_serial_stop_xmit): Write to IDR, not IER.
+ (at91_serial_ISR): Return CYG_ISR_HANDLED.
+
+2001-07-24 Gary Thomas <gthomas@redhat.com>
+
+ * src/at91_serial.h:
+ * src/at91_serial.c:
+ * cdl/ser_arm_at91.cdl: New file(s) - initial package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/at91/current/cdl/ser_arm_at91.cdl b/ecos/packages/devs/serial/arm/at91/current/cdl/ser_arm_at91.cdl
new file mode 100644
index 0000000..914c05b
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/at91/current/cdl/ser_arm_at91.cdl
@@ -0,0 +1,292 @@
+# ====================================================================
+#
+# ser_arm_at91.cdl
+#
+# eCos serial Atmel AT91 (ARM) configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: tkoeller
+# Date: 2001-07-24
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_AT91 {
+ display "Atmel AT91 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_AT91
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ Atmel AT91."
+
+ implements CYGINT_IO_SERIAL_BLOCK_TRANSFER
+
+ compile -library=libextras.a at91_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_at91.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0 {
+ display "Atmel AT91 serial port 0 driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the Atmel AT91
+ port 0 (serial A)."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_AT91_SERIAL0_NAME {
+ display "Device name for Atmel AT91 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device for the
+ Atmel AT91 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BAUD {
+ display "Baud rate for the Atmel AT91 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ Atmel AT91 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BUFSIZE {
+ display "Buffer size for the Atmel AT91 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the Atmel AT91 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_RCV_CHUNK_SIZE {
+ display "Receive data chunk size"
+ flavor data
+ legal_values 1 to 65519
+ default_value 1
+ description "
+ This parameter can be used to reduce the number of interrupts
+ that must be processed by the driver. An interrupt will only
+ be generated if either this many data bytes have been received
+ or the receiver has been idle for some time. This reduces
+ overall system load at the expense of making the driver less
+ responsive and using slightly more memory for buffering data.
+ Setting this parameter to 1 will give standard behavior."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1 {
+ display "Atmel AT91 serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the Atmel AT91
+ port 1 (serial B)."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_AT91_SERIAL1_NAME {
+ display "Device name for Atmel AT91 serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of the serial device for the
+ Atmel AT91 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BAUD {
+ display "Baud rate for the Atmel AT91 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ Atmel AT91 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BUFSIZE {
+ display "Buffer size for the Atmel AT91 serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the Atmel AT91 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_RCV_CHUNK_SIZE {
+ display "Receive data chunk size"
+ flavor data
+ legal_values 1 to 65519
+ default_value 1
+ description "
+ This parameter can be used to reduce the number of interrupts
+ that must be processed by the driver. An interrupt will only
+ be generated if either this many data bytes have been received
+ or the receiver has been idle for some time. This reduces
+ overall system load at the expense of making the driver less
+ responsive and using slightly more memory for buffering data.
+ Setting this parameter to 1 will give standard behavior."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_ARM_AT91_SERIAL2 {
+ display "Atmel AT91 serial port 2 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the Atmel AT91
+ port 2 (serial C)."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_AT91_SERIAL2_NAME {
+ display "Device name for Atmel AT91 serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the name of the serial device for the
+ Atmel AT91 port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BAUD {
+ display "Baud rate for the Atmel AT91 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ Atmel AT91 port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BUFSIZE {
+ display "Buffer size for the Atmel AT91 serial port 2 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the Atmel AT91 port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_RCV_CHUNK_SIZE {
+ display "Receive data chunk size"
+ flavor data
+ legal_values 1 to 65519
+ default_value 1
+ description "
+ This parameter can be used to reduce the number of interrupts
+ that must be processed by the driver. An interrupt will only
+ be generated if either this many data bytes have been received
+ or the receiver has been idle for some time. This reduces
+ overall system load at the expense of making the driver less
+ responsive and using slightly more memory for buffering data.
+ Setting this parameter to 1 will give standard behavior."
+ }
+}
+
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AT91_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_AT91_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_AT91_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_AT91_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_AT91_SERIAL1_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"eb40\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+
+# EOF ser_arm_at91.cdl
diff --git a/ecos/packages/devs/serial/arm/at91/current/src/at91_serial.c b/ecos/packages/devs/serial/arm/at91/current/src/at91_serial.c
new file mode 100644
index 0000000..26b0d14
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/at91/current/src/at91_serial.c
@@ -0,0 +1,650 @@
+//==========================================================================
+//
+// devs/serial/arm/at91/at91_serial.c
+//
+// Atmel AT91/EB40 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, tkoeller, sblock
+// Date: 2001-07-24
+// Purpose: Atmel AT91/EB40 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/infra.h>
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <pkgconf/kernel.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+
+externC void * memcpy( void *, const void *, size_t );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AT91
+
+#include "at91_serial.h"
+
+#define RCVBUF_EXTRA 16
+#define RCV_TIMEOUT 10
+
+#define SIFLG_NONE 0x00
+#define SIFLG_TX_READY 0x01
+#define SIFLG_XMIT_BUSY 0x02
+#define SIFLG_XMIT_CONTINUE 0x04
+
+typedef struct at91_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ CYG_WORD stat;
+ int transmit_size;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+ cyg_uint8 *rcv_buffer[2];
+ cyg_uint16 rcv_chunk_size;
+ cyg_uint8 curbuf;
+ cyg_uint8 flags;
+} at91_serial_info;
+
+static bool at91_serial_init(struct cyg_devtab_entry *tab);
+static bool at91_serial_putc_interrupt(serial_channel *chan, unsigned char c);
+#if (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL2) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BUFSIZE == 0)
+static bool at91_serial_putc_polled(serial_channel *chan, unsigned char c);
+#endif
+static Cyg_ErrNo at91_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char at91_serial_getc_interrupt(serial_channel *chan);
+#if (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL2) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BUFSIZE == 0)
+static unsigned char at91_serial_getc_polled(serial_channel *chan);
+#endif
+static Cyg_ErrNo at91_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void at91_serial_start_xmit(serial_channel *chan);
+static void at91_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 at91_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void at91_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+#if (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BUFSIZE > 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BUFSIZE > 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL2) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BUFSIZE > 0)
+static SERIAL_FUNS(at91_serial_funs_interrupt,
+ at91_serial_putc_interrupt,
+ at91_serial_getc_interrupt,
+ at91_serial_set_config,
+ at91_serial_start_xmit,
+ at91_serial_stop_xmit
+ );
+#endif
+
+#if (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL2) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BUFSIZE == 0)
+static SERIAL_FUNS(at91_serial_funs_polled,
+ at91_serial_putc_polled,
+ at91_serial_getc_polled,
+ at91_serial_set_config,
+ at91_serial_start_xmit,
+ at91_serial_stop_xmit
+ );
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0
+static cyg_uint8 at91_serial_rcv_buffer_0
+ [2][CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_RCV_CHUNK_SIZE + RCVBUF_EXTRA];
+static at91_serial_info at91_serial_info0 = {
+ base : (CYG_ADDRWORD) AT91_USART0,
+ int_num : CYGNUM_HAL_INTERRUPT_USART0,
+ rcv_chunk_size : CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_RCV_CHUNK_SIZE,
+ rcv_buffer : {at91_serial_rcv_buffer_0[0], at91_serial_rcv_buffer_0[1]}
+};
+
+#if CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BUFSIZE > 0
+static unsigned char at91_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BUFSIZE];
+static unsigned char at91_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(at91_serial_channel0,
+ at91_serial_funs_interrupt,
+ at91_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &at91_serial_out_buf0[0], sizeof(at91_serial_out_buf0),
+ &at91_serial_in_buf0[0], sizeof(at91_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(at91_serial_channel0,
+ at91_serial_funs_polled,
+ at91_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(at91_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_AT91_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ at91_serial_init,
+ at91_serial_lookup, // Serial driver may need initializing
+ &at91_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1
+static cyg_uint8 at91_serial_rcv_buffer_1
+ [2][CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_RCV_CHUNK_SIZE + RCVBUF_EXTRA];
+static at91_serial_info at91_serial_info1 = {
+ base : (CYG_ADDRWORD) AT91_USART1,
+ int_num : CYGNUM_HAL_INTERRUPT_USART1,
+ rcv_chunk_size : CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_RCV_CHUNK_SIZE,
+ rcv_buffer : {at91_serial_rcv_buffer_1[0], at91_serial_rcv_buffer_1[1]}
+};
+#if CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BUFSIZE > 0
+static unsigned char at91_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BUFSIZE];
+static unsigned char at91_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(at91_serial_channel1,
+ at91_serial_funs_interrupt,
+ at91_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &at91_serial_out_buf1[0], sizeof(at91_serial_out_buf1),
+ &at91_serial_in_buf1[0], sizeof(at91_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(at91_serial_channel1,
+ at91_serial_funs_polled,
+ at91_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(at91_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_AT91_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ at91_serial_init,
+ at91_serial_lookup, // Serial driver may need initializing
+ &at91_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1
+
+
+#ifdef CYGPKG_IO_SERIAL_ARM_AT91_SERIAL2
+
+static cyg_uint8 at91_serial_rcv_buffer_2
+ [2][CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_RCV_CHUNK_SIZE + RCVBUF_EXTRA];
+static at91_serial_info at91_serial_info2 = {
+ base : (CYG_ADDRWORD) AT91_USART2,
+ int_num : CYGNUM_HAL_INTERRUPT_USART2,
+ rcv_chunk_size : CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_RCV_CHUNK_SIZE,
+ rcv_buffer : {at91_serial_rcv_buffer_2[0], at91_serial_rcv_buffer_2[1]}
+};
+
+#if CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BUFSIZE > 0
+static unsigned char at91_serial_out_buf2[CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BUFSIZE];
+static unsigned char at91_serial_in_buf2[CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(at91_serial_channel2,
+ at91_serial_funs_interrupt,
+ at91_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &at91_serial_out_buf2[0], sizeof(at91_serial_out_buf2),
+ &at91_serial_in_buf2[0], sizeof(at91_serial_in_buf2)
+ );
+#else
+static SERIAL_CHANNEL(at91_serial_channel2,
+ at91_serial_funs_polled,
+ at91_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(at91_serial_io2,
+ CYGDAT_IO_SERIAL_ARM_AT91_SERIAL2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ at91_serial_init,
+ at91_serial_lookup, // Serial driver may need initializing
+ &at91_serial_channel2
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_AT91_SERIAL2
+
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+at91_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ at91_serial_info * const at91_chan = (at91_serial_info *)chan->dev_priv;
+ const CYG_ADDRWORD base = at91_chan->base;
+ cyg_uint32 parity = select_parity[new_config->parity];
+ cyg_uint32 word_length = select_word_length[new_config->word_length-CYGNUM_SERIAL_WORD_LENGTH_5];
+ cyg_uint32 stop_bits = select_stop_bits[new_config->stop];
+
+ if ((word_length == 0xFF) ||
+ (parity == 0xFF) ||
+ (stop_bits == 0xFF)) {
+ return false; // Unsupported configuration
+ }
+
+ // Reset device
+ HAL_WRITE_UINT32(base + AT91_US_CR, AT91_US_CR_RxRESET | AT91_US_CR_TxRESET);
+
+ // Configuration
+ HAL_WRITE_UINT32(base + AT91_US_MR, parity | word_length | stop_bits);
+
+ // Baud rate
+ HAL_WRITE_UINT32(base + AT91_US_BRG, AT91_US_BAUD(select_baud[new_config->baud]));
+
+ // Disable all interrupts
+ HAL_WRITE_UINT32(base + AT91_US_IDR, 0xFFFFFFFF);
+
+ // Start receiver
+ at91_chan->curbuf = 0;
+ HAL_WRITE_UINT32(base + AT91_US_RPR, (CYG_ADDRESS) at91_chan->rcv_buffer[0]);
+ HAL_WRITE_UINT32(base + AT91_US_RTO, RCV_TIMEOUT);
+ HAL_WRITE_UINT32(base + AT91_US_IER, AT91_US_IER_ENDRX | AT91_US_IER_TIMEOUT);
+ HAL_WRITE_UINT32(base + AT91_US_RCR, at91_chan->rcv_chunk_size);
+
+ // Enable RX and TX
+ HAL_WRITE_UINT32(
+ base + AT91_US_CR,
+ AT91_US_CR_RxENAB | AT91_US_CR_TxENAB | AT91_US_CR_RSTATUS | AT91_US_CR_STTTO
+ );
+
+ // Enable the DMA is the control register exists
+#ifdef AT91_US_PTCR
+ HAL_WRITE_UINT32(base + AT91_US_PTCR,
+ AT91_US_PTCR_RXTEN |
+ AT91_US_PTCR_TXTEN);
+#endif
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+at91_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel * const chan = (serial_channel *) tab->priv;
+ at91_serial_info * const at91_chan = (at91_serial_info *) chan->dev_priv;
+ int res;
+
+#ifdef CYGDBG_IO_INIT
+ diag_printf("AT91 SERIAL init - dev: %x.%d\n", at91_chan->base, at91_chan->int_num);
+#endif
+ at91_chan->curbuf = 0;
+ at91_chan->flags = SIFLG_NONE;
+ at91_chan->stat = 0;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(at91_chan->int_num,
+ 4, // Priority
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ at91_serial_ISR,
+ at91_serial_DSR,
+ &at91_chan->serial_interrupt_handle,
+ &at91_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(at91_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(at91_chan->int_num);
+ }
+ res = at91_serial_config_port(chan, &chan->config, true);
+ return res;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+at91_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel * const chan = (serial_channel *) (*tab)->priv;
+
+#ifdef AT91_PMC_PCER
+ // Enable the peripheral clock to the device
+ at91_serial_info * const at91_chan = (at91_serial_info *)chan->dev_priv;
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER,
+ (1 << at91_chan->int_num));
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+at91_serial_putc_interrupt(serial_channel *chan, unsigned char c)
+{
+ at91_serial_info * const at91_chan = (at91_serial_info *) chan->dev_priv;
+ const bool res = (at91_chan->flags & SIFLG_XMIT_BUSY) == 0;
+
+ if (res) {
+ const CYG_ADDRWORD base = at91_chan->base;
+ HAL_WRITE_UINT32(base + AT91_US_THR, c);
+ at91_chan->flags |= SIFLG_XMIT_BUSY;
+ }
+ return res;
+}
+
+#if (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL2) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BUFSIZE == 0)
+static bool
+at91_serial_putc_polled(serial_channel *chan, unsigned char c)
+{
+ at91_serial_info * const at91_chan = (at91_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = at91_chan->base;
+ CYG_WORD32 w;
+
+ while (HAL_READ_UINT32(base + AT91_US_CSR, w), (w & AT91_US_IER_TxRDY) == 0)
+ CYG_EMPTY_STATEMENT;
+ HAL_WRITE_UINT32(base + AT91_US_THR, c);
+ return true;
+}
+#endif
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+at91_serial_getc_interrupt(serial_channel *chan)
+{
+ at91_serial_info * const at91_chan = (at91_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = at91_chan->base;
+ CYG_WORD32 c;
+
+ // Read data
+ HAL_READ_UINT32(base + AT91_US_RHR, c);
+ return (unsigned char) c;
+}
+
+#if (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL0) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL0_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL1) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL1_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_ARM_AT91_SERIAL2) && CYGNUM_IO_SERIAL_ARM_AT91_SERIAL2_BUFSIZE == 0)
+static unsigned char
+at91_serial_getc_polled(serial_channel *chan)
+{
+ at91_serial_info * const at91_chan = (at91_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = at91_chan->base;
+ CYG_WORD32 c;
+
+ while (HAL_READ_UINT32(base + AT91_US_CSR, c), (c & AT91_US_IER_RxRDY) == 0)
+ CYG_EMPTY_STATEMENT;
+ // Read data
+ HAL_READ_UINT32(base + AT91_US_RHR, c);
+ return (unsigned char) c;
+}
+#endif
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+at91_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != at91_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+at91_serial_start_xmit(serial_channel *chan)
+{
+ at91_serial_info * const at91_chan = (at91_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = at91_chan->base;
+ unsigned char * chars;
+ xmt_req_reply_t res;
+
+ cyg_drv_dsr_lock();
+ if ((at91_chan->flags & SIFLG_XMIT_CONTINUE) == 0) {
+ res = (chan->callbacks->data_xmt_req)(chan, 0xffff, &at91_chan->transmit_size, &chars);
+ switch (res)
+ {
+ case CYG_XMT_OK:
+ HAL_WRITE_UINT32(base + AT91_US_TPR, (CYG_WORD32) chars);
+ HAL_WRITE_UINT32(base + AT91_US_TCR, at91_chan->transmit_size);
+ at91_chan->flags |= SIFLG_XMIT_CONTINUE;
+ HAL_WRITE_UINT32(base + AT91_US_IER, AT91_US_IER_ENDTX);
+ break;
+ case CYG_XMT_DISABLED:
+ (chan->callbacks->xmt_char)(chan); // Kick transmitter
+ at91_chan->flags |= SIFLG_XMIT_CONTINUE;
+ HAL_WRITE_UINT32(base + AT91_US_IER, AT91_US_IER_TxRDY);
+ break;
+ default:
+ // No data or unknown error - can't do anything about it
+ break;
+ }
+ }
+ cyg_drv_dsr_unlock();
+}
+
+// Disable the transmitter on the device
+static void
+at91_serial_stop_xmit(serial_channel *chan)
+{
+ at91_serial_info * const at91_chan = (at91_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = at91_chan->base;
+ HAL_WRITE_UINT32(base + AT91_US_IDR, AT91_US_IER_TxRDY | AT91_US_IER_ENDTX);
+ at91_chan->flags &= ~SIFLG_XMIT_CONTINUE;
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+at91_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel * const chan = (serial_channel *) data;
+ at91_serial_info * const at91_chan = (at91_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = at91_chan->base;
+ CYG_WORD32 stat, mask;
+ cyg_uint32 retcode = 0;
+
+ HAL_READ_UINT32(base + AT91_US_CSR, stat);
+ HAL_READ_UINT32(base + AT91_US_IMR, mask);
+ stat &= mask;
+
+ if (stat & (AT91_US_IER_ENDRX | AT91_US_IER_TIMEOUT)) {
+ cyg_uint32 x;
+ HAL_WRITE_UINT32(base + AT91_US_IDR, AT91_US_IER_ENDRX | AT91_US_IER_TIMEOUT);
+ HAL_WRITE_UINT32(base + AT91_US_RCR, 0);
+ HAL_WRITE_UINT32(base + AT91_US_RTO, 0);
+ HAL_READ_UINT32(base + AT91_US_RPR, x);
+ HAL_WRITE_UINT32(
+ base + AT91_US_RCR,
+ (CYG_ADDRESS) at91_chan->rcv_buffer[at91_chan->curbuf]
+ + at91_chan->rcv_chunk_size + RCVBUF_EXTRA - x
+ );
+ retcode = CYG_ISR_CALL_DSR;
+ }
+
+ if (stat & (AT91_US_IER_TxRDY | AT91_US_IER_ENDTX)) {
+ HAL_WRITE_UINT32(base + AT91_US_IDR, AT91_US_IER_TxRDY | AT91_US_IER_ENDTX);
+ retcode = CYG_ISR_CALL_DSR;
+ }
+ at91_chan->stat |= stat;
+
+ cyg_drv_interrupt_acknowledge(vector);
+ return retcode;
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+at91_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel * const chan = (serial_channel *) data;
+ at91_serial_info * const at91_chan = (at91_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = at91_chan->base;
+ CYG_WORD32 stat;
+
+ cyg_drv_interrupt_mask(vector);
+ stat = at91_chan->stat;
+ at91_chan->stat = 0;
+ cyg_drv_interrupt_unmask(vector);
+
+ if (stat & (AT91_US_IER_ENDRX | AT91_US_IER_TIMEOUT)) {
+ const cyg_uint8 cb = at91_chan->curbuf, nb = cb ^ 0x01;
+ const cyg_uint8 * p = at91_chan->rcv_buffer[cb], * end;
+ cyg_uint32 temp_word;
+
+ at91_chan->curbuf = nb;
+ HAL_WRITE_UINT32(base + AT91_US_RCR, 0);
+ HAL_READ_UINT32(base + AT91_US_RPR, temp_word);
+ end = (const cyg_uint8 *)temp_word;
+ HAL_WRITE_UINT32(base + AT91_US_RTO, RCV_TIMEOUT);
+ HAL_WRITE_UINT32(base + AT91_US_CR, AT91_US_CR_RSTATUS | AT91_US_CR_STTTO);
+ HAL_WRITE_UINT32(base + AT91_US_RPR, (CYG_ADDRESS) at91_chan->rcv_buffer[nb]);
+ HAL_WRITE_UINT32(base + AT91_US_RCR, at91_chan->rcv_chunk_size);
+ HAL_WRITE_UINT32(
+ base + AT91_US_IER,
+ AT91_US_IER_ENDRX | AT91_US_IER_TIMEOUT
+ );
+
+ while (p < end) {
+ rcv_req_reply_t res;
+ int space_avail;
+ unsigned char *space;
+
+ res = (chan->callbacks->data_rcv_req)(
+ chan,
+ end - at91_chan->rcv_buffer[cb],
+ &space_avail,
+ &space
+ );
+
+ switch (res)
+ {
+ case CYG_RCV_OK:
+ memcpy(space, p, space_avail);
+ (chan->callbacks->data_rcv_done)(chan, space_avail);
+ p += space_avail;
+ break;
+ case CYG_RCV_DISABLED:
+ (chan->callbacks->rcv_char)(chan, *p++);
+ break;
+ default:
+ // Buffer full or unknown error, can't do anything about it
+ // Discard data
+ p = end;
+ break;
+ }
+ }
+ }
+
+ if (stat & AT91_US_IER_TxRDY) {
+ at91_chan->flags &= ~SIFLG_XMIT_BUSY;
+ (chan->callbacks->xmt_char)(chan);
+ if (at91_chan->flags & SIFLG_XMIT_CONTINUE)
+ HAL_WRITE_UINT32(base + AT91_US_IER, AT91_US_IER_TxRDY);
+ }
+
+ if (stat & AT91_US_IER_ENDTX) {
+ (chan->callbacks->data_xmt_done)(chan, at91_chan->transmit_size);
+ if (at91_chan->flags & SIFLG_XMIT_CONTINUE) {
+ unsigned char * chars;
+ xmt_req_reply_t res;
+
+ res = (chan->callbacks->data_xmt_req)(chan, 0xffff, &at91_chan->transmit_size, &chars);
+
+ switch (res)
+ {
+ case CYG_XMT_OK:
+ HAL_WRITE_UINT32(base + AT91_US_TPR, (CYG_WORD32) chars);
+ HAL_WRITE_UINT32(base + AT91_US_TCR, at91_chan->transmit_size);
+ at91_chan->flags |= SIFLG_XMIT_CONTINUE;
+ HAL_WRITE_UINT32(base + AT91_US_IER, AT91_US_IER_ENDTX);
+ break;
+ default:
+ // No data or unknown error - can't do anything about it
+ // CYG_XMT_DISABLED should not happen here!
+ break;
+ }
+ }
+ }
+}
+#endif
diff --git a/ecos/packages/devs/serial/arm/at91/current/src/at91_serial.h b/ecos/packages/devs/serial/arm/at91/current/src/at91_serial.h
new file mode 100644
index 0000000..4227143
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/at91/current/src/at91_serial.h
@@ -0,0 +1,108 @@
+#ifndef CYGONCE_ARM_AT91_SERIAL_H
+#define CYGONCE_ARM_AT91_SERIAL_H
+
+// ====================================================================
+//
+// at91_serial.h
+//
+// Device I/O - Description of Atmel AT91/EB40 serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2001-07-24
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports on Atmel AT91/EB40
+
+#include <cyg/hal/plf_io.h> // Register definitions
+
+#define AT91_UART_RX_INTS (AT91_US_IER_RxRDY)
+
+static cyg_uint32 select_word_length[] = {
+ AT91_US_MR_LENGTH_5,
+ AT91_US_MR_LENGTH_6,
+ AT91_US_MR_LENGTH_7,
+ AT91_US_MR_LENGTH_8
+};
+
+static cyg_uint32 select_stop_bits[] = {
+ 0,
+ AT91_US_MR_STOP_1, // 1 stop bit
+ AT91_US_MR_STOP_1_5, // 1.5 stop bit
+ AT91_US_MR_STOP_2 // 2 stop bits
+};
+
+static cyg_uint32 select_parity[] = {
+ AT91_US_MR_PARITY_NONE, // No parity
+ AT91_US_MR_PARITY_EVEN, // Even parity
+ AT91_US_MR_PARITY_ODD, // Odd parity
+ AT91_US_MR_PARITY_MARK, // Mark (1) parity
+ AT91_US_MR_PARITY_SPACE // Space (0) parity
+};
+
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 0, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 230400, // 230400
+};
+
+#endif // CYGONCE_ARM_AT91_SERIAL_H
diff --git a/ecos/packages/devs/serial/arm/cerfpda/current/ChangeLog b/ecos/packages/devs/serial/arm/cerfpda/current/ChangeLog
new file mode 100644
index 0000000..0af182b
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/cerfpda/current/ChangeLog
@@ -0,0 +1,32 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_cerfpda.cdl: Remove irrelevant doc link.
+
+2002-02-04 Gary Thomas <gthomas@redhat.com>
+
+ * include/arm_sa1110_cerfpda_ser.inl:
+ * cdl/ser_arm_cerfpda.cdl: New file(s) - port to Intrinsyc CerfPDA.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/cerfpda/current/cdl/ser_arm_cerfpda.cdl b/ecos/packages/devs/serial/arm/cerfpda/current/cdl/ser_arm_cerfpda.cdl
new file mode 100644
index 0000000..0e7001c
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/cerfpda/current/cdl/ser_arm_cerfpda.cdl
@@ -0,0 +1,130 @@
+# ====================================================================
+#
+# ser_arm_cerfpda.cdl
+#
+# eCos serial CERFPDA configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_CERFPDA {
+ display "Cerfpda 16x5x serial device driver"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_SA11X0_CERFPDA
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial 16x5x device drivers for the
+ Cerfpda."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 4"
+ }
+
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/arm_sa11x0_cerfpda_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_arm_cerfpda.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_CERFPDA_SERIAL1 {
+ display "Cerfpda serial port 1 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the
+ Cerfpda port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_CERFPDA_SERIAL1_NAME {
+ display "Device name for cerfpda serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of the serial device
+ for the Cerfpda port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_CERFPDA_SERIAL1_BAUD {
+ display "Baud rate for the cerfpda serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the Cerfpda port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_CERFPDA_SERIAL1_BUFSIZE {
+ display "Buffer size for the cerfpda serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal
+ buffers used for the cerfpda port 1."
+ }
+ }
+
+}
+
+# EOF ser_arm_cerfpda.cdl
diff --git a/ecos/packages/devs/serial/arm/cerfpda/current/include/arm_sa1110_cerfpda_ser.inl b/ecos/packages/devs/serial/arm/cerfpda/current/include/arm_sa1110_cerfpda_ser.inl
new file mode 100644
index 0000000..a06c6c5
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/cerfpda/current/include/arm_sa1110_cerfpda_ser.inl
@@ -0,0 +1,122 @@
+//==========================================================================
+//
+// io/serial/arm/arm_sa1110_cerpda_ser.inl
+//
+// Cerfpda Serial I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jlarmour
+// Date: 1999-02-04
+// Purpose: Cerfpda Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/cerfpda.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50
+ 18432,// 75
+ 12657,// 110
+ 10278,// 134.5
+ 9216, // 150
+ 6912, // 200
+ 4608, // 300
+ 2304, // 600
+ 1152, // 1200
+ 768, // 1800
+ 576, // 2400
+ 384, // 3600
+ 288, // 4800
+ 192, // 7200
+ 144, // 9600
+ 96, // 14400
+ 72, // 19200
+ 36, // 38400
+ 24, // 57600
+ 12, // 115200
+ 6, // 230400
+};
+
+#ifdef CYGPKG_IO_SERIAL_ARM_CERFPDA_SERIAL1
+static pc_serial_info cerfpda_serial_info1 = {0x18000000, SA1110_IRQ_GPIO_16X5X};
+#if CYGNUM_IO_SERIAL_ARM_CERFPDA_SERIAL1_BUFSIZE > 0
+static unsigned char cerfpda_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_CERFPDA_SERIAL1_BUFSIZE];
+static unsigned char cerfpda_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_CERFPDA_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(cerfpda_serial_channel1,
+ pc_serial_funs,
+ cerfpda_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CERFPDA_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &cerfpda_serial_out_buf1[0], sizeof(cerfpda_serial_out_buf1),
+ &cerfpda_serial_in_buf1[0], sizeof(cerfpda_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(cerfpda_serial_channel1,
+ pc_serial_funs,
+ cerfpda_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CERFPDA_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(cerfpda_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_CERFPDA_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &cerfpda_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_CERFPDA_SERIAL1
+
+// EOF arm_sa1110_cerfpda_ser.inl
diff --git a/ecos/packages/devs/serial/arm/cma230/current/ChangeLog b/ecos/packages/devs/serial/arm/cma230/current/ChangeLog
new file mode 100644
index 0000000..58908f3
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/cma230/current/ChangeLog
@@ -0,0 +1,1187 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_cma230.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_arm_cma230.cdl:
+ Fix 234000->230400 typo.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * src/cma230_serial.c: Fix typo.
+
+ * cdl/ser_arm_cma230.cdl: Testing parameters moved here.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/cma230_serial.c (cma230_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_arm_cma230.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/cma230/current/cdl/ser_arm_cma230.cdl b/ecos/packages/devs/serial/arm/cma230/current/cdl/ser_arm_cma230.cdl
new file mode 100644
index 0000000..8b9dd3d
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/cma230/current/cdl/ser_arm_cma230.cdl
@@ -0,0 +1,207 @@
+# ====================================================================
+#
+# ser_arm_cma230.cdl
+#
+# eCos serial ARM/CMA230 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_CMA230 {
+ display "Cogent ARM/CMA230 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_CMA230
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ Cogent ARM/CMA230."
+
+ compile -library=libextras.a cma230_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_cma230.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_A {
+ display "Cogent ARM/CMA230 serial port A driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the Cogent
+ ARM/CMA230 port A."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_A_NAME {
+ display "Device name for Cogent ARM/CMA230 serial port A"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the Cogent
+ ARM/CMA230 port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BAUD {
+ display "Baud rate for the Cogent ARM/CMA230 serial port A driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ Cogent ARM/CMA230 port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE {
+ display "Buffer size for the Cogent ARM/CMA230 serial port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the Cogent ARM/CMA230 port A."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_B {
+ display "Cogent ARM/CMA230 serial port B driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the Cogent
+ ARM/CMA230 port B."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_B_NAME {
+ display "Device name for Cogent ARM/CMA230 serial port B"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the Cogent
+ ARM/CMA230 port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BAUD {
+ display "Baud rate for the Cogent ARM/CMA230 serial port B driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ Cogent ARM/CMA230 port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE {
+ display "Buffer size for the Cogent ARM/CMA230 serial port B driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the Cogent ARM/CMA230 port B."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_CMA230_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_CMA230_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_CMA230_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_CMA230_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_A
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_A_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"armcma\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+
+# EOF ser_arm_cma230.cdl
diff --git a/ecos/packages/devs/serial/arm/cma230/current/src/cma230_serial.c b/ecos/packages/devs/serial/arm/cma230/current/src/cma230_serial.c
new file mode 100644
index 0000000..c024f18
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/cma230/current/src/cma230_serial.c
@@ -0,0 +1,344 @@
+//==========================================================================
+//
+// io/serial/arm/cma230_serial.c
+//
+// Cogent CMA230 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-02-04
+// Purpose: CMA230 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/hal/hal_cma230.h>
+#include <cyg/infra/diag.h>
+
+#ifdef CYGPKG_IO_SERIAL_ARM_CMA230
+
+#include "cma230_serial.h"
+
+typedef struct cma230_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} cma230_serial_info;
+
+static bool cma230_serial_init(struct cyg_devtab_entry *tab);
+static bool cma230_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo cma230_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char cma230_serial_getc(serial_channel *chan);
+static Cyg_ErrNo cma230_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void cma230_serial_start_xmit(serial_channel *chan);
+static void cma230_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 cma230_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void cma230_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(cma230_serial_funs,
+ cma230_serial_putc,
+ cma230_serial_getc,
+ cma230_serial_set_config,
+ cma230_serial_start_xmit,
+ cma230_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_A
+static cma230_serial_info cma230_serial_info0 = {CMA101_DUARTA,
+ CYGNUM_HAL_INTERRUPT_SERIAL_A};
+#if CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE > 0
+static unsigned char cma230_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE];
+static unsigned char cma230_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(cma230_serial_channel0,
+ cma230_serial_funs,
+ cma230_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &cma230_serial_out_buf0[0], sizeof(cma230_serial_out_buf0),
+ &cma230_serial_in_buf0[0], sizeof(cma230_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(cma230_serial_channel0,
+ cma230_serial_funs,
+ cma230_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(cma230_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_A_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ cma230_serial_init,
+ cma230_serial_lookup, // Serial driver may need initializing
+ &cma230_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_A
+
+#ifdef CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_B
+static cma230_serial_info cma230_serial_info1 = {CMA101_DUARTB,
+ CYGNUM_HAL_INTERRUPT_SERIAL_B};
+#if CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE > 0
+static unsigned char cma230_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE];
+static unsigned char cma230_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(cma230_serial_channel1,
+ cma230_serial_funs,
+ cma230_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &cma230_serial_out_buf1[0], sizeof(cma230_serial_out_buf1),
+ &cma230_serial_in_buf1[0], sizeof(cma230_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(cma230_serial_channel1,
+ cma230_serial_funs,
+ cma230_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(cma230_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_B_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ cma230_serial_init,
+ cma230_serial_lookup, // Serial driver may need initializing
+ &cma230_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_B
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+cma230_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base;
+ unsigned short baud_divisor = select_baud[new_config->baud];
+ unsigned char _lcr, _ier;
+ if (baud_divisor == 0) return false; // Invalid configuration
+ _ier = port->ier;
+ port->ier = 0; // Disable port interrupts while changing hardware
+ _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ port->lcr = _lcr;
+ port->lcr |= LCR_DL;
+ port->mdl = baud_divisor >> 8;
+ port->ldl = baud_divisor & 0xFF;
+ port->lcr &= ~LCR_DL;
+ if (init) {
+ port->fcr = 0x07; // Enable and clear FIFO
+ if (chan->out_cbuf.len != 0) {
+ port->ier = IER_RCV;
+ } else {
+ port->ier = 0;
+ }
+ port->mcr = MCR_INT|MCR_DTR|MCR_RTS; // Master interrupt enable
+ } else {
+ port->ier = _ier;
+ }
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+cma230_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("CMA230 SERIAL init - dev: %x.%d\n", cma230_chan->base, cma230_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(cma230_chan->int_num,
+ 99, // Priority - what goes here?
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ cma230_serial_ISR,
+ cma230_serial_DSR,
+ &cma230_chan->serial_interrupt_handle,
+ &cma230_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(cma230_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(cma230_chan->int_num);
+ }
+ cma230_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+cma230_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+cma230_serial_putc(serial_channel *chan, unsigned char c)
+{
+ cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base;
+ if (port->lsr & LSR_THE) {
+// Transmit buffer is empty
+ port->thr = c;
+ return true;
+ } else {
+// No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+cma230_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base;
+ while ((port->lsr & LSR_RSR) == 0) ; // Wait for char
+ c = port->rhr;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+cma230_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != cma230_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+cma230_serial_start_xmit(serial_channel *chan)
+{
+ cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base;
+ port->ier |= IER_XMT; // Enable xmit interrupt
+}
+
+// Disable the transmitter on the device
+static void
+cma230_serial_stop_xmit(serial_channel *chan)
+{
+ cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base;
+ port->ier &= ~IER_XMT; // Disable xmit interrupt
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+cma230_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(cma230_chan->int_num);
+ cyg_drv_interrupt_acknowledge(cma230_chan->int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+cma230_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base;
+ unsigned char isr;
+ isr = port->isr & 0x0E;
+ if (isr == ISR_Tx) {
+ (chan->callbacks->xmt_char)(chan);
+ } else if (isr == ISR_Rx) {
+ (chan->callbacks->rcv_char)(chan, port->rhr);
+ }
+ cyg_drv_interrupt_unmask(cma230_chan->int_num);
+}
+#endif
diff --git a/ecos/packages/devs/serial/arm/cma230/current/src/cma230_serial.h b/ecos/packages/devs/serial/arm/cma230/current/src/cma230_serial.h
new file mode 100644
index 0000000..0eb5e4c
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/cma230/current/src/cma230_serial.h
@@ -0,0 +1,161 @@
+#ifndef CYGONCE_ARM_CMA230_SERIAL_H
+#define CYGONCE_ARM_CMA230_SERIAL_H
+
+// ====================================================================
+//
+// cma230_serial.h
+//
+// Device I/O - Description of Cogent CMA230 serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-05-20
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports on Cogent CMA230
+
+struct serial_port {
+ unsigned char _byte[32];
+};
+
+#define reg(n) _byte[n*8]
+
+// Receive control registers
+#define rhr reg(0) // Receive holding register
+#define isr reg(2) // Interrupt status register
+#define lsr reg(5) // Line status register
+#define msr reg(6) // Modem status register
+#define scr reg(7) // Scratch register
+
+// Transmit control registers
+#define thr reg(0) // Transmit holding register
+#define ier reg(1) // Interrupt enable register
+#define fcr reg(2) // FIFO control register
+#define lcr reg(3) // Line control register
+#define mcr reg(4) // Modem control register
+#define ldl reg(0) // LSB of baud rate
+#define mdl reg(1) // MSB of baud rate
+
+// Interrupt Enable Register
+#define IER_RCV 0x01
+#define IER_XMT 0x02
+#define IER_LS 0x04
+#define IER_MS 0x08
+
+// Line Control Register
+#define LCR_WL5 0x00 // Word length
+#define LCR_WL6 0x01
+#define LCR_WL7 0x02
+#define LCR_WL8 0x03
+#define LCR_SB1 0x00 // Number of stop bits
+#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words
+#define LCR_SB2 0x04
+#define LCR_PN 0x00 // Parity mode - none
+#define LCR_PE 0x0C // Parity mode - even
+#define LCR_PO 0x08 // Parity mode - odd
+#define LCR_PM 0x28 // Forced "mark" parity
+#define LCR_PS 0x38 // Forced "space" parity
+#define LCR_DL 0x80 // Enable baud rate latch
+
+// Line Status Register
+#define LSR_RSR 0x01
+#define LSR_THE 0x20
+
+// Modem Control Register
+#define MCR_DTR 0x01
+#define MCR_RTS 0x02
+#define MCR_INT 0x08 // Enable interrupts
+
+// Interrupt status register
+#define ISR_Tx 0x02
+#define ISR_Rx 0x04
+
+static unsigned char select_word_length[] = {
+ LCR_WL5, // 5 bits / word (char)
+ LCR_WL6,
+ LCR_WL7,
+ LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ LCR_SB1, // 1 stop bit
+ LCR_SB1_5, // 1.5 stop bit
+ LCR_SB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ LCR_PN, // No parity
+ LCR_PE, // Even parity
+ LCR_PO, // Odd parity
+ LCR_PM, // Mark parity
+ LCR_PS, // Space parity
+};
+
+// The Cogent board has a 3.6864 MHz crystal
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 4608, // 50
+ 0, // 75
+ 2094, // 110
+ 0, // 134.5
+ 1536, // 150
+ 0, // 200
+ 768, // 300
+ 384, // 600
+ 182, // 1200
+ 0, // 1800
+ 96, // 2400
+ 0, // 3600
+ 48, // 4800
+ 32, // 7200
+ 24, // 9600
+ 16, // 14400
+ 12, // 19200
+ 6, // 38400
+ 4, // 57600
+ 2, // 115200
+ 0, // 230400
+};
+
+#endif // CYGONCE_ARM_CMA230_SERIAL_H
diff --git a/ecos/packages/devs/serial/arm/e7t/current/ChangeLog b/ecos/packages/devs/serial/arm/e7t/current/ChangeLog
new file mode 100644
index 0000000..cf6da8b
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/e7t/current/ChangeLog
@@ -0,0 +1,38 @@
+2004-02-11 Roland Caßebohm <roland.cassebohm@visionsystem.de>
+
+ * src/e7t_serial.c: The UART doesn't generate an interrupt befor the
+ first time a character was send. Changed e7t_serial_start_xmit()
+ to first try to send characters.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_e7t.cdl: Remove irrelevant doc link.
+
+2001-10-19 Lars Lindqvist <Lars.Lindqvist@combitechsystems.com>
+2001-10-19 Jonathan Larmour <jlarmour@redhat.com>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/e7t/current/cdl/ser_arm_e7t.cdl b/ecos/packages/devs/serial/arm/e7t/current/cdl/ser_arm_e7t.cdl
new file mode 100644
index 0000000..fbeea37
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/e7t/current/cdl/ser_arm_e7t.cdl
@@ -0,0 +1,209 @@
+# ====================================================================
+#
+# ser_arm_e7t.cdl
+#
+# eCos serial ARM/AEB-2 (E7T) configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Lars.Lindqvist@combitechsystems.com
+# Contributors: jlarmour
+# Date: 2001-10-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_E7T {
+ display "ARM E7T serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_E7T
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This package contains serial device drivers for the
+ ARM AEB-2 (E7T)."
+
+ compile -library=libextras.a e7t_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_e7t.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_ARM_E7T_SERIAL0 {
+ display "ARM E7T serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the ARM E7T
+ port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_E7T_SERIAL0_NAME {
+ display "Deviccce name for the ARM E7T serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option sets the name of the serial device for the ARM
+ E7T port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_E7T_SERIAL0_BAUD {
+ display "Baud rate for the ARM E7T serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ ARM E7T port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_E7T_SERIAL0_BUFSIZE {
+ display "Buffer size for the ARM E7T serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the ARM E7T port 0."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_ARM_E7T_SERIAL1 {
+ display "ARM E7T serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the ARM
+ E7T port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_E7T_SERIAL1_NAME {
+ display "Device name for the ARM E7T serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for the
+ ARM E7T port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_E7T_SERIAL1_BAUD {
+ display "Baud rate for the ARM E7T serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ ARM E7T port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_E7T_SERIAL1_BUFSIZE {
+ display "Buffer size for the ARM E7T serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ARM E7T port 1."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_E7T_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_E7T_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_E7T_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_E7T_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_E7T_SERIAL1
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_38400
+ implements CYGINT_IO_SERIAL_TEST_SKIP_57600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_E7T_SERIAL1_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"arme7t\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+
+# EOF ser_arm_e7t.cdl
diff --git a/ecos/packages/devs/serial/arm/e7t/current/src/e7t_serial.c b/ecos/packages/devs/serial/arm/e7t/current/src/e7t_serial.c
new file mode 100644
index 0000000..3de6647
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/e7t/current/src/e7t_serial.c
@@ -0,0 +1,376 @@
+//==========================================================================
+//
+// io/serial/arm/e7t_serial.c
+//
+// ARM AEB-2 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Lars.Lindqvist@combitechsystems.com
+// Contributors: jlarmour
+// Date: 2001-10-19
+// Purpose: ARM AEB-2 Serial I/O Interface Module (interrupt driven)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/io/serialio.h>
+#include <cyg/infra/diag.h>
+
+#ifdef CYGPKG_IO_SERIAL_ARM_E7T
+
+#include "e7t_serial.h"
+
+typedef struct e7t_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD tx_int_num;
+ CYG_WORD rx_int_num;
+ cyg_interrupt serial_tx_interrupt;
+ cyg_interrupt serial_rx_interrupt;
+ cyg_handle_t serial_tx_interrupt_handle;
+ cyg_handle_t serial_rx_interrupt_handle;
+ bool tx_enabled;
+} e7t_serial_info;
+
+static bool e7t_serial_init(struct cyg_devtab_entry *tab);
+static bool e7t_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo e7t_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char e7t_serial_getc(serial_channel *chan);
+static Cyg_ErrNo e7t_serial_set_config(serial_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void e7t_serial_start_xmit(serial_channel *chan);
+static void e7t_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 e7t_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void e7t_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static cyg_uint32 e7t_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void e7t_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(e7t_serial_funs,
+ e7t_serial_putc,
+ e7t_serial_getc,
+ e7t_serial_set_config,
+ e7t_serial_start_xmit,
+ e7t_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_E7T_SERIAL0
+static e7t_serial_info e7t_serial_info0 = {0x07FFd000,
+ CYGNUM_HAL_INTERRUPT_UART0_TX,
+ CYGNUM_HAL_INTERRUPT_UART0_RX};
+#if CYGNUM_IO_SERIAL_ARM_E7T_SERIAL0_BUFSIZE > 0
+static unsigned char e7t_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_E7T_SERIAL0_BUFSIZE];
+static unsigned char e7t_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_E7T_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(e7t_serial_channel0,
+ e7t_serial_funs,
+ e7t_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_E7T_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &e7t_serial_out_buf0[0], sizeof(e7t_serial_out_buf0),
+ &e7t_serial_in_buf0[0], sizeof(e7t_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(e7t_serial_channel0,
+ e7t_serial_funs,
+ e7t_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_E7T_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(e7t_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_E7T_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ e7t_serial_init,
+ e7t_serial_lookup, // Serial driver may need initializing
+ &e7t_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_E7T_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_ARM_E7T_SERIAL1
+static e7t_serial_info e7t_serial_info1 = {0x07FFe000,
+ CYGNUM_HAL_INTERRUPT_UART1_TX,
+ CYGNUM_HAL_INTERRUPT_UART1_RX};
+#if CYGNUM_IO_SERIAL_ARM_E7T_SERIAL1_BUFSIZE > 0
+static unsigned char e7t_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_E7T_SERIAL1_BUFSIZE];
+static unsigned char e7t_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_E7T_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(e7t_serial_channel1,
+ e7t_serial_funs,
+ e7t_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_E7T_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &e7t_serial_out_buf1[0], sizeof(e7t_serial_out_buf1),
+ &e7t_serial_in_buf1[0], sizeof(e7t_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(e7t_serial_channel1,
+ e7t_serial_funs,
+ e7t_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_E7T_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(e7t_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_E7T_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ e7t_serial_init,
+ e7t_serial_lookup, // Serial driver may need initializing
+ &e7t_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_E7T_SERIAL1
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+e7t_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ e7t_serial_info *e7t_chan = (e7t_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)e7t_chan->base;
+ cyg_uint32 word_length = select_word_length[(new_config->word_length)-CYGNUM_SERIAL_WORD_LENGTH_5];
+ cyg_uint32 stop_bits = select_stop_bits[(new_config->stop)-CYGNUM_SERIAL_STOP_1];
+ cyg_uint32 parity_mode = select_parity[(new_config->parity)-CYGNUM_SERIAL_PARITY_NONE];
+ cyg_uint32 baud_divisor = select_baud[(new_config->baud)-CYGNUM_SERIAL_BAUD_50];
+ cyg_uint32 res = word_length | stop_bits | parity_mode | ULCON_SCI | ULCON_IROFF;
+ if ((word_length|stop_bits|parity_mode|baud_divisor) == U_NOT_SUPP) {
+ return false;
+ };
+ port->REG_ULCON = res;
+ port->REG_UCON = UCON_RXMINT | UCON_RXSIOFF | UCON_TXMINT | UCON_DSROFF | UCON_SBKOFF | UCON_LPBOFF;
+ port->REG_UBRDIV = baud_divisor;
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ };
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+e7t_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ e7t_serial_info *e7t_chan = (e7t_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("E7T SERIAL init - dev: %x.%d.%d\n", e7t_chan->base, e7t_chan->tx_int_num, e7t_chan->rx_int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) { // If bufferlength > 0 then interrupts are used for tx
+ cyg_drv_interrupt_create(e7t_chan->tx_int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ e7t_serial_tx_ISR,
+ e7t_serial_tx_DSR,
+ &e7t_chan->serial_tx_interrupt_handle,
+ &e7t_chan->serial_tx_interrupt);
+ cyg_drv_interrupt_attach(e7t_chan->serial_tx_interrupt_handle);
+ cyg_drv_interrupt_mask(e7t_chan->tx_int_num);
+ e7t_chan->tx_enabled = false;
+ }
+ if (chan->in_cbuf.len != 0) { // If bufferlength > 0 then interrupts are used for rx
+ cyg_drv_interrupt_create(e7t_chan->rx_int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ e7t_serial_rx_ISR,
+ e7t_serial_rx_DSR,
+ &e7t_chan->serial_rx_interrupt_handle,
+ &e7t_chan->serial_rx_interrupt);
+ cyg_drv_interrupt_attach(e7t_chan->serial_rx_interrupt_handle);
+ cyg_drv_interrupt_unmask(e7t_chan->rx_int_num);
+ }
+ e7t_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+e7t_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+e7t_serial_putc(serial_channel *chan, unsigned char c)
+{
+ e7t_serial_info *e7t_chan = (e7t_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)e7t_chan->base;
+
+ if (port->REG_USTAT & USTAT_TBE) {
+ // Transmit buffer is empty
+ port->REG_UTXBUF = c;
+ return true;
+ } else {
+ // No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+e7t_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ e7t_serial_info *e7t_chan = (e7t_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)e7t_chan->base;
+ while ((port->REG_USTAT & USTAT_RDR) == 0) ; // Wait for char
+ c = port->REG_URXBUF;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+e7t_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != e7t_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+e7t_serial_start_xmit(serial_channel *chan)
+{
+ e7t_serial_info *e7t_chan = (e7t_serial_info *)chan->dev_priv;
+ e7t_chan->tx_enabled = true;
+ (chan->callbacks->xmt_char)(chan);
+ if (e7t_chan->tx_enabled) {
+ cyg_drv_interrupt_unmask(e7t_chan->tx_int_num);
+ }
+}
+
+// Disable the transmitter on the device
+static void
+e7t_serial_stop_xmit(serial_channel *chan)
+{
+ e7t_serial_info *e7t_chan = (e7t_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(e7t_chan->tx_int_num);
+ e7t_chan->tx_enabled = false;
+}
+
+// Serial I/O - low level tx interrupt handler (ISR)
+static cyg_uint32
+e7t_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ e7t_serial_info *e7t_chan = (e7t_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(e7t_chan->tx_int_num);
+ cyg_drv_interrupt_acknowledge(e7t_chan->tx_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level tx interrupt handler (DSR)
+static void
+e7t_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ e7t_serial_info *e7t_chan = (e7t_serial_info *)chan->dev_priv;
+ (chan->callbacks->xmt_char)(chan);
+ if (e7t_chan->tx_enabled) {
+ cyg_drv_interrupt_unmask(e7t_chan->tx_int_num);
+ }
+}
+
+// Serial I/O - low level rx interrupt handler (ISR)
+static cyg_uint32
+e7t_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ e7t_serial_info *e7t_chan = (e7t_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(e7t_chan->rx_int_num);
+ cyg_drv_interrupt_acknowledge(e7t_chan->rx_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level rx interrupt handler (DSR)
+static void
+e7t_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ e7t_serial_info *e7t_chan = (e7t_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)e7t_chan->base;
+ (chan->callbacks->rcv_char)(chan, port->REG_URXBUF);
+ cyg_drv_interrupt_unmask(e7t_chan->rx_int_num);
+}
+
+#endif // CYGPKG_IO_SERIAL_ARM_E7T
+
+// EOF e7t_serial.c
diff --git a/ecos/packages/devs/serial/arm/e7t/current/src/e7t_serial.h b/ecos/packages/devs/serial/arm/e7t/current/src/e7t_serial.h
new file mode 100644
index 0000000..336d99d
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/e7t/current/src/e7t_serial.h
@@ -0,0 +1,196 @@
+#ifndef CYGONCE_ARM_E7T_SERIAL_H
+#define CYGONCE_ARM_E7T_SERIAL_H
+// ====================================================================
+//
+// e7t_serial.h
+//
+// Device I/O - Description of ARM AEB-2 serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Lars.Lindqvist@combitechsystems.com
+// Contributors: jlarmour
+// Date: 2001-10-19
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+#include <pkgconf/hal.h> // Value CYGNUM_HAL_ARM_E7T_CLOCK_SPEED needed
+#include <cyg/infra/cyg_type.h> // base types
+
+// Description of serial ports on ARM AEB-2
+
+struct serial_port {
+ cyg_uint32 _reg[8];
+};
+
+#define REG(n) _reg[n]
+
+// Misc values
+#define U_NOT_SUPP (0xFFFFFFFF) // Used to indicate unsupported parameter values
+
+// Registers
+#define REG_ULCON REG(0) // Line control registers
+#define REG_UCON REG(1) // Control registers
+#define REG_USTAT REG(2) // Status registers
+#define REG_UTXBUF REG(3) // Transmit buffer registers
+#define REG_URXBUF REG(4) // Receive buffer registers
+#define REG_UBRDIV REG(5) // Baud rate divisor registers
+
+// Line Control Register Values
+#define ULCON_WL5 (0x00000000 << 0) // Word length 5
+#define ULCON_WL6 (0x00000001 << 0) // Word length 6
+#define ULCON_WL7 (0x00000002 << 0) // Word length 7
+#define ULCON_WL8 (0x00000003 << 0) // Word length 8
+#define ULCON_STB1 (0x00000000 << 2) // One stop bit
+#define ULCON_STB2 (0x00000001 << 2) // Two stop bits
+#define ULCON_PMDOFF (0x00000000 << 3) // No parity
+#define ULCON_PMDODD (0x00000004 << 3) // Odd parity
+#define ULCON_PMDEVEN (0x00000005 << 3) // Even parity
+#define ULCON_PMDFC1 (0x00000006 << 3) // Parity forced/checked as 1
+#define ULCON_PMDFC0 (0x00000007 << 3) // Parity forced/checked as 0
+#define ULCON_SCI (0x00000000 << 6) // Internal clock
+#define ULCON_SCE (0x00000001 << 6) // External clock
+#define ULCON_IROFF (0x00000000 << 7) // Normal mode
+#define ULCON_IRON (0x00000001 << 7) // IR mode
+
+// Control Register Values
+#define UCON_RXMOFF (0x00000000 << 0) // Disable Rx mode
+#define UCON_RXMINT (0x00000001 << 0) // Interrupt request Rx mode
+#define UCON_RXMDMA0 (0x00000002 << 0) // GDMA channel 0 request Rx mode
+#define UCON_RXMDMA1 (0x00000003 << 0) // GDMA channel 1 request Rx mode
+#define UCON_RXSIOFF (0x00000000 << 2) // Rx status interrupt disabled
+#define UCON_RXSION (0x00000001 << 2) // Rx status interrupt enabled
+#define UCON_TXMOFF (0x00000000 << 3) // Disable Tx mode
+#define UCON_TXMINT (0x00000001 << 3) // Interrupt request Tx mode
+#define UCON_TXMDMA0 (0x00000002 << 3) // GDMA channel 0 request Tx mode
+#define UCON_TXMDMA1 (0x00000003 << 3) // GDMA channel 1 request Tx mode
+#define UCON_DSROFF (0x00000000 << 5) // Data set ready output off
+#define UCON_DSRON (0x00000001 << 5) // Data set ready output on
+#define UCON_SBKOFF (0x00000000 << 6) // No break sent
+#define UCON_SBKON (0x00000001 << 6) // Break sent
+#define UCON_LPBOFF (0x00000000 << 7) // Loop back mode off
+#define UCON_LPBON (0x00000001 << 7) // Loop back mode on
+
+// Status Register Values
+#define USTAT_OV (0x00000001 << 0) // Overrun error
+#define USTAT_PE (0x00000001 << 1) // Parity error
+#define USTAT_FE (0x00000001 << 2) // Frame error
+
+#define USTAT_BKD (0x00000001 << 3) // Break detect
+#define USTAT_DTR (0x00000001 << 4) // Data terminal ready
+#define USTAT_RDR (0x00000001 << 5) // Receive data ready
+#define USTAT_TBE (0x00000001 << 6) // Transmit buffer register empty
+#define USTAT_TC (0x00000001 << 7) // Transmit complete
+
+// Baud rate divisor registers
+#define UBRDIV_50 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/16/16/50)-1)<<4)|1)
+#define UBRDIV_75 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/16/16/75)-1)<<4)|1)
+#define UBRDIV_110 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/16/16/110)-1)<<4)|1)
+#define UBRDIV_134_5 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/16/8/269)-1)<<4)|1)
+#define UBRDIV_150 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/16/16/150)-1)<<4)|1)
+#define UBRDIV_200 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/16/16/200)-1)<<4)|1)
+#define UBRDIV_300 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/16/16/300)-1)<<4)|1)
+#define UBRDIV_600 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/600)-1)<<4)|0)
+#define UBRDIV_1200 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/1200)-1)<<4)|0)
+#define UBRDIV_1800 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/1800)-1)<<4)|0)
+#define UBRDIV_2400 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/2400)-1)<<4)|0)
+#define UBRDIV_3600 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/3600)-1)<<4)|0)
+#define UBRDIV_4800 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/4800)-1)<<4)|0)
+#define UBRDIV_7200 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/7200)-1)<<4)|0)
+#define UBRDIV_9600 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/9600)-1)<<4)|0)
+#define UBRDIV_14400 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/14400)-1)<<4)|0)
+#define UBRDIV_19200 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/19200)-1)<<4)|0)
+#define UBRDIV_38400 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/38400)-1)<<4)|0)
+#define UBRDIV_57600 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/57600)-1)<<4)|0)
+#define UBRDIV_115200 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/115200)-1)<<4)|0)
+#define UBRDIV_230400 ((((CYGNUM_HAL_ARM_E7T_CLOCK_SPEED/2/1/16/230400)-1)<<4)|0)
+
+
+// Arrays used for conversion of eCos serial driver
+// configuration parameters to parameters for E7T
+
+static cyg_uint32 select_word_length[] = {
+ ULCON_WL5, // 5 bits / word (char)
+ ULCON_WL6,
+ ULCON_WL7,
+ ULCON_WL8
+};
+
+static cyg_uint32 select_stop_bits[] = {
+ ULCON_STB1, // 1 stop bit
+ U_NOT_SUPP, // 1.5 stop bit not supported
+ ULCON_STB2 // 2 stop bits
+};
+
+static cyg_uint32 select_parity[] = {
+ ULCON_PMDOFF, // No parity
+ ULCON_PMDEVEN, // Even parity
+ ULCON_PMDODD, // Odd parity
+ ULCON_PMDFC1, // Mark parity
+ ULCON_PMDFC0, // Space parity
+};
+
+static cyg_uint32 select_baud[] = {
+ UBRDIV_50, // 50
+ UBRDIV_75, // 75
+ UBRDIV_110, // 110
+ UBRDIV_134_5, // 134.5
+ UBRDIV_150, // 150
+ UBRDIV_200, // 200
+ UBRDIV_300, // 300
+ UBRDIV_600, // 600
+ UBRDIV_1200, // 1200
+ UBRDIV_1800, // 1800
+ UBRDIV_2400, // 2400
+ UBRDIV_3600, // 3600
+ UBRDIV_4800, // 4800
+ UBRDIV_7200, // 7200
+ UBRDIV_9600, // 9600
+ UBRDIV_14400, // 14400
+ UBRDIV_19200, // 19200
+ UBRDIV_38400, // 38400
+ UBRDIV_57600, // 57600
+ UBRDIV_115200, // 115200
+ UBRDIV_230400, // 230400
+};
+
+#endif // CYGONCE_ARM_E7T_SERIAL_H
+
+// EOF e7t_serial.h
diff --git a/ecos/packages/devs/serial/arm/ebsa285/current/ChangeLog b/ecos/packages/devs/serial/arm/ebsa285/current/ChangeLog
new file mode 100644
index 0000000..9194fef
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/ebsa285/current/ChangeLog
@@ -0,0 +1,1198 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_ebsa285.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_arm_ebsa285.cdl:
+ Fix 234000->230400 typo.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_arm_ebsa285.cdl: Testing parameters moved here.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/ebsa285_serial.c (ebsa285_serial_set_config): Now use keys
+ to make more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-12 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/ebsa285_serial.c (ebsa285_serial_init): Fix silly debug
+ message - enabled by serial1 test permutation.
+
+2000-04-12 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/ebsa285_serial.c (ebsa285_serial_tx_DSR): Record
+ whether tx is to be enabled in ebsa285_chan->tx_active, so that
+ the DSR does not universally unmask it regardless. That led to an
+ interrupt loop, when the DSR callback had turned off the tx.
+ Also removed a typo - rx data was being read twice!
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_arm_ebsa285.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/ebsa285/current/cdl/ser_arm_ebsa285.cdl b/ecos/packages/devs/serial/arm/ebsa285/current/cdl/ser_arm_ebsa285.cdl
new file mode 100644
index 0000000..3d64d6f
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/ebsa285/current/cdl/ser_arm_ebsa285.cdl
@@ -0,0 +1,163 @@
+# ====================================================================
+#
+# ser_arm_ebsa285.cdl
+#
+# eCos serial ARM/EBSA285 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): hmt
+# Original data: gthomas
+# Contributors: jskov
+# Date: 2000-04-04
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_ARM_EBSA285 {
+ display "Intel StrongARM/EBSA285 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_EBSA285
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ StrongARM/EBSA285."
+
+ compile -library=libextras.a ebsa285_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_ebsa285.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL {
+ display "Intel StrongARM/EBSA285 serial driver"
+ flavor bool
+ default_value 1
+ description "
+ The serial device driver for the Intel StrongARM/EBSA285.
+ There is only one serial device on this board."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_EBSA285_SERIAL_NAME {
+ display "Device name for the Intel StrongARM/EBSA285 serial port"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for the
+ Intel StrongARM/EBSA285 serial port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BAUD {
+ display "Baud rate for the Intel StrongARM/EBSA285 serial port"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 \
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ Intel StrongARM/EBSA285 serial port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE {
+ display "Buffer size for the Intel StrongARM/EBSA285 serial driver"
+ flavor data
+ default_value 128
+ legal_values 0 to 8192
+ description "
+ This option specifies the size of the internal buffers used
+ for the Intel StrongARM/EBSA285 serial port."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_EBSA285_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_EBSA285_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_EBSA285_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_EBSA285_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_EBSA285_SERIAL_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"arm285\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+
+# EOF ser_arm_ebsa285.cdl
diff --git a/ecos/packages/devs/serial/arm/ebsa285/current/src/ebsa285_serial.c b/ecos/packages/devs/serial/arm/ebsa285/current/src/ebsa285_serial.c
new file mode 100644
index 0000000..cec6599
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/ebsa285/current/src/ebsa285_serial.c
@@ -0,0 +1,453 @@
+//==========================================================================
+//
+// devs/serial/arm/ebsa285/current/src/ebsa285_serial.c
+//
+// ARM EBSA285 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 1999-07-26
+// Purpose: EBSA285 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#ifdef CYGPKG_IO_SERIAL_ARM_EBSA285
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/hal_ebsa285.h> // Hardware definitions
+
+// ------------------------------------------------------------------------
+// Baud rates and the like, table-driven setup
+#define FCLK_MHZ 50
+
+struct _baud {
+ unsigned char divisor_high, divisor_low;
+};
+
+// The indexing of this table must match the enum in serialio.h
+// The arithmetic is (clock/4)/(baud * 16) - 1
+
+#define NONE {0,0}
+const static struct _baud bauds[] = {
+#if (FCLK_MHZ == 50)
+ NONE, // unused
+ NONE, // 50
+ NONE, // 75
+ NONE, // 110
+ NONE, // 134.5
+ NONE, // 150
+ NONE, // 200
+ { 0xA, 0x2B }, // 300 2603 = 0x0A2B
+ { 0x5, 0x15 }, // 600 1301 = 0x0515
+ { 0x2, 0x8A }, // 1200 650 = 0x028A
+ { 0x1, 0xB1 }, // 1800 433 = 0x01B1
+ { 0x1, 0x45 }, // 2400 325 = 0x0145
+ { 0x0, 0xD8 }, // 3600 216 = 0x00D8
+ { 0x0, 0xA2 }, // 4800 162 = 0x00A2
+ { 0x0, 0x6B }, // 7200 107 = 0x006B
+ { 0x0, 0x50 }, // 9600 80 = 0x0050
+ { 0x0, 0x35 }, // 14400 53 = 0x0035
+ { 0x0, 0x28 }, // 19200 40 = 0x0028
+ { 0x0, 0x13 }, // 38400 19 = 0x0013
+ NONE, // 57600
+ NONE, // 115200
+ NONE // 230400
+#elif (FCLK_MHZ == 60)
+#error NOT SUPPORTED - these figures are more for documentation
+ { /* 300, */ 0xC, 0x34}, /* 2603 = 0x0A2B */
+ { /* 600, */ 0x6, 0x19}, /* 1301 = 0x0515 */
+ { /* 1200, */ 0x3, 0x0C}, /* 650 = 0x028A */
+ { /* 2400, */ 0x1, 0x86}, /* 325 = 0x0145 */
+ { /* 4800, */ 0x0, 0xC2}, /* 162 = 0x00A2 */
+ { /* 9600, */ 0x0, 0x61}, /* 80 = 0x0050 */
+ { /* 19200, */ 0x0, 0x30}, /* 40 = 0x0028 */
+ { /* 38400, */ 0x0, 0x17}, /* 19 = 0x0013 */
+#endif
+};
+
+static int select_word_length[] = {
+ SA110_UART_DATA_LENGTH_5_BITS, // 5 bits
+ SA110_UART_DATA_LENGTH_6_BITS, // 6 bits
+ SA110_UART_DATA_LENGTH_7_BITS, // 7 bits
+ SA110_UART_DATA_LENGTH_8_BITS // 8 bits
+};
+
+static int select_stop_bits[] = {
+ -1, // unused
+ SA110_UART_STOP_BITS_ONE, // 1 stop bit
+ -1, // 1.5 stop bit
+ SA110_UART_STOP_BITS_TWO // 2 stop bits
+};
+
+static int select_parity[] = {
+ SA110_UART_PARITY_DISABLED, // No parity
+ SA110_UART_PARITY_ENABLED | SA110_UART_PARITY_EVEN, // Even parity
+ SA110_UART_PARITY_ENABLED | SA110_UART_PARITY_ODD, // Odd parity
+ -1, // Mark parity
+ -1 // Space parity
+};
+
+// ------------------------------------------------------------------------
+// some forward references
+
+struct ebsa285_serial_interrupt {
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+};
+
+typedef struct ebsa285_serial_info {
+ struct ebsa285_serial_interrupt rx;
+ struct ebsa285_serial_interrupt tx;
+ int tx_active;
+} ebsa285_serial_info;
+
+static bool ebsa285_serial_init(struct cyg_devtab_entry *tab);
+static bool ebsa285_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo ebsa285_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char ebsa285_serial_getc(serial_channel *chan);
+static Cyg_ErrNo ebsa285_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+
+static void ebsa285_serial_start_xmit(serial_channel *chan);
+static void ebsa285_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 ebsa285_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void ebsa285_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static cyg_uint32 ebsa285_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void ebsa285_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(ebsa285_serial_funs,
+ ebsa285_serial_putc,
+ ebsa285_serial_getc,
+ ebsa285_serial_set_config,
+ ebsa285_serial_start_xmit,
+ ebsa285_serial_stop_xmit
+ );
+
+
+// ------------------------------------------------------------------------
+// this is dummy in config: there is only one device on the EBSA285
+#ifdef CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL
+
+static ebsa285_serial_info ebsa285_serial_info1 = {
+ { CYGNUM_HAL_INTERRUPT_SERIAL_RX },
+ { CYGNUM_HAL_INTERRUPT_SERIAL_TX },
+ 0
+};
+
+#if CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE > 0
+static unsigned char ebsa285_serial_out_buf[CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE];
+static unsigned char ebsa285_serial_in_buf[CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(ebsa285_serial_channel,
+ ebsa285_serial_funs,
+ ebsa285_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &ebsa285_serial_out_buf[0], sizeof(ebsa285_serial_out_buf),
+ &ebsa285_serial_in_buf[0], sizeof(ebsa285_serial_in_buf)
+ );
+#else
+static SERIAL_CHANNEL(ebsa285_serial_channel,
+ ebsa285_serial_funs,
+ ebsa285_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(ebsa285_serial_io,
+ CYGDAT_IO_SERIAL_ARM_EBSA285_SERIAL_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ ebsa285_serial_init,
+ ebsa285_serial_lookup, // Serial driver may need initializing
+ &ebsa285_serial_channel
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL
+
+// ------------------------------------------------------------------------
+
+
+// ------------------------------------------------------------------------
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+ebsa285_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ int dummy, h, m, l;
+
+ // Make sure everything is off
+ *SA110_UART_CONTROL_REGISTER = SA110_UART_DISABLED | SA110_SIR_DISABLED;
+
+ // Read the RXStat to drain the fifo
+ dummy = *SA110_UART_RXSTAT;
+
+ // Set the baud rate - this also turns the uart on.
+ //
+ // Note that the ordering of these writes is critical,
+ // and the writes to the H_BAUD_CONTROL and CONTROL_REGISTER
+ // are necessary to force the UART to update its register
+ // contents.
+
+ l = bauds[new_config->baud].divisor_low; // zeros in unused slots here
+ m = bauds[new_config->baud].divisor_high; // and here
+ h = SA110_UART_BREAK_DISABLED |
+ select_stop_bits[new_config->stop] | // -1s in unused slots for these
+ select_parity[new_config->parity] | // and these
+ SA110_UART_FIFO_ENABLED | // and these below
+ select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];
+
+ if ( 0 != (l + m) && h >= 0 && h < 256 ) {
+ *SA110_UART_L_BAUD_CONTROL = l;
+ *SA110_UART_M_BAUD_CONTROL = m;
+ *SA110_UART_H_BAUD_CONTROL = h;
+ init = true; // AOK
+ }
+ else if ( init ) {
+ // put in some sensible defaults
+ *SA110_UART_L_BAUD_CONTROL = 0x13; // bp->divisor_low;
+ *SA110_UART_M_BAUD_CONTROL = 0x00; // bp->divisor_high;
+ *SA110_UART_H_BAUD_CONTROL = SA110_UART_BREAK_DISABLED |
+ SA110_UART_PARITY_DISABLED |
+ SA110_UART_STOP_BITS_ONE |
+ SA110_UART_FIFO_ENABLED |
+ SA110_UART_DATA_LENGTH_8_BITS;
+ }
+
+ // All set, re-enable the device:
+ *SA110_UART_CONTROL_REGISTER = SA110_UART_ENABLED | SA110_SIR_DISABLED;
+
+ if (init && new_config != &chan->config) {
+ // record the new setup
+ chan->config = *new_config;
+ }
+ // All done
+ return init;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+ebsa285_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("EBSA285 SERIAL init - dev: %x\n", ebsa285_chan);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+
+ // first for rx
+ cyg_drv_interrupt_create(ebsa285_chan->rx.int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ ebsa285_serial_rx_ISR,
+ ebsa285_serial_rx_DSR,
+ &ebsa285_chan->rx.serial_interrupt_handle,
+ &ebsa285_chan->rx.serial_interrupt);
+ cyg_drv_interrupt_attach(ebsa285_chan->rx.serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(ebsa285_chan->rx.int_num);
+
+ // then for tx
+ cyg_drv_interrupt_create(ebsa285_chan->tx.int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ ebsa285_serial_tx_ISR,
+ ebsa285_serial_tx_DSR,
+ &ebsa285_chan->tx.serial_interrupt_handle,
+ &ebsa285_chan->tx.serial_interrupt);
+ cyg_drv_interrupt_attach(ebsa285_chan->tx.serial_interrupt_handle);
+ // DO NOT cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num);
+ ebsa285_chan->tx_active = 0;
+ }
+ (void)ebsa285_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+ebsa285_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+ebsa285_serial_putc(serial_channel *chan, unsigned char c)
+{
+ if ((*SA110_UART_FLAG_REGISTER & SA110_TX_FIFO_STATUS_MASK) == SA110_TX_FIFO_BUSY)
+ return false; // No space
+
+ *SA110_UART_DATA_REGISTER = c; // Transmit buffer is empty
+ return true;
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+ebsa285_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ while ((*SA110_UART_FLAG_REGISTER & SA110_RX_FIFO_STATUS_MASK) == SA110_RX_FIFO_EMPTY)
+ ; // wait for char
+ c = (char)(*SA110_UART_DATA_REGISTER & 0xFF);
+ // no error checking... no way to return the info
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+ebsa285_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != ebsa285_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device (nope, already in use by hal_diag)
+static void
+ebsa285_serial_start_xmit(serial_channel *chan)
+{
+ ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;
+ ebsa285_chan->tx_active = 1;
+ cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num);
+}
+
+// Disable the transmitter on the device (nope, remains in use by hal_diag)
+static void
+ebsa285_serial_stop_xmit(serial_channel *chan)
+{
+ ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(ebsa285_chan->tx.int_num);
+ ebsa285_chan->tx_active = 0;
+}
+
+// Serial I/O - low level interrupt handlers (ISR)
+static cyg_uint32
+ebsa285_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(ebsa285_chan->rx.int_num);
+ cyg_drv_interrupt_acknowledge(ebsa285_chan->rx.int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+static cyg_uint32
+ebsa285_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(ebsa285_chan->tx.int_num);
+ cyg_drv_interrupt_acknowledge(ebsa285_chan->tx.int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handlers (DSR)
+static void
+ebsa285_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;
+ if ((*SA110_UART_FLAG_REGISTER & SA110_RX_FIFO_STATUS_MASK) != SA110_RX_FIFO_EMPTY) {
+ char c;
+ int status;
+ c = (char)(*SA110_UART_DATA_REGISTER & 0xFF);
+ status = *SA110_UART_RXSTAT;
+ if ( 0 == (status & (SA110_UART_FRAMING_ERROR_MASK |
+ SA110_UART_PARITY_ERROR_MASK |
+ SA110_UART_OVERRUN_ERROR_MASK)) )
+ (chan->callbacks->rcv_char)(chan, c);
+ }
+ cyg_drv_interrupt_unmask(ebsa285_chan->rx.int_num);
+}
+
+static void
+ebsa285_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;
+ if ((*SA110_UART_FLAG_REGISTER & SA110_TX_FIFO_STATUS_MASK) != SA110_TX_FIFO_BUSY) {
+ (chan->callbacks->xmt_char)(chan);
+ }
+ if ( ebsa285_chan->tx_active ) // it might be halted in callback above
+ cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num);
+}
+#endif // CYGPKG_IO_SERIAL_ARM_EBSA285
+
+// ------------------------------------------------------------------------
+// EOF ebsa285_serial.c
diff --git a/ecos/packages/devs/serial/arm/edb7xxx/current/ChangeLog b/ecos/packages/devs/serial/arm/edb7xxx/current/ChangeLog
new file mode 100644
index 0000000..8b71da0
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/edb7xxx/current/ChangeLog
@@ -0,0 +1,1189 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_edb7xxx.cdl: Remove irrelevant doc link.
+
+2001-10-12 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_arm_edb7xxx.cdl: Clarify package description strings.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_arm_edb7xxx.cdl:
+ Fix 234000->230400 typo.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_arm_edb7xxx.cdl: Moved testing parameters here.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/edb7xxx_serial.c (edb7xxx_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_arm_edb7xxx.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/edb7xxx/current/cdl/ser_arm_edb7xxx.cdl b/ecos/packages/devs/serial/arm/edb7xxx/current/cdl/ser_arm_edb7xxx.cdl
new file mode 100644
index 0000000..2d69ba0
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/edb7xxx/current/cdl/ser_arm_edb7xxx.cdl
@@ -0,0 +1,208 @@
+# ====================================================================
+#
+# ser_arm_edb7xxx.cdl
+#
+# eCos serial ARM/EDB7XXX configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_EDB7XXX {
+ display "Cirrus Logic ARM based boards serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_EDB7XXX
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ Cirrus Logic ARM based development boards."
+
+ compile -library=libextras.a edb7xxx_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_edb7xxx.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL1 {
+ display "Cirrus Logic EDB7XXX serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the Cirrus Logic EDB7XXX
+ port 1."
+
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL1_NAME {
+ display "Device name for the Cirrus Logic EDB7XXX serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for the ARM
+ EDB7XXX port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BAUD {
+ display "Baud rate for the Cirrus Logic EDB7XXX serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the ARM
+ EDB7XXX port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE {
+ display "Buffer size for the Cirrus Logic EDB7XXX serial port 1 driver"
+ flavor data
+ default_value 128
+ legal_values 0 to 8192
+ description "
+ This option specifies the size of the internal buffers used
+ for the Cirrus Logic EDB7XXX port 1."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2 {
+ display "Cirrus Logic EDB7XXX serial port 2 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the ARM
+ EDB7XXX port 2."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL2_NAME {
+ display "Device name for the Cirrus Logic EDB7XXX serial port 2 driver"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the name of serial device for the ARM
+ EDB7XXX port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BAUD {
+ display "Baud rate for the Cirrus Logic EDB7XXX serial port 2 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ Cirrus Logic EDB7XXX port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE {
+ display "Buffer size for the Cirrus Logic EDB7XXX serial port 2 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the Cirrus Logic EDB7XXX port 2."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_EDB7XXX_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_EDB7XXX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_EDB7XXX_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_EDB7XXX_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL1
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL1_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"armedb7xxx\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+
+# EOF ser_arm_edb7xxx.cdl
diff --git a/ecos/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.c b/ecos/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.c
new file mode 100644
index 0000000..a2db2d1
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.c
@@ -0,0 +1,408 @@
+//==========================================================================
+//
+// io/serial/arm/edb7xxx_serial.c
+//
+// Cirrus Logic EDB7XXX Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-02-04
+// Purpose: EDB7XXX Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#ifdef CYGPKG_IO_SERIAL_ARM_EDB7XXX
+
+#include "edb7xxx_serial.h"
+
+typedef struct edb7xxx_serial_info {
+ CYG_ADDRWORD data, // Pointer to data register
+ control, // Pointer to baud rate/line control register
+ stat, // Pointer to system flags for this port
+ syscon; // Pointer to system control for this port
+ CYG_WORD tx_int_num, // Transmit interrupt number
+ rx_int_num, // Receive interrupt number
+ ms_int_num; // Modem Status Change interrupt number
+ cyg_interrupt serial_tx_interrupt,
+ serial_rx_interrupt,
+ serial_ms_interrupt;
+ cyg_handle_t serial_tx_interrupt_handle,
+ serial_rx_interrupt_handle,
+ serial_ms_interrupt_handle;
+ bool tx_enabled;
+} edb7xxx_serial_info;
+
+static bool edb7xxx_serial_init(struct cyg_devtab_entry *tab);
+static bool edb7xxx_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo edb7xxx_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char edb7xxx_serial_getc(serial_channel *chan);
+static Cyg_ErrNo edb7xxx_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void edb7xxx_serial_start_xmit(serial_channel *chan);
+static void edb7xxx_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 edb7xxx_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void edb7xxx_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static cyg_uint32 edb7xxx_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void edb7xxx_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static cyg_uint32 edb7xxx_serial_ms_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void edb7xxx_serial_ms_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(edb7xxx_serial_funs,
+ edb7xxx_serial_putc,
+ edb7xxx_serial_getc,
+ edb7xxx_serial_set_config,
+ edb7xxx_serial_start_xmit,
+ edb7xxx_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL1
+static edb7xxx_serial_info edb7xxx_serial_info1 = {UARTDR1, // Data register
+ UBLCR1, // Port control
+ SYSFLG1, // Status
+ SYSCON1, // System config
+ CYGNUM_HAL_INTERRUPT_UTXINT1, // Tx interrupt
+ CYGNUM_HAL_INTERRUPT_URXINT1, // Rx interrupt
+ 0 /*CYGNUM_HAL_INTERRUPT_UMSINT*/}; // Modem control
+#if CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE > 0
+static unsigned char edb7xxx_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE];
+static unsigned char edb7xxx_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(edb7xxx_serial_channel1,
+ edb7xxx_serial_funs,
+ edb7xxx_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &edb7xxx_serial_out_buf1[0], sizeof(edb7xxx_serial_out_buf1),
+ &edb7xxx_serial_in_buf1[0], sizeof(edb7xxx_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(edb7xxx_serial_channel1,
+ edb7xxx_serial_funs,
+ edb7xxx_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(edb7xxx_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ edb7xxx_serial_init,
+ edb7xxx_serial_lookup, // Serial driver may need initializing
+ &edb7xxx_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2
+
+#ifdef CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2
+static edb7xxx_serial_info edb7xxx_serial_info2 = {UARTDR2, // Data register
+ UBLCR2, // Port control
+ SYSFLG2, // Status
+ SYSCON2, // System config
+ CYGNUM_HAL_INTERRUPT_UTXINT2, // Tx interrupt
+ CYGNUM_HAL_INTERRUPT_URXINT2, // Rx interrupt
+ 0}; // No modem control
+#if CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE > 0
+static unsigned char edb7xxx_serial_out_buf2[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE];
+static unsigned char edb7xxx_serial_in_buf2[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(edb7xxx_serial_channel2,
+ edb7xxx_serial_funs,
+ edb7xxx_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &edb7xxx_serial_out_buf2[0], sizeof(edb7xxx_serial_out_buf2),
+ &edb7xxx_serial_in_buf2[0], sizeof(edb7xxx_serial_in_buf2)
+ );
+#else
+static SERIAL_CHANNEL(edb7xxx_serial_channel2,
+ edb7xxx_serial_funs,
+ edb7xxx_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(edb7xxx_serial_io2,
+ CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ edb7xxx_serial_init,
+ edb7xxx_serial_lookup, // Serial driver may need initializing
+ &edb7xxx_serial_channel2
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+edb7xxx_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+ volatile cyg_uint32 *syscon = (volatile cyg_uint32 *)edb7xxx_chan->syscon;
+ volatile cyg_uint32 *blcfg = (volatile cyg_uint32 *)edb7xxx_chan->control;
+ unsigned int baud_divisor = select_baud[new_config->baud];
+ cyg_uint32 _lcr;
+ if (baud_divisor == 0) return false;
+ // Disable port interrupts while changing hardware
+ _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity] |
+ UBLCR_FIFOEN | UART_BITRATE(baud_divisor);
+#ifdef CYGDBG_IO_INIT
+ diag_printf("Set CTL: %x = %x\n", blcfg, _lcr);
+#endif
+ *blcfg = _lcr;
+ *syscon |= SYSCON1_UART1EN;
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+edb7xxx_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("EDB7XXX SERIAL init - dev: %x.%d\n", edb7xxx_chan->control, edb7xxx_chan->tx_int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(edb7xxx_chan->tx_int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ edb7xxx_serial_tx_ISR,
+ edb7xxx_serial_tx_DSR,
+ &edb7xxx_chan->serial_tx_interrupt_handle,
+ &edb7xxx_chan->serial_tx_interrupt);
+ cyg_drv_interrupt_attach(edb7xxx_chan->serial_tx_interrupt_handle);
+ cyg_drv_interrupt_mask(edb7xxx_chan->tx_int_num);
+ edb7xxx_chan->tx_enabled = false;
+ }
+ if (chan->in_cbuf.len != 0) {
+ cyg_drv_interrupt_create(edb7xxx_chan->rx_int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ edb7xxx_serial_rx_ISR,
+ edb7xxx_serial_rx_DSR,
+ &edb7xxx_chan->serial_rx_interrupt_handle,
+ &edb7xxx_chan->serial_rx_interrupt);
+ cyg_drv_interrupt_attach(edb7xxx_chan->serial_rx_interrupt_handle);
+ cyg_drv_interrupt_unmask(edb7xxx_chan->rx_int_num);
+ }
+ edb7xxx_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+edb7xxx_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+edb7xxx_serial_putc(serial_channel *chan, unsigned char c)
+{
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+ volatile cyg_uint8 *data = (volatile cyg_uint8 *)edb7xxx_chan->data;
+ volatile cyg_uint32 *stat = (volatile cyg_uint32 *)edb7xxx_chan->stat;
+ if ((*stat & SYSFLG1_UTXFF1) == 0) {
+// Transmit buffer/FIFO is not full
+ *data = c;
+ return true;
+ } else {
+// No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+edb7xxx_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+ volatile cyg_uint32 *data = (volatile cyg_uint32 *)edb7xxx_chan->data;
+ volatile cyg_uint32 *stat = (volatile cyg_uint32 *)edb7xxx_chan->stat;
+ while (*stat & SYSFLG1_URXFE1) ; // Wait for char
+ c = *data;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+edb7xxx_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != edb7xxx_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter (interrupt) on the device
+static void
+edb7xxx_serial_start_xmit(serial_channel *chan)
+{
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+ edb7xxx_chan->tx_enabled = true;
+ cyg_drv_interrupt_unmask(edb7xxx_chan->tx_int_num);
+}
+
+// Disable the transmitter on the device
+static void
+edb7xxx_serial_stop_xmit(serial_channel *chan)
+{
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(edb7xxx_chan->tx_int_num);
+ edb7xxx_chan->tx_enabled = false;
+}
+
+// Serial I/O - low level Tx interrupt handler (ISR)
+static cyg_uint32
+edb7xxx_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(edb7xxx_chan->tx_int_num);
+ cyg_drv_interrupt_acknowledge(edb7xxx_chan->tx_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level Tx interrupt handler (DSR)
+static void
+edb7xxx_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+ (chan->callbacks->xmt_char)(chan);
+ if (edb7xxx_chan->tx_enabled) {
+ cyg_drv_interrupt_unmask(edb7xxx_chan->tx_int_num);
+ }
+}
+
+// Serial I/O - low level Rx interrupt handler (ISR)
+static cyg_uint32
+edb7xxx_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(edb7xxx_chan->rx_int_num);
+ cyg_drv_interrupt_acknowledge(edb7xxx_chan->rx_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level Rx interrupt handler (DSR)
+static void
+edb7xxx_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+ volatile cyg_uint32 *datreg = (volatile cyg_uint32 *)edb7xxx_chan->data;
+ volatile cyg_uint32 *stat = (volatile cyg_uint32 *)edb7xxx_chan->stat;
+ while (!(*stat & SYSFLG1_URXFE1))
+ (chan->callbacks->rcv_char)(chan, *datreg);
+ cyg_drv_interrupt_unmask(edb7xxx_chan->rx_int_num);
+}
+
+// Serial I/O - low level Ms interrupt handler (ISR)
+static cyg_uint32
+edb7xxx_serial_ms_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(edb7xxx_chan->ms_int_num);
+ cyg_drv_interrupt_acknowledge(edb7xxx_chan->ms_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level Ms interrupt handler (DSR)
+static void
+edb7xxx_serial_ms_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+}
+#endif // CYGPKG_IO_SERIAL_ARM_EDB7XXX
+
diff --git a/ecos/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.h b/ecos/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.h
new file mode 100644
index 0000000..2be9b47
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.h
@@ -0,0 +1,108 @@
+#ifndef CYGONCE_ARM_EDB7XXX_SERIAL_H
+#define CYGONCE_ARM_EDB7XXX_SERIAL_H
+
+// ====================================================================
+//
+// edb7xxx_serial.h
+//
+// Device I/O - Description of Cirrus Logic EDB7XXX serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-02-04
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports on Cirrus Logic EDB7XXX
+
+#include <cyg/hal/hal_edb7xxx.h> // Hardware definitions
+
+static unsigned int select_word_length[] = {
+ UBLCR_WRDLEN5, // 5 bits / word (char)
+ UBLCR_WRDLEN6,
+ UBLCR_WRDLEN7,
+ UBLCR_WRDLEN8
+};
+
+static unsigned int select_stop_bits[] = {
+ 0,
+ 0, // 1 stop bit
+ 0, // 1.5 stop bit
+ UBLCR_XSTOP // 2 stop bits
+};
+
+static unsigned int select_parity[] = {
+ 0, // No parity
+ UBLCR_PRTEN|UBLCR_EVENPRT, // Even parity
+ UBLCR_PRTEN, // Odd parity
+ 0, // Mark parity
+ 0, // Space parity
+};
+
+// Baud rate values, based on PLL clock
+
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 0, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 0, // 230400
+};
+
+#endif // CYGONCE_ARM_EDB7XXX_SERIAL_H
diff --git a/ecos/packages/devs/serial/arm/gps4020/current/ChangeLog b/ecos/packages/devs/serial/arm/gps4020/current/ChangeLog
new file mode 100644
index 0000000..4d23b04
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/gps4020/current/ChangeLog
@@ -0,0 +1,29 @@
+2003-11-10 Gary Thomas <gary@mlbassoc.com>
+
+ * src/gps4020_serial.c:
+
+ * cdl/ser_arm_gps4020.cdl: New package - serial driver for GPS4020
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/gps4020/current/cdl/ser_arm_gps4020.cdl b/ecos/packages/devs/serial/arm/gps4020/current/cdl/ser_arm_gps4020.cdl
new file mode 100644
index 0000000..ba4fc97
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/gps4020/current/cdl/ser_arm_gps4020.cdl
@@ -0,0 +1,208 @@
+# ====================================================================
+#
+# ser_arm_gps4020.cdl
+#
+# eCos GPS4020 serial driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_GPS4020 {
+ display "GPS4020 serial device driver"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_GPS4020
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ GPS-4020 board."
+
+ compile -library=libextras.a gps4020_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_gps4020.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_ARM_GPS4020_SERIAL1 {
+ display "GPS4020 serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the GPS4020
+ port 1."
+
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_GPS4020_SERIAL1_NAME {
+ display "Device name for the GPS4020 serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for the ARM
+ GPS4020 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL1_BAUD {
+ display "Baud rate for the GPS4020 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 57600
+ description "
+ This option specifies the default baud rate (speed) for the ARM
+ GPS4020 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL1_BUFSIZE {
+ display "Buffer size for the GPS4020 serial port 1 driver"
+ flavor data
+ default_value 128
+ legal_values 0 to 8192
+ description "
+ This option specifies the size of the internal buffers used
+ for the GPS4020 port 1."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_ARM_GPS4020_SERIAL2 {
+ display "GPS4020 serial port 2 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the ARM
+ GPS4020 port 2."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_GPS4020_SERIAL2_NAME {
+ display "Device name for the GPS4020 serial port 2 driver"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the name of serial device for the ARM
+ GPS4020 port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL2_BAUD {
+ display "Baud rate for the GPS4020 serial port 2 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 57600
+ description "
+ This option specifies the default baud rate (speed) for the
+ GPS4020 port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL2_BUFSIZE {
+ display "Buffer size for the GPS4020 serial port 2 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the GPS4020 port 2."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_GPS4020_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_GPS4020_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_GPS4020_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_GPS4020_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_GPS4020_SERIAL1
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_GPS4020_SERIAL1_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"gps4020\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+
+# EOF ser_arm_gps4020.cdl
diff --git a/ecos/packages/devs/serial/arm/gps4020/current/src/gps4020_serial.c b/ecos/packages/devs/serial/arm/gps4020/current/src/gps4020_serial.c
new file mode 100644
index 0000000..74ee83e
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/gps4020/current/src/gps4020_serial.c
@@ -0,0 +1,463 @@
+//==========================================================================
+//
+// io/serial/arm/gps4020_serial.c
+//
+// GPS4020 Serial I/O Interface Module
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-02-04
+// Purpose: GPS4020 Serial I/O module
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_if.h>
+
+#include <cyg/hal/gps4020.h> // Hardware definitions
+
+static short select_word_length[] = {
+ -1, // 5 bits / word (char)
+ -1, // 6 bits / word
+ SMR_LENGTH_7, // 7 bits/word
+ SMR_LENGTH_8 // 8 bits/word
+};
+
+static short select_stop_bits[] = {
+ -1,
+ SMR_STOP_1, // 1 stop bit
+ -1, // 1.5 stop bit
+ SMR_STOP_2 // 2 stop bits
+};
+
+static short select_parity[] = {
+ SMR_PARITY_OFF, // No parity
+ SMR_PARITY_ON|SMR_PARITY_EVEN, // Even parity
+ SMR_PARITY_ON|SMR_PARITY_ODD, // Odd parity
+ -1, // Mark parity
+ -1, // Space parity
+};
+
+// Baud rate values, based on internal system (20MHz) clock
+// Note: the extra *10 stuff is for rounding. Since these values
+// are so small, a little error here can make/break the calculation
+#define BAUD_DIVISOR(baud) (((((20000000*10)/(16*baud))+5)/10)-1)
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ BAUD_DIVISOR(50), // 50
+ BAUD_DIVISOR(75), // 75
+ BAUD_DIVISOR(110), // 110
+ 0, // 134.5
+ BAUD_DIVISOR(150), // 150
+ BAUD_DIVISOR(200), // 200
+ BAUD_DIVISOR(300), // 300
+ BAUD_DIVISOR(600), // 600
+ BAUD_DIVISOR(1200), // 1200
+ BAUD_DIVISOR(1800), // 1800
+ BAUD_DIVISOR(2400), // 2400
+ BAUD_DIVISOR(3600), // 3600
+ BAUD_DIVISOR(4800), // 4800
+ BAUD_DIVISOR(7200), // 7200
+ BAUD_DIVISOR(9600), // 9600
+ BAUD_DIVISOR(14400), // 14400
+ BAUD_DIVISOR(19200), // 19200
+ BAUD_DIVISOR(38400), // 38400
+ BAUD_DIVISOR(57600), // 57600
+ BAUD_DIVISOR(115200), // 115200
+ BAUD_DIVISOR(230400), // 230400
+};
+
+typedef struct gps4020_serial_info {
+ CYG_ADDRWORD regs; // Pointer to UART registers
+ CYG_WORD tx_int_num, // Transmit interrupt number
+ rx_int_num, // Receive interrupt number
+ ms_int_num; // Modem Status Change interrupt number
+ cyg_interrupt serial_tx_interrupt,
+ serial_rx_interrupt,
+ serial_ms_interrupt;
+ cyg_handle_t serial_tx_interrupt_handle,
+ serial_rx_interrupt_handle,
+ serial_ms_interrupt_handle;
+ bool tx_enabled;
+} gps4020_serial_info;
+
+static bool gps4020_serial_init(struct cyg_devtab_entry *tab);
+static bool gps4020_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo gps4020_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char gps4020_serial_getc(serial_channel *chan);
+static Cyg_ErrNo gps4020_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void gps4020_serial_start_xmit(serial_channel *chan);
+static void gps4020_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 gps4020_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void gps4020_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static cyg_uint32 gps4020_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void gps4020_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+#if 0 // FIXME - handle modem & errors
+static cyg_uint32 gps4020_serial_ms_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void gps4020_serial_ms_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+#endif
+
+static SERIAL_FUNS(gps4020_serial_funs,
+ gps4020_serial_putc,
+ gps4020_serial_getc,
+ gps4020_serial_set_config,
+ gps4020_serial_start_xmit,
+ gps4020_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_GPS4020_SERIAL1
+static gps4020_serial_info gps4020_serial_info1 = {GPS4020_UART1, // Data register
+ CYGNUM_HAL_INTERRUPT_UART1_TX, // Tx interrupt
+ CYGNUM_HAL_INTERRUPT_UART1_RX, // Rx interrupt
+ CYGNUM_HAL_INTERRUPT_UART1_ERR, // Modem & Error interrupt
+ };
+#if CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL1_BUFSIZE > 0
+static unsigned char gps4020_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL1_BUFSIZE];
+static unsigned char gps4020_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(gps4020_serial_channel1,
+ gps4020_serial_funs,
+ gps4020_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &gps4020_serial_out_buf1[0], sizeof(gps4020_serial_out_buf1),
+ &gps4020_serial_in_buf1[0], sizeof(gps4020_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(gps4020_serial_channel1,
+ gps4020_serial_funs,
+ gps4020_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(gps4020_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_GPS4020_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ gps4020_serial_init,
+ gps4020_serial_lookup, // Serial driver may need initializing
+ &gps4020_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_GPS4020_SERIAL2
+
+#ifdef CYGPKG_IO_SERIAL_ARM_GPS4020_SERIAL2
+static gps4020_serial_info gps4020_serial_info2 = {GPS4020_UART2, // Data register
+ CYGNUM_HAL_INTERRUPT_UART2_TX, // Tx interrupt
+ CYGNUM_HAL_INTERRUPT_UART2_RX, // Rx interrupt
+ CYGNUM_HAL_INTERRUPT_UART2_ERR, // Modem & Error interrupt
+ };
+#if CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL2_BUFSIZE > 0
+static unsigned char gps4020_serial_out_buf2[CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL2_BUFSIZE];
+static unsigned char gps4020_serial_in_buf2[CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(gps4020_serial_channel2,
+ gps4020_serial_funs,
+ gps4020_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &gps4020_serial_out_buf2[0], sizeof(gps4020_serial_out_buf2),
+ &gps4020_serial_in_buf2[0], sizeof(gps4020_serial_in_buf2)
+ );
+#else
+static SERIAL_CHANNEL(gps4020_serial_channel2,
+ gps4020_serial_funs,
+ gps4020_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_GPS4020_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(gps4020_serial_io2,
+ CYGDAT_IO_SERIAL_ARM_GPS4020_SERIAL2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ gps4020_serial_init,
+ gps4020_serial_lookup, // Serial driver may need initializing
+ &gps4020_serial_channel2
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_GPS4020_SERIAL2
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+gps4020_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+ volatile struct _gps4020_uart *regs = (volatile struct _gps4020_uart *)gps4020_chan->regs;
+ unsigned int baud_divisor = select_baud[new_config->baud];
+ short word_len = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];
+ short stop_bits = select_stop_bits[new_config->stop];
+ short parity = select_parity[new_config->parity];
+ short mode = word_len | stop_bits | parity;
+ int prescale = 0;
+
+ if (mode >= 0) {
+ while (baud_divisor > 0xFF) {
+ prescale++;
+ baud_divisor >>= 1;
+ }
+#ifdef CYGDBG_IO_INIT
+ diag_printf("I/O MODE: %x, BAUD: %x\n", mode, baud_divisor);
+ CYGACC_CALL_IF_DELAY_US((cyg_int32)2*100000);
+#endif
+ regs->mode = mode | SMR_DIV(prescale);
+ regs->baud = baud_divisor;
+ regs->modem_control = SMR_DTR | SMR_RTS;
+ regs->control = SCR_TEN | SCR_REN | SCR_TIE | SCR_RIE;
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+gps4020_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("GPS4020 SERIAL init - dev: %x.%d\n", gps4020_chan->regs, gps4020_chan->tx_int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(gps4020_chan->tx_int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ gps4020_serial_tx_ISR,
+ gps4020_serial_tx_DSR,
+ &gps4020_chan->serial_tx_interrupt_handle,
+ &gps4020_chan->serial_tx_interrupt);
+ cyg_drv_interrupt_attach(gps4020_chan->serial_tx_interrupt_handle);
+ cyg_drv_interrupt_mask(gps4020_chan->tx_int_num);
+ gps4020_chan->tx_enabled = false;
+ }
+ if (chan->in_cbuf.len != 0) {
+ cyg_drv_interrupt_create(gps4020_chan->rx_int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ gps4020_serial_rx_ISR,
+ gps4020_serial_rx_DSR,
+ &gps4020_chan->serial_rx_interrupt_handle,
+ &gps4020_chan->serial_rx_interrupt);
+ cyg_drv_interrupt_attach(gps4020_chan->serial_rx_interrupt_handle);
+ cyg_drv_interrupt_unmask(gps4020_chan->rx_int_num);
+ }
+ gps4020_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+gps4020_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+gps4020_serial_putc(serial_channel *chan, unsigned char c)
+{
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+ volatile struct _gps4020_uart *regs = (volatile struct _gps4020_uart *)gps4020_chan->regs;
+
+ if ((regs->status & SSR_TxEmpty) != 0) {
+ // Transmit buffer/FIFO is not full
+ regs->TxRx = c;
+ return true;
+ } else {
+ // No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+gps4020_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+ volatile struct _gps4020_uart *regs = (volatile struct _gps4020_uart *)gps4020_chan->regs;
+
+ while ((regs->status & SSR_RxFull) == 0) ; // Wait for character
+ c = regs->TxRx;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+gps4020_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != gps4020_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter (interrupt) on the device
+static void
+gps4020_serial_start_xmit(serial_channel *chan)
+{
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+ gps4020_chan->tx_enabled = true;
+ cyg_drv_interrupt_unmask(gps4020_chan->tx_int_num);
+}
+
+// Disable the transmitter on the device
+static void
+gps4020_serial_stop_xmit(serial_channel *chan)
+{
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(gps4020_chan->tx_int_num);
+ gps4020_chan->tx_enabled = false;
+}
+
+// Serial I/O - low level Tx interrupt handler (ISR)
+static cyg_uint32
+gps4020_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(gps4020_chan->tx_int_num);
+ cyg_drv_interrupt_acknowledge(gps4020_chan->tx_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level Tx interrupt handler (DSR)
+static void
+gps4020_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+ (chan->callbacks->xmt_char)(chan);
+ if (gps4020_chan->tx_enabled) {
+ cyg_drv_interrupt_unmask(gps4020_chan->tx_int_num);
+ }
+}
+
+// Serial I/O - low level Rx interrupt handler (ISR)
+static cyg_uint32
+gps4020_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(gps4020_chan->rx_int_num);
+ cyg_drv_interrupt_acknowledge(gps4020_chan->rx_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level Rx interrupt handler (DSR)
+static void
+gps4020_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+ volatile struct _gps4020_uart *regs = (volatile struct _gps4020_uart *)gps4020_chan->regs;
+
+ while ((regs->status & SSR_RxFull) != 0)
+ (chan->callbacks->rcv_char)(chan, regs->TxRx);
+ cyg_drv_interrupt_unmask(gps4020_chan->rx_int_num);
+}
+
+#if 0 // FIXME - handle modem & errors
+// Serial I/O - low level Ms interrupt handler (ISR)
+static cyg_uint32
+gps4020_serial_ms_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ gps4020_serial_info *gps4020_chan = (gps4020_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(gps4020_chan->ms_int_num);
+ cyg_drv_interrupt_acknowledge(gps4020_chan->ms_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level Ms interrupt handler (DSR)
+static void
+gps4020_serial_ms_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+}
+#endif
+
diff --git a/ecos/packages/devs/serial/arm/integrator/current/ChangeLog b/ecos/packages/devs/serial/arm/integrator/current/ChangeLog
new file mode 100644
index 0000000..a8b5209
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/integrator/current/ChangeLog
@@ -0,0 +1,47 @@
+2003-03-18 Gary Thomas <gary@mlbassoc.com>
+
+ * src/integrator_serial_with_ints.c (integrator_serial_set_config):
+ Flag for CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE is 32 bits.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_integrator.cdl: Remove irrelevant doc link.
+
+2002-03-06 Nick Garnett <nickg@redhat.com>
+
+ * cdl/ser_arm_integrator.cdl:
+ Disable testing of 57600 and 115200 baud rates. The CPUs we are
+ currently using (ARM7TDMI and ARM966E) have no cache and are too
+ slow to handle the higher baud rates in the FIFO-free UARTs we
+ have. In the future we may need to revisit this an make it
+ conditional on the CPU available.
+
+2001-10-30 Philippe Robin <Philippe.Robin@arm.com>
+2001-10-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * New package for ARM Integrator serial driver derived from
+ ARM PID serial driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/integrator/current/cdl/ser_arm_integrator.cdl b/ecos/packages/devs/serial/arm/integrator/current/cdl/ser_arm_integrator.cdl
new file mode 100644
index 0000000..44049a9
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/integrator/current/cdl/ser_arm_integrator.cdl
@@ -0,0 +1,177 @@
+# ====================================================================
+#
+# ser_arm_integrator.cdl
+#
+# eCos serial ARM/INTEGRATOR configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): David A Rusling
+# Original data: David A Rusling
+# Contributors: Philippe Robin
+# Date: November 7, 2000
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_INTEGRATOR {
+ display "ARM INTEGRATOR serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_INTEGRATOR
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ description "
+ This option enables the serial device drivers for the
+ ARM INTEGRATOR."
+
+ compile -library=libextras.a integrator_serial_with_ints.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_integrator.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL0 {
+ display "ARM INTEGRATOR serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the ARM INTEGRATOR
+ port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_NAME {
+ display "Device name for ARM INTEGRATOR serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device for the
+ ARM INTEGRATOR port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BAUD {
+ display "Baud rate for the ARM INTEGRATOR serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 234000
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ ARM INTEGRATOR port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BUFSIZE {
+ display "Buffer size for the ARM INTEGRATOR serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ARM INTEGRATOR port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL1 {
+ display "ARM INTEGRATOR serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the ARM INTEGRATOR
+ port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_NAME {
+ display "Device name for ARM INTEGRATOR serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of the serial device for the
+ ARM INTEGRATOR port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BAUD {
+ display "Baud rate for the ARM INTEGRATOR serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 234000
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ ARM INTEGRATOR port 1."
+ }
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BUFSIZE {
+ display "Buffer size for the ARM INTEGRATOR serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ARM INTEGRATOR port 1."
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_INTEGRATOR_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL0
+
+ # The combination of non-FIFO UARTs and no cache means that some
+ # Integrator based systems are too slow to handle the higher baud rates.
+ implements CYGINT_IO_SERIAL_TEST_SKIP_57600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"arminteg\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_arm_integrator.cdl
diff --git a/ecos/packages/devs/serial/arm/integrator/current/src/integrator_serial.h b/ecos/packages/devs/serial/arm/integrator/current/src/integrator_serial.h
new file mode 100644
index 0000000..57bd6eb
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/integrator/current/src/integrator_serial.h
@@ -0,0 +1,213 @@
+#ifndef CYGONCE_ARM_INTEGRATOR_SERIAL_H
+#define CYGONCE_ARM_INTEGRATOR_SERIAL_H
+
+// ====================================================================
+//
+// integrator_serial.h
+//
+// Device I/O - Description of ARM INTEGRATOR serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): David A Rusling
+// Contributors: Philippe Robin
+// Date: November 7, 2000
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports on ARM INTEGRATOR7T
+
+struct serial_port {
+ unsigned char _byte[32];
+};
+
+// Little-endian version
+#if (CYG_BYTEORDER == CYG_LSBFIRST)
+
+#define reg(n) _byte[n*4]
+
+#else // Big-endian version
+
+#define reg(n) _byte[(n*4)^3]
+
+#endif
+
+/* -------------------------------------------------------------------------------
+ * From AMBA UART (PL010) Block Specification (ARM-0001-CUST-DSPC-A03)
+ * -------------------------------------------------------------------------------
+ * UART Register Offsets.
+ *
+ */
+#define AMBA_UARTDR 0x00 /* Data read or written from the interface. */
+#define AMBA_UARTRSR 0x04 /* Receive status register (Read). */
+#define AMBA_UARTECR 0x04 /* Error clear register (Write). */
+#define AMBA_UARTLCR_H 0x08 /* Line control register, high byte. */
+#define AMBA_UARTLCR_M 0x0C /* Line control register, middle byte. */
+#define AMBA_UARTLCR_L 0x10 /* Line control register, low byte. */
+#define AMBA_UARTCR 0x14 /* Control register. */
+#define AMBA_UARTFR 0x18 /* Flag register (Read only). */
+#define AMBA_UARTIIR 0x1C /* Interrupt indentification register (Read). */
+#define AMBA_UARTICR 0x1C /* Interrupt clear register (Write). */
+#define AMBA_UARTILPR 0x20 /* IrDA low power counter register. */
+
+#define AMBA_UARTRSR_OE 0x08
+#define AMBA_UARTRSR_BE 0x04
+#define AMBA_UARTRSR_PE 0x02
+#define AMBA_UARTRSR_FE 0x01
+
+#define AMBA_UARTFR_TXFF 0x20
+#define AMBA_UARTFR_RXFE 0x10
+#define AMBA_UARTFR_BUSY 0x08
+#define AMBA_UARTFR_TMSK (AMBA_UARTFR_TXFF + AMBA_UARTFR_BUSY)
+
+#define AMBA_UARTCR_RTIE 0x40
+#define AMBA_UARTCR_TIE 0x20
+#define AMBA_UARTCR_RIE 0x10
+#define AMBA_UARTCR_MSIE 0x08
+#define AMBA_UARTCR_IIRLP 0x04
+#define AMBA_UARTCR_SIREN 0x02
+#define AMBA_UARTCR_UARTEN 0x01
+
+#define AMBA_UARTLCR_H_WLEN_8 0x60
+#define AMBA_UARTLCR_H_WLEN_7 0x40
+#define AMBA_UARTLCR_H_WLEN_6 0x20
+#define AMBA_UARTLCR_H_WLEN_5 0x00
+#define AMBA_UARTLCR_H_FEN 0x10
+#define AMBA_UARTLCR_H_STP2 0x08
+#define AMBA_UARTLCR_H_EPS 0x04
+#define AMBA_UARTLCR_H_PEN 0x02
+#define AMBA_UARTLCR_H_BRK 0x01
+
+#define AMBA_UARTIIR_RTIS 0x08
+#define AMBA_UARTIIR_TIS 0x04
+#define AMBA_UARTIIR_RIS 0x02
+#define AMBA_UARTIIR_MIS 0x01
+
+#define ARM_BAUD_460800 1
+#define ARM_BAUD_230400 3
+#define ARM_BAUD_115200 7
+#define ARM_BAUD_57600 15
+#define ARM_BAUD_38400 23
+#define ARM_BAUD_19200 47
+#define ARM_BAUD_14400 63
+#define ARM_BAUD_9600 95
+#define ARM_BAUD_4800 191
+#define ARM_BAUD_2400 383
+#define ARM_BAUD_1200 767
+
+// Interrupt Enable Register
+#define IER_RCV 0x01
+#define IER_XMT 0x02
+#define IER_LS 0x04
+#define IER_MS 0x08
+
+// Line Control Register
+#define LCR_WL5 0x00 // Word length
+#define LCR_WL6 0x20
+#define LCR_WL7 0x40
+#define LCR_WL8 0x60
+
+#define LCR_SB1 0x00 // Number of stop bits
+#define LCR_SB1_5 0x00 // 1.5 -> only valid with 5 bit words
+#define LCR_SB2 0x08
+
+#define LCR_PN 0x00 // Parity mode - none
+#define LCR_PE 0x06 // Parity mode - even
+#define LCR_PO 0x02 // Parity mode - odd
+#define LCR_PM 0x00 // Forced "mark" parity
+#define LCR_PS 0x00 // Forced "space" parity
+
+// Line Status Register
+#define LSR_RSR 0x01
+#define LSR_THE 0x20
+
+// Modem Control Register
+#define MCR_DTR 0x01
+#define MCR_RTS 0x02
+#define MCR_INT 0x08 // Enable interrupts
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 0, // 110
+ 0, // 134.5
+ 0, // 150
+ 0, // 200
+ 0, // 300
+ 0, // 600
+ ARM_BAUD_1200, // 1200
+ 0, // 1800
+ ARM_BAUD_2400, // 2400
+ 0, // 3600
+ ARM_BAUD_4800, // 4800
+ 0, // 7200
+ ARM_BAUD_9600, // 9600
+ ARM_BAUD_14400, // 14400
+ ARM_BAUD_19200, // 19200
+ ARM_BAUD_38400, // 38400
+ ARM_BAUD_57600, // 57600
+ ARM_BAUD_115200, // 115200
+ ARM_BAUD_230400, // 230400
+};
+
+static unsigned char select_word_length[] = {
+ LCR_WL5, // 5 bits / word (char)
+ LCR_WL6,
+ LCR_WL7,
+ LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ LCR_SB1, // 1 stop bit
+ LCR_SB1_5, // 1.5 stop bit
+ LCR_SB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ LCR_PN, // No parity
+ LCR_PE, // Even parity
+ LCR_PO, // Odd parity
+ LCR_PM, // Mark parity
+ LCR_PS, // Space parity
+};
+
+#endif // CYGONCE_ARM_INTEGRATOR_SERIAL_H
diff --git a/ecos/packages/devs/serial/arm/integrator/current/src/integrator_serial_with_ints.c b/ecos/packages/devs/serial/arm/integrator/current/src/integrator_serial_with_ints.c
new file mode 100644
index 0000000..4d2a2b7
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/integrator/current/src/integrator_serial_with_ints.c
@@ -0,0 +1,410 @@
+//==========================================================================
+//
+// io/serial/arm/integrator_serial_with_ints.c
+//
+// ARM INTEGRATOR Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): David A Rusling
+// Contributors: Philippe Robin
+// Date: November 7, 2000
+// Purpose: INTEGRATOR Serial I/O module (interrupt driven)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io.h>
+#include <pkgconf/io_serial.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#ifdef CYGPKG_IO_SERIAL_ARM_INTEGRATOR
+#include "integrator_serial.h"
+
+typedef struct integrator_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} integrator_serial_info;
+
+static bool integrator_serial_init(struct cyg_devtab_entry *tab);
+static bool integrator_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo integrator_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char integrator_serial_getc(serial_channel *chan);
+static Cyg_ErrNo integrator_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void integrator_serial_start_xmit(serial_channel *chan);
+static void integrator_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 integrator_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void integrator_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(integrator_serial_funs,
+ integrator_serial_putc,
+ integrator_serial_getc,
+ integrator_serial_set_config,
+ integrator_serial_start_xmit,
+ integrator_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL0
+#define INTEGRATOR_UART0_BASE 0x16000000 /* UART 0 */
+static integrator_serial_info integrator_serial_info0 = {INTEGRATOR_UART0_BASE, CYGNUM_HAL_INTERRUPT_UARTINT0};
+#if CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BUFSIZE > 0
+static unsigned char integrator_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BUFSIZE];
+static unsigned char integrator_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(integrator_serial_channel0,
+ integrator_serial_funs,
+ integrator_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &integrator_serial_out_buf0[0], sizeof(integrator_serial_out_buf0),
+ &integrator_serial_in_buf0[0], sizeof(integrator_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(integrator_serial_channel0,
+ integrator_serial_funs,
+ integrator_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(integrator_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_INTEGRATOR_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ integrator_serial_init,
+ integrator_serial_lookup, // Serial driver may need initializing
+ &integrator_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL1
+#define INTEGRATOR_UART1_BASE 0x17000000 /* UART 1 */
+static integrator_serial_info integrator_serial_info1 = {INTEGRATOR_UART1_BASE, CYGNUM_HAL_INTERRUPT_UARTINT1};
+#if CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BUFSIZE > 0
+static unsigned char integrator_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BUFSIZE];
+static unsigned char integrator_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(integrator_serial_channel1,
+ integrator_serial_funs,
+ integrator_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &integrator_serial_out_buf1[0], sizeof(integrator_serial_out_buf1),
+ &integrator_serial_in_buf1[0], sizeof(integrator_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(integrator_serial_channel1,
+ integrator_serial_funs,
+ integrator_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(integrator_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_INTEGRATOR_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ integrator_serial_init,
+ integrator_serial_lookup, // Serial driver may need initializing
+ &integrator_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_INTEGRATOR_SERIAL1
+
+#define GET_INTERRUPT_STATUS(p) IO_READ((p) + AMBA_UARTIIR)
+#define GET_STATUS(p) (IO_READ((p) + AMBA_UARTFR))
+#define GET_CHAR(p) (IO_READ((p) + AMBA_UARTDR))
+#define PUT_CHAR(p, c) (IO_WRITE(((p) + AMBA_UARTDR), (c)))
+#define IO_READ(p) ((*(volatile unsigned int *)(p)) & 0xFF)
+#define IO_WRITE(p, c) (*(unsigned int *)(p) = (c))
+#define RX_DATA(s) (((s) & AMBA_UARTFR_RXFE) == 0)
+#define TX_READY(s) (((s) & AMBA_UARTFR_TXFF) == 0)
+#define TX_EMPTY(p) ((GET_STATUS(p) & AMBA_UARTFR_TMSK) == 0)
+
+// debugging help
+static int chars_rx = 0 ;
+static int chars_tx = 0 ;
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+integrator_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+ unsigned int port = (unsigned int)integrator_chan->base;
+ unsigned short baud_divisor = select_baud[new_config->baud];
+ unsigned char _lcr ;
+
+ // don't do this baud rate...
+ if (baud_divisor == 0) return false; // Invalid configuration
+
+ // first, disable everything
+ IO_WRITE(port + AMBA_UARTCR, 0x0);
+
+ // Set baud rate
+ IO_WRITE(port + AMBA_UARTLCR_M, ((baud_divisor & 0xf00) >> 8));
+ IO_WRITE(port + AMBA_UARTLCR_L, (baud_divisor & 0xff));
+
+ // ----------v----------v----------v----------v----------
+ // NOTE: MUST BE WRITTEN LAST (AFTER UARTLCR_M & UARTLCR_L)
+ // ----------^----------^----------^----------^----------
+ _lcr =
+ select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity] | AMBA_UARTLCR_H_FEN ;
+ IO_WRITE(port + AMBA_UARTLCR_H, _lcr);
+
+ // finally, enable the uart
+ IO_WRITE(port + AMBA_UARTCR, (AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE | AMBA_UARTCR_UARTEN));
+
+ // save the configuration
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+
+ // success
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+integrator_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("INTEGRATOR SERIAL init - dev: %x.%d\n", integrator_chan->base, integrator_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(integrator_chan->int_num,
+ 99, // Priority - what goes here?
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ integrator_serial_ISR,
+ integrator_serial_DSR,
+ &integrator_chan->serial_interrupt_handle,
+ &integrator_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(integrator_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(integrator_chan->int_num);
+ }
+ integrator_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+integrator_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+integrator_serial_putc(serial_channel *chan, unsigned char c)
+{
+ integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+ unsigned int status = GET_STATUS(integrator_chan->base) ;
+
+ if (TX_READY(status)) {
+// Transmit buffer is empty
+ PUT_CHAR(integrator_chan->base, c) ;
+ chars_tx++ ;
+ return true;
+ } else {
+// No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+integrator_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+ unsigned int status ;
+
+ do {
+ status = GET_STATUS(integrator_chan->base) ;
+ } while (!RX_DATA(status)) ; // Wait for char
+
+ chars_rx++ ;
+
+ // get it
+ c = GET_CHAR(integrator_chan->base) ;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+integrator_serial_set_config(serial_channel *chan, cyg_uint32 key, const void *xbuf,
+ cyg_uint32 *len)
+{
+ integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != integrator_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+#ifdef FIXME
+ case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE:
+ {
+ volatile struct serial_port *port = (volatile struct serial_port *)integrator_chan->base;
+ cyg_uint32 *f = (cyg_uint32 *)xbuf;
+ unsigned char mask=0;
+ if ( *len < *f )
+ return -EINVAL;
+
+ if ( chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX )
+ mask = MCR_RTS;
+ if ( chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_RX )
+ mask |= MCR_DTR;
+ if (*f) // we should throttle
+ port->REG_mcr &= ~mask;
+ else // we should no longer throttle
+ port->REG_mcr |= mask;
+ }
+ break;
+ case CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG:
+ // Nothing to do because we do support both RTSCTS and DSRDTR flow
+ // control.
+ // Other targets would clear any unsupported flags here.
+ // We just return ENOERR.
+ break;
+#else
+#error "Flow control for Integrator not integrated!"
+#endif
+#endif
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+integrator_serial_start_xmit(serial_channel *chan)
+{
+ integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+
+ IO_WRITE(integrator_chan->base + AMBA_UARTCR,
+ IO_READ(integrator_chan->base + AMBA_UARTCR) | AMBA_UARTCR_TIE);
+}
+
+// Disable the transmitter on the device
+static void
+integrator_serial_stop_xmit(serial_channel *chan)
+{
+ integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+
+ IO_WRITE(integrator_chan->base + AMBA_UARTCR,
+ IO_READ(integrator_chan->base + AMBA_UARTCR) & ~AMBA_UARTCR_TIE);
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+integrator_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(integrator_chan->int_num);
+ cyg_drv_interrupt_acknowledge(integrator_chan->int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+integrator_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ integrator_serial_info *integrator_chan = (integrator_serial_info *)chan->dev_priv;
+ volatile unsigned char isr = GET_INTERRUPT_STATUS(integrator_chan->base) ;
+
+ while ((isr & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_TIS | AMBA_UARTIIR_RIS)) != 0) {
+ if (isr & AMBA_UARTIIR_TIS) {
+ (chan->callbacks->xmt_char)(chan);
+ } else if (isr & AMBA_UARTIIR_RTIS) {
+ chars_rx++ ;
+ (chan->callbacks->rcv_char)(chan, GET_CHAR(integrator_chan->base));
+ } else if (isr & AMBA_UARTIIR_RIS) {
+ chars_rx++ ;
+ (chan->callbacks->rcv_char)(chan, GET_CHAR(integrator_chan->base));
+ }
+ isr = GET_INTERRUPT_STATUS(integrator_chan->base) ;
+ }
+ cyg_drv_interrupt_unmask(integrator_chan->int_num);
+}
+#endif
diff --git a/ecos/packages/devs/serial/arm/iop310/current/ChangeLog b/ecos/packages/devs/serial/arm/iop310/current/ChangeLog
new file mode 100644
index 0000000..4acc098
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/iop310/current/ChangeLog
@@ -0,0 +1,41 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_iop310.cdl: Remove irrelevant doc link.
+
+2002-11-12 Gary Thomas <gary@mlbassoc.com>
+
+ * include/arm_iop310_ser.inl:
+ * cdl/ser_arm_iop310.cdl: New Xscale platforms layout.
+
+2001-09-03 Jesper Skov <jskov@redhat.com>
+
+ * include/arm_iq80310_ser.inl: Fix interrupt vector name typos.
+
+2000-10-25 Mark Salter <msalter@redhat.com>
+
+ * include/arm_iq80310_ser.inl: Initial checkin.
+ * cdl/ser_arm_iq80310.cdl: Ditto.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/iop310/current/cdl/ser_arm_iop310.cdl b/ecos/packages/devs/serial/arm/iop310/current/cdl/ser_arm_iop310.cdl
new file mode 100644
index 0000000..b9d5e23
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/iop310/current/cdl/ser_arm_iop310.cdl
@@ -0,0 +1,197 @@
+# ====================================================================
+#
+# ser_arm_iop310.cdl
+#
+# eCos serial IQ80200/80310 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data: msalter, gthomas
+# Contributors:
+# Date: 2000-10-10
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_XSCALE_IOP310 {
+ display "XScale IOP310 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_XSCALE_IOP310
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ Xscale board using the IOP310 chipset."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 1"
+ }
+
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/arm_iop310_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_arm_xscale_iop310.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_IOP310_SERIAL0 {
+ display "ARM Xscale IOP310 serial port 0 driver"
+ flavor bool
+ default_value 1
+ active_if { CYGHWR_HAL_ARM_IQ80310_SERIAL_PORTA != 0 }
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the
+ Xscale IOP310 port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_IOP310_SERIAL0_NAME {
+ display "Device name for IOP310 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device
+ for the Xscale IOP310 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL0_BAUD {
+ display "Baud rate for the Xscale IOP310 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the Xscale IOP310 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL0_BUFSIZE {
+ display "Buffer size for the Xscale IOP310 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the Xscale IOP310 port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_IOP310_SERIAL1 {
+ display "ARM Xscale IOP310 serial port 1 driver"
+ flavor bool
+ default_value 1
+ active_if { CYGHWR_HAL_ARM_IQ80310_SERIAL_PORTB != 0 }
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the Xscale
+ IOP310 port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_IOP310_SERIAL1_NAME {
+ display "Device name for IOP310 serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of the serial device
+ for the Xscale IOP310 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL1_BAUD {
+ display "Baud rate for the Xscale IOP310 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the Xscale IOP310 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL1_BUFSIZE {
+ display "Buffer size for the Xscale IOP310 serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the Xscale IOP310 port 1."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_IOP310_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_IOP310_SERIAL0
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_IOP310_SERIAL1_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"iop310\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_arm_iop310.cdl
diff --git a/ecos/packages/devs/serial/arm/iop310/current/include/arm_iop310_ser.inl b/ecos/packages/devs/serial/arm/iop310/current/include/arm_iop310_ser.inl
new file mode 100644
index 0000000..c6eb5c2
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/iop310/current/include/arm_iop310_ser.inl
@@ -0,0 +1,161 @@
+//==========================================================================
+//
+// io/serial/arm/arm_iop310_ser.inl
+//
+// Cyclone IOP310 Serial I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: msalter
+// Date: 2000-10-10
+// Purpose: IOP310 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 1047, // 110
+ 0, // 134.5
+ 768, // 150
+ 0, // 200
+ 384, // 300
+ 192, // 600
+ 96, // 1200
+ 24, // 1800
+ 48, // 2400
+ 0, // 3600
+ 24, // 4800
+ 16, // 7200
+ 12, // 9600
+ 8, // 14400
+ 6, // 19200
+ 3, // 38400
+ 2, // 57600
+ 1, // 115200
+};
+
+#ifdef CYGPKG_IO_SERIAL_ARM_IOP310_SERIAL0
+static pc_serial_info iop310_serial_info0 = {IOP310_SERIAL_PORT_A,
+ CYGNUM_HAL_INTERRUPT_SERIAL_A};
+#if CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL0_BUFSIZE > 0
+static unsigned char iop310_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL0_BUFSIZE];
+static unsigned char iop310_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(iop310_serial_channel0,
+ pc_serial_funs,
+ iop310_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &iop310_serial_out_buf0[0], sizeof(iop310_serial_out_buf0),
+ &iop310_serial_in_buf0[0], sizeof(iop310_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(iop310_serial_channel0,
+ pc_serial_funs,
+ iop310_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(iop310_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_IOP310_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &iop310_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_IOP310_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_ARM_IOP310_SERIAL1
+static pc_serial_info iop310_serial_info1 = {IOP310_SERIAL_PORT_B,
+ CYGNUM_HAL_INTERRUPT_SERIAL_B};
+#if CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL1_BUFSIZE > 0
+static unsigned char iop310_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL1_BUFSIZE];
+static unsigned char iop310_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(iop310_serial_channel1,
+ pc_serial_funs,
+ iop310_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &iop310_serial_out_buf1[0], sizeof(iop310_serial_out_buf1),
+ &iop310_serial_in_buf1[0], sizeof(iop310_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(iop310_serial_channel1,
+ pc_serial_funs,
+ iop310_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_IOP310_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(iop310_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_IOP310_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &iop310_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_IOP310_SERIAL1
+
+// EOF arm_iop310_ser.inl
diff --git a/ecos/packages/devs/serial/arm/iq80321/current/ChangeLog b/ecos/packages/devs/serial/arm/iq80321/current/ChangeLog
new file mode 100644
index 0000000..8c31537
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/iq80321/current/ChangeLog
@@ -0,0 +1,33 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_iq80321.cdl: Remove irrelevant doc link.
+
+2002-01-25 Nick Garnett <nickg@redhat.com>
+
+ * include/arm_iq80321_ser.inl:
+ * cdl/ser_arm_iq80321.cdl:
+ IQ80321 files created, by copying the IQ80310 versions and editing.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/iq80321/current/cdl/ser_arm_iq80321.cdl b/ecos/packages/devs/serial/arm/iq80321/current/cdl/ser_arm_iq80321.cdl
new file mode 100644
index 0000000..41396aa
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/iq80321/current/cdl/ser_arm_iq80321.cdl
@@ -0,0 +1,150 @@
+# ====================================================================
+#
+# ser_arm_iq80321.cdl
+#
+# eCos serial IQ80321 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data: msalter
+# Contributors:
+# Date: 2000-10-10
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_IQ80321 {
+ display "XScale IQ80321 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_XSCALE_IQ80321
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ IQ80321 evaluation board."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 1"
+ }
+
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/arm_iq80321_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_arm_iq80321.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_IQ80321_SERIAL0 {
+ display "ARM IQ80321 serial port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the Cyclone
+ IQ80321 port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_IQ80321_SERIAL0_NAME {
+ display "Device name for IQ80321 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device
+ for the Cyclone IQ80321 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_IQ80321_SERIAL0_BAUD {
+ display "Baud rate for the Cyclone IQ80321 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 115200
+ description "
+ This option specifies the default baud rate (speed)
+ for the Cyclone IQ80321 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_IQ80321_SERIAL0_BUFSIZE {
+ display "Buffer size for the Cyclone IQ80321 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the Cyclone IQ80321 port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_IQ80321_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_IQ80321_SERIAL0
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_IQ80321_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"iq80321\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_arm_iq80321.cdl
diff --git a/ecos/packages/devs/serial/arm/iq80321/current/include/arm_iq80321_ser.inl b/ecos/packages/devs/serial/arm/iq80321/current/include/arm_iq80321_ser.inl
new file mode 100644
index 0000000..3affcf2
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/iq80321/current/include/arm_iq80321_ser.inl
@@ -0,0 +1,122 @@
+//==========================================================================
+//
+// io/serial/arm/arm_iq80321_ser.inl
+//
+// IQ80321 Serial I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: msalter
+// Date: 2000-10-10
+// Purpose: IQ80321 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/iq80321.h> // platform definitions
+
+//-----------------------------------------------------------------------------
+// Baud rate specification
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 1047, // 110
+ 0, // 134.5
+ 768, // 150
+ 0, // 200
+ 384, // 300
+ 192, // 600
+ 96, // 1200
+ 24, // 1800
+ 48, // 2400
+ 0, // 3600
+ 24, // 4800
+ 16, // 7200
+ 12, // 9600
+ 8, // 14400
+ 6, // 19200
+ 3, // 38400
+ 2, // 57600
+ 1, // 115200
+};
+
+#ifdef CYGPKG_IO_SERIAL_ARM_IQ80321_SERIAL0
+static pc_serial_info iq80321_serial_info0 = {IQ80321_UART_ADDR,
+ CYGNUM_HAL_INTERRUPT_UART};
+#if CYGNUM_IO_SERIAL_ARM_IQ80321_SERIAL0_BUFSIZE > 0
+static unsigned char iq80321_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_IQ80321_SERIAL0_BUFSIZE];
+static unsigned char iq80321_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_IQ80321_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(iq80321_serial_channel0,
+ pc_serial_funs,
+ iq80321_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_IQ80321_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &iq80321_serial_out_buf0[0], sizeof(iq80321_serial_out_buf0),
+ &iq80321_serial_in_buf0[0], sizeof(iq80321_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(iq80321_serial_channel0,
+ pc_serial_funs,
+ iq80321_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_IQ80321_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(iq80321_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_IQ80321_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &iq80321_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_IQ80321_SERIAL0
+
+// EOF arm_iq80321_ser.inl
diff --git a/ecos/packages/devs/serial/arm/lpc24xx/current/ChangeLog b/ecos/packages/devs/serial/arm/lpc24xx/current/ChangeLog
new file mode 100755
index 0000000..90a9c0e
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/lpc24xx/current/ChangeLog
@@ -0,0 +1,39 @@
+2011-12-21 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/ser_arm_lpc24xx.cdl:
+ Fixed interrupt priority. [ Bugzilla 1001432 ]
+
+2010-12-29 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/ser_arm_lpc24xx.cdl:
+ * include/arm_lpc24xx_ser.inl:
+ Added support for LPC17XX CPUs.
+
+2008-07-07 Uwe Kindler <uwe_kindler@web.de>
+
+ * include/arm_lpc24xx_ser.inl:
+ Serial driver for ARM LPC24XX, using generic 16X5X driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/lpc24xx/current/cdl/ser_arm_lpc24xx.cdl b/ecos/packages/devs/serial/arm/lpc24xx/current/cdl/ser_arm_lpc24xx.cdl
new file mode 100755
index 0000000..87a2f5f
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/lpc24xx/current/cdl/ser_arm_lpc24xx.cdl
@@ -0,0 +1,192 @@
+# ====================================================================
+#
+# ser_arm_lpc24xx.cdl
+#
+# eCos serial ARM LPC24XX / Cortex-M LPC17XX configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Uwe Kindler
+# Original data: gthomas, jskov
+# Contributors: ilijak
+# Date: 2008-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_ARM_LPC24XX {
+ display "ARM LPC24XX / Cortex-M LPC17XX serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if ( CYGPKG_HAL_ARM_LPC24XX || CYGPKG_HAL_CORTEXM_LPC17XX )
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the ARM
+ LPC24XX and Cortex-M LPC17XX."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 4"
+ }
+
+ requires {
+ is_active(CYGPKG_HAL_CORTEXM_LPC17XX)
+ implies CYGPKG_IO_SERIAL_GENERIC_16X5X_XMIT_REQUIRE_PRIME == "1"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/arm_lpc24xx_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_arm_lpc24xx.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ # For backward compatibility with LPC24XX platforms
+ cdl_option CYGNUM_IO_SERIAL_IRQ_PRIORITY_MIN {
+ display "Interrupt priority levels"
+ flavor data
+ calculated { CYGNUM_HAL_IRQ_PRIORITY_MIN ? CYGNUM_HAL_IRQ_PRIORITY_MIN : 15 }
+ description "
+ For backward compatibility with LPC 24XX plarforms that
+ do not have CYGNUM_HAL_IRQ_PRIORITY_MIN defined."
+ }
+
+ # Support up to 4 on-chip UART modules. The number may vary between
+ # processor variants so it is easy to update this here
+ for { set ::channel 0 } { $::channel < 4 } { incr ::channel } {
+
+ cdl_interface CYGINT_IO_SERIAL_LPC24XX_UART[set ::channel] {
+ display "Platform provides UART [set ::channel]"
+ flavor bool
+ description "
+ This interface will be implemented if the specific
+ LPC24XX / LPC17XX processor being used has on-chip UART
+ [set ::channel], and if that UART is accessible on the
+ target hardware."
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL[set ::channel] {
+ display "ARM LPC24XX / Cortex LPC17XX UART [set ::channel] driver"
+ flavor bool
+ active_if CYGINT_IO_SERIAL_LPC24XX_UART[set ::channel]
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the
+ ARM LPC24XX / LPC17XX UART [set ::channel]."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL[set ::channel]_NAME {
+ display "Device name for UART [set ::channel]"
+ flavor data
+ default_value [format {"\"/dev/ser%d\""} $::channel]
+ description "
+ This option specifies the name of the serial device
+ for the ARM LPC24XX / LPC17XX UART [set ::channel]."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL[set ::channel]_BAUD {
+ display "Baud rate for UART [set ::channel]"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800
+ 2400 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the ARM LPC24XX / LPC17XX UART [set ::channel]."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL[set ::channel]_BUFSIZE {
+ display "Buffer size for the UART [set ::channel]"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the ARM LPC24XX / LPC17XX UART [set ::channel]."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL[set ::channel]_INTPRIO {
+ display "Interrupt priority of UART [set ::channel]"
+ flavor data
+ legal_values 0 to CYGNUM_IO_SERIAL_IRQ_PRIORITY_MIN
+ default_value CYGNUM_IO_SERIAL_IRQ_PRIORITY_MIN
+ description "
+ This option selects the interupt priority for
+ the UART [set ::channel] interrupts. The
+ reset value of these registers defaults all interrupt
+ to the lowest priority, allowing a single write to
+ elevate the priority of an individual interrupt."
+ }
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_LPC24XX_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL0
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"armlpc24xx\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_arm_lpc24xx.cdl
diff --git a/ecos/packages/devs/serial/arm/lpc24xx/current/include/arm_lpc24xx_ser.inl b/ecos/packages/devs/serial/arm/lpc24xx/current/include/arm_lpc24xx_ser.inl
new file mode 100755
index 0000000..a178846
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/lpc24xx/current/include/arm_lpc24xx_ser.inl
@@ -0,0 +1,350 @@
+//==========================================================================
+//
+// io/serial/arm/arm_lpc24xx_ser.inl
+//
+// ARM LPC24XX / Cortex-M LPC17XX Serial I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Uwe Kindler
+// Contributors: gthomas, jlarmour, ilijak
+// Date: 2008-06-07
+// Purpose: LPC24XX and LPC17XX Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+//==========================================================================
+// INCLUDES
+//==========================================================================
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGPKG_HAL_CORTEXM_LPC17XX
+# include <cyg/hal/lpc17xx_misc.h>
+#else
+# include <cyg/hal/lpc24xx_misc.h>
+#endif
+
+//==========================================================================
+// STATIC DATA
+//==========================================================================
+// Baud rate specification
+static const unsigned int select_baud[] =
+{
+ 9999, // Unused
+ 50,
+ 75,
+ 110,
+ 134.5,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 3600,
+ 4800,
+ 7200,
+ 9600,
+ 14400,
+ 19200,
+ 38400,
+ 57600,
+ 115200,
+ 230400
+};
+
+
+//==========================================================================
+// Return baudrate devisor for certain baudrate
+//==========================================================================
+unsigned short lpc24xx_baud_generator(pc_serial_info *ser_chan,
+ cyg_serial_baud_rate_t baud)
+{
+ cyg_uint8 pclk_id = CYNUM_HAL_LPC24XX_PCLK_UART0;
+ switch (ser_chan->base)
+ {
+ case CYGARC_HAL_LPC24XX_REG_UART0_BASE:
+ pclk_id = CYNUM_HAL_LPC24XX_PCLK_UART0;
+ break;
+
+ case CYGARC_HAL_LPC24XX_REG_UART1_BASE:
+ pclk_id = CYNUM_HAL_LPC24XX_PCLK_UART1;
+ break;
+
+ case CYGARC_HAL_LPC24XX_REG_UART2_BASE:
+ pclk_id = CYNUM_HAL_LPC24XX_PCLK_UART2;
+ break;
+
+ case CYGARC_HAL_LPC24XX_REG_UART3_BASE:
+ pclk_id = CYNUM_HAL_LPC24XX_PCLK_UART3;
+ break;
+
+ default:
+ CYG_FAIL("Invalid UART base address");
+ } // (ser_chan->base)
+
+ return CYG_HAL_ARM_LPC24XX_BAUD_GENERATOR(pclk_id, select_baud[baud]);
+}
+
+
+#define CYG_IO_SERIAL_GENERIC_16X5X_CHAN_BAUD_GENERATOR(_ser_chan_, _baud_) \
+ lpc24xx_baud_generator((_ser_chan_), (_baud_))
+
+
+
+//==========================================================================
+// SERIAL CHANNEL 0
+//==========================================================================
+#ifdef CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL0
+static pc_serial_info lpc24xx_serial_info0 =
+{
+ CYGARC_HAL_LPC24XX_REG_UART0_BASE,
+ CYGNUM_HAL_INTERRUPT_UART0,
+ CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_INTPRIO
+};
+
+#if CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_BUFSIZE > 0
+static unsigned char
+lpc24xx_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_BUFSIZE];
+static unsigned char
+lpc24xx_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(lpc24xx_serial_channel0,
+ pc_serial_funs,
+ lpc24xx_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &lpc24xx_serial_out_buf0[0],
+ sizeof(lpc24xx_serial_out_buf0),
+ &lpc24xx_serial_in_buf0[0],
+ sizeof(lpc24xx_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(lpc24xx_serial_channel0,
+ pc_serial_funs,
+ lpc24xx_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(lpc24xx_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL0_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &lpc24xx_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL0
+
+
+//==========================================================================
+// SERIAL CHANNEL 1
+//==========================================================================
+#ifdef CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL1
+static pc_serial_info lpc24xx_serial_info1 =
+{
+ CYGARC_HAL_LPC24XX_REG_UART1_BASE,
+ CYGNUM_HAL_INTERRUPT_UART1,
+ CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_INTPRIO
+};
+
+#if CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_BUFSIZE > 0
+static unsigned char
+lpc24xx_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_BUFSIZE];
+static unsigned char
+lpc24xx_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(lpc24xx_serial_channel1,
+ pc_serial_funs,
+ lpc24xx_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &lpc24xx_serial_out_buf1[0],
+ sizeof(lpc24xx_serial_out_buf1),
+ &lpc24xx_serial_in_buf1[0],
+ sizeof(lpc24xx_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(lpc24xx_serial_channel1,
+ pc_serial_funs,
+ lpc24xx_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(lpc24xx_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL1_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &lpc24xx_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL1
+
+
+//==========================================================================
+// SERIAL CHANNEL 2
+//==========================================================================
+#ifdef CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL2
+static pc_serial_info lpc24xx_serial_info2 =
+{
+ CYGARC_HAL_LPC24XX_REG_UART2_BASE,
+ CYGNUM_HAL_INTERRUPT_UART2,
+ CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_INTPRIO
+};
+
+#if CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_BUFSIZE > 0
+static unsigned char
+lpc24xx_serial_out_buf2[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_BUFSIZE];
+static unsigned char
+lpc24xx_serial_in_buf2[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(lpc24xx_serial_channel2,
+ pc_serial_funs,
+ lpc24xx_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &lpc24xx_serial_out_buf2[0],
+ sizeof(lpc24xx_serial_out_buf2),
+ &lpc24xx_serial_in_buf2[0],
+ sizeof(lpc24xx_serial_in_buf2)
+ );
+#else
+static SERIAL_CHANNEL(lpc24xx_serial_channel2,
+ pc_serial_funs,
+ lpc24xx_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(lpc24xx_serial_io2,
+ CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL2_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &lpc24xx_serial_channel2
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL2
+
+
+//==========================================================================
+// SERIAL CHANNEL 3
+//==========================================================================
+#ifdef CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL3
+static pc_serial_info lpc24xx_serial_info3 =
+{
+ CYGARC_HAL_LPC24XX_REG_UART3_BASE,
+ CYGNUM_HAL_INTERRUPT_UART3,
+ CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_INTPRIO
+};
+
+#if CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_BUFSIZE > 0
+static unsigned char
+lpc24xx_serial_out_buf3[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_BUFSIZE];
+static unsigned char
+lpc24xx_serial_in_buf3[CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(lpc24xx_serial_channel3,
+ pc_serial_funs,
+ lpc24xx_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &lpc24xx_serial_out_buf3[0],
+ sizeof(lpc24xx_serial_out_buf3),
+ &lpc24xx_serial_in_buf3[0],
+ sizeof(lpc24xx_serial_in_buf3)
+ );
+#else
+static SERIAL_CHANNEL(lpc24xx_serial_channel3,
+ pc_serial_funs,
+ lpc24xx_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC24XX_SERIAL3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(lpc24xx_serial_io3,
+ CYGDAT_IO_SERIAL_ARM_LPC24XX_SERIAL3_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &lpc24xx_serial_channel3
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_LPC24XX_SERIAL3
+
+
+//----------------------------------------------------------------------------
+// EOF arm_lpc2xxx_ser.inl
diff --git a/ecos/packages/devs/serial/arm/lpc2xxx/current/ChangeLog b/ecos/packages/devs/serial/arm/lpc2xxx/current/ChangeLog
new file mode 100644
index 0000000..6406ae3
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/lpc2xxx/current/ChangeLog
@@ -0,0 +1,46 @@
+2008-11-23 Martin Laabs <martin.laabs@mailbox.tu-dresden.de>
+ Andrew Lunn <andrew@lunn.ch>
+
+ * cdl/ser_arm_lpc2xxx.cdl:
+ * include/arm_lpc2xxx_ser.inl: Ensure the serial interrupts are
+ using different priorities, otherwise we get spurious interrupts.
+
+2007-06-22 Alexander Aganichev <aaganichev@gmail.com>
+
+ * cdl/ser_arm_lpc2xxx.cdl:
+ Added requirement of
+ CYGPKG_IO_SERIAL_GENERIC_16X5X_XMIT_REQUIRE_PRIME option.
+
+2004-11-15 Jani Monoses <jani@iv.ro>
+
+ * include/arm_lpc2xxx_ser.inl:
+ Get rid of unused external function declaration.
+
+2004-09-12 Jani Monoses <jani@iv.ro>
+
+ * include/arm_lpc2xxx_ser.inl:
+ Serial driver for ARM LPC2XXX, using generic 16X5X driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/lpc2xxx/current/cdl/ser_arm_lpc2xxx.cdl b/ecos/packages/devs/serial/arm/lpc2xxx/current/cdl/ser_arm_lpc2xxx.cdl
new file mode 100644
index 0000000..8afb6b8
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/lpc2xxx/current/cdl/ser_arm_lpc2xxx.cdl
@@ -0,0 +1,226 @@
+# ====================================================================
+#
+# ser_arm_lpc2xxx.cdl
+#
+# eCos serial ARM/LPC2XXX configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_ARM_LPC2XXX {
+ display "ARM LPC2XXX serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_LPC2XXX
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO
+
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ ARM LPC2XXX."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 4"
+ }
+
+ requires { CYGPKG_IO_SERIAL_GENERIC_16X5X_XMIT_REQUIRE_PRIME == "1" }
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/arm_lpc2xxx_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_arm_lpc2xxx.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_LPC2XXX_SERIAL0 {
+ display "ARM LPC2XXX serial port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the ARM
+ LPC2XXX port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_LPC2XXX_SERIAL0_NAME {
+ display "Device name for ARM LPC2XXX serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device
+ for the ARM LPC2XXX port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BAUD {
+ display "Baud rate for the ARM LPC2XXX serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the ARM LPC2XXX port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE {
+ display "Buffer size for the ARM LPC2XXX serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the ARM LPC2XXX port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_INTPRIO {
+ display "Interrupt priority of the serial port 0 ISR"
+ flavor data
+ legal_values 0 to 15
+ default_value 14
+ requires { is_active(CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_INTPRIO)
+ implies CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_INTPRIO !=
+ CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_INTPRIO
+ }
+ description "
+ This option specifies the interrupt priority of the
+ ISR of the serial port 0 interrupt in the VIC.
+ Slot 0 has the highest priority and slot 15 the lowest."
+ }
+
+
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_LPC2XXX_SERIAL1 {
+ display "ARM LPC2XXX serial port 1 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the ARM
+ LPC2XXX port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_LPC2XXX_SERIAL1_NAME {
+ display "Device name for ARM LPC2XXX serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of the serial device
+ for the ARM LPC2XXX port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_BAUD {
+ display "Baud rate for the ARM LPC2XXX serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the ARM LPC2XXX port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_BUFSIZE {
+ display "Buffer size for the ARM LPC2XXX serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal
+ buffers used for the ARM LPC2XXX port 1."
+ }
+
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_INTPRIO {
+ display "Interrupt priority of the serial port 1 ISR"
+ flavor data
+ legal_values 0 to 15
+ default_value 15
+ description "
+ This option specifies the interrupt priority of the
+ ISR of the serial port 1 interrupt in the VIC.
+ Slot 0 has the highest priority and slot 15 the lowest."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_LPC2XXX_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_LPC2XXX_SERIAL0
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_LPC2XXX_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"armlpc2xxx\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_arm_lpc2xxx.cdl
diff --git a/ecos/packages/devs/serial/arm/lpc2xxx/current/include/arm_lpc2xxx_ser.inl b/ecos/packages/devs/serial/arm/lpc2xxx/current/include/arm_lpc2xxx_ser.inl
new file mode 100644
index 0000000..89efb49
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/lpc2xxx/current/include/arm_lpc2xxx_ser.inl
@@ -0,0 +1,185 @@
+//==========================================================================
+//
+// io/serial/arm/arm_lpc2xxx_ser.inl
+//
+// ARM LPC2XXX Serial I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jani
+// Contributors: gthomas, jlarmour
+// Date: 1999-02-04
+// Purpose: LPC2XXX Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification
+
+static unsigned int select_baud[] = {
+ 9999, // Unused
+ 50,
+ 75,
+ 110,
+ 134.5,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 3600,
+ 4800,
+ 7200,
+ 9600,
+ 14400,
+ 19200,
+ 38400,
+ 57600,
+ 115200,
+ 230400
+};
+
+// we need dynamically generated divider values because they depend on the
+// value of pclk which in turn is changeable
+
+#define CYG_IO_SERIAL_GENERIC_16X5X_BAUD_GENERATOR \
+ CYG_HAL_ARM_LPC2XXX_BAUD_GENERATOR
+
+#ifdef CYGPKG_IO_SERIAL_ARM_LPC2XXX_SERIAL0
+static pc_serial_info lpc2xxx_serial_info0 =
+ { CYGARC_HAL_LPC2XXX_REG_UART0_BASE,
+ CYGNUM_HAL_INTERRUPT_UART0,
+ CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_INTPRIO
+ };
+
+#if CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE > 0
+static unsigned char
+lpc2xxx_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE];
+static unsigned char
+lpc2xxx_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(lpc2xxx_serial_channel0,
+ pc_serial_funs,
+ lpc2xxx_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &lpc2xxx_serial_out_buf0[0],
+ sizeof(lpc2xxx_serial_out_buf0),
+ &lpc2xxx_serial_in_buf0[0],
+ sizeof(lpc2xxx_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(lpc2xxx_serial_channel0,
+ pc_serial_funs,
+ lpc2xxx_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(lpc2xxx_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_LPC2XXX_SERIAL0_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &lpc2xxx_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_LPC2XXX_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_ARM_LPC2XXX_SERIAL1
+static pc_serial_info lpc2xxx_serial_info1 =
+ { CYGARC_HAL_LPC2XXX_REG_UART1_BASE,
+ CYGNUM_HAL_INTERRUPT_UART1,
+ CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_INTPRIO
+ };
+#if CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_BUFSIZE > 0
+static unsigned char
+lpc2xxx_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_BUFSIZE];
+static unsigned char
+lpc2xxx_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(lpc2xxx_serial_channel1,
+ pc_serial_funs,
+ lpc2xxx_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &lpc2xxx_serial_out_buf1[0],
+ sizeof(lpc2xxx_serial_out_buf1),
+ &lpc2xxx_serial_in_buf1[0],
+ sizeof(lpc2xxx_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(lpc2xxx_serial_channel1,
+ pc_serial_funs,
+ lpc2xxx_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_LPC2XXX_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(lpc2xxx_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_LPC2XXX_SERIAL1_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &lpc2xxx_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_LPC2XXX_SERIAL1
+
+// EOF arm_lpc2xxx_ser.inl
diff --git a/ecos/packages/devs/serial/arm/pid/current/ChangeLog b/ecos/packages/devs/serial/arm/pid/current/ChangeLog
new file mode 100644
index 0000000..c3fae52
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/pid/current/ChangeLog
@@ -0,0 +1,213 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_pid.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_arm_pid.cdl:
+ Fix 234000->230400 typo.
+
+2000-09-18 Jesper Skov <jskov@redhat.com>
+
+ * src/pid_serial.h: [removed]
+ * src/pid_serial_with_ints.c: [removed] Moved driver to generic
+ 16x5x package.
+ * include/arm_arm7_pid_ser.inl: [added] Make use of generic
+ driver.
+ * cdl/ser_arm_pid.cdl: Matching changes.
+
+ * ChangeLog: Cleaned out non-pid entries.
+
+2000-08-24 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/pid_serial_with_ints.c (pid_serial_DSR): Remove accidental
+ OVERRUNERR check duplication
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/pid_serial_with_ints.c: Throughout, add support for line status
+ and modem status callbacks, hardware RTS/CTS and DSR/DTR flow control
+ (pid_serial_set_config): Now use keys to make
+ more flexible.
+
+ * src/pid_serial.h: Add more line status, interrupt status and modem
+ status register definitions
+
+ * cdl/ser_arm_pid.cdl: Implements flow control and line status
+ interfaces
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-06-09 Jesper Skov <jskov@redhat.com>
+
+ * src/pid_serial_with_ints.c:
+ * src/pid_serial.h:
+ Cleaned up defines and made DSR handle all received characters.
+ (Dave Airlie (airlied at parthus dot com))
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_arm_pid.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/arm/pid_serial.h: Added BE support.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv
+ interrupts properly (can't ignore them even with TO bit set).
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ Check for receive interrupt before reading.
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c:
+ Update CDL to follow naming conventions.
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change
+ so that the physical port is not modified unless the provided
+ configuration is valid.
+
+ * src/arm/pid_serial_with_ints.c:
+ Add configury for baud rate and buffer size.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo
+ in comment.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c:
+ Update device names to match CDL.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Add 'CYGDBG_IO_INIT' for control
+ of init messages.
+
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/pid/current/cdl/ser_arm_pid.cdl b/ecos/packages/devs/serial/arm/pid/current/cdl/ser_arm_pid.cdl
new file mode 100644
index 0000000..b408b60
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/pid/current/cdl/ser_arm_pid.cdl
@@ -0,0 +1,195 @@
+# ====================================================================
+#
+# ser_arm_pid.cdl
+#
+# eCos serial ARM/PID configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_PID {
+ display "ARM PID serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_PID
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ ARM PID."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 4"
+ }
+
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/arm_arm7_pid_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_arm_pid.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_PID_SERIAL0 {
+ display "ARM PID serial port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the ARM
+ PID port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_PID_SERIAL0_NAME {
+ display "Device name for ARM PID serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device
+ for the ARM PID port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BAUD {
+ display "Baud rate for the ARM PID serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the ARM PID port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE {
+ display "Buffer size for the ARM PID serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the ARM PID port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_PID_SERIAL1 {
+ display "ARM PID serial port 1 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the ARM
+ PID port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_PID_SERIAL1_NAME {
+ display "Device name for ARM PID serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of the serial device
+ for the ARM PID port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BAUD {
+ display "Baud rate for the ARM PID serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the ARM PID port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE {
+ display "Buffer size for the ARM PID serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal
+ buffers used for the ARM PID port 1."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_PID_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_PID_SERIAL0
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_PID_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"armpid\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_arm_pid.cdl
diff --git a/ecos/packages/devs/serial/arm/pid/current/include/arm_arm7_pid_ser.inl b/ecos/packages/devs/serial/arm/pid/current/include/arm_arm7_pid_ser.inl
new file mode 100644
index 0000000..1880af6
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/pid/current/include/arm_arm7_pid_ser.inl
@@ -0,0 +1,162 @@
+//==========================================================================
+//
+// io/serial/arm/arm_arm7_pid_ser.inl
+//
+// ARM PID Serial I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jlarmour
+// Date: 1999-02-04
+// Purpose: PID Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 1047, // 110
+ 0, // 134.5
+ 768, // 150
+ 0, // 200
+ 384, // 300
+ 192, // 600
+ 96, // 1200
+ 24, // 1800
+ 48, // 2400
+ 0, // 3600
+ 24, // 4800
+ 16, // 7200
+ 12, // 9600
+ 8, // 14400
+ 6, // 19200
+ 3, // 38400
+ 2, // 57600
+ 1, // 115200
+ 0, // 230400
+};
+
+#ifdef CYGPKG_IO_SERIAL_ARM_PID_SERIAL0
+static pc_serial_info pid_serial_info0 = {0x0D800000,
+ CYGNUM_HAL_INTERRUPT_SERIALA};
+#if CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE > 0
+static unsigned char pid_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE];
+static unsigned char pid_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(pid_serial_channel0,
+ pc_serial_funs,
+ pid_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &pid_serial_out_buf0[0], sizeof(pid_serial_out_buf0),
+ &pid_serial_in_buf0[0], sizeof(pid_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(pid_serial_channel0,
+ pc_serial_funs,
+ pid_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(pid_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_PID_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &pid_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_PID_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_ARM_PID_SERIAL1
+static pc_serial_info pid_serial_info1 = {0x0D800020,
+ CYGNUM_HAL_INTERRUPT_SERIALB};
+#if CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE > 0
+static unsigned char pid_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE];
+static unsigned char pid_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(pid_serial_channel1,
+ pc_serial_funs,
+ pid_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &pid_serial_out_buf1[0], sizeof(pid_serial_out_buf1),
+ &pid_serial_in_buf1[0], sizeof(pid_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(pid_serial_channel1,
+ pc_serial_funs,
+ pid_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(pid_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_PID_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &pid_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_PID_SERIAL1
+
+// EOF arm_arm7_pid_ser.inl
diff --git a/ecos/packages/devs/serial/arm/pxa2x0/current/ChangeLog b/ecos/packages/devs/serial/arm/pxa2x0/current/ChangeLog
new file mode 100644
index 0000000..0f8e620
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/pxa2x0/current/ChangeLog
@@ -0,0 +1,37 @@
+2006-11-21 Alexander Neundorf <alexander.neundorf@jenoptik.com>
+
+ * generic PXA 2X0 serial IO support, based on the IQ80321 driver
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_iq80321.cdl: Remove irrelevant doc link.
+
+2002-01-25 Nick Garnett <nickg@redhat.com>
+
+ * include/arm_iq80321_ser.inl:
+ * cdl/ser_arm_iq80321.cdl:
+ IQ80321 files created, by copying the IQ80310 versions and editing.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/pxa2x0/current/cdl/ser_arm_xscale_pxa2x0.cdl b/ecos/packages/devs/serial/arm/pxa2x0/current/cdl/ser_arm_xscale_pxa2x0.cdl
new file mode 100644
index 0000000..6c044db
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/pxa2x0/current/cdl/ser_arm_xscale_pxa2x0.cdl
@@ -0,0 +1,154 @@
+# ====================================================================
+#
+# ser_arm_xscale_pxa2x0.cdl
+#
+# eCos serial PXA 2X0 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): msalter
+# Original data: msalter
+# Contributors: Alexander Neundorf
+# Date: 21st November 2006 (last modification)
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0 {
+ display "PXA2X0 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_XSCALE_PXA2X0
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for pxa."
+ doc redirect/ecos-device-drivers.html
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 4"
+ }
+
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/arm_xscale_pxa2x0_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_arm_xscale_pxa2x0.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0 {
+ display "ARM XSCALE PXA2X0 serial port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+ implements CYGNUM_SERIAL_FLOW_RTSCTS_RX
+ implements CYGNUM_SERIAL_FLOW_RTSCTS_TX
+
+
+ description "
+ This option includes the serial device driver for the PXA 2X0."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_NAME {
+ display "Device name for PXA 2X0 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device
+ for the PXA 2X0 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BAUD {
+ display "Baud rate for the PXA2X0 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 115200
+ description "
+ This option specifies the default baud rate (speed)
+ for the PXA2X0 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BUFSIZE {
+ display "Buffer size for the serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for port 0."
+ }
+ }
+
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"pxa2x0\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+
+}
+
+# EOF ser_arm_xscale_pxa2x0.cdl
diff --git a/ecos/packages/devs/serial/arm/pxa2x0/current/include/arm_xscale_pxa2x0_ser.inl b/ecos/packages/devs/serial/arm/pxa2x0/current/include/arm_xscale_pxa2x0_ser.inl
new file mode 100644
index 0000000..0050c9d
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/pxa2x0/current/include/arm_xscale_pxa2x0_ser.inl
@@ -0,0 +1,122 @@
+//==========================================================================
+//
+// io/serial/arm/arm_xscale_pxa2x0_ser.inl
+//
+// Generic PXA 2X0 Serial I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: msalter, Alexander Neundorf
+// Date: 21st November 2006
+// Purpose: PXA2X0 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 0, // 110
+ 0, // 134.5
+ 0, // 150
+ 0, // 200
+ 0, // 300
+ 0, // 600
+ 0, // 1200
+ 0, // 1800
+ 0, // 2400
+ 0, // 3600
+ 0, // 4800
+ 0, // 7200
+ 0, // 9600
+ 64, // 14400
+ 48, // 19200
+ 24, // 38400
+ 16, // 57600
+ 8, // 115200
+};
+
+#ifdef CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0
+static pc_serial_info pxa2x0_serial_info0 = {PXA2X0_FFUART_BASE,
+ CYGNUM_HAL_INTERRUPT_FFUART};
+#if CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BUFSIZE > 0
+static unsigned char pxa2x0_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BUFSIZE];
+static unsigned char pxa2x0_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(pxa2x0_serial_channel0,
+ pc_serial_funs,
+ pxa2x0_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &pxa2x0_serial_out_buf0[0], sizeof(pxa2x0_serial_out_buf0),
+ &pxa2x0_serial_in_buf0[0], sizeof(pxa2x0_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(pxa2x0_serial_channel0,
+ pc_serial_funs,
+ pxa2x0_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(pxa2x0_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &pxa2x0_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_XSCALE_PXA2X0_SERIAL0
+
+
+// EOF arm_xscale_pxa2x0_ser.inl
diff --git a/ecos/packages/devs/serial/arm/s3c4510/current/ChangeLog b/ecos/packages/devs/serial/arm/s3c4510/current/ChangeLog
new file mode 100755
index 0000000..c886cef
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/s3c4510/current/ChangeLog
@@ -0,0 +1,38 @@
+2004-02-11 Roland Caßebohm <roland.cassebohm@visionsystem.de>
+
+ * src/s3c4510_serial.c: The UART doesn't generate an interrupt
+ before the first time a character was send. Changed
+ s3c4510_serial_start_xmit() to first try to send characters.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_s3c4510.cdl: Remove irrelevant doc link.
+
+2001-10-19 Lars Lindqvist <Lars.Lindqvist@combitechsystems.com>
+2001-10-19 Jonathan Larmour <jlarmour@redhat.com>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/s3c4510/current/cdl/ser_arm_s3c4510.cdl b/ecos/packages/devs/serial/arm/s3c4510/current/cdl/ser_arm_s3c4510.cdl
new file mode 100755
index 0000000..8795163
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/s3c4510/current/cdl/ser_arm_s3c4510.cdl
@@ -0,0 +1,112 @@
+# ====================================================================
+#
+# ser_arm_s3c4510.cdl
+#
+# eCos serial ARM/S3C4510 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Lars.Lindqvist@combitechsystems.com
+# Contributors: jlarmour
+# Date: 2001-10-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_S3C4510 {
+ display "ARM S3C4510 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+
+ active_if CYGINT_IO_SERIAL_ARM_S3C4510_REQUIRED
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This package contains serial device drivers for the
+ ARM S3C4510."
+
+ compile -library=libextras.a s3c4510_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#ifndef CYGDAT_IO_SERIAL_DEVICE_HEADER"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_s3c4510.h>"
+ puts $::cdl_system_header "#endif"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_IO_SERIAL_ARM_S3C4510_CFG";
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_S3C4510_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_S3C4510_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_S3C4510_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+}
+
+# EOF ser_arm_s3c4510.cdl
diff --git a/ecos/packages/devs/serial/arm/s3c4510/current/src/s3c4510_serial.c b/ecos/packages/devs/serial/arm/s3c4510/current/src/s3c4510_serial.c
new file mode 100755
index 0000000..5ef4cc0
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/s3c4510/current/src/s3c4510_serial.c
@@ -0,0 +1,296 @@
+//==========================================================================
+//
+// io/serial/arm/s3c4510_serial.c
+//
+// ARM S3C4510 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Lars.Lindqvist@combitechsystems.com
+// Contributors: jlarmour
+// Date: 2001-10-19
+// Purpose: ARM S3C4510 Serial I/O Interface Module (interrupt driven)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/io/serialio.h>
+#include <cyg/infra/diag.h>
+
+#if defined(CYGPKG_IO_SERIAL_ARM_S3C4510) && defined(CYGDAT_IO_SERIAL_ARM_S3C4510_INL)
+
+typedef struct s3c4510_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD tx_int_num;
+ CYG_WORD rx_int_num;
+ cyg_interrupt serial_tx_interrupt;
+ cyg_interrupt serial_rx_interrupt;
+ cyg_handle_t serial_tx_interrupt_handle;
+ cyg_handle_t serial_rx_interrupt_handle;
+ bool tx_enabled;
+} s3c4510_serial_info;
+
+static bool s3c4510_serial_init(struct cyg_devtab_entry *tab);
+static bool s3c4510_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo s3c4510_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char s3c4510_serial_getc(serial_channel *chan);
+static Cyg_ErrNo s3c4510_serial_set_config(serial_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void s3c4510_serial_start_xmit(serial_channel *chan);
+static void s3c4510_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 s3c4510_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void s3c4510_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static cyg_uint32 s3c4510_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void s3c4510_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(s3c4510_serial_funs,
+ s3c4510_serial_putc,
+ s3c4510_serial_getc,
+ s3c4510_serial_set_config,
+ s3c4510_serial_start_xmit,
+ s3c4510_serial_stop_xmit
+ );
+
+#include CYGDAT_IO_SERIAL_ARM_S3C4510_INL
+
+#include "s3c4510_serial.h"
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+s3c4510_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ s3c4510_serial_info *s3c4510_chan = (s3c4510_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)s3c4510_chan->base;
+ cyg_uint32 word_length = select_word_length[(new_config->word_length)-CYGNUM_SERIAL_WORD_LENGTH_5];
+ cyg_uint32 stop_bits = select_stop_bits[(new_config->stop)-CYGNUM_SERIAL_STOP_1];
+ cyg_uint32 parity_mode = select_parity[(new_config->parity)-CYGNUM_SERIAL_PARITY_NONE];
+ cyg_uint32 baud_divisor = select_baud[(new_config->baud)-CYGNUM_SERIAL_BAUD_50];
+ cyg_uint32 res = word_length | stop_bits | parity_mode | ULCON_SCI | ULCON_IROFF;
+ if ((word_length|stop_bits|parity_mode|baud_divisor) == U_NOT_SUPP) {
+ return false;
+ };
+ port->REG_ULCON = res;
+ port->REG_UCON = UCON_RXMINT | UCON_RXSIOFF | UCON_TXMINT | UCON_DSROFF | UCON_SBKOFF | UCON_LPBOFF;
+ port->REG_UBRDIV = baud_divisor;
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ };
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+s3c4510_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ s3c4510_serial_info *s3c4510_chan = (s3c4510_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("S3C4510 SERIAL init - dev: %x.%d.%d\n", s3c4510_chan->base, s3c4510_chan->tx_int_num, s3c4510_chan->rx_int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) { // If bufferlength > 0 then interrupts are used for tx
+ cyg_drv_interrupt_create(s3c4510_chan->tx_int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ s3c4510_serial_tx_ISR,
+ s3c4510_serial_tx_DSR,
+ &s3c4510_chan->serial_tx_interrupt_handle,
+ &s3c4510_chan->serial_tx_interrupt);
+ cyg_drv_interrupt_attach(s3c4510_chan->serial_tx_interrupt_handle);
+ cyg_drv_interrupt_mask(s3c4510_chan->tx_int_num);
+ s3c4510_chan->tx_enabled = false;
+ }
+ if (chan->in_cbuf.len != 0) { // If bufferlength > 0 then interrupts are used for rx
+ cyg_drv_interrupt_create(s3c4510_chan->rx_int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ s3c4510_serial_rx_ISR,
+ s3c4510_serial_rx_DSR,
+ &s3c4510_chan->serial_rx_interrupt_handle,
+ &s3c4510_chan->serial_rx_interrupt);
+ cyg_drv_interrupt_attach(s3c4510_chan->serial_rx_interrupt_handle);
+ cyg_drv_interrupt_unmask(s3c4510_chan->rx_int_num);
+ }
+ s3c4510_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+s3c4510_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+s3c4510_serial_putc(serial_channel *chan, unsigned char c)
+{
+ s3c4510_serial_info *s3c4510_chan = (s3c4510_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)s3c4510_chan->base;
+
+ if (port->REG_USTAT & USTAT_TBE) {
+ // Transmit buffer is empty
+ port->REG_UTXBUF = c;
+ return true;
+ } else {
+ // No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+s3c4510_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ s3c4510_serial_info *s3c4510_chan = (s3c4510_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)s3c4510_chan->base;
+ while ((port->REG_USTAT & USTAT_RDR) == 0) ; // Wait for char
+ c = port->REG_URXBUF;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+s3c4510_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != s3c4510_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+s3c4510_serial_start_xmit(serial_channel *chan)
+{
+ s3c4510_serial_info *s3c4510_chan = (s3c4510_serial_info *)chan->dev_priv;
+ s3c4510_chan->tx_enabled = true;
+ (chan->callbacks->xmt_char)(chan);
+ if (s3c4510_chan->tx_enabled) {
+ cyg_drv_interrupt_unmask(s3c4510_chan->tx_int_num);
+ }
+}
+
+// Disable the transmitter on the device
+static void
+s3c4510_serial_stop_xmit(serial_channel *chan)
+{
+ s3c4510_serial_info *s3c4510_chan = (s3c4510_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(s3c4510_chan->tx_int_num);
+ s3c4510_chan->tx_enabled = false;
+}
+
+// Serial I/O - low level tx interrupt handler (ISR)
+static cyg_uint32
+s3c4510_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ s3c4510_serial_info *s3c4510_chan = (s3c4510_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(s3c4510_chan->tx_int_num);
+ cyg_drv_interrupt_acknowledge(s3c4510_chan->tx_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level tx interrupt handler (DSR)
+static void
+s3c4510_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ s3c4510_serial_info *s3c4510_chan = (s3c4510_serial_info *)chan->dev_priv;
+ (chan->callbacks->xmt_char)(chan);
+ if (s3c4510_chan->tx_enabled) {
+ cyg_drv_interrupt_unmask(s3c4510_chan->tx_int_num);
+ }
+}
+
+// Serial I/O - low level rx interrupt handler (ISR)
+static cyg_uint32
+s3c4510_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ s3c4510_serial_info *s3c4510_chan = (s3c4510_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(s3c4510_chan->rx_int_num);
+ cyg_drv_interrupt_acknowledge(s3c4510_chan->rx_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level rx interrupt handler (DSR)
+static void
+s3c4510_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ s3c4510_serial_info *s3c4510_chan = (s3c4510_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)s3c4510_chan->base;
+ (chan->callbacks->rcv_char)(chan, port->REG_URXBUF);
+ cyg_drv_interrupt_unmask(s3c4510_chan->rx_int_num);
+}
+
+#endif // CYGPKG_IO_SERIAL_ARM_S3C4510 && CYGDAT_IO_SERIAL_ARM_S3C4510_INL
+
+// EOF s3c4510_serial.c
diff --git a/ecos/packages/devs/serial/arm/s3c4510/current/src/s3c4510_serial.h b/ecos/packages/devs/serial/arm/s3c4510/current/src/s3c4510_serial.h
new file mode 100755
index 0000000..66e837f
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/s3c4510/current/src/s3c4510_serial.h
@@ -0,0 +1,195 @@
+#ifndef CYGONCE_ARM_S3C4510_SERIAL_H
+#define CYGONCE_ARM_S3C4510_SERIAL_H
+// ====================================================================
+//
+// s3c4510_serial.h
+//
+// Device I/O - Description of ARM S3C4510 serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Lars.Lindqvist@combitechsystems.com
+// Contributors: jlarmour
+// Date: 2001-10-19
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+#include <pkgconf/hal.h> // Value CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED needed
+#include <cyg/infra/cyg_type.h> // base types
+
+// Description of serial ports on ARM S3C4510
+
+struct serial_port {
+ cyg_uint32 _reg[8];
+};
+
+#define REG(n) _reg[n]
+
+// Misc values
+#define U_NOT_SUPP (0xFFFFFFFF) // Used to indicate unsupported parameter values
+
+// Registers
+#define REG_ULCON REG(0) // Line control registers
+#define REG_UCON REG(1) // Control registers
+#define REG_USTAT REG(2) // Status registers
+#define REG_UTXBUF REG(3) // Transmit buffer registers
+#define REG_URXBUF REG(4) // Receive buffer registers
+#define REG_UBRDIV REG(5) // Baud rate divisor registers
+
+// Line Control Register Values
+#define ULCON_WL5 (0x00000000 << 0) // Word length 5
+#define ULCON_WL6 (0x00000001 << 0) // Word length 6
+#define ULCON_WL7 (0x00000002 << 0) // Word length 7
+#define ULCON_WL8 (0x00000003 << 0) // Word length 8
+#define ULCON_STB1 (0x00000000 << 2) // One stop bit
+#define ULCON_STB2 (0x00000001 << 2) // Two stop bits
+#define ULCON_PMDOFF (0x00000000 << 3) // No parity
+#define ULCON_PMDODD (0x00000004 << 3) // Odd parity
+#define ULCON_PMDEVEN (0x00000005 << 3) // Even parity
+#define ULCON_PMDFC1 (0x00000006 << 3) // Parity forced/checked as 1
+#define ULCON_PMDFC0 (0x00000007 << 3) // Parity forced/checked as 0
+#define ULCON_SCI (0x00000000 << 6) // Internal clock
+#define ULCON_SCE (0x00000001 << 6) // External clock
+#define ULCON_IROFF (0x00000000 << 7) // Normal mode
+#define ULCON_IRON (0x00000001 << 7) // IR mode
+
+// Control Register Values
+#define UCON_RXMOFF (0x00000000 << 0) // Disable Rx mode
+#define UCON_RXMINT (0x00000001 << 0) // Interrupt request Rx mode
+#define UCON_RXMDMA0 (0x00000002 << 0) // GDMA channel 0 request Rx mode
+#define UCON_RXMDMA1 (0x00000003 << 0) // GDMA channel 1 request Rx mode
+#define UCON_RXSIOFF (0x00000000 << 2) // Rx status interrupt disabled
+#define UCON_RXSION (0x00000001 << 2) // Rx status interrupt enabled
+#define UCON_TXMOFF (0x00000000 << 3) // Disable Tx mode
+#define UCON_TXMINT (0x00000001 << 3) // Interrupt request Tx mode
+#define UCON_TXMDMA0 (0x00000002 << 3) // GDMA channel 0 request Tx mode
+#define UCON_TXMDMA1 (0x00000003 << 3) // GDMA channel 1 request Tx mode
+#define UCON_DSROFF (0x00000000 << 5) // Data set ready output off
+#define UCON_DSRON (0x00000001 << 5) // Data set ready output on
+#define UCON_SBKOFF (0x00000000 << 6) // No break sent
+#define UCON_SBKON (0x00000001 << 6) // Break sent
+#define UCON_LPBOFF (0x00000000 << 7) // Loop back mode off// Baud rate divisor registers
+#define UCON_LPBON (0x00000001 << 7) // Loop back mode on^M
+
+// Status Register Values
+#define USTAT_OV (0x00000001 << 0) // Overrun error
+#define USTAT_PE (0x00000001 << 1) // Parity error
+#define USTAT_FE (0x00000001 << 2) // Frame error
+
+#define USTAT_BKD (0x00000001 << 3) // Break detect
+#define USTAT_DTR (0x00000001 << 4) // Data terminal ready
+#define USTAT_RDR (0x00000001 << 5) // Receive data ready
+#define USTAT_TBE (0x00000001 << 6) // Transmit buffer register empty
+#define USTAT_TC (0x00000001 << 7) // Transmit complete
+
+// Baud rate divisor registers
+#define UBRDIV_50 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/16/16/50)-1)<<4)|1)
+#define UBRDIV_75 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/16/16/75)-1)<<4)|1)
+#define UBRDIV_110 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/16/16/110)-1)<<4)|1)
+#define UBRDIV_134_5 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/16/8/269)-1)<<4)|1)
+#define UBRDIV_150 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/16/16/150)-1)<<4)|1)
+#define UBRDIV_200 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/16/16/200)-1)<<4)|1)
+#define UBRDIV_300 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/16/16/300)-1)<<4)|1)
+#define UBRDIV_600 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/600)-1)<<4)|0)
+#define UBRDIV_1200 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/1200)-1)<<4)|0)
+#define UBRDIV_1800 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/1800)-1)<<4)|0)
+#define UBRDIV_2400 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/2400)-1)<<4)|0)
+#define UBRDIV_3600 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/3600)-1)<<4)|0)
+#define UBRDIV_4800 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/4800)-1)<<4)|0)
+#define UBRDIV_7200 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/7200)-1)<<4)|0)
+#define UBRDIV_9600 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/9600)-1)<<4)|0)
+#define UBRDIV_14400 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/14400)-1)<<4)|0)
+#define UBRDIV_19200 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/19200)-1)<<4)|0)
+#define UBRDIV_38400 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/38400)-1)<<4)|0)
+#define UBRDIV_57600 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/57600)-1)<<4)|0)
+#define UBRDIV_115200 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/115200)-1)<<4)|0)
+#define UBRDIV_230400 ((((CYGNUM_HAL_ARM_S3C4510_CLOCK_SPEED/2/1/16/230400)-1)<<4)|0)
+
+// Arrays used for conversion of eCos serial driver
+// configuration parameters to parameters for S3C4510
+
+static cyg_uint32 select_word_length[] = {
+ ULCON_WL5, // 5 bits / word (char)
+ ULCON_WL6,
+ ULCON_WL7,
+ ULCON_WL8
+};
+
+static cyg_uint32 select_stop_bits[] = {
+ ULCON_STB1, // 1 stop bit
+ U_NOT_SUPP, // 1.5 stop bit not supported
+ ULCON_STB2 // 2 stop bits
+};
+
+static cyg_uint32 select_parity[] = {
+ ULCON_PMDOFF, // No parity
+ ULCON_PMDEVEN, // Even parity
+ ULCON_PMDODD, // Odd parity
+ ULCON_PMDFC1, // Mark parity
+ ULCON_PMDFC0, // Space parity
+};
+
+static cyg_uint32 select_baud[] = {
+ UBRDIV_50, // 50
+ UBRDIV_75, // 75
+ UBRDIV_110, // 110
+ UBRDIV_134_5, // 134.5
+ UBRDIV_150, // 150
+ UBRDIV_200, // 200
+ UBRDIV_300, // 300
+ UBRDIV_600, // 600
+ UBRDIV_1200, // 1200
+ UBRDIV_1800, // 1800
+ UBRDIV_2400, // 2400
+ UBRDIV_3600, // 3600
+ UBRDIV_4800, // 4800
+ UBRDIV_7200, // 7200
+ UBRDIV_9600, // 9600
+ UBRDIV_14400, // 14400
+ UBRDIV_19200, // 19200
+ UBRDIV_38400, // 38400
+ UBRDIV_57600, // 57600
+ UBRDIV_115200, // 115200
+ UBRDIV_230400, // 230400
+};
+
+#endif // CYGONCE_ARM_S3C4510_SERIAL_H
+
+// EOF s3c4510_serial.h
diff --git a/ecos/packages/devs/serial/arm/sa11x0/current/ChangeLog b/ecos/packages/devs/serial/arm/sa11x0/current/ChangeLog
new file mode 100644
index 0000000..4b13179
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/sa11x0/current/ChangeLog
@@ -0,0 +1,65 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_arm_sa11x0.cdl: Remove irrelevant doc link.
+
+2001-10-09 Hugo Tyson <hmt@redhat.com>
+
+ * src/sa11x0_serial.c (sa11x0_serial_DSR): Acknowledge the
+ interrupts for start or end of a line break, otherwise messing
+ with the wiring can cause an interrupt loop and hang the target.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_arm_sa11x0.cdl:
+ Fix 234000->230400 typo.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_arm_sa11x0.cdl: Testing parameters moved here.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/sa11x0_serial.c (sa11x0_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-29 Jesper Skov <jskov@redhat.com>
+
+ * src/sa11x0_serial.h:
+ * src/sa11x0_serial.c:
+ Registers renamed.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-05-10 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/ser_arm_sa11x0.cdl:
+ * src/sa11x0_serial.h:
+ * src/sa11x0_serial.c: New file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/arm/sa11x0/current/cdl/ser_arm_sa11x0.cdl b/ecos/packages/devs/serial/arm/sa11x0/current/cdl/ser_arm_sa11x0.cdl
new file mode 100644
index 0000000..979219b
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/sa11x0/current/cdl/ser_arm_sa11x0.cdl
@@ -0,0 +1,204 @@
+# ====================================================================
+#
+# ser_arm_sa11x0.cdl
+#
+# eCos serial ARM/SA11x0 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors:
+# Date: 2000-05-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_SA11X0 {
+ display "ARM SA11X0 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_SA11X0
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ StrongARM SA11X0."
+
+ compile -library=libextras.a sa11x0_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_sa11x0.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_ARM_SA11X0_SERIAL0 {
+ display "ARM SA11X0 serial port 0 driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the ARM SA11X0
+ port 0 (UART 3)."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_SA11X0_SERIAL0_NAME {
+ display "Device name for ARM SA11X0 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device for the
+ ARM SA11X0 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL0_BAUD {
+ display "Baud rate for the ARM SA11X0 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ ARM SA11X0 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL0_BUFSIZE {
+ display "Buffer size for the ARM SA11X0 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ARM SA11X0 port 0."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_ARM_SA11X0_SERIAL1 {
+ display "ARM SA11X0 serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the ARM SA11X0
+ port 1 (UART 1)."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_SA11X0_SERIAL1_NAME {
+ display "Device name for ARM SA11X0 serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of the serial device for the
+ ARM SA11X0 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL1_BAUD {
+ display "Baud rate for the ARM SA11X0 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ ARM SA11X0 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL1_BUFSIZE {
+ display "Buffer size for the ARM SA11X0 serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ARM SA11X0 port 1."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_SA11X0_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_SA11X0_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_SA11X0_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_SA11X0_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_SA11X0_SERIAL1
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_SA11X0_SERIAL1_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"assabet\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+
+# EOF ser_arm_sa11x0.cdl
diff --git a/ecos/packages/devs/serial/arm/sa11x0/current/src/sa11x0_serial.c b/ecos/packages/devs/serial/arm/sa11x0/current/src/sa11x0_serial.c
new file mode 100644
index 0000000..51c256a
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/sa11x0/current/src/sa11x0_serial.c
@@ -0,0 +1,354 @@
+//==========================================================================
+//
+// io/serial/arm/sa11x0/sa11x0_serial.c
+//
+// StrongARM SA11x0 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-05-08
+// Purpose: StrongARM SA11x0 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <pkgconf/kernel.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#ifdef CYGPKG_IO_SERIAL_ARM_SA11X0
+
+#include "sa11x0_serial.h"
+
+typedef struct sa11x0_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} sa11x0_serial_info;
+
+static bool sa11x0_serial_init(struct cyg_devtab_entry *tab);
+static bool sa11x0_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo sa11x0_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char sa11x0_serial_getc(serial_channel *chan);
+static Cyg_ErrNo sa11x0_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void sa11x0_serial_start_xmit(serial_channel *chan);
+static void sa11x0_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 sa11x0_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void sa11x0_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(sa11x0_serial_funs,
+ sa11x0_serial_putc,
+ sa11x0_serial_getc,
+ sa11x0_serial_set_config,
+ sa11x0_serial_start_xmit,
+ sa11x0_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_SA11X0_SERIAL0
+static sa11x0_serial_info sa11x0_serial_info0 = {(CYG_ADDRWORD)SA11X0_UART3_CONTROL0,
+ CYGNUM_HAL_INTERRUPT_UART3};
+#if CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL0_BUFSIZE > 0
+static unsigned char sa11x0_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL0_BUFSIZE];
+static unsigned char sa11x0_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(sa11x0_serial_channel0,
+ sa11x0_serial_funs,
+ sa11x0_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &sa11x0_serial_out_buf0[0], sizeof(sa11x0_serial_out_buf0),
+ &sa11x0_serial_in_buf0[0], sizeof(sa11x0_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(sa11x0_serial_channel0,
+ sa11x0_serial_funs,
+ sa11x0_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(sa11x0_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_SA11X0_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ sa11x0_serial_init,
+ sa11x0_serial_lookup, // Serial driver may need initializing
+ &sa11x0_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_SA11X0_SERIAL1
+
+#ifdef CYGPKG_IO_SERIAL_ARM_SA11X0_SERIAL1
+static sa11x0_serial_info sa11x0_serial_info1 = {(CYG_ADDRWORD)SA11X0_UART1_CONTROL0,
+ CYGNUM_HAL_INTERRUPT_UART1};
+#if CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL1_BUFSIZE > 0
+static unsigned char sa11x0_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL1_BUFSIZE];
+static unsigned char sa11x0_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(sa11x0_serial_channel1,
+ sa11x0_serial_funs,
+ sa11x0_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &sa11x0_serial_out_buf1[0], sizeof(sa11x0_serial_out_buf1),
+ &sa11x0_serial_in_buf1[0], sizeof(sa11x0_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(sa11x0_serial_channel1,
+ sa11x0_serial_funs,
+ sa11x0_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SA11X0_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(sa11x0_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_SA11X0_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ sa11x0_serial_init,
+ sa11x0_serial_lookup, // Serial driver may need initializing
+ &sa11x0_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_SA11X0_SERIAL1
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+sa11x0_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ sa11x0_serial_info *sa11x0_chan = (sa11x0_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)sa11x0_chan->base;
+ unsigned char parity = select_parity[new_config->parity];
+ unsigned char word_length = select_word_length[new_config->word_length-CYGNUM_SERIAL_WORD_LENGTH_5];
+ unsigned char stop_bits = select_stop_bits[new_config->stop];
+ int baud = SA11X0_UART_BAUD_RATE_DIVISOR(select_baud[new_config->baud]);
+ if ((word_length == 0xFF) ||
+ (parity == 0xFF) ||
+ (stop_bits == 0xFF)) {
+ return false; // Unsupported configuration
+ }
+ // Disable Receiver and Transmitter (clears FIFOs)
+ port->ctl3 = SA11X0_UART_RX_DISABLED |
+ SA11X0_UART_TX_DISABLED;
+
+ // Clear sticky (writable) status bits.
+ port->stat0 = SA11X0_UART_RX_IDLE |
+ SA11X0_UART_RX_BEGIN_OF_BREAK |
+ SA11X0_UART_RX_END_OF_BREAK;
+
+ // Set parity, word length, stop bits
+ port->ctl0 = parity |
+ word_length |
+ stop_bits;
+
+ // Set the desired baud rate.
+ port->ctl1 = (baud >> 8) & SA11X0_UART_H_BAUD_RATE_DIVISOR_MASK;
+ port->ctl2 = baud & SA11X0_UART_L_BAUD_RATE_DIVISOR_MASK;
+
+ // Enable the receiver (with interrupts) and the transmitter.
+ port->ctl3 = SA11X0_UART_RX_ENABLED |
+ SA11X0_UART_TX_ENABLED |
+ SA11X0_UART_RX_FIFO_INT_ENABLED;
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+sa11x0_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ sa11x0_serial_info *sa11x0_chan = (sa11x0_serial_info *)chan->dev_priv;
+ int res;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("SA11X0 SERIAL init - dev: %x.%d\n", sa11x0_chan->base, sa11x0_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(sa11x0_chan->int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sa11x0_serial_ISR,
+ sa11x0_serial_DSR,
+ &sa11x0_chan->serial_interrupt_handle,
+ &sa11x0_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(sa11x0_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(sa11x0_chan->int_num);
+ }
+ res = sa11x0_serial_config_port(chan, &chan->config, true);
+ return res;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+sa11x0_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+sa11x0_serial_putc(serial_channel *chan, unsigned char c)
+{
+ sa11x0_serial_info *sa11x0_chan = (sa11x0_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)sa11x0_chan->base;
+ if (port->stat1 & SA11X0_UART_TX_FIFO_NOT_FULL) {
+ port->data = c;
+ return true;
+ } else {
+ return false; // Couldn't send, tx was busy
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+sa11x0_serial_getc(serial_channel *chan)
+{
+ sa11x0_serial_info *sa11x0_chan = (sa11x0_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)sa11x0_chan->base;
+ return port->data;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+sa11x0_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != sa11x0_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+sa11x0_serial_start_xmit(serial_channel *chan)
+{
+ sa11x0_serial_info *sa11x0_chan = (sa11x0_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)sa11x0_chan->base;
+ (chan->callbacks->xmt_char)(chan); // Kick transmitter (if necessary)
+ port->ctl3 |= SA11X0_UART_TX_FIFO_INT_ENABLED;
+}
+
+// Disable the transmitter on the device
+static void
+sa11x0_serial_stop_xmit(serial_channel *chan)
+{
+ sa11x0_serial_info *sa11x0_chan = (sa11x0_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)sa11x0_chan->base;
+ port->ctl3 &= ~SA11X0_UART_TX_FIFO_INT_ENABLED;
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+sa11x0_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+sa11x0_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sa11x0_serial_info *sa11x0_chan = (sa11x0_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)sa11x0_chan->base;
+ unsigned int stat0 = port->stat0;
+ if (stat0 & SA11X0_UART_TX_SERVICE_REQUEST) {
+ (chan->callbacks->xmt_char)(chan);
+ }
+ if (stat0 & SA11X0_UART_RX_INTS) {
+ while (port->stat1 & SA11X0_UART_RX_FIFO_NOT_EMPTY) {
+ (chan->callbacks->rcv_char)(chan, port->data);
+ }
+ port->stat0 = SA11X0_UART_RX_IDLE; // Need to clear this manually
+ }
+ if (stat0 & (SA11X0_UART_RX_BEGIN_OF_BREAK |
+ SA11X0_UART_RX_END_OF_BREAK ) ) {
+ // Need to clear any of these manually also or noise
+ // from plugging in can cause an interrupt loop!
+ port->stat0 = stat0 & (SA11X0_UART_RX_BEGIN_OF_BREAK |
+ SA11X0_UART_RX_END_OF_BREAK );
+ }
+ cyg_drv_interrupt_unmask(vector);
+}
+#endif
diff --git a/ecos/packages/devs/serial/arm/sa11x0/current/src/sa11x0_serial.h b/ecos/packages/devs/serial/arm/sa11x0/current/src/sa11x0_serial.h
new file mode 100644
index 0000000..33f2d5f
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/sa11x0/current/src/sa11x0_serial.h
@@ -0,0 +1,122 @@
+#ifndef CYGONCE_ARM_SA11X0_SERIAL_H
+#define CYGONCE_ARM_SA11X0_SERIAL_H
+
+// ====================================================================
+//
+// sa11x0_serial.h
+//
+// Device I/O - Description of StrongARM SA11x0 serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2000-05-08
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports on StrongARM SA11x0
+
+#include <cyg/hal/hal_sa11x0.h> // Register definitions
+
+struct serial_port {
+ unsigned long ctl0; // 0x00
+ unsigned long ctl1; // 0x04
+ unsigned long ctl2; // 0x08
+ unsigned long ctl3; // 0x0C
+ unsigned long _unused0;
+ unsigned long data; // 0x14
+ unsigned long _unused1;
+ unsigned long stat0; // 0x1C
+ unsigned long stat1; // 0x20
+};
+
+#define SA11X0_UART_RX_INTS (SA11X0_UART_RX_SERVICE_REQUEST|SA11X0_UART_RX_IDLE)
+
+static unsigned char select_word_length[] = {
+ 0xFF, // 5 bits / word (char)
+ 0xFF,
+ SA11X0_UART_DATA_BITS_7,
+ SA11X0_UART_DATA_BITS_8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ SA11X0_UART_STOP_BITS_1, // 1 stop bit
+ 0xFF, // 1.5 stop bit
+ SA11X0_UART_STOP_BITS_2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ SA11X0_UART_PARITY_DISABLED, // No parity
+ SA11X0_UART_PARITY_ENABLED| // Even parity
+ SA11X0_UART_PARITY_EVEN,
+ SA11X0_UART_PARITY_ENABLED| // Odd parity
+ SA11X0_UART_PARITY_ODD,
+ 0xFF, // Mark parity
+ 0xFF, // Space parity
+};
+
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 0, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 230400, // 230400
+};
+
+#endif // CYGONCE_ARM_SA11X0_SERIAL_H
diff --git a/ecos/packages/devs/serial/arm/smdk2410/current/ChangeLog b/ecos/packages/devs/serial/arm/smdk2410/current/ChangeLog
new file mode 100644
index 0000000..8353195
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/smdk2410/current/ChangeLog
@@ -0,0 +1,7 @@
+2003-08-06 Michael Anburaj <embeddedeng@hotmail.com>
+
+ * cdl/ser_arm_smdk2410.cdl:
+ * src/smdk2410_serial.c:
+ * src/smdk2410_serial.h:
+ New package to support the serial device on a Samsung
+ ARM9/SMDK2410 development board.
diff --git a/ecos/packages/devs/serial/arm/smdk2410/current/cdl/ser_arm_smdk2410.cdl b/ecos/packages/devs/serial/arm/smdk2410/current/cdl/ser_arm_smdk2410.cdl
new file mode 100644
index 0000000..5aea95f
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/smdk2410/current/cdl/ser_arm_smdk2410.cdl
@@ -0,0 +1,198 @@
+# ====================================================================
+#
+# ser_arm_smdk2410.cdl
+#
+# eCos serial ARM/SMDK2410 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): michael anburaj <michaelanburaj@hotmail.com>
+# Contributors: michael anburaj <michaelanburaj@hotmail.com>
+# Date: 2003-08-01
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_ARM_SMDK2410 {
+ display "Samsung ARM9/SMDK2410 board serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_ARM_ARM9_SMDK2410
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ Samsung SMDK2410 and S3c2410x (ARM9) based development boards."
+
+ compile -library=libextras.a smdk2410_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_arm_smdk2410.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL0 {
+ display "Samsung SMDK2410 serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the Samsung SMDK2410 port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_SMDK2410_SERIAL0_NAME {
+ display "Device name for the Samsung SMDK2410 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of serial device for the Samsung SMDK2410 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BAUD {
+ display "Baud rate for the Samsung SMDK2410 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the Samsung SMDK2410 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BUFSIZE {
+ display "Buffer size for the Samsung SMDK2410 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the Samsung SMDK2410 port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL1 {
+ display "Samsung SMDK2410 serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the Samsung SMDK2410 port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_ARM_SMDK2410_SERIAL1_NAME {
+ display "Device name for the Samsung SMDK2410 serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for the Samsung SMDK2410 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BAUD {
+ display "Baud rate for the Samsung SMDK2410 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the Samsung SMDK2410 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BUFSIZE {
+ display "Buffer size for the Samsung SMDK2410 serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the Samsung SMDK2410 port 1."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_SMDK2410_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_SMDK2410_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_ARM_SMDK2410_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_ARM_SMDK2410_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL1
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_ARM_SMDK2410_SERIAL1_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"smdk2410\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+
+# EOF ser_arm_smdk2410.cdl
diff --git a/ecos/packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.c b/ecos/packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.c
new file mode 100644
index 0000000..8880412
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.c
@@ -0,0 +1,384 @@
+//==========================================================================
+//
+// io/serial/arm/smdk2410_serial.c
+//
+// Samsung SMDK2410 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): michael anburaj <michaelanburaj@hotmail.com>
+// Contributors: michael anburaj <michaelanburaj@hotmail.com>
+// Date: 2003-08-01
+// Purpose: SMDK2410 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h> // interrupt
+#include <cyg/hal/hal_io.h> // register base
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#ifdef CYGPKG_IO_SERIAL_ARM_SMDK2410
+
+#include "smdk2410_serial.h"
+
+typedef struct smdk2410_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_uint32 bit_sub_rxd;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} smdk2410_serial_info;
+
+static bool smdk2410_serial_init(struct cyg_devtab_entry *tab);
+static bool smdk2410_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo smdk2410_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char smdk2410_serial_getc(serial_channel *chan);
+static Cyg_ErrNo smdk2410_serial_set_config(serial_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void smdk2410_serial_start_xmit(serial_channel *chan);
+static void smdk2410_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 smdk2410_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void smdk2410_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(smdk2410_serial_funs,
+ smdk2410_serial_putc,
+ smdk2410_serial_getc,
+ smdk2410_serial_set_config,
+ smdk2410_serial_start_xmit,
+ smdk2410_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL0
+static smdk2410_serial_info smdk2410_serial_info0 = {(cyg_uint32)ULCON0,
+ CYGNUM_HAL_INTERRUPT_UART0,
+ BIT_SUB_RXD0};
+#if CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BUFSIZE > 0
+static unsigned char smdk2410_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BUFSIZE];
+static unsigned char smdk2410_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(smdk2410_serial_channel0,
+ smdk2410_serial_funs,
+ smdk2410_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &smdk2410_serial_out_buf0[0], sizeof(smdk2410_serial_out_buf0),
+ &smdk2410_serial_in_buf0[0], sizeof(smdk2410_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(smdk2410_serial_channel0,
+ smdk2410_serial_funs,
+ smdk2410_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(smdk2410_serial_io0,
+ CYGDAT_IO_SERIAL_ARM_SMDK2410_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ smdk2410_serial_init,
+ smdk2410_serial_lookup, // Serial driver may need initializing
+ &smdk2410_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL1
+static smdk2410_serial_info smdk2410_serial_info1 = {(cyg_uint32)ULCON1,
+ CYGNUM_HAL_INTERRUPT_UART1,
+ BIT_SUB_RXD1};
+#if CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BUFSIZE > 0
+static unsigned char smdk2410_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BUFSIZE];
+static unsigned char smdk2410_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(smdk2410_serial_channel1,
+ smdk2410_serial_funs,
+ smdk2410_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &smdk2410_serial_out_buf1[0], sizeof(smdk2410_serial_out_buf1),
+ &smdk2410_serial_in_buf1[0], sizeof(smdk2410_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(smdk2410_serial_channel1,
+ smdk2410_serial_funs,
+ smdk2410_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_SMDK2410_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(smdk2410_serial_io1,
+ CYGDAT_IO_SERIAL_ARM_SMDK2410_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ smdk2410_serial_init,
+ smdk2410_serial_lookup, // Serial driver may need initializing
+ &smdk2410_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_ARM_SMDK2410_SERIAL1
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+smdk2410_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+ CYG_ADDRWORD base = smdk2410_chan->base;
+ unsigned short baud_divisor = select_baud[new_config->baud];
+ cyg_uint32 _lcr;
+
+ if (baud_divisor == 0) return false;
+
+ if (init) {
+ //UART FIFO control register
+ HAL_WRITE_UINT32(base+OFS_UFCON, (3<<6) | (3<<4) | (1<<2) | (1<<1) | (1<<0));
+
+ //UART modem control register
+ HAL_WRITE_UINT32(base+OFS_UMCON, 0);
+ }
+
+ _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ HAL_WRITE_UINT32(base+OFS_ULCON, _lcr);
+
+ //UART control register, Enable Rx Timeout Int
+ HAL_WRITE_UINT32(base+OFS_UCON, 0x085);
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+smdk2410_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+ cyg_uint32 _intsubm;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("SMDK2410 SERIAL init - dev: 0x%08x.%d\n",
+ smdk2410_chan->base, smdk2410_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(smdk2410_chan->int_num,
+ 1, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ smdk2410_serial_ISR,
+ smdk2410_serial_DSR,
+ &smdk2410_chan->serial_interrupt_handle,
+ &smdk2410_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(smdk2410_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(smdk2410_chan->int_num);
+
+ HAL_READ_UINT32(INTSUBMSK, _intsubm);
+ _intsubm &= ~(smdk2410_chan->bit_sub_rxd<<0); // BIT_SUB_RXD
+ HAL_WRITE_UINT32(INTSUBMSK, _intsubm);
+ }
+ smdk2410_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+smdk2410_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+smdk2410_serial_putc(serial_channel *chan, unsigned char c)
+{
+ smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+ CYG_ADDRWORD base = smdk2410_chan->base;
+ cyg_uint32 _status;
+
+ HAL_READ_UINT32(base+OFS_UFSTAT, _status);
+ if (_status & 0x200) {
+ // No space
+ return false;
+ } else {
+ // Transmit buffer is not full
+ HAL_WRITE_UINT8(base+OFS_UTXH, (cyg_uint32)c);
+ return true;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+smdk2410_serial_getc(serial_channel *chan)
+{
+ smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+ CYG_ADDRWORD base = smdk2410_chan->base;
+ cyg_uint32 _status;
+ cyg_uint8 _c;
+
+ do {
+ HAL_READ_UINT32(base+OFS_UFSTAT, _status);
+ } while ((_status & 0xf) == 0);
+
+ HAL_READ_UINT8(base+OFS_URXH, _c);
+ return (unsigned char)_c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+smdk2410_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != smdk2410_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+smdk2410_serial_start_xmit(serial_channel *chan)
+{
+ smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+ cyg_uint32 _intsubm;
+
+ HAL_READ_UINT32(INTSUBMSK, _intsubm);
+ _intsubm &= ~(smdk2410_chan->bit_sub_rxd<<1); // BIT_SUB_TXD
+ HAL_WRITE_UINT32(INTSUBMSK, _intsubm);
+}
+
+// Disable the transmitter on the device
+static void
+smdk2410_serial_stop_xmit(serial_channel *chan)
+{
+ smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+ cyg_uint32 _intsubm;
+
+ HAL_READ_UINT32(INTSUBMSK, _intsubm);
+ _intsubm |= (smdk2410_chan->bit_sub_rxd<<1); // BIT_SUB_TXD
+ HAL_WRITE_UINT32(INTSUBMSK, _intsubm);
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+smdk2410_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(smdk2410_chan->int_num);
+ cyg_drv_interrupt_acknowledge(smdk2410_chan->int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+smdk2410_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
+ CYG_ADDRWORD base = smdk2410_chan->base;
+ cyg_uint32 _intsubpnd, _status, _c;
+ cyg_uint32 _rxd_bit = (smdk2410_chan->bit_sub_rxd<<0), _txd_bit=(smdk2410_chan->bit_sub_rxd<<1);
+
+ HAL_READ_UINT32(SUBSRCPND, _intsubpnd);
+
+ // Empty Rx FIFO
+ if (_intsubpnd & _rxd_bit) {
+ HAL_READ_UINT32(base+OFS_UFSTAT, _status);
+ while((_status & 0x0f) != 0) {
+ HAL_READ_UINT8(base+OFS_URXH, _c);
+ (chan->callbacks->rcv_char)(chan, (unsigned char)_c);
+ HAL_READ_UINT32(base+OFS_UFSTAT, _status);
+ }
+ HAL_WRITE_UINT32(SUBSRCPND, _rxd_bit);
+ }
+
+ // Fill into Tx FIFO. xmt_char will mask the interrupt when it
+ // runs out of chars, so doing this in a loop is OK.
+ if (_intsubpnd & _txd_bit) {
+ (chan->callbacks->xmt_char)(chan);
+ HAL_WRITE_UINT32(SUBSRCPND, _txd_bit);
+ }
+
+ cyg_drv_interrupt_unmask(smdk2410_chan->int_num);
+}
+
+#endif // CYGPKG_IO_SERIAL_ARM_SMDK2410
+
+// EOF smdk2410_serial.c
diff --git a/ecos/packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.h b/ecos/packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.h
new file mode 100644
index 0000000..abeab11
--- /dev/null
+++ b/ecos/packages/devs/serial/arm/smdk2410/current/src/smdk2410_serial.h
@@ -0,0 +1,127 @@
+#ifndef CYGONCE_ARM_SMDK2410_SERIAL_H
+#define CYGONCE_ARM_SMDK2410_SERIAL_H
+
+// ====================================================================
+//
+// smdk2410_serial.h
+//
+// Device I/O - Description of Samsung SMDK2410 serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): michael anburaj <michaelanburaj@hotmail.com>
+// Contributors: michael anburaj <michaelanburaj@hotmail.com>
+// Date: 2003-08-01
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Baud rate divisor registers values
+// (PCLK/16./BAUD_RATE+0.5) -1)
+#define UBRDIV_50 ((PCLK/16./50)-1)
+#define UBRDIV_75 ((PCLK/16./75)-1)
+#define UBRDIV_110 ((PCLK/16./110)-1)
+#define UBRDIV_134_5 ((PCLK/16./134.5)-1)
+#define UBRDIV_150 ((PCLK/16./150)-1)
+#define UBRDIV_200 ((PCLK/16./200)-1)
+#define UBRDIV_300 ((PCLK/16./300)-1)
+#define UBRDIV_600 ((PCLK/16./600)-1)
+#define UBRDIV_1200 ((PCLK/16./1200)-1)
+#define UBRDIV_1800 ((PCLK/16./1800)-1)
+#define UBRDIV_2400 ((PCLK/16./2400)-1)
+#define UBRDIV_3600 ((PCLK/16./3600)-1)
+#define UBRDIV_4800 ((PCLK/16./4800)-1)
+#define UBRDIV_7200 ((PCLK/16./7200)-1)
+#define UBRDIV_9600 ((PCLK/16./9600)-1)
+#define UBRDIV_14400 ((PCLK/16./14400)-1)
+#define UBRDIV_19200 ((PCLK/16./19200)-1)
+#define UBRDIV_38400 ((PCLK/16./38400)-1)
+#define UBRDIV_57600 ((PCLK/16./57600)-1)
+#define UBRDIV_115200 ((PCLK/16./115200)-1)
+#define UBRDIV_230400 ((PCLK/16./230400)-1)
+
+static unsigned char select_word_length[] = {
+ VAL_ULCON_WL_5,
+ VAL_ULCON_WL_6,
+ VAL_ULCON_WL_7,
+ VAL_ULCON_WL_8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0, // Unused
+ VAL_ULCON_SB_1, // 1 stop bit
+ 0, // 1.5 stop bit (not supported)
+ VAL_ULCON_SB_2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ VAL_ULCON_PM_N, // No parity
+ VAL_ULCON_PM_E, // Even parity
+ VAL_ULCON_PM_O, // Odd parity
+ VAL_ULCON_PM_FC1, // Mark parity
+ VAL_ULCON_PM_FC0, // Space parity
+};
+
+// Baud rate values, based on PCLK
+static unsigned short select_baud[] = {
+ 0, // Unused
+ UBRDIV_50, // 50
+ UBRDIV_75, // 75
+ UBRDIV_110, // 110
+ UBRDIV_134_5, // 134.5
+ UBRDIV_150, // 150
+ UBRDIV_200, // 200
+ UBRDIV_300, // 300
+ UBRDIV_600, // 600
+ UBRDIV_1200, // 1200
+ UBRDIV_1800, // 1800
+ UBRDIV_2400, // 2400
+ UBRDIV_3600, // 3600
+ UBRDIV_4800, // 4800
+ UBRDIV_7200, // 7200
+ UBRDIV_9600, // 9600
+ UBRDIV_14400, // 14400
+ UBRDIV_19200, // 19200
+ UBRDIV_38400, // 38400
+ UBRDIV_57600, // 57600
+ UBRDIV_115200,// 115200
+ UBRDIV_230400,// 230400
+};
+
+#endif // CYGONCE_ARM_SMDK2410_SERIAL_H
diff --git a/ecos/packages/devs/serial/coldfire/mcf5272/current/ChangeLog b/ecos/packages/devs/serial/coldfire/mcf5272/current/ChangeLog
new file mode 100644
index 0000000..dcc83f1
--- /dev/null
+++ b/ecos/packages/devs/serial/coldfire/mcf5272/current/ChangeLog
@@ -0,0 +1,39 @@
+2006-05-09 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/mcf5272_serial.c (MCF5272_uart_init): Fix compiler warning
+ with diag_printf().
+
+2005-06-24 Enrico Piria <epiriaNOSPAM@NOSPAMfastwebnet.it>
+
+ * src/mcf5272_serial.c:
+ * src/mcf5272_serial.h:
+ * cdl/mcf5272_serial.cdl:
+ Rework of the original driver contributed by Wade Jensen.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_mcf5272_uart.cdl: Remove irrelevant doc link.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/coldfire/mcf5272/current/cdl/mcf5272_serial.cdl b/ecos/packages/devs/serial/coldfire/mcf5272/current/cdl/mcf5272_serial.cdl
new file mode 100644
index 0000000..cfc5a0c
--- /dev/null
+++ b/ecos/packages/devs/serial/coldfire/mcf5272/current/cdl/mcf5272_serial.cdl
@@ -0,0 +1,192 @@
+# ====================================================================
+#
+# ser_MCF5272_uart.cdl
+#
+# eCos serial driver for MCF5272 UART
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_COLDFIRE_MCF5272 {
+ display "Serial driver for MCF5272 UART"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ description "
+ This option enables the serial device drivers for the
+ ColdFire MCF5272."
+
+ compile -library=libextras.a mcf5272_serial.c
+
+ cdl_component CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0 {
+ display "MCF5272 UART serial port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "This option includes the serial device driver
+ for the MCF5272 UART port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_NAME {
+ display "Device name for the MCF5272 UART serial port 0"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of serial device for the
+ MCF5272 UART port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BAUD {
+ display "Baud rate for the MCF5272 UART serial port 0"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 19200
+ description "
+ This option specifies the default baud rate (speed) for the
+ MCF5272 UART port 0."
+ }
+
+ cdl_option CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_AUTOBAUD {
+ display "Enable automatic baud rate detection for the MCF5272 UART serial port 0."
+ flavor bool
+ default_value 0
+ active_if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE > 0
+ description "
+ This option enables automatic baud rate detection for
+ MCF5272 UART port 0. Sending a BREAK character on the
+ line will start the detection. The first character following
+ the BREAK should occupy an odd position in the character table
+ (like \'a\'). This option requires interrupts to be enabled
+ for the port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE {
+ display "Buffer size for the MCF5272 UART serial port 0"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the MCF5272 UART port 0. If the size specified is 0, the
+ driver will not use interrupts."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_PRIORITY {
+ display "Interrupt priority level for MCF5272 UART serial port 0"
+ flavor data
+ legal_values 1 to 6
+ default_value 2
+ active_if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE > 0
+ description "
+ This option specifies the priority associated to interrupts
+ coming from the MCF5272 UART port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1 {
+ display "MCF5272 UART serial port 1 driver"
+ flavor bool
+ default_value 0
+
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "This option includes the serial device driver for the
+ MCF5272 UART port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_NAME {
+ display "Device name for the MCF5272 UART serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for the
+ MCF5272 UART port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BAUD {
+ display "Baud rate for the MCF5272 UART serial port 1"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 19200
+ description "
+ This option specifies the default baud rate (speed) for the
+ MCF5272 UART port 1."
+ }
+
+ cdl_option CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_AUTOBAUD {
+ display "Enable automatic baud rate detection for the MCF5272 UART serial port 1."
+ flavor bool
+ default_value 0
+ active_if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE > 0
+ description "
+ This option enables automatic baud rate detection for
+ MCF5272 UART port 1. Sending a BREAK character on the
+ line will start the detection. The first character following
+ the BREAK should occupy an odd position in the character table
+ (like \'a\'). This option requires interrupts to be enabled
+ for the port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE {
+ display "Buffer size for the MCF5272 UART serial port 1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the MCF5272 UART port 1. If the size specified is 0, the
+ driver will not use interrupts."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_PRIORITY {
+ display "Interrupt priority level for MCF5272 UART serial port 1"
+ flavor data
+ legal_values 1 to 6
+ default_value 2
+ active_if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE > 0
+ description "
+ This option specifies the priority associated to interrupts
+ coming from the MCF5272 UART port 1."
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/serial/coldfire/mcf5272/current/src/mcf5272_serial.c b/ecos/packages/devs/serial/coldfire/mcf5272/current/src/mcf5272_serial.c
new file mode 100644
index 0000000..7e0033b
--- /dev/null
+++ b/ecos/packages/devs/serial/coldfire/mcf5272/current/src/mcf5272_serial.c
@@ -0,0 +1,1138 @@
+//==========================================================================
+//
+// devs/serial/coldfire/mcf5272/mcf5272_serial.c
+//
+// ColdFire MCF5272 UART Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Wade Jensen, Enrico Piria
+// Contributors:
+// Date: 2005-06-25
+// Purpose: MCF5272 Serial I/O module (interrupt driven version).
+// Description:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+#include <string.h> // memset, strcmp
+
+#include "mcf5272_serial.h"
+
+
+// Use this macro to determine if at least one of the ports uses
+// autobaud detection.
+#if defined(CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_AUTOBAUD) || \
+ defined(CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_AUTOBAUD)
+#define REQUESTED_AUTOBAUD
+#endif
+
+// Autobaud states
+typedef enum autobaud_states_t
+{
+ AB_IDLE = 0, // Normal state. Autobaud process hasn't been initiated yet.
+ AB_BEGIN_BREAK, // Detected a start of the break.
+ AB_BEGIN, // Detected the end of the break and has set up the autobaud.
+ AB_DISABLED // Autobaud detection disabled for this port.
+} autobaud_states_t;
+
+typedef struct MCF5272_uart_info_t
+{
+ volatile mcf5272_uart_t *base; // Base address of the UART registers
+ cyg_uint32 uart_vector; // UART interrupt vector number
+
+ cyg_interrupt serial_interrupt; // Interrupt context
+ cyg_handle_t serial_interrupt_handle; // Interrupt handle
+
+ volatile cyg_uint8 imr_mirror; // Interrupt mask register mirror
+
+ cyg_serial_info_t config; // The channel configuration
+
+ autobaud_states_t autobaud_state; // The autobaud state
+
+
+} MCF5272_uart_info_t;
+
+// Function prototypes for the MCF5272 UART ISR and DSR.
+static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+// Function prototypes for the serial functions.
+static bool MCF5272_uart_init(struct cyg_devtab_entry * tab);
+static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab, const char *name);
+static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c);
+static unsigned char MCF5272_uart_getc(serial_channel *chan);
+Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void MCF5272_uart_start_xmit(serial_channel *chan);
+static void MCF5272_uart_stop_xmit(serial_channel * chan);
+
+// Declare the serial functions that are called by the common serial
+// driver layer.
+static SERIAL_FUNS
+(
+ MCF5272_uart_funs,
+ MCF5272_uart_putc,
+ MCF5272_uart_getc,
+ MCF5272_uart_set_config,
+ MCF5272_uart_start_xmit,
+ MCF5272_uart_stop_xmit
+);
+
+
+// Definition for channel 0 UART configuration.
+//***********************************************
+#ifdef CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0
+
+// Data structure contains channel information.
+static MCF5272_uart_info_t MCF5272_uart_channel_info_0;
+
+// If the channel buffer size is zero, do not include interrupt UART processing
+#if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE > 0
+
+// Allocate receive and transmit buffer. The size of the buffer is
+// configured by the configtool.
+static unsigned char
+MCF5272_uart_out_buf0[CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE];
+static unsigned char
+MCF5272_uart_in_buf0[CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BUFSIZE];
+
+// Channel function table. We register the UART functions here so
+// that uppper serial drivers can call the serial driver's routines.
+static SERIAL_CHANNEL_USING_INTERRUPTS(
+ MCF5272_uart_channel_0,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ MCF5272_uart_out_buf0, sizeof(MCF5272_uart_out_buf0),
+ MCF5272_uart_in_buf0, sizeof(MCF5272_uart_in_buf0)
+);
+
+#else
+
+// Don't use interrupt processing for the UART.
+static SERIAL_CHANNEL(
+ MCF5272_uart_channel_0,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+);
+#endif
+
+DEVTAB_ENTRY(
+ MCF5272_uart_io0,
+ CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio, // The table of I/O functions.
+ MCF5272_uart_init, // UART initialization function.
+ MCF5272_uart_lookup, // The UART lookup function. This
+ // function typically sets
+ // up the device for actual use,
+ // turning on interrupts,
+ // configuring the port, etc.
+ &MCF5272_uart_channel_0
+);
+#endif // ifdef CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0
+
+
+// Definition for channel 1 UART configuration.
+//***********************************************
+#ifdef CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1
+
+// Data structure contains channel informtion.
+static MCF5272_uart_info_t MCF5272_uart_channel_info_1;
+
+// If the channel buffer size is zero, do not include interrupt UART processing
+#if CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE > 0
+
+// Allocate receive and transmit buffer. The size of the buffer is
+// configured by the configtool.
+static unsigned char
+MCF5272_uart_out_buf1[CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE];
+static unsigned char
+MCF5272_uart_in_buf1[CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BUFSIZE];
+
+// Channel function table. We register the UART functions here so
+// that uppper serial drivers can call the serial driver's routines.
+static SERIAL_CHANNEL_USING_INTERRUPTS(
+ MCF5272_uart_channel_1,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ MCF5272_uart_out_buf1, sizeof(MCF5272_uart_out_buf1),
+ MCF5272_uart_in_buf1, sizeof(MCF5272_uart_in_buf1)
+);
+
+#else
+
+static SERIAL_CHANNEL(
+ MCF5272_uart_channel_1,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+);
+#endif
+
+DEVTAB_ENTRY(
+ MCF5272_uart_io1,
+ CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio, // The table of I/O functions.
+ MCF5272_uart_init, // UART initialization function.
+ MCF5272_uart_lookup, // The UART lookup function. This function
+ // typically sets up the device for actual use,
+ // turing on interrupts, configuring the port, etc.
+ &MCF5272_uart_channel_1
+);
+#endif // ifdef CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1
+
+
+// Function Prototypes
+
+// Internal function to actually configure the hardware to desired
+// baud rate, etc.
+static bool MCF5272_uart_config_port(serial_channel*, cyg_serial_info_t*);
+static void MCF5272_uart_start_xmit(serial_channel*);
+
+
+// The table contains dividers to divide the clock to configure an
+// approppriate baud rate for the UART.
+
+#define DIVIDER(_baudrate_) \
+ ((CYGHWR_HAL_SYSTEM_CLOCK_MHZ * 1000000) / ((_baudrate_) * 32))
+
+static unsigned long dividers_table[]=
+{
+ 0,
+ DIVIDER(50), // CYGNUM_SERIAL_BAUD_50 = 1
+ DIVIDER(75), // CYGNUM_SERIAL_BAUD_75
+ DIVIDER(110), // CYGNUM_SERIAL_BAUD_110
+ DIVIDER(134.5), // CYGNUM_SERIAL_BAUD_134_5
+ DIVIDER(150), // CYGNUM_SERIAL_BAUD_150
+ DIVIDER(200), // CYGNUM_SERIAL_BAUD_200
+ DIVIDER(300), // CYGNUM_SERIAL_BAUD_300
+ DIVIDER(600), // CYGNUM_SERIAL_BAUD_600
+ DIVIDER(1200), // CYGNUM_SERIAL_BAUD_1200
+ DIVIDER(1800), // CYGNUM_SERIAL_BAUD_1800
+ DIVIDER(2400), // CYGNUM_SERIAL_BAUD_2400
+ DIVIDER(3600), // CYGNUM_SERIAL_BAUD_3600
+ DIVIDER(4800), // CYGNUM_SERIAL_BAUD_4800
+ DIVIDER(7200), // CYGNUM_SERIAL_BAUD_7200
+ DIVIDER(9600), // CYGNUM_SERIAL_BAUD_9600
+ DIVIDER(14400), // CYGNUM_SERIAL_BAUD_14400
+ DIVIDER(19200), // CYGNUM_SERIAL_BAUD_19200
+ DIVIDER(38400), // CYGNUM_SERIAL_BAUD_38400
+ DIVIDER(57600), // CYGNUM_SERIAL_BAUD_57600
+ DIVIDER(115200), // CYGNUM_SERIAL_BAUD_115200
+ DIVIDER(230400) // CYGNUM_SERIAL_BAUD_230400
+};
+
+
+// ****************************************************************************
+// MCF5272_uart_init() - This routine is called during bootstrap to set up the
+// UART driver.
+//
+// INPUT:
+// Pointer to the the device table.
+//
+// RETURN:
+// Returns true if the initialization is successful. Otherwise, it retuns
+// false.
+
+static bool MCF5272_uart_init(struct cyg_devtab_entry * tab)
+{
+ serial_channel *chan = (serial_channel *) tab->priv;
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+ int priority_level = 0;
+
+
+#ifdef CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0
+
+ // Instantiation of the UART channel 0 data structure. This data
+ // structure contains channel information.
+ if (strcmp(tab->name, CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_NAME)
+ == 0)
+ {
+
+ cyg_uint32 pbcnt;
+
+ // A priority makes sense only if interrupts are enabled
+#ifdef CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_PRIORITY
+ priority_level = CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_PRIORITY;
+#else
+ priority_level = 0;
+#endif
+
+ // Initialize the UART information data to all zeros
+ memset(port, sizeof(MCF5272_uart_info_t), 0);
+
+ // Set the base address of the UART registers to differentiate
+ // itself from the different registers for the other UART port.
+ port->base = (mcf5272_uart_t *) &MCF5272_DEVS->uart[0];
+
+ // Set the UART interrupt vector number
+ port->uart_vector = CYGNUM_HAL_INTERRUPT_UART1;
+
+#ifdef CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0_AUTOBAUD
+
+ // Set the autobaud state to idle
+ port->autobaud_state = AB_IDLE;
+#else
+ // Disable autobaud detection for this port
+ port->autobaud_state = AB_DISABLED;
+#endif
+
+ // Initialize the UART 0 output pins
+ HAL_READ_UINT32(&MCF5272_DEVS->gpio.pbcnt, pbcnt);
+ HAL_WRITE_UINT32(&MCF5272_DEVS->gpio.pbcnt,
+ MCF5272_GPIO_PBCNT_URT0_EN |
+ (pbcnt & ~MCF5272_GPIO_PBCNT_URT0_MSK));
+ }
+#endif // CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL0
+
+#ifdef CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1
+
+ // Instantiation of the UART channel 1 data strucutre. This data
+ // structure contains channel information.
+ if (strcmp(tab->name, CYGDAT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_NAME)
+ == 0)
+ {
+ cyg_uint32 pdcnt;
+
+ // A priority makes sense only if interrupts are enabled
+#ifdef CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_PRIORITY
+ priority_level = CYGNUM_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_PRIORITY;
+#else
+ priority_level = 0;
+#endif
+
+ // Initialize the UART information data to all zeros
+ memset(port, sizeof(MCF5272_uart_info_t), 0);
+
+ // Set the base address of the UART registers to differentiate
+ // itself from the different regusters for the other UART port.
+ port->base = (mcf5272_uart_t *) &MCF5272_DEVS->uart[1];
+
+ // Set the UART interrupt vector number
+ port->uart_vector = CYGNUM_HAL_INTERRUPT_UART2;
+
+#ifdef CYGOPT_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1_AUTOBAUD
+
+ // Set the autobaud state to idle
+ port->autobaud_state = AB_IDLE;
+#else
+ // Disable autobaud detection for this port
+ port->autobaud_state = AB_DISABLED;
+#endif
+
+ // Initialize the UART 1 output pins
+ HAL_READ_UINT32(&MCF5272_DEVS->gpio.pdcnt, pdcnt);
+ HAL_WRITE_UINT32(&MCF5272_DEVS->gpio.pdcnt,
+ MCF5272_GPIO_PDCNT_URT1_EN |
+ (pdcnt & ~MCF5272_GPIO_PDCNT_URT1_MSK));
+
+ }
+#endif // CYGPKG_IO_SERIAL_COLDFIRE_MCF5272_CHANNEL1
+
+
+ if (chan->out_cbuf.len > 0)
+ {
+ // If the the buffer is greater than zero, then the driver will
+ // use interrupt driven I/O. Hence, the driver creates an
+ // interrupt context for the UART device.
+
+ cyg_drv_interrupt_create(port->uart_vector,
+ priority_level, // Priority
+ (cyg_addrword_t)chan, // Data item passed
+ // to interrupt handler
+ MCF5272_uart_ISR,
+ MCF5272_uart_DSR,
+ &port->serial_interrupt_handle,
+ &port->serial_interrupt);
+
+ cyg_drv_interrupt_attach(port->serial_interrupt_handle);
+
+ cyg_drv_interrupt_unmask(port->uart_vector);
+ }
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+
+#ifdef CYGDBG_IO_INIT
+ diag_printf("MCF5272 UART init - dev: %p.%d\n", port->base,
+ port->uart_vector);
+#endif
+
+ // Configure Serial device
+ return (MCF5272_uart_config_port(chan, &chan->config));
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_config_port() - Configure the UART port.
+//
+// Internal function to actually configure the hardware to desired baud rate,
+// etc.
+//
+// INPUT:
+// chan - The channel information.
+// new_confg - The port configuration which include the desired
+// baud rate, etc.
+//
+// RETURN:
+// Returns true if the port configuration is successful. Otherwise,
+// it retuns false.
+
+static bool MCF5272_uart_config_port(serial_channel *chan,
+ cyg_serial_info_t *new_config)
+{
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+ cyg_uint8 mode_reg = 0;
+ cyg_uint32 ubgs;
+
+
+ // If we are configuring the port once again, disable all interrupts
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, 0);
+
+ // If the baud rate is null, we don't configure the port
+ if (new_config->baud == 0) return false;
+
+ // Get the divider from the baudrate table which will use to
+ // configure the port's baud rate.
+ ubgs = (cyg_uint16) dividers_table[new_config->baud];
+
+ // Save the configuration value for later use
+ port->config = *new_config;
+
+ // We first write the reset values into the device and then configure
+ // the device the way we want to use it.
+
+ // Reset Transmitter
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_RESET_TX);
+
+ // Reset Receiver
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_RESET_RX);
+
+ // Reset Mode Register
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_RESET_MR);
+
+ // Translate the parity configuration to UART mode bits
+ switch(port->config.parity)
+ {
+ default:
+ case CYGNUM_SERIAL_PARITY_NONE:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_NONE;
+ break;
+
+ case CYGNUM_SERIAL_PARITY_EVEN:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_EVEN;
+ break;
+
+ case CYGNUM_SERIAL_PARITY_ODD:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_ODD;
+ break;
+
+ case CYGNUM_SERIAL_PARITY_MARK:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_HI;
+ break;
+
+ case CYGNUM_SERIAL_PARITY_SPACE:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_LO;
+ break;
+ }
+
+ // Translate the number of bits per character configuration to
+ // UART mode bits
+ switch(port->config.word_length)
+ {
+ case CYGNUM_SERIAL_WORD_LENGTH_5:
+ mode_reg |= MCF5272_UART_UMR1_BC_5;
+ break;
+
+ case CYGNUM_SERIAL_WORD_LENGTH_6:
+ mode_reg |= MCF5272_UART_UMR1_BC_6;
+ break;
+
+ case CYGNUM_SERIAL_WORD_LENGTH_7:
+ mode_reg |= MCF5272_UART_UMR1_BC_7;
+ break;
+
+ default:
+ case CYGNUM_SERIAL_WORD_LENGTH_8:
+ mode_reg |= MCF5272_UART_UMR1_BC_8;
+ break;
+ }
+
+ // Enable HW flow control for receiver
+ if(port->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX)
+ mode_reg |= MCF5272_UART_UMR1_RXRTS;
+
+ // Configure the parity, HW flow control and the bits per character.
+ // After this write MR pointer points to mode register 2.
+ HAL_WRITE_UINT8(&port->base->umr, mode_reg);
+
+ // Translate the stop bit length to UART mode bits
+ switch(port->config.stop)
+ {
+ default:
+ case CYGNUM_SERIAL_STOP_1:
+ mode_reg = MCF5272_UART_UMR2_STOP_BITS_1;
+ break;
+
+ case CYGNUM_SERIAL_STOP_1_5:
+ mode_reg = MCF5272_UART_UMR2_STOP_BITS_15;
+ break;
+
+ case CYGNUM_SERIAL_STOP_2:
+ mode_reg = MCF5272_UART_UMR2_STOP_BITS_2;
+ break;
+ }
+
+ // Enable HW flow control for transmitter
+ if(port->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX)
+ mode_reg |= MCF5272_UART_UMR2_TXCTS;
+
+ // No echo or loopback
+ mode_reg |= MCF5272_UART_UMR2_CM_NORMAL;
+
+ // Write to mode register 2
+ HAL_WRITE_UINT8(&port->base->umr, mode_reg);
+
+ // Set Rx and Tx baud by timer
+ HAL_WRITE_UINT8(&port->base->usr_ucsr, 0 | MCF5272_UART_UCSR_RCS(0xD) |
+ MCF5272_UART_UCSR_TCS(0xD));
+
+ // Mask all UART interrupts
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, 0);
+
+ // Program the baud settings to the device
+ HAL_WRITE_UINT8(&port->base->udu, (cyg_uint8)((ubgs & 0xFF00) >> 8));
+ HAL_WRITE_UINT8(&port->base->udl, (cyg_uint8)(ubgs & 0x00FF));
+
+ // Enable receiver and transmitter
+ HAL_WRITE_UINT8(&port->base->ucr, 0 | MCF5272_UART_UCR_TXRXEN);
+
+ // Enable both transmit and receive interrupt
+ port->imr_mirror = MCF5272_UART_UIMR_TXRDY | MCF5272_UART_UIMR_FFULL_RXRDY;
+
+ // Enable break interrupt only if autobaud is enabled
+ if (port->autobaud_state != AB_DISABLED)
+ port->imr_mirror |= MCF5272_UART_UIMR_DB;
+
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, port->imr_mirror);
+
+ // Return true to indicate a successful configuration
+ return true;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_lookup() - This routine is called when the device is "looked"
+// up (i.e. attached)
+//
+// INPUT:
+// tab - pointer to a pointer of the device table.
+// sub_tab - Pointer to the sub device table.
+// name - name of the device.
+//
+// RETURN:
+// Always return ENOERR.
+
+static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ return ENOERR;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_putc() - Send a character to the device output buffer.
+//
+// INPUT:
+// chan - pointer to the serial private data.
+// c - the character to output.
+//
+// RETURN:
+// 'true' if character is sent to device, return 'false' when we've
+// ran out of buffer space in the device itself.
+
+static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c)
+{
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+ cyg_uint8 usr_ucsr;
+
+ // Make sure the transmitter is not full. If it is full, return false.
+ HAL_READ_UINT8(&port->base->usr_ucsr, usr_ucsr);
+ if (!(usr_ucsr & MCF5272_UART_USR_TXRDY))
+ return false;
+
+ // Send the character
+ HAL_WRITE_UINT8(&port->base->urb_utb, c);
+
+ return true ;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_getc() - Fetch a character from the device input buffer and
+// return it to the calling routine. Wait until there
+// is a character ready.
+//
+// INPUT:
+// chan - pointer to the serial private data.
+//
+// RETURN:
+// the character read from the UART.
+
+static unsigned char MCF5272_uart_getc(serial_channel *chan)
+{
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+ cyg_uint8 usr_ucsr, urb_utb;
+
+ // Wait until character has been received
+ do
+ {
+ HAL_READ_UINT8(&port->base->usr_ucsr, usr_ucsr);
+ }
+ while (!(usr_ucsr & MCF5272_UART_USR_RXRDY)) ;
+
+ // Read the character from the FIFO queue
+ HAL_READ_UINT8(&port->base->urb_utb, urb_utb);
+
+ return urb_utb;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_set_config() - Set up the device characteristics; baud rate,
+// etc.
+//
+// INPUT:
+// chan - pointer to the serial private data.
+// key - configuration key (command).
+// xbuf - pointer to the configuration buffer.
+// len - the length of the configuration buffer.
+//
+// RETURN:
+// NOERR - If the configuration is successful.
+// EINVAL - If the argument is invalid.
+
+Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan,
+ cyg_uint32 key,
+ const void *xbuf,
+ cyg_uint32 *len)
+{
+ cyg_serial_info_t *config = (cyg_serial_info_t *) xbuf;
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+ switch (key)
+ {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ // Set serial configuration
+ if (*len < sizeof(cyg_serial_info_t))
+ return EINVAL;
+
+ *len = sizeof(cyg_serial_info_t);
+
+ if (!MCF5272_uart_config_port(chan, config))
+ return EINVAL;
+ }
+ break;
+
+ case CYG_IO_GET_CONFIG_SERIAL_INFO:
+ // Retrieve UART configuration
+ *config = port->config;
+ break;
+
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+ case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE:
+ {
+ cyg_uint32 *f = (cyg_uint32 *)xbuf;
+
+ if (*len < sizeof(*f))
+ return -EINVAL;
+
+ // we should throttle
+ if (*f) HAL_WRITE_UINT8(&port->base->uop0, MCF5272_UART_UOP0_RTS);
+ // we should no longer throttle
+ else HAL_WRITE_UINT8(&port->base->uop1, MCF5272_UART_UOP1_RTS);
+ }
+ break;
+
+ case CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG:
+ // We only support RTSCTS (and software) flow control.
+ // We clear any unsupported flags here and
+ // then return -ENOSUPP - the higher layer can then query
+ // what flags are set and decide what to do.
+ {
+ unsigned int flags_mask;
+ cyg_uint8 umr1_mask, umr2_mask;
+
+ // These are the control flow modes we support
+ flags_mask = (CYGNUM_SERIAL_FLOW_RTSCTS_RX |
+ CYGNUM_SERIAL_FLOW_RTSCTS_RX);
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE
+ flags_mask |= (CYGNUM_SERIAL_FLOW_XONXOFF_RX |
+ CYGNUM_SERIAL_FLOW_XONXOFF_TX);
+#endif
+ if (chan->config.flags & ~flags_mask)
+ {
+ chan->config.flags &= flags_mask;
+ return -ENOSUPP;
+ }
+
+ // For security, mask UART interrupt while we change configuration
+ cyg_drv_interrupt_mask(port->uart_vector);
+
+ // Reset mode register pointer
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_RESET_MR);
+
+ // Read mode register 1
+ HAL_READ_UINT8(&port->base->umr, umr1_mask);
+
+ // Read mode register 2
+ HAL_READ_UINT8(&port->base->umr, umr2_mask);
+
+ if (chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX)
+ umr1_mask |= MCF5272_UART_UMR1_RXRTS;
+ else umr1_mask &= ~MCF5272_UART_UMR1_RXRTS;
+
+ if (chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX)
+ umr2_mask |= MCF5272_UART_UMR2_TXCTS;
+ else umr2_mask &= ~MCF5272_UART_UMR2_TXCTS;
+
+ // Reset mode register pointer
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_RESET_MR);
+
+ // Write mode register 1
+ HAL_WRITE_UINT8(&port->base->umr, umr1_mask);
+
+ // Write mode register 2
+ HAL_WRITE_UINT8(&port->base->umr, umr2_mask);
+
+ // Unmask UART interrupt
+ cyg_drv_interrupt_unmask(port->uart_vector);
+ }
+ break;
+#endif // CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+
+ default:
+ return EINVAL;
+ }
+
+ return ENOERR;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_start_xmit() - Enable the transmitter on the device.
+//
+// INPUT:
+// chan - pointer to the serial private data.
+
+static void MCF5272_uart_start_xmit(serial_channel *chan)
+{
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+
+ // Mask UART interrupt to prevent race conditions
+ cyg_drv_interrupt_mask(port->uart_vector);
+
+ // Enable the UART transmitter.
+ // Eventually, preserve the ongoing autobaud calculation.
+#ifdef REQUESTED_AUTOBAUD
+ if(port->autobaud_state == AB_BEGIN)
+ HAL_WRITE_UINT8(&port->base->ucr, (MCF5272_UART_UCR_TX_ENABLED |
+ MCF5272_UART_UCR_ENAB));
+ else
+#endif
+ {
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_TX_ENABLED);
+ }
+
+ // Enable transmitter interrupt
+ port->imr_mirror |= MCF5272_UART_UIMR_TXRDY;
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, port->imr_mirror);
+
+ // Unmask UART interrupt
+ cyg_drv_interrupt_unmask(port->uart_vector);
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_stop_xmit() - Disable the transmitter on the device
+//
+// INPUT:
+// chan - pointer to the serial private data.
+
+static void MCF5272_uart_stop_xmit(serial_channel * chan)
+{
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+
+ // Mask UART interrupt to prevent race conditions
+ cyg_drv_interrupt_mask(port->uart_vector);
+
+ // Disable transmitter interrupt
+ port->imr_mirror &= ~MCF5272_UART_UIMR_TXRDY;
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, port->imr_mirror);
+
+ // Disable the UART transmitter.
+ // Eventually, preserve the ongoing autobaud calculation.
+ // !!!!!!!!!!!!!
+ // !!!WARNING!!!
+ // !!!!!!!!!!!!!
+ // If the transmitter is disabled
+ // the diag_printf routines will poll forever to transmit the
+ // a character. Hence, don't ever disable the transmitter if
+ // you want it to work with diag_printf.
+#ifdef REQUESTED_AUTOBAUD
+ if(port->autobaud_state == AB_BEGIN)
+ HAL_WRITE_UINT8(&port->base->ucr, (MCF5272_UART_UCR_TX_DISABLED |
+ MCF5272_UART_UCR_ENAB));
+ else
+#endif
+ {
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_TX_DISABLED);
+ }
+
+ // Unmask UART interrupt
+ cyg_drv_interrupt_unmask(port->uart_vector);
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_ISR() - UART I/O interrupt interrupt service routine (ISR).
+//
+// INPUT:
+// vector - the interrupt vector number.
+// data - user parameter.
+//
+// RETURN:
+// returns CYG_ISR_CALL_DSR to call the DSR.
+
+static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *) data;
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+
+ // Write the value in the interrupt status register back
+ // to the mask register to disable the interrupt temporarily.
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, 0);
+
+ // Cause DSR to run
+ return CYG_ISR_CALL_DSR;
+}
+
+
+// ***************************************************************************
+// MCF5272_uart_DSR() - Defered Service Routine (DSR) - This routine processes
+// the interrupt from the device.
+//
+// INPUT:
+// vector - The interrupt vector number.
+// count - The nunber of DSR requests.
+// data - Device specific information.
+//
+// The autobaud feature is implemented by means of a simple finite state
+// machine which can take the following states:
+// AB_DISABLED: autobaud is disabled.
+// AB_IDLE: no autobaud calculation is in progress. If autobaud calculation
+// has completed, retrieve the new baud rate.
+// AB_BEGIN_BREAK: the start of a break character was detected.
+// AB_BEGIN: the end of a break character was detected. Start autobaud
+// calculation.
+//
+// The state diagram is the following:
+// AB_IDLE --> AB_BEGIN_BREAK --> AB_BEGIN --> Back to AB_IDLE
+// The state AB_DISABLED is isolated and means that the autobaud feature is
+// not active for that port.
+
+static void MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *) data;
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *) chan->dev_priv;
+ volatile cyg_uint8 isr;
+ cyg_uint8 uisr_uimr;
+
+
+ while (1)
+ {
+ // First of all, the exit condition
+
+ // Retrieve the interrupt status bits. We use these status bits to
+ // figure out what process should we perform: read from the UART or
+ // inform of a completion of a data transmission.
+ HAL_READ_UINT8(&port->base->uisr_uimr, uisr_uimr);
+ isr = uisr_uimr & port->imr_mirror;
+
+ // If there are no more events pending, exit the loop
+ if (!isr) break;
+
+#ifdef REQUESTED_AUTOBAUD
+ switch (port->autobaud_state)
+ {
+ case AB_DISABLED:
+ // Nothing to check for
+ break;
+
+ case AB_BEGIN_BREAK:
+ if (isr & MCF5272_UART_UISR_DB)
+ {
+ // Detected the end of a break, set the state to
+ // AB_BEGIN, and setup autobaud detection.
+ port->autobaud_state = AB_BEGIN;
+
+ // Initialize divider
+ HAL_WRITE_UINT8(&port->base->udu, 0);
+ HAL_WRITE_UINT8(&port->base->udl, 0);
+
+ // Reset the Delta Break bit in the UISR and
+ //Enable autobaud
+ HAL_WRITE_UINT8(&port->base->ucr,
+ MCF5272_UART_UCR_RESET_BKCHGINT);
+
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_ENAB);
+
+ // Enable autobaud completion interrupt
+ port->imr_mirror |= MCF5272_UART_UIMR_ABC;
+
+ // Disable the delta break interrupt so we can't receive
+ // anymore break interrupt.
+ port->imr_mirror &= ~MCF5272_UART_UIMR_DB;
+
+ }
+ break;
+
+ case AB_BEGIN:
+ if (isr & MCF5272_UART_UISR_ABC)
+ {
+ int count;
+ unsigned int threshold;
+ cyg_uint8 uabu, uabl;
+
+ // Retrieve the detected baud rate
+ HAL_READ_UINT8(&port->base->uabu, uabu);
+ HAL_READ_UINT8(&port->base->uabl, uabl);
+
+ cyg_uint16 divider = (uabu << 8) + uabl;
+
+ // Search in the list to find a match
+ for (count = sizeof(dividers_table)/
+ sizeof(unsigned long) - 1;
+ count > 1; count--)
+ {
+ if (divider < dividers_table[count - 1]) break;
+ }
+
+ // Modify baud rate only if it is in range
+ if (count > 1)
+ {
+ // Set the baud rate to the nearest standard rate
+ threshold = (dividers_table[count] +
+ dividers_table[count - 1]) / 2;
+ port->config.baud = (divider < threshold) ? count :
+ count - 1;
+ }
+
+ divider = dividers_table[port->config.baud];
+
+ // Program the baud settings to the device
+ HAL_WRITE_UINT8(&port->base->udu,
+ (cyg_uint8)((divider & 0xFF00) >> 8));
+ HAL_WRITE_UINT8(&port->base->udl,
+ (cyg_uint8)(divider & 0x00FF));
+
+ // Autobaud completion
+ port->autobaud_state = AB_IDLE;
+
+ // Disable autobaud
+ HAL_WRITE_UINT8(&port->base->ucr, MCF5272_UART_UCR_NONE);
+
+#if 0
+ // In case patch submitted July 11, 2005 gets committed
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ // Inform upper layers of the new baud rate
+ {
+ cyg_serial_line_status_t stat;
+
+ stat.which = CYGNUM_SERIAL_STATUS_NEWBAUDRATE;
+ stat.value = port->config.baud;
+
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+#endif
+ // Ignore autobaud completion interrupt
+ port->imr_mirror &= ~MCF5272_UART_UIMR_ABC;
+
+ // Reenable delta break interrupt
+ port->imr_mirror |= MCF5272_UART_UIMR_DB;
+
+ }
+ break;
+
+ default:
+ case AB_IDLE:
+ if (isr & MCF5272_UART_UISR_DB)
+ {
+ // Detected the begin of a break, set the state to
+ // AB_BEGIN_BREAK
+ port->autobaud_state = AB_BEGIN_BREAK;
+
+ // Reset the delta break bit in the UISR
+ HAL_WRITE_UINT8(&port->base->ucr,
+ MCF5272_UART_UCR_RESET_BKCHGINT);
+ }
+ break;
+ }
+#endif // REQUESTED_AUTOBAUD
+
+ // Receive character interrupt
+ if ((isr & MCF5272_UART_UISR_RXRDY))
+ {
+ char c;
+ cyg_uint8 usr_ucsr;
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ cyg_serial_line_status_t stat;
+#endif
+
+ // Read all the characters in the fifo
+ while (1)
+ {
+ // First of all, the exit condition
+
+ // If there are no more characters waiting, exit the loop
+ HAL_READ_UINT8(&port->base->uisr_uimr, uisr_uimr);
+ if (!(uisr_uimr & MCF5272_UART_UISR_RXRDY)) break;
+
+ // Read port status
+ HAL_READ_UINT8(&port->base->usr_ucsr, usr_ucsr);
+
+ // Received break
+ if (usr_ucsr & MCF5272_UART_USR_RB)
+ {
+ // Ignore break character
+ HAL_READ_UINT8(&port->base->urb_utb, c);
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ stat.which = CYGNUM_SERIAL_STATUS_BREAK;
+ (chan->callbacks->indicate_status)(chan, &stat);
+#endif
+ continue;
+ }
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ // Overrun error
+ if (usr_ucsr & MCF5272_UART_USR_OE)
+ {
+ stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ // Framing error
+ if (usr_ucsr & MCF5272_UART_USR_FE)
+ {
+ stat.which = CYGNUM_SERIAL_STATUS_FRAMEERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ // Parity error
+ if (usr_ucsr & MCF5272_UART_USR_PE)
+ {
+ stat.which = CYGNUM_SERIAL_STATUS_PARITYERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+
+ // Read the character from the UART
+ HAL_READ_UINT8(&port->base->urb_utb, c);
+
+ // Pass the read character to the upper layer
+ (chan->callbacks->rcv_char)(chan, c);
+ }
+ }
+
+ // Transmit complete interrupt
+ if ((isr & MCF5272_UART_UISR_TXRDY))
+ {
+ // Transmit holding register is empty
+ (chan->callbacks->xmt_char)(chan);
+ }
+ }
+
+ // Unmask all the UART interrupts that were masked in the ISR, so
+ // that we can receive the next interrupt.
+ HAL_WRITE_UINT8(&port->base->uisr_uimr, port->imr_mirror);
+}
diff --git a/ecos/packages/devs/serial/coldfire/mcf5272/current/src/mcf5272_serial.h b/ecos/packages/devs/serial/coldfire/mcf5272/current/src/mcf5272_serial.h
new file mode 100644
index 0000000..b075a14
--- /dev/null
+++ b/ecos/packages/devs/serial/coldfire/mcf5272/current/src/mcf5272_serial.h
@@ -0,0 +1,141 @@
+#ifndef CYGONCE_MCF5272_SERIAL_H
+#define CYGONCE_MCF5272_SERIAL_H
+
+//==========================================================================
+//
+// devs/serial/coldfire/mcf5272/mcf5272_serial.h
+//
+// ColdFire MCF5272 serial I/O module definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Enrico Piria, Wade Jensen
+// Contributors:
+// Date: 2005-06-25
+// Purpose: MCF5272 serial I/O module definitions.
+// Description:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+#include <pkgconf/io_serial_coldfire_mcf5272.h>
+
+// Bit level definitions and macros
+#define MCF5272_UART_UMR1_RXRTS (0x80)
+#define MCF5272_UART_UMR1_RXIRQ (0x40)
+#define MCF5272_UART_UMR1_ERR (0x20)
+#define MCF5272_UART_UMR1_PM_MULTI_ADDR (0x1C)
+#define MCF5272_UART_UMR1_PM_MULTI_DATA (0x18)
+#define MCF5272_UART_UMR1_PM_NONE (0x10)
+#define MCF5272_UART_UMR1_PM_FORCE_HI (0x0C)
+#define MCF5272_UART_UMR1_PM_FORCE_LO (0x08)
+#define MCF5272_UART_UMR1_PM_ODD (0x04)
+#define MCF5272_UART_UMR1_PM_EVEN (0x00)
+#define MCF5272_UART_UMR1_BC_5 (0x00)
+#define MCF5272_UART_UMR1_BC_6 (0x01)
+#define MCF5272_UART_UMR1_BC_7 (0x02)
+#define MCF5272_UART_UMR1_BC_8 (0x03)
+
+#define MCF5272_UART_UMR2_CM_NORMAL (0x00)
+#define MCF5272_UART_UMR2_CM_ECHO (0x40)
+#define MCF5272_UART_UMR2_CM_LOCAL_LOOP (0x80)
+#define MCF5272_UART_UMR2_CM_REMOTE_LOO (0xC0)
+#define MCF5272_UART_UMR2_TXRTS (0x20)
+#define MCF5272_UART_UMR2_TXCTS (0x10)
+#define MCF5272_UART_UMR2_STOP_BITS_1 (0x07)
+#define MCF5272_UART_UMR2_STOP_BITS_15 (0x08)
+#define MCF5272_UART_UMR2_STOP_BITS_2 (0x0F)
+// Stop Bit Length
+#define MCF5272_UART_UMR2_STOP_BITS(a) ((a)&0x0f)
+
+#define MCF5272_UART_USR_RB (0x80)
+#define MCF5272_UART_USR_FE (0x40)
+#define MCF5272_UART_USR_PE (0x20)
+#define MCF5272_UART_USR_OE (0x10)
+#define MCF5272_UART_USR_TXEMP (0x08)
+#define MCF5272_UART_USR_TXRDY (0x04)
+#define MCF5272_UART_USR_FFULL (0x02)
+#define MCF5272_UART_USR_RXRDY (0x01)
+
+// Rx Clk Select
+#define MCF5272_UART_UCSR_RCS(a) (((a) & 0x0f) << 4)
+// Tx Clk Select
+#define MCF5272_UART_UCSR_TCS(a) ((a) & 0x0f)
+
+
+#define MCF5272_UART_UCR_NONE (0x00)
+#define MCF5272_UART_UCR_ENAB (0x80)
+#define MCF5272_UART_UCR_STOP_BREAK (0x70)
+#define MCF5272_UART_UCR_START_BREAK (0x60)
+#define MCF5272_UART_UCR_RESET_BKCHGINT (0x50)
+#define MCF5272_UART_UCR_RESET_ERROR (0x40)
+#define MCF5272_UART_UCR_RESET_TX (0x30)
+#define MCF5272_UART_UCR_RESET_RX (0x20)
+#define MCF5272_UART_UCR_RESET_MR (0x10)
+#define MCF5272_UART_UCR_TX_DISABLED (0x08)
+#define MCF5272_UART_UCR_TX_ENABLED (0x04)
+#define MCF5272_UART_UCR_RX_DISABLED (0x02)
+#define MCF5272_UART_UCR_RX_ENABLED (0x01)
+
+#define MCF5272_UART_UCR_TXRXEN \
+ (MCF5272_UART_UCR_TX_ENABLED | MCF5272_UART_UCR_RX_ENABLED)
+
+#define MCF5272_UART_UCCR_COS (0x10)
+#define MCF5272_UART_UCCR_CTS (0x01)
+
+#define MCF5272_UART_UACR_BRG (0x80)
+#define MCF5272_UART_UACR_CTMS_TIMER (0x60)
+#define MCF5272_UART_UACR_IEC (0x01)
+
+#define MCF5272_UART_UISR_COS (0x80)
+#define MCF5272_UART_UISR_ABC (0x40)
+#define MCF5272_UART_UISR_DB (0x04)
+#define MCF5272_UART_UISR_RXRDY (0x02)
+#define MCF5272_UART_UISR_TXRDY (0x01)
+
+#define MCF5272_UART_UIMR_COS (0x80)
+#define MCF5272_UART_UIMR_ABC (0x40)
+#define MCF5272_UART_UIMR_DB (0x04)
+#define MCF5272_UART_UIMR_FFULL_RXRDY (0x02)
+#define MCF5272_UART_UIMR_TXRDY (0x01)
+
+#define MCF5272_UART_UOP0_RTS (0x01)
+#define MCF5272_UART_UOP1_RTS (0x01)
+
+// ---------------------------------------------------------------------------
+// End of mcf5272_serial.h
+#endif // CYGONCE_MCF5272_SERIAL_H
diff --git a/ecos/packages/devs/serial/cortexm/a2fxxx/current/ChangeLog b/ecos/packages/devs/serial/cortexm/a2fxxx/current/ChangeLog
new file mode 100644
index 0000000..0dffdc0
--- /dev/null
+++ b/ecos/packages/devs/serial/cortexm/a2fxxx/current/ChangeLog
@@ -0,0 +1,30 @@
+2011-03-20 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * cdl/ser_cortexm_a2fxxx.cdl
+ * include/ser_cortexm_a2fxxx.inl
+ New package -- Actel smartfusion Serial Driver
+ [Bugzilla 1001291]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/cortexm/a2fxxx/current/cdl/ser_cortexm_a2fxxx.cdl b/ecos/packages/devs/serial/cortexm/a2fxxx/current/cdl/ser_cortexm_a2fxxx.cdl
new file mode 100644
index 0000000..fe6fcdb
--- /dev/null
+++ b/ecos/packages/devs/serial/cortexm/a2fxxx/current/cdl/ser_cortexm_a2fxxx.cdl
@@ -0,0 +1,219 @@
+# ====================================================================
+#
+# ser_cortexm_a2fxxx.cdl
+#
+# eCos serial Cortex-M3/Actel Smartfusion configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ccoutand
+# Original data: gthomas
+# Contributors:
+# Date: 2011-03-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_CORTEXM_A2FXXX {
+ display "Cortex-M3/Actel Smartfusion serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_CORTEXM_A2FXXX
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO
+
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ Cortex-M3/Actel Smartfusion."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 4"
+ }
+
+ requires { CYGPKG_IO_SERIAL_GENERIC_16X5X_XMIT_REQUIRE_PRIME == "1" }
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/ser_cortexm_a2fxxx.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_cortexm_a2fxxx.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0 {
+ display "Cortex-M3/Actel Smartfusion serial port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the
+ Cortex-M3/Actel Smartfusion port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_NAME {
+ display "Device name for the serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device
+ for the Cortex-M3/Actel Smartfusion port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_BAUD {
+ display "Baud rate for the serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the Cortex-M3/Actel Smartfusion port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_BUFSIZE {
+ display "Buffer size for the serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the Cortex-M3/Actel Smartfusion port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_INTPRIO {
+ display "Interrupt priority of the serial port 0 ISR"
+ flavor data
+ default_value { CYGNUM_DEVS_SERIAL_CORTEXM_A2FXXX_SERIAL0_ISR_SP }
+ requires { is_active(CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_INTPRIO)
+ implies CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_INTPRIO !=
+ CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_INTPRIO }
+ description "
+ This option specifies the interrupt priority of the
+ ISR of the serial port 1 interrupt in the NVIC."
+ }
+
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1 {
+ display "Cortex-M3/Actel Smartfusion serial port 1 driver"
+ flavor bool
+ default_value 0
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the
+ Cortex-M3/Actel Smartfusion port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_NAME {
+ display "Device name for the serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of the serial device
+ for the Cortex-M3/Actel Smartfusion port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_BAUD {
+ display "Baud rate for the serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the Cortex-M3/Actel Smartfusion port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_BUFSIZE {
+ display "Buffer size for the serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal
+ buffers used for the Cortex-M3/Actel Smartfusion port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_INTPRIO {
+ display "Interrupt priority of the serial port 1 ISR"
+ flavor data
+ default_value { CYGNUM_DEVS_SERIAL_CORTEXM_A2FXXX_SERIAL0_ISR_SP }
+ description "
+ This option specifies the interrupt priority of the
+ ISR of the serial port 1 interrupt in the NVIC."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_CORTEXM_A2FXXX_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"a2fxxx\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_cortexm_a2fxx.cdl
diff --git a/ecos/packages/devs/serial/cortexm/a2fxxx/current/include/ser_cortexm_a2fxxx.inl b/ecos/packages/devs/serial/cortexm/a2fxxx/current/include/ser_cortexm_a2fxxx.inl
new file mode 100644
index 0000000..7d7ab23
--- /dev/null
+++ b/ecos/packages/devs/serial/cortexm/a2fxxx/current/include/ser_cortexm_a2fxxx.inl
@@ -0,0 +1,210 @@
+//==========================================================================
+//
+// ser_cortexm_a2fxxx.inl
+//
+// eCos serial Cortex-M3/Actel Smartfusion I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand
+// Contributors:
+// Date: 2011-03-20
+// Purpose: Cortex-M3/Actel Smartfusion Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification
+
+// Baud rate specification
+static const unsigned int select_baud[] =
+{
+ 9999, // Unused
+ 50,
+ 75,
+ 110,
+ 134.5,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 3600,
+ 4800,
+ 7200,
+ 9600,
+ 14400,
+ 19200,
+ 38400,
+ 57600,
+ 115200,
+ 230400
+};
+
+
+//-----------------------------------------------------------------------------
+// Return baudrate devisor for certain baudrate
+
+unsigned short a2fxxx_baud_generator(pc_serial_info *ser_chan,
+ cyg_serial_baud_rate_t baud)
+{
+ cyg_uint8 pclk_id = 0;
+ switch (ser_chan->base)
+ {
+ case CYGHWR_HAL_A2FXXX_UART0:
+ pclk_id = 0;
+ break;
+
+ case CYGHWR_HAL_A2FXXX_UART1:
+ pclk_id = 1;
+ break;
+ default:
+ CYG_FAIL("Invalid UART base address");
+ } // (ser_chan->base)
+
+ return CYG_HAL_CORTEXM_A2FXXX_BAUD_GENERATOR(pclk_id, select_baud[baud]);
+}
+
+
+#define CYG_IO_SERIAL_GENERIC_16X5X_CHAN_BAUD_GENERATOR(_ser_chan_, _baud_) \
+ a2fxxx_baud_generator((_ser_chan_), (_baud_))
+
+
+#ifdef CYGPKG_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0
+static pc_serial_info a2fxxx_serial_info0 =
+ { CYGHWR_HAL_A2FXXX_UART0,
+ CYGNUM_HAL_INTERRUPT_UART0,
+ CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_INTPRIO
+ };
+
+#if CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_BUFSIZE > 0
+static unsigned char
+a2fxxx_serial_out_buf0[CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_BUFSIZE];
+static unsigned char
+a2fxxx_serial_in_buf0[CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(a2fxxx_serial_channel0,
+ pc_serial_funs,
+ a2fxxx_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &a2fxxx_serial_out_buf0[0],
+ sizeof(a2fxxx_serial_out_buf0),
+ &a2fxxx_serial_in_buf0[0],
+ sizeof(a2fxxx_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(a2fxxx_serial_channel0,
+ pc_serial_funs,
+ a2fxxx_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(a2fxxx_serial_io0,
+ CYGDAT_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &a2fxxx_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_CORTEXM_A2FXXX_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1
+static pc_serial_info a2fxxx_serial_info1 =
+ { CYGHWR_HAL_A2FXXX_UART1,
+ CYGNUM_HAL_INTERRUPT_UART1,
+ CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_INTPRIO
+ };
+#if CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_BUFSIZE > 0
+static unsigned char
+a2fxxx_serial_out_buf1[CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_BUFSIZE];
+static unsigned char
+a2fxxx_serial_in_buf1[CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(a2fxxx_serial_channel1,
+ pc_serial_funs,
+ a2fxxx_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &a2fxxx_serial_out_buf1[0],
+ sizeof(a2fxxx_serial_out_buf1),
+ &a2fxxx_serial_in_buf1[0],
+ sizeof(a2fxxx_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(a2fxxx_serial_channel1,
+ pc_serial_funs,
+ a2fxxx_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(a2fxxx_serial_io1,
+ CYGDAT_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1_NAME,
+ 0, // Does not depend on a lower
+ // level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &a2fxxx_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_CORTEXM_A2FXXX_SERIAL1
+
+// EOF ser_cortexm_a2fxxx.inl
diff --git a/ecos/packages/devs/serial/cortexm/stm32/current/ChangeLog b/ecos/packages/devs/serial/cortexm/stm32/current/ChangeLog
new file mode 100644
index 0000000..4c8561e
--- /dev/null
+++ b/ecos/packages/devs/serial/cortexm/stm32/current/ChangeLog
@@ -0,0 +1,70 @@
+2012-04-02 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/stm32_serial.h: Revert unnecessary change in previous
+ commit, reinstating previous code.
+ * src/stm32_serial.c (stm32_serial_config_port): Ditto.
+
+2011-12-15 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_cortexm_stm32.cdl: Default baud rates to the HAL
+ diag console channel. Add support for serial port 5
+ (USART6 in STM32 speak). Select serial/tty test devices better
+ according to the configuration.
+ * src/stm32_serial.c: Support serial port 5. Make use of AFIO
+ remap specific to F1 processors.
+
+2010-12-31 John Dallaway <john@dallaway.org.uk>
+
+ * src/stm32_serial.c, src/stm32_serial.h: Set the M bit when
+ configuring for 8 data bits + parity bit. [ Bugzilla 1001068 ]
+
+2009-12-03 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/ser_cortexm_stm32.cdl:
+ * src/stm32_serial.c (stm32_serial_info, stm32_serial_info0)
+ (stm32_serial_info1, stm32_serial_info2, stm32_serial_info3)
+ (stm32_serial_info4, stm32_serial_init):
+ Add configuration options to set serial ISR interrupt priorities.
+
+2009-07-02 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/stm32_serial.c (stm32_serial_info)
+ (stm32_serial_config_port): Add support for UART pin remap.
+
+2009-06-29 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/stm32_serial.c (stm32_serial_info)
+ (stm32_serial_config_port): Add support for individual clock
+ enable on each UART.
+
+2008-10-07 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/ser_cortexm_stm32.cdl:
+ * src/stm32_serial.h:
+ * src/stm32_serial.c:
+ New package: serial driver support for ST STM32
+ microcontrollers.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/cortexm/stm32/current/cdl/ser_cortexm_stm32.cdl b/ecos/packages/devs/serial/cortexm/stm32/current/cdl/ser_cortexm_stm32.cdl
new file mode 100644
index 0000000..a5b1e91
--- /dev/null
+++ b/ecos/packages/devs/serial/cortexm/stm32/current/cdl/ser_cortexm_stm32.cdl
@@ -0,0 +1,422 @@
+# ====================================================================
+#
+# ser_cortexm_stm32.cdl
+#
+# eCos serial ST STM32 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008, 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): nickg
+# Date: 2008-09-10
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_CORTEXM_STM32 {
+ display "ST STM32 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_CORTEXM_STM32
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ description "
+ This option enables the serial device drivers for the
+ ST STM32."
+
+ compile -library=libextras.a stm32_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_cortexm_stm32.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL0 {
+ display "ST STM32 serial port 0 driver"
+ flavor bool
+ default_value CYGINT_HAL_STM32_UART0>0
+ description "
+ This option includes the serial device driver for the ST STM32
+ port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL0_NAME {
+ display "Device name for ST STM32 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device for the
+ ST STM32 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BAUD {
+ display "Baud rate for the ST STM32 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value { CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD }
+ description "
+ This option specifies the default baud rate (speed) for the
+ ST STM32 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BUFSIZE {
+ display "Buffer size for the ST STM32 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ST STM32 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_INT_PRI {
+ display "Interrupt priority for STM32 serial port 0"
+ flavor data
+ default_value 128
+ legal_values 0 to 255
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL1 {
+ display "ST STM32 serial port 1 driver"
+ flavor bool
+ default_value CYGINT_HAL_STM32_UART1>0
+ description "
+ This option includes the serial device driver for the ST STM32
+ port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL1_NAME {
+ display "Device name for ST STM32 serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of the serial device for the
+ ST STM32 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BAUD {
+ display "Baud rate for the ST STM32 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
+ description "
+ This option specifies the default baud rate (speed) for the
+ ST STM32 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BUFSIZE {
+ display "Buffer size for the ST STM32 serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ST STM32 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_INT_PRI {
+ display "Interrupt priority for STM32 serial port 1"
+ flavor data
+ default_value 128
+ legal_values 0 to 255
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL2 {
+ display "ST STM32 serial port 2 driver"
+ flavor bool
+ default_value CYGINT_HAL_STM32_UART2>0
+ description "
+ This option includes the serial device driver for the ST STM32
+ port 2."
+
+ cdl_option CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL2_NAME {
+ display "Device name for ST STM32 serial port 2 driver"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the name of the serial device for the
+ ST STM32 port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BAUD {
+ display "Baud rate for the ST STM32 serial port 2 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
+ description "
+ This option specifies the default baud rate (speed) for the
+ ST STM32 port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BUFSIZE {
+ display "Buffer size for the ST STM32 serial port 2 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ST STM32 port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_INT_PRI {
+ display "Interrupt priority for STM32 serial port 2"
+ flavor data
+ default_value 128
+ legal_values 0 to 255
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL3 {
+ display "ST STM32 serial port 3 driver"
+ flavor bool
+ default_value CYGINT_HAL_STM32_UART3>0
+ description "
+ This option includes the serial device driver for the ST STM32
+ port 3."
+
+ cdl_option CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL3_NAME {
+ display "Device name for ST STM32 serial port 3 driver"
+ flavor data
+ default_value {"\"/dev/ser3\""}
+ description "
+ This option specifies the name of the serial device for the
+ ST STM32 port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BAUD {
+ display "Baud rate for the ST STM32 serial port 3 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
+ description "
+ This option specifies the default baud rate (speed) for the
+ ST STM32 port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BUFSIZE {
+ display "Buffer size for the ST STM32 serial port 3 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ST STM32 port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_INT_PRI {
+ display "Interrupt priority for STM32 serial port 3"
+ flavor data
+ default_value 128
+ legal_values 0 to 255
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL4 {
+ display "ST STM32 serial port 4 driver"
+ flavor bool
+ default_value CYGINT_HAL_STM32_UART4>0
+ description "
+ This option includes the serial device driver for the ST STM32
+ port 4."
+
+ cdl_option CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL4_NAME {
+ display "Device name for ST STM32 serial port 4 driver"
+ flavor data
+ default_value {"\"/dev/ser4\""}
+ description "
+ This option specifies the name of the serial device for the
+ ST STM32 port 4."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BAUD {
+ display "Baud rate for the ST STM32 serial port 4 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
+ description "
+ This option specifies the default baud rate (speed) for the
+ ST STM32 port 4."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BUFSIZE {
+ display "Buffer size for the ST STM32 serial port 4 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ST STM32 port 4."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_INT_PRI {
+ display "Interrupt priority for STM32 serial port 4"
+ flavor data
+ default_value 128
+ legal_values 0 to 255
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL5 {
+ display "ST STM32 serial port 5 driver"
+ flavor bool
+ default_value CYGINT_HAL_STM32_UART5>0
+ description "
+ This option includes the serial device driver for the ST STM32
+ port 5."
+
+ cdl_option CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL5_NAME {
+ display "Device name for ST STM32 serial port 5 driver"
+ flavor data
+ default_value {"\"/dev/ser5\""}
+ description "
+ This option specifies the name of the serial device for the
+ ST STM32 port 5."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BAUD {
+ display "Baud rate for the ST STM32 serial port 5 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
+ description "
+ This option specifies the default baud rate (speed) for the
+ ST STM32 port 5."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BUFSIZE {
+ display "Buffer size for the ST STM32 serial port 5 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the ST STM32 port 5."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_INT_PRI {
+ display "Interrupt priority for STM32 serial port 5"
+ flavor data
+ default_value 128
+ legal_values 0 to 255
+ }
+}
+
+
+ cdl_component CYGPKG_IO_SERIAL_CORTEXM_STM32_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_CORTEXM_STM32_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_CORTEXM_STM32_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_CORTEXM_STM32_TESTING {
+ display "Testing parameters"
+ flavor none
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_57600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_38400
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL0 ? CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL0_NAME : \
+ CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL1 ? CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL1_NAME : \
+ CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL2 ? CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL2_NAME : \
+ CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL3 ? CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL3_NAME : \
+ CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL4 ? CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL4_NAME : \
+ CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL5_NAME }
+ }
+
+ cdl_option CYGPRI_SER_TEST_TTY_DEV {
+ display "TTY-mode serial device used for testing"
+ flavor data
+ default_value { CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL0 ? "\"/dev/tty0\"" : \
+ CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL1 ? "\"/dev/tty1\"" : \
+ CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL2 ? "\"/dev/tty2\"" : \
+ CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL3 ? "\"/dev/tty3\"" : \
+ CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL4 ? "\"/dev/tty4\"" : \
+ "\"/dev/tty5\"" }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"stm32\""
+ }
+ }
+}
+
+# EOF ser_cortexm_stm32.cdl
diff --git a/ecos/packages/devs/serial/cortexm/stm32/current/src/stm32_serial.c b/ecos/packages/devs/serial/cortexm/stm32/current/src/stm32_serial.c
new file mode 100644
index 0000000..8572d62
--- /dev/null
+++ b/ecos/packages/devs/serial/cortexm/stm32/current/src/stm32_serial.c
@@ -0,0 +1,946 @@
+//==========================================================================
+//
+// devs/serial/cortexm/stm32/stm32_serial.c
+//
+// ST STM32 Serial I/O Interface Module
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998-2002, 2004-2006, 2008-2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Date: 2008-09-10
+// Purpose: ST STM32 Serial I/O module
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/infra.h>
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <pkgconf/kernel.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+
+
+#ifdef CYGPKG_IO_SERIAL_CORTEXM_STM32
+
+#include "stm32_serial.h"
+
+//==========================================================================
+
+#define STM32_RXBUFSIZE 16
+
+typedef struct stm32_serial_info
+{
+ CYG_WORD uart;
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_int32 int_pri;
+ cyg_int32 rx_pin;
+ cyg_int32 tx_pin;
+ cyg_int32 rts_pin;
+ cyg_int32 cts_pin;
+ cyg_int32 clk_enable;
+#if defined(CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1)
+ cyg_int32 remap;
+#endif
+
+ cyg_bool tx_active;
+
+ volatile cyg_uint8 buf[STM32_RXBUFSIZE];
+ volatile int buf_head;
+ volatile int buf_tail;
+
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} stm32_serial_info;
+
+//==========================================================================
+
+static bool stm32_serial_init(struct cyg_devtab_entry *tab);
+static bool stm32_serial_putc_interrupt(serial_channel *chan, unsigned char c);
+#if (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL0) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL1) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL2) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL3) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL4) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL5) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BUFSIZE == 0)
+static bool stm32_serial_putc_polled(serial_channel *chan, unsigned char c);
+#endif
+static Cyg_ErrNo stm32_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char stm32_serial_getc_interrupt(serial_channel *chan);
+#if (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL0) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL1) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL2) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL3) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL4) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL5) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BUFSIZE == 0)
+static unsigned char stm32_serial_getc_polled(serial_channel *chan);
+#endif
+static Cyg_ErrNo stm32_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void stm32_serial_start_xmit(serial_channel *chan);
+static void stm32_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 stm32_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void stm32_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+//==========================================================================
+
+#if (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL0) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BUFSIZE > 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL1) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BUFSIZE > 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL2) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BUFSIZE > 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL3) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BUFSIZE > 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL4) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BUFSIZE > 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL5) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BUFSIZE > 0)
+static SERIAL_FUNS(stm32_serial_funs_interrupt,
+ stm32_serial_putc_interrupt,
+ stm32_serial_getc_interrupt,
+ stm32_serial_set_config,
+ stm32_serial_start_xmit,
+ stm32_serial_stop_xmit
+ );
+#endif
+
+#if (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL0) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL1) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL2) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL3) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL4) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BUFSIZE == 0) \
+ || (defined(CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL5) && CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BUFSIZE == 0)
+static SERIAL_FUNS(stm32_serial_funs_polled,
+ stm32_serial_putc_polled,
+ stm32_serial_getc_polled,
+ stm32_serial_set_config,
+ stm32_serial_start_xmit,
+ stm32_serial_stop_xmit
+ );
+#endif
+
+//==========================================================================
+
+#ifdef CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL0
+static stm32_serial_info stm32_serial_info0 = {
+ uart : 0,
+ base : (CYG_ADDRWORD) CYGHWR_HAL_STM32_UART1,
+ int_num : CYGNUM_HAL_INTERRUPT_UART1,
+ int_pri : CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_INT_PRI,
+ rx_pin : CYGHWR_HAL_STM32_UART1_RX,
+ tx_pin : CYGHWR_HAL_STM32_UART1_TX,
+ rts_pin : CYGHWR_HAL_STM32_UART1_RTS,
+ cts_pin : CYGHWR_HAL_STM32_UART1_CTS,
+ clk_enable : CYGHWR_HAL_STM32_UART1_CLOCK,
+#ifdef CYGHWR_HAL_STM32_UART1_REMAP_CONFIG
+ remap : CYGHWR_HAL_STM32_UART1_REMAP_CONFIG,
+#endif
+};
+
+#if CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BUFSIZE > 0
+static unsigned char stm32_serial_out_buf0[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BUFSIZE];
+static unsigned char stm32_serial_in_buf0[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(stm32_serial_channel0,
+ stm32_serial_funs_interrupt,
+ stm32_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &stm32_serial_out_buf0[0], sizeof(stm32_serial_out_buf0),
+ &stm32_serial_in_buf0[0], sizeof(stm32_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(stm32_serial_channel0,
+ stm32_serial_funs_polled,
+ stm32_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(stm32_serial_io0,
+ CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ stm32_serial_init,
+ stm32_serial_lookup, // Serial driver may need initializing
+ &stm32_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL0
+
+//==========================================================================
+
+#ifdef CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL1
+static stm32_serial_info stm32_serial_info1 = {
+ uart : 1,
+ base : (CYG_ADDRWORD) CYGHWR_HAL_STM32_UART2,
+ int_num : CYGNUM_HAL_INTERRUPT_UART2,
+ int_pri : CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_INT_PRI,
+ rx_pin : CYGHWR_HAL_STM32_UART2_RX,
+ tx_pin : CYGHWR_HAL_STM32_UART2_TX,
+ rts_pin : CYGHWR_HAL_STM32_UART2_RTS,
+ cts_pin : CYGHWR_HAL_STM32_UART2_CTS,
+ clk_enable : CYGHWR_HAL_STM32_UART2_CLOCK,
+#ifdef CYGHWR_HAL_STM32_UART2_REMAP_CONFIG
+ remap : CYGHWR_HAL_STM32_UART2_REMAP_CONFIG,
+#endif
+};
+
+#if CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BUFSIZE > 0
+static unsigned char stm32_serial_out_buf1[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BUFSIZE];
+static unsigned char stm32_serial_in_buf1[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(stm32_serial_channel1,
+ stm32_serial_funs_interrupt,
+ stm32_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &stm32_serial_out_buf1[0], sizeof(stm32_serial_out_buf1),
+ &stm32_serial_in_buf1[0], sizeof(stm32_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(stm32_serial_channel1,
+ stm32_serial_funs_polled,
+ stm32_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(stm32_serial_io1,
+ CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ stm32_serial_init,
+ stm32_serial_lookup, // Serial driver may need initializing
+ &stm32_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL1
+
+//==========================================================================
+
+#ifdef CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL2
+static stm32_serial_info stm32_serial_info2 = {
+ uart : 2,
+ base : (CYG_ADDRWORD) CYGHWR_HAL_STM32_UART3,
+ int_num : CYGNUM_HAL_INTERRUPT_UART3,
+ int_pri : CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_INT_PRI,
+ rx_pin : CYGHWR_HAL_STM32_UART3_RX,
+ tx_pin : CYGHWR_HAL_STM32_UART3_TX,
+ rts_pin : CYGHWR_HAL_STM32_UART3_RTS,
+ cts_pin : CYGHWR_HAL_STM32_UART3_CTS,
+ clk_enable : CYGHWR_HAL_STM32_UART3_CLOCK,
+#ifdef CYGHWR_HAL_STM32_UART3_REMAP_CONFIG
+ remap : CYGHWR_HAL_STM32_UART3_REMAP_CONFIG,
+#endif
+};
+
+#if CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BUFSIZE > 0
+static unsigned char stm32_serial_out_buf2[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BUFSIZE];
+static unsigned char stm32_serial_in_buf2[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(stm32_serial_channel2,
+ stm32_serial_funs_interrupt,
+ stm32_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &stm32_serial_out_buf2[0], sizeof(stm32_serial_out_buf2),
+ &stm32_serial_in_buf2[0], sizeof(stm32_serial_in_buf2)
+ );
+#else
+static SERIAL_CHANNEL(stm32_serial_channel2,
+ stm32_serial_funs_polled,
+ stm32_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(stm32_serial_io2,
+ CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ stm32_serial_init,
+ stm32_serial_lookup, // Serial driver may need initializing
+ &stm32_serial_channel2
+ );
+#endif // CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL2
+
+//==========================================================================
+
+#ifdef CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL3
+static stm32_serial_info stm32_serial_info3 = {
+ uart : 3,
+ base : (CYG_ADDRWORD) CYGHWR_HAL_STM32_UART4,
+ int_num : CYGNUM_HAL_INTERRUPT_UART4,
+ int_pri : CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_INT_PRI,
+ rx_pin : CYGHWR_HAL_STM32_UART4_RX,
+ tx_pin : CYGHWR_HAL_STM32_UART4_TX,
+ rts_pin : CYGHWR_HAL_STM32_UART4_RTS,
+ cts_pin : CYGHWR_HAL_STM32_UART4_CTS,
+ clk_enable : CYGHWR_HAL_STM32_UART4_CLOCK,
+#ifdef CYGHWR_HAL_STM32_UART4_REMAP_CONFIG
+ remap : CYGHWR_HAL_STM32_UART4_REMAP_CONFIG,
+#endif
+};
+
+#if CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BUFSIZE > 0
+static unsigned char stm32_serial_out_buf3[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BUFSIZE];
+static unsigned char stm32_serial_in_buf3[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(stm32_serial_channel3,
+ stm32_serial_funs_interrupt,
+ stm32_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &stm32_serial_out_buf3[0], sizeof(stm32_serial_out_buf3),
+ &stm32_serial_in_buf3[0], sizeof(stm32_serial_in_buf3)
+ );
+#else
+static SERIAL_CHANNEL(stm32_serial_channel3,
+ stm32_serial_funs_polled,
+ stm32_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(stm32_serial_io3,
+ CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL3_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ stm32_serial_init,
+ stm32_serial_lookup, // Serial driver may need initializing
+ &stm32_serial_channel3
+ );
+#endif // CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL3
+
+//==========================================================================
+
+#ifdef CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL4
+static stm32_serial_info stm32_serial_info4 = {
+ uart : 4,
+ base : (CYG_ADDRWORD) CYGHWR_HAL_STM32_UART5,
+ int_num : CYGNUM_HAL_INTERRUPT_UART5,
+ int_pri : CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_INT_PRI,
+ rx_pin : CYGHWR_HAL_STM32_UART5_RX,
+ tx_pin : CYGHWR_HAL_STM32_UART5_TX,
+ rts_pin : CYGHWR_HAL_STM32_UART5_RTS,
+ cts_pin : CYGHWR_HAL_STM32_UART5_CTS,
+ clk_enable : CYGHWR_HAL_STM32_UART5_CLOCK,
+#ifdef CYGHWR_HAL_STM32_UART5_REMAP_CONFIG
+ remap : CYGHWR_HAL_STM32_UART5_REMAP_CONFIG,
+#endif
+};
+
+#if CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BUFSIZE > 0
+static unsigned char stm32_serial_out_buf4[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BUFSIZE];
+static unsigned char stm32_serial_in_buf4[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(stm32_serial_channel4,
+ stm32_serial_funs_interrupt,
+ stm32_serial_info4,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &stm32_serial_out_buf4[0], sizeof(stm32_serial_out_buf4),
+ &stm32_serial_in_buf4[0], sizeof(stm32_serial_in_buf4)
+ );
+#else
+static SERIAL_CHANNEL(stm32_serial_channel4,
+ stm32_serial_funs_polled,
+ stm32_serial_info4,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL4_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(stm32_serial_io4,
+ CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL4_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ stm32_serial_init,
+ stm32_serial_lookup, // Serial driver may need initializing
+ &stm32_serial_channel4
+ );
+#endif // CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL4
+
+
+//==========================================================================
+
+#ifdef CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL5
+static stm32_serial_info stm32_serial_info5 = {
+ uart : 5,
+ base : (CYG_ADDRWORD) CYGHWR_HAL_STM32_UART6,
+ int_num : CYGNUM_HAL_INTERRUPT_UART6,
+ int_pri : CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_INT_PRI,
+ rx_pin : CYGHWR_HAL_STM32_UART6_RX,
+ tx_pin : CYGHWR_HAL_STM32_UART6_TX,
+ rts_pin : CYGHWR_HAL_STM32_UART6_RTS,
+ cts_pin : CYGHWR_HAL_STM32_UART6_CTS,
+ clk_enable : CYGHWR_HAL_STM32_UART6_CLOCK,
+#ifdef CYGHWR_HAL_STM32_UART6_REMAP_CONFIG
+ remap : CYGHWR_HAL_STM32_UART6_REMAP_CONFIG,
+#endif
+};
+
+#if CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BUFSIZE > 0
+static unsigned char stm32_serial_out_buf5[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BUFSIZE];
+static unsigned char stm32_serial_in_buf5[CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(stm32_serial_channel5,
+ stm32_serial_funs_interrupt,
+ stm32_serial_info5,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &stm32_serial_out_buf5[0], sizeof(stm32_serial_out_buf5),
+ &stm32_serial_in_buf5[0], sizeof(stm32_serial_in_buf5)
+ );
+#else
+static SERIAL_CHANNEL(stm32_serial_channel5,
+ stm32_serial_funs_polled,
+ stm32_serial_info5,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_CORTEXM_STM32_SERIAL5_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(stm32_serial_io5,
+ CYGDAT_IO_SERIAL_CORTEXM_STM32_SERIAL5_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ stm32_serial_init,
+ stm32_serial_lookup, // Serial driver may need initializing
+ &stm32_serial_channel5
+ );
+#endif // CYGPKG_IO_SERIAL_CORTEXM_STM32_SERIAL5
+
+
+//==========================================================================
+// Internal function to actually configure the hardware to desired baud
+// rate, etc.
+
+static bool
+stm32_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *)chan->dev_priv;
+ const CYG_ADDRWORD base = stm32_chan->base;
+ cyg_uint32 parity = select_parity[new_config->parity];
+ cyg_uint32 word_length = ((new_config->word_length == CYGNUM_SERIAL_WORD_LENGTH_8) &&
+ (new_config->parity != CYGNUM_SERIAL_PARITY_NONE)) ?
+ CYGHWR_HAL_STM32_UART_CR1_M_9 : CYGHWR_HAL_STM32_UART_CR1_M_8;
+ cyg_uint32 stop_bits = select_stop_bits[new_config->stop];
+ cyg_uint32 cr1 = 0;
+ cyg_uint32 cr2 = 0;
+ cyg_uint32 cr3 = 0;
+
+ // Set up FIFO buffer
+ stm32_chan->buf_head = stm32_chan->buf_tail = 0;
+
+ // Set up GPIO pins
+ CYGHWR_HAL_STM32_GPIO_SET( stm32_chan->rx_pin );
+ CYGHWR_HAL_STM32_GPIO_SET( stm32_chan->tx_pin );
+ CYGHWR_HAL_STM32_GPIO_SET( stm32_chan->rts_pin );
+ CYGHWR_HAL_STM32_GPIO_SET( stm32_chan->cts_pin );
+
+ // Enable clock
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( stm32_chan->clk_enable );
+
+ // Handle any pin remapping
+#if defined (CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1)
+ if( stm32_chan->remap != 0 )
+ {
+ CYG_ADDRESS afio = CYGHWR_HAL_STM32_AFIO;
+ cyg_uint32 mapr;
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( CYGHWR_HAL_STM32_AFIO_CLOCK );
+ HAL_READ_UINT32( afio+CYGHWR_HAL_STM32_AFIO_MAPR, mapr );
+ mapr |= stm32_chan->remap;
+ HAL_WRITE_UINT32( afio+CYGHWR_HAL_STM32_AFIO_MAPR, mapr );
+ }
+#endif
+
+ // Select line parameters
+ cr1 |= parity|word_length;
+ cr2 |= stop_bits;
+
+ cr1 |= CYGHWR_HAL_STM32_UART_CR1_TE | CYGHWR_HAL_STM32_UART_CR1_RE;
+
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_UART_CR1, cr1 );
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_UART_CR2, cr2 );
+
+ // Set up baud rate
+ hal_stm32_uart_setbaud( base, select_baud[new_config->baud] );
+
+ // Enable the uart
+ cr1 |= CYGHWR_HAL_STM32_UART_CR1_UE;
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_UART_CR1, cr1 );
+
+
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+ // Handle RTS by hand but leave CTS to be handled by the UART hardware
+ if ( (new_config->flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX) && stm32_chan->cts_pin != CYGHWR_HAL_STM32_GPIO_NONE )
+ {
+ cr3 |= CYGHWR_HAL_STM32_UART_CR3_CTSE;
+ }
+#endif
+
+ if(1)
+ {
+ // Enable receive and error interrupts
+
+ cr1 |= CYGHWR_HAL_STM32_UART_CR1_RXNEIE;
+ cr3 |= CYGHWR_HAL_STM32_UART_CR3_EIE;
+
+ HAL_WRITE_UINT32( base + CYGHWR_HAL_STM32_UART_CR1, cr1 );
+ }
+
+ HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_UART_CR3, cr3 );
+
+ stm32_chan->tx_active = false;
+
+ if (new_config != &chan->config)
+ chan->config = *new_config;
+
+ return true;
+}
+
+//==========================================================================
+// Function to initialize the device. Called at bootstrap time.
+
+static bool
+stm32_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel * const chan = (serial_channel *) tab->priv;
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ int res;
+
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(stm32_chan->int_num,
+ stm32_chan->int_pri,
+ (cyg_addrword_t)chan,
+ stm32_serial_ISR,
+ stm32_serial_DSR,
+ &stm32_chan->serial_interrupt_handle,
+ &stm32_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(stm32_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(stm32_chan->int_num);
+
+ }
+
+ res = stm32_serial_config_port(chan, &chan->config, true);
+ return res;
+}
+
+//==========================================================================
+// This routine is called when the device is "looked" up (i.e. attached)
+
+static Cyg_ErrNo
+stm32_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel * const chan = (serial_channel *) (*tab)->priv;
+
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+//==========================================================================
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+
+static bool
+stm32_serial_putc_interrupt(serial_channel *chan, unsigned char c)
+{
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = stm32_chan->base;
+ cyg_uint32 status;
+
+ HAL_READ_UINT32( base + CYGHWR_HAL_STM32_UART_SR, status );
+
+ if (status & CYGHWR_HAL_STM32_UART_SR_TXE)
+ {
+ HAL_WRITE_UINT32( base + CYGHWR_HAL_STM32_UART_DR, c );
+ return true;
+ }
+
+ return false;
+}
+
+//==========================================================================
+
+static bool
+stm32_serial_putc_polled(serial_channel *chan, unsigned char c)
+{
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = stm32_chan->base;
+ cyg_uint32 status;
+
+ do {
+ HAL_READ_UINT32( base + CYGHWR_HAL_STM32_UART_SR, status );
+ } while ((status & CYGHWR_HAL_STM32_UART_SR_TXE) == 0);
+
+ HAL_WRITE_UINT32( base + CYGHWR_HAL_STM32_UART_DR, c );
+
+ return true;
+}
+
+//==========================================================================
+// Fetch a character from the device input buffer
+
+static unsigned char
+stm32_serial_getc_interrupt(serial_channel *chan)
+{
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = stm32_chan->base;
+ CYG_WORD32 c;
+
+ // Read data
+ HAL_READ_UINT32( base + CYGHWR_HAL_STM32_UART_DR, c);
+ return (unsigned char) (c&0xFF);
+}
+
+//==========================================================================
+
+static unsigned char
+stm32_serial_getc_polled(serial_channel *chan)
+{
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = stm32_chan->base;
+ cyg_uint32 stat;
+ cyg_uint32 c;
+
+ do {
+ HAL_READ_UINT32( base + CYGHWR_HAL_STM32_UART_SR, stat );
+ } while ((stat & CYGHWR_HAL_STM32_UART_SR_RXNE) == 0);
+
+ HAL_READ_UINT32( base + CYGHWR_HAL_STM32_UART_DR, c);
+
+ return (unsigned char) (c&0xFF);
+}
+
+//==========================================================================
+// Set up the device characteristics; baud rate, etc.
+
+static Cyg_ErrNo
+stm32_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != stm32_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+
+ case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE:
+ {
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ cyg_uint32 *f = (cyg_uint32 *)xbuf;
+
+ if ( *len < sizeof(*f) )
+ return -EINVAL;
+
+ if ( chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX )
+ {
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+
+ // Note that the RTS line is active-low, so set it to 1
+ // to throttle and 0 to allow the data to flow.
+ if( *f )
+ CYGHWR_HAL_STM32_GPIO_OUT( stm32_chan->rts_pin, 1 );
+ else
+ CYGHWR_HAL_STM32_GPIO_OUT( stm32_chan->rts_pin, 0 );
+ }
+ }
+ break;
+
+ case CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG:
+ {
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ Cyg_ErrNo result = ENOERR;
+
+ // If the client is asking for DSR/DTR, refuse to do it.
+ if (0 != (chan->config.flags & (CYGNUM_SERIAL_FLOW_DSRDTR_RX | CYGNUM_SERIAL_FLOW_DSRDTR_TX)))
+ {
+ chan->config.flags &= ~(CYGNUM_SERIAL_FLOW_DSRDTR_RX | CYGNUM_SERIAL_FLOW_DSRDTR_TX);
+ result = -ENOSUPP;
+ }
+
+ // If the client is asking for RTS/CTS then only allow it if
+ // the port has RTS/CTS lines attached to it.
+ if (0 != (chan->config.flags & (CYGNUM_SERIAL_FLOW_RTSCTS_RX | CYGNUM_SERIAL_FLOW_RTSCTS_TX)))
+ {
+ if( stm32_chan->rts_pin != CYGHWR_HAL_STM32_GPIO_NONE &&
+ stm32_chan->cts_pin != CYGHWR_HAL_STM32_GPIO_NONE )
+ {
+ chan->config.flags &= (CYGNUM_SERIAL_FLOW_RTSCTS_RX | CYGNUM_SERIAL_FLOW_RTSCTS_TX);
+ }
+ else
+ {
+ chan->config.flags &= ~(CYGNUM_SERIAL_FLOW_RTSCTS_RX | CYGNUM_SERIAL_FLOW_RTSCTS_TX);
+ result = -ENOSUPP;
+ }
+ }
+ return result;
+ }
+
+#endif
+
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+//==========================================================================
+// Enable the transmitter on the device
+
+static void
+stm32_serial_start_xmit(serial_channel *chan)
+{
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = stm32_chan->base;
+ cyg_uint32 cr1;
+
+ if( !stm32_chan->tx_active )
+ {
+ stm32_chan->tx_active = true;
+ HAL_READ_UINT32( base + CYGHWR_HAL_STM32_UART_CR1, cr1 );
+ cr1 |= CYGHWR_HAL_STM32_UART_CR1_TXEIE;
+ HAL_WRITE_UINT32( base + CYGHWR_HAL_STM32_UART_CR1, cr1 );
+ }
+
+}
+
+//==========================================================================
+// Disable the transmitter on the device
+
+static void
+stm32_serial_stop_xmit(serial_channel *chan)
+{
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = stm32_chan->base;
+ cyg_uint32 cr1;
+
+ if( stm32_chan->tx_active )
+ {
+ stm32_chan->tx_active = false;
+ HAL_READ_UINT32( base + CYGHWR_HAL_STM32_UART_CR1, cr1 );
+ cr1 &= ~CYGHWR_HAL_STM32_UART_CR1_TXEIE;
+ HAL_WRITE_UINT32( base + CYGHWR_HAL_STM32_UART_CR1, cr1 );
+ }
+
+}
+
+//==========================================================================
+// Serial I/O - low level interrupt handler (ISR)
+//
+// This ISR does rather more than other serial driver ISRs. Normally,
+// the ISR just masks the interrupt vector and schedules the DSR,
+// which then handles all IO. However, if the processor is running out
+// of external RAM it is too slow to handle higher baud rates using
+// that technique. Something that is exacerbated by the lack of FIFOs
+// in the USART hardware.
+//
+// Instead, this ISR receives any incoming data into a circular
+// buffer, essentially providing the FIFO lacking in the
+// hardware. Transmission is still offloaded to the DSR. Only TX
+// interrupts are masked while this is done to prevent an interrupt
+// loop, and to avoid blocking RX interrupts.
+
+static cyg_uint32
+stm32_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel * const chan = (serial_channel *) data;
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = stm32_chan->base;
+ cyg_uint32 stat;
+ cyg_uint32 ret = CYG_ISR_HANDLED;
+ cyg_drv_interrupt_acknowledge(vector);
+
+ HAL_READ_UINT32(base + CYGHWR_HAL_STM32_UART_SR, stat);
+
+ if( stat & CYGHWR_HAL_STM32_UART_SR_RXNE )
+ {
+ cyg_uint32 c;
+
+ while( stat & CYGHWR_HAL_STM32_UART_SR_RXNE )
+ {
+ int next = stm32_chan->buf_head+1;
+
+ if( next == STM32_RXBUFSIZE ) next = 0;
+
+ HAL_READ_UINT32( base + CYGHWR_HAL_STM32_UART_DR, c);
+
+ if( next != stm32_chan->buf_tail )
+ {
+ stm32_chan->buf[stm32_chan->buf_head] = c&0xFF;
+ stm32_chan->buf_head = next;
+ ret |= CYG_ISR_CALL_DSR;
+ }
+ else
+ {
+ // TODO: deal with buffer overflow
+ }
+
+ HAL_READ_UINT32(base + CYGHWR_HAL_STM32_UART_SR, stat);
+ }
+ }
+ else if( stat & CYGHWR_HAL_STM32_UART_SR_TXE )
+ {
+ cyg_uint32 cr1;
+ HAL_READ_UINT32( base + CYGHWR_HAL_STM32_UART_CR1, cr1 );
+ cr1 &= ~CYGHWR_HAL_STM32_UART_CR1_TXEIE;
+ HAL_WRITE_UINT32( base + CYGHWR_HAL_STM32_UART_CR1, cr1 );
+
+ ret |= CYG_ISR_CALL_DSR;
+ }
+
+
+ if( stat & CYGHWR_HAL_STM32_UART_SR_CTS )
+ {
+ // Clear CTS status if we see it.
+ stat &= ~CYGHWR_HAL_STM32_UART_SR_CTS;
+ HAL_WRITE_UINT32( base + CYGHWR_HAL_STM32_UART_SR, stat );
+ }
+
+ if( stat & (CYGHWR_HAL_STM32_UART_SR_FE|CYGHWR_HAL_STM32_UART_SR_NE|CYGHWR_HAL_STM32_UART_SR_ORE) )
+ {
+ // TODO: Handle hardware errors
+ }
+
+ return ret;
+}
+
+//==========================================================================
+// Serial I/O - high level interrupt handler (DSR)
+
+static void
+stm32_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel * const chan = (serial_channel *) data;
+ stm32_serial_info * const stm32_chan = (stm32_serial_info *) chan->dev_priv;
+ const CYG_ADDRWORD base = stm32_chan->base;
+ CYG_WORD32 stat;
+
+ while( stm32_chan->buf_head != stm32_chan->buf_tail )
+ {
+ int next = stm32_chan->buf_tail+1;
+ cyg_uint8 c;
+
+ if( next == STM32_RXBUFSIZE ) next = 0;
+ c = stm32_chan->buf[stm32_chan->buf_tail];
+ stm32_chan->buf_tail = next;
+
+ (chan->callbacks->rcv_char)(chan, c);
+ }
+
+ HAL_READ_UINT32(base + CYGHWR_HAL_STM32_UART_SR, stat);
+
+ if( stm32_chan->tx_active && stat & CYGHWR_HAL_STM32_UART_SR_TXE )
+ {
+ cyg_uint32 cr1;
+
+ (chan->callbacks->xmt_char)(chan);
+
+ if( stm32_chan->tx_active )
+ {
+ HAL_READ_UINT32( base + CYGHWR_HAL_STM32_UART_CR1, cr1 );
+ cr1 |= CYGHWR_HAL_STM32_UART_CR1_TXEIE;
+ HAL_WRITE_UINT32( base + CYGHWR_HAL_STM32_UART_CR1, cr1 );
+ }
+ }
+}
+
+//==========================================================================
+#endif // CYGPKG_IO_SERIAL_CORTEXM_STM32
+// end of stm32_serial.c
diff --git a/ecos/packages/devs/serial/cortexm/stm32/current/src/stm32_serial.h b/ecos/packages/devs/serial/cortexm/stm32/current/src/stm32_serial.h
new file mode 100644
index 0000000..a43994d
--- /dev/null
+++ b/ecos/packages/devs/serial/cortexm/stm32/current/src/stm32_serial.h
@@ -0,0 +1,105 @@
+#ifndef CYGONCE_CORTEXM_STM32_SERIAL_H
+#define CYGONCE_CORTEXM_STM32_SERIAL_H
+
+// ====================================================================
+//
+// stm32_serial.h
+//
+// Device I/O - Description of ST STM32 serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Date: 2008-09-10
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+#include <cyg/hal/hal_io.h> // Register definitions
+
+// ====================================================================
+// Translate system stop bit selector into control register bits.
+
+static cyg_uint32 select_stop_bits[] = {
+ CYGHWR_HAL_STM32_UART_CR2_STOP_0_5, // 0.5 stop bits
+ CYGHWR_HAL_STM32_UART_CR2_STOP_1, // 1 stop bit
+ CYGHWR_HAL_STM32_UART_CR2_STOP_1_5, // 1.5 stop bit
+ CYGHWR_HAL_STM32_UART_CR2_STOP_2 // 2 stop bit
+};
+
+// Translate system parity selector into local values.
+static cyg_uint32 select_parity[] = {
+ 0, // No parity
+ CYGHWR_HAL_STM32_UART_CR1_PCE|CYGHWR_HAL_STM32_UART_CR1_PS_EVEN, // Even parity
+ CYGHWR_HAL_STM32_UART_CR1_PCE|CYGHWR_HAL_STM32_UART_CR1_PS_ODD, // Odd parity
+ 0, // Mark (1) parity -- not supported
+ 0 // Space (0) parity -- not supported
+};
+
+// ====================================================================
+// Translate system baud selector into direct baud rate value. This is
+// then used to calculate the clock divisor from the PCLK clock.
+
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 0, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 230400, // 230400
+};
+
+// ====================================================================
+#endif // CYGONCE_CORTEXM_STM32_SERIAL_H
diff --git a/ecos/packages/devs/serial/freescale/esci/drv/current/ChangeLog b/ecos/packages/devs/serial/freescale/esci/drv/current/ChangeLog
new file mode 100644
index 0000000..1522d50
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/esci/drv/current/ChangeLog
@@ -0,0 +1,46 @@
+2007-01-10 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_freescale_esci_h.cdl: CYGPKG_IO_SERIAL_FREESCALE_ESCI_H
+ moved in a new directory due ecosadmin.tcl issue
+ reported by John Dallaway
+
+2006-08-31 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_freescale_esci.cdl: driver now requires at least 1 selected
+ channel
+
+2006-08-08 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_esci.h : platform dependent clock related macros
+ removed and placed in platform/var header
+
+2006-05-24 Ilija Koco <ilijak@siva.com.mk>
+
+ * cdl/ser_freescale_esci.cdl:
+ * include/ser_esci.h:
+ * src/ser_esci.c
+ New package
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/freescale/esci/drv/current/cdl/ser_freescale_esci.cdl b/ecos/packages/devs/serial/freescale/esci/drv/current/cdl/ser_freescale_esci.cdl
new file mode 100644
index 0000000..7bf77e3
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/esci/drv/current/cdl/ser_freescale_esci.cdl
@@ -0,0 +1,305 @@
+# ====================================================================
+#
+# ser_freescale_esci.cdl
+#
+# eCos serial Freescale/esci configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Koco <ilijak@siva.com.mk>
+# Original data:
+# Contributors:
+# Date: 2006-04-20
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_FREESCALE_ESCI {
+ display "eSCI device driver"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+
+ requires CYGPKG_IO_SERIAL_FREESCALE_ESCI_H
+
+ requires (CYGPKG_ERROR && (CYGPKG_IO_SERIAL_FREESCALE_ESCI_A || \
+ CYGPKG_IO_SERIAL_FREESCALE_ESCI_B || \
+ CYGPKG_IO_SERIAL_FREESCALE_ESCI_C || \
+ CYGPKG_IO_SERIAL_FREESCALE_ESCI_D) \
+ )
+
+ include_dir cyg/devs
+
+ description "
+ This option enables the serial device drivers for the
+ Freescale eSCI - Enhanced Serial Communication Interface.
+ eSCI is on-chip serial controller found on some freescale
+ microcontrollers such as: MAC7100 familly, etc.
+ "
+ compile -library=libextras.a ser_esci.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_freescale_esci.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_ESCI_A {
+ display "eSCI port A driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the eSCI port A."
+
+ cdl_option CYGDAT_IO_SERIAL_FREESCALE_ESCI_A_NAME {
+ display "Device name for eSCI port A"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the device name for the eSCI port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BAUD {
+ display "Baud rate for the eSCI serial port A driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ eSCI port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BUFSIZE {
+ display "Buffer size for the sSCI port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the eSCI port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_INT_PRIORITY {
+ display "eSCI port A INTC priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 7
+ description "
+ INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+ "
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_ESCI_B {
+ display "eSCI port B driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the eSCI port B."
+
+ cdl_option CYGDAT_IO_SERIAL_FREESCALE_ESCI_B_NAME {
+ display "Device name for eSCI port B"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the eSCI port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BAUD {
+ display "Baud rate for the eSCI serial port A driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ eSCI port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BUFSIZE {
+ display "Buffer size for the sSCI port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the eSCI port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_INT_PRIORITY {
+ display "eSCI prot B INTC priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 7
+ description "
+ INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+ "
+ }
+
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_ESCI_C {
+ display "eSCI port C driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the eSCI port C."
+
+ cdl_option CYGDAT_IO_SERIAL_FREESCALE_ESCI_C_NAME {
+ display "Device name for eSCI port C"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the eSCI port C."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BAUD {
+ display "Baud rate for the eSCI serial port A driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ eSCI port C."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BUFSIZE {
+ display "Buffer size for the sSCI port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the eSCI port C."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_INT_PRIORITY {
+ display "eSCI prot B INTC priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 6
+ description "
+ INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+ "
+ }
+
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_ESCI_D {
+ display "eSCI port D driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for the eSCI port D."
+
+ cdl_option CYGDAT_IO_SERIAL_FREESCALE_ESCI_D_NAME {
+ display "Device name for eSCI port D"
+ flavor data
+ default_value {"\"/dev/ser3\""}
+ description "
+ This option specifies the device name for the eSCI port D."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BAUD {
+ display "Baud rate for the eSCI serial port A driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400
+ 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ eSCI port D."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BUFSIZE {
+ display "Buffer size for the sSCI port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the eSCI port D."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_INT_PRIORITY {
+ display "eSCI prot B INTC priority"
+ flavor data
+ legal_values 0 to 15
+ default_value 6
+ description "
+ INTC has 16 interrupt levels: 0 (lowest) to 15 (highest).
+ "
+ }
+ }
+
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_ESCI_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_FREESCALE_ESCI_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_FREESCALE_ESCI_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_freescale_esci.cdl
diff --git a/ecos/packages/devs/serial/freescale/esci/drv/current/src/ser_esci.c b/ecos/packages/devs/serial/freescale/esci/drv/current/src/ser_esci.c
new file mode 100644
index 0000000..97092d2
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/esci/drv/current/src/ser_esci.c
@@ -0,0 +1,548 @@
+//==========================================================================
+//
+// ser_esci.c
+//
+// Freescale sSCI Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-04-20
+// Purpose: eSCI Serial I/O module (interrupt driven version)
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arbiter.h>
+#include <cyg/hal/var_io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+#include <cyg/devs/ser_esci.h>
+
+// Only build this driver for if ESCI is needed.
+#ifdef CYGPKG_IO_SERIAL_FREESCALE_ESCI
+
+typedef struct esci_serial_info {
+ CYG_ADDRWORD esci_base; // Base address of the esci port
+ CYG_WORD interrupt_num; // INTC interrupt vector
+ cyg_priority_t interrupt_priority; // INTC interupt priority
+ cyg_interrupt interrupt_obj; // Interrupt object
+ cyg_handle_t interrupt_handle; // Interrupt handle
+} esci_serial_info;
+
+static bool esci_serial_init(struct cyg_devtab_entry * tab);
+static bool esci_serial_putc(serial_channel * chan, unsigned char c);
+static Cyg_ErrNo esci_serial_lookup(struct cyg_devtab_entry ** tab,
+ struct cyg_devtab_entry * sub_tab,
+ const char * name);
+static unsigned char esci_serial_getc(serial_channel *chan);
+static Cyg_ErrNo esci_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void esci_serial_start_xmit(serial_channel *chan);
+static void esci_serial_stop_xmit(serial_channel *chan);
+
+// Interrupt servers
+static cyg_uint32 esci_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void esci_serial_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+
+static SERIAL_FUNS(esci_serial_funs,
+ esci_serial_putc,
+ esci_serial_getc,
+ esci_serial_set_config,
+ esci_serial_start_xmit,
+ esci_serial_stop_xmit);
+
+// Available baud rates
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50 bps unsupported
+ 0, // 75 bps unsupported
+ 0, // 110 bps unsupported
+ 0, // 134_5 bps unsupported
+ 0, // 150 bps unsupported
+ 0, // 200 bps unsupported
+ FREESCALE_ESCI_BAUD(300), // 300 bps
+ FREESCALE_ESCI_BAUD(600), // 600 bps
+ FREESCALE_ESCI_BAUD(1200), // 1200 bps
+ 0, // 1800 bps unsupported
+ FREESCALE_ESCI_BAUD(2400), // 2400 bps
+ 0, // 3600 bps unsupported
+ FREESCALE_ESCI_BAUD(4800), // 4800 bps
+ 0, // 7200 bps unsupported
+ FREESCALE_ESCI_BAUD(9600), // 9600 bps
+ FREESCALE_ESCI_BAUD(14400), // 14400 bps
+ FREESCALE_ESCI_BAUD(19200), // 19200 bps
+ FREESCALE_ESCI_BAUD(38400), // 38400 bps
+ FREESCALE_ESCI_BAUD(57600), // 57600 bps
+ FREESCALE_ESCI_BAUD(115200), // 115200 bps
+ 0 // 230400 bps unsupported
+};
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_A
+static esci_serial_info esci_serial_info0 = {
+ esci_base : CYGADDR_IO_SERIAL_FREESCALE_ESCI_A_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_INT_PRIORITY
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BUFSIZE > 0
+static unsigned char
+ esci_serial_out_buf0[CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BUFSIZE];
+static unsigned char
+ esci_serial_in_buf0[CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(
+ esci_serial_channel0,
+ esci_serial_funs,
+ esci_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &esci_serial_out_buf0[0],
+ sizeof(esci_serial_out_buf0),
+ &esci_serial_in_buf0[0],
+ sizeof(esci_serial_in_buf0));
+#else
+static
+SERIAL_CHANNEL(esci_serial_channel0,
+ esci_serial_funs,
+ esci_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(esci_serial_io0,
+ CYGDAT_IO_SERIAL_FREESCALE_ESCI_A_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ esci_serial_init,
+ esci_serial_lookup,
+ &esci_serial_channel0);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_ESCI_A
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_B
+static esci_serial_info esci_serial_info1 = {
+ esci_base : CYGADDR_IO_SERIAL_FREESCALE_ESCI_B_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_INT_PRIORITY
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BUFSIZE > 0
+static unsigned char
+ esci_serial_out_buf1[CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BUFSIZE];
+static unsigned char
+ esci_serial_in_buf1[CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(esci_serial_channel1,
+ esci_serial_funs,
+ esci_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &esci_serial_out_buf1[0],
+ sizeof(esci_serial_out_buf1),
+ &esci_serial_in_buf1[0],
+ sizeof(esci_serial_in_buf1));
+#else
+static
+SERIAL_CHANNEL(esci_serial_channel1,
+ esci_serial_funs,
+ esci_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(esci_serial_io1,
+ CYGDAT_IO_SERIAL_FREESCALE_ESCI_B_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ esci_serial_init,
+ esci_serial_lookup,
+ &esci_serial_channel1);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_ESCI_B
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_C
+static esci_serial_info esci_serial_info2 = {
+ esci_base : CYGADDR_IO_SERIAL_FREESCALE_ESCI_C_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_INT_PRIORITY
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BUFSIZE > 0
+static unsigned char
+ esci_serial_out_buf2[CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BUFSIZE];
+static unsigned char
+ esci_serial_in_buf2[CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(esci_serial_channel2,
+ esci_serial_funs,
+ esci_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &esci_serial_out_buf2[0],
+ sizeof(esci_serial_out_buf2),
+ &esci_serial_in_buf2[0],
+ sizeof(esci_serial_in_buf2));
+#else
+static
+SERIAL_CHANNEL(esci_serial_channel2,
+ esci_serial_funs,
+ esci_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(esci_serial_io2,
+ CYGDAT_IO_SERIAL_FREESCALE_ESCI_C_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ esci_serial_init,
+ esci_serial_lookup,
+ &esci_serial_channel2);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_ESCI_C
+
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_D
+static esci_serial_info esci_serial_info3 = {
+ esci_base : CYGADDR_IO_SERIAL_FREESCALE_ESCI_D_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_INT_PRIORITY
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BUFSIZE > 0
+static unsigned char
+ esci_serial_out_buf3[CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BUFSIZE];
+static unsigned char
+ esci_serial_in_buf3[CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(esci_serial_channel3,
+ esci_serial_funs,
+ esci_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &esci_serial_out_buf3[0],
+ sizeof(esci_serial_out_buf3),
+ &esci_serial_in_buf3[0],
+ sizeof(esci_serial_in_buf3));
+#else
+static
+SERIAL_CHANNEL(esci_serial_channel3,
+ esci_serial_funs,
+ esci_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(esci_serial_io3,
+ CYGDAT_IO_SERIAL_FREESCALE_ESCI_D_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ esci_serial_init,
+ esci_serial_lookup,
+ &esci_serial_channel3);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_ESCI_D
+
+//----------------------------------------------------------------------------
+// Internal function to actually configure the hardware to desired
+// baud rate, etc.
+//----------------------------------------------------------------------------
+static bool
+esci_serial_config_port(serial_channel * chan, cyg_serial_info_t * new_config,
+ bool init)
+{
+ esci_serial_info * esci_chan = (esci_serial_info *)(chan->dev_priv);
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+ cyg_uint16 baud_rate = ((new_config->baud >= 0) &&
+ (new_config->baud < (sizeof(select_baud)/
+ sizeof(select_baud[0]))))
+ ? select_baud[new_config->baud] : 0;
+
+ cyg_uint16 esci_cr12=0, esci_cr12_old;
+
+ HAL_WRITE_UINT8(FREESCALE_ESCI_CR3(esci_base), 0);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_LINCTRL(esci_base), 0);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), 0);
+
+ if(!baud_rate) return false; // Invalid baud rate selected
+
+ switch(new_config->word_length){
+ case 8: break;
+ default: return false;
+ }
+
+ switch(new_config->parity){
+ case CYGNUM_SERIAL_PARITY_ODD:
+ esci_cr12 |= FREESCALE_ESCI_CR12_PT;
+ case CYGNUM_SERIAL_PARITY_EVEN:
+ esci_cr12 |= FREESCALE_ESCI_CR12_PE;
+ case CYGNUM_SERIAL_PARITY_NONE:
+ break;
+ default: return false;
+ }
+
+ if(new_config->stop!=CYGNUM_SERIAL_STOP_1) return false;
+
+ // Enable the device
+ esci_cr12 |= FREESCALE_ESCI_CR12_TE | FREESCALE_ESCI_CR12_RE;
+
+ if(init){ // Enable the receiver interrupt
+ esci_cr12 |= FREESCALE_ESCI_CR12_RIE;
+ }else{ // Restore the old interrupt state
+ HAL_READ_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12_old);
+ esci_cr12 |= (esci_cr12_old & FREESCALE_ESCI_CR12_RIE);
+ }
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12);
+
+ if(new_config != &chan->config)
+ chan->config = *new_config;
+
+ return true;
+}
+
+//--------------------------------------------------------------
+// Function to initialize the device. Called at bootstrap time.
+//--------------------------------------------------------------
+static bool
+esci_serial_init(struct cyg_devtab_entry * tab)
+{
+ serial_channel * chan = (serial_channel *)tab->priv;
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ if(chan->out_cbuf.len != 0){
+ cyg_drv_interrupt_create(esci_chan->interrupt_num,
+ esci_chan->interrupt_priority,
+ // Data item passed to interrupt handler
+ (cyg_addrword_t)chan,
+ esci_serial_ISR,
+ esci_serial_DSR,
+ &esci_chan->interrupt_handle,
+ &esci_chan->interrupt_obj);
+
+ cyg_drv_interrupt_attach(esci_chan->interrupt_handle);
+ cyg_drv_interrupt_unmask(esci_chan->interrupt_num);
+ }
+ return esci_serial_config_port(chan, &chan->config, true);
+}
+
+//----------------------------------------------------------------------
+// This routine is called when the device is "looked" up (i.e. attached)
+//----------------------------------------------------------------------
+static Cyg_ErrNo
+esci_serial_lookup(struct cyg_devtab_entry ** tab,
+ struct cyg_devtab_entry * sub_tab, const char * name)
+{
+ serial_channel * chan = (serial_channel *)(*tab)->priv;
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+
+ return ENOERR;
+}
+
+//-----------------------------------------------------------------
+// Send a character to Tx
+//-----------------------------------------------------------------
+static bool
+esci_serial_putc(serial_channel * chan, unsigned char ch_out)
+{
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+ cyg_uint16 esci_sr;
+
+ HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ if(esci_sr & FREESCALE_ESCI_SR_TDRE){
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_TDRE);
+ HAL_WRITE_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_out);
+ return true;
+ }else
+ return false;
+}
+
+//---------------------------------------------------------------------
+// Fetch a character Rx (for polled operation only)
+//---------------------------------------------------------------------
+static unsigned char
+esci_serial_getc(serial_channel * chan)
+{
+ cyg_uint8 ch_in;
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+
+ cyg_uint16 esci_sr;
+
+ do{
+ HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ }while(esci_sr & FREESCALE_ESCI_SR_RDRF);
+
+ HAL_READ_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_in);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_RDRF);
+
+ return ch_in;
+}
+
+//---------------------------------------------------
+// Set up the device characteristics; baud rate, etc.
+//---------------------------------------------------
+static bool
+esci_serial_set_config(serial_channel * chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 * len)
+{
+ switch(key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:{
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if(*len < sizeof(cyg_serial_info_t)) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if(true != esci_serial_config_port(chan, config, false))
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+//-------------------------------------
+// Enable the transmitter on the device
+//-------------------------------------
+static void esci_serial_start_xmit(serial_channel * chan)
+{
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+ cyg_uint16 esci_cr12;
+
+ HAL_READ_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12);
+ esci_cr12 |= FREESCALE_ESCI_CR12_TIE;
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12);
+}
+
+//--------------------------------------
+// Disable the transmitter on the device
+//--------------------------------------
+static void esci_serial_stop_xmit(serial_channel * chan)
+{
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+ cyg_uint16 esci_cr12;
+
+ HAL_READ_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12);
+ esci_cr12 &= ~FREESCALE_ESCI_CR12_TIE;
+ HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), esci_cr12);
+}
+
+//-----------------------------------------
+// The low level interrupt handler
+//-----------------------------------------
+static
+cyg_uint32 esci_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel * chan = (serial_channel *)data;
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(esci_chan->interrupt_num);
+ cyg_drv_interrupt_acknowledge(esci_chan->interrupt_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+
+//------------------------------------------
+// The high level interrupt handler
+//------------------------------------------
+
+#define FREESCALE_ESCI_SR_ERRORS (FREESCALE_ESCI_SR_OR | \
+ FREESCALE_ESCI_SR_NF | \
+ FREESCALE_ESCI_SR_FE | \
+ FREESCALE_ESCI_SR_PF)
+
+static void
+esci_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel * chan = (serial_channel *)data;
+ esci_serial_info * esci_chan = (esci_serial_info *)chan->dev_priv;
+ cyg_addrword_t esci_base = esci_chan->esci_base;
+ cyg_uint16 esci_sr;
+ cyg_uint8 esci_dr;
+
+ HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ if(esci_sr & FREESCALE_ESCI_SR_RDRF){ // Receiver full
+ HAL_READ_UINT8(FREESCALE_ESCI_DRL(esci_base), esci_dr);
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_RDRF);
+ if(esci_sr &= (cyg_uint16)FREESCALE_ESCI_SR_ERRORS){
+ HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
+ }else{
+ (chan->callbacks->rcv_char)(chan, (cyg_uint8)esci_dr);
+ }
+ }else if(esci_sr & FREESCALE_ESCI_SR_TDRE){ //Transmitter empty
+ (chan->callbacks->xmt_char)(chan);
+ }
+
+ cyg_drv_interrupt_unmask(esci_chan->interrupt_num);
+}
+
+#endif // CYGPKG_IO_SERIAL_FREESCALE_ESCI_[ABCD]
+// EOF ser_esci.c
diff --git a/ecos/packages/devs/serial/freescale/esci/hdr/current/ChangeLog b/ecos/packages/devs/serial/freescale/esci/hdr/current/ChangeLog
new file mode 100644
index 0000000..e4e3253
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/esci/hdr/current/ChangeLog
@@ -0,0 +1,47 @@
+2007-01-10 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_freescale_esci_h.cdl: moved in a newly created directory for
+ CYGPKG_IO_SERIAL_FREESCALE_ESCI_H due ecosadmin.tcl issue
+ reported by John Dallaway
+
+
+2006-08-31 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_freescale_esci.cdl: driver now requires at least 1 selected
+ channel
+
+2006-08-08 Ilija Koco <ilijak@siva.com.mk>
+
+ * ser_esci.h : platform dependent clock related macros
+ removed and placed in platform/var header
+
+2006-05-24 Ilija Koco <ilijak@siva.com.mk>
+
+ * cdl/ser_freescale_esci.cdl:
+ * include/ser_esci.h:
+ * src/ser_esci.c
+ New package
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/freescale/esci/hdr/current/cdl/ser_freescale_esci_h.cdl b/ecos/packages/devs/serial/freescale/esci/hdr/current/cdl/ser_freescale_esci_h.cdl
new file mode 100644
index 0000000..18b758c
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/esci/hdr/current/cdl/ser_freescale_esci_h.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# ser_freescale_esci_h.cdl
+#
+# eCos serial Freescale/esci configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Koco <ilijak@siva.com.mk>
+# Original data:
+# Contributors:
+# Date: 2006-05-30
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_FREESCALE_ESCI_H {
+ display "eSCI header"
+
+ include_dir cyg/devs
+ description "
+ This option provides header for Freescale eSCI - Enhanced
+ Serial Communication Interface. eSCI is on-chip serial
+ controller found on some Freescale micro controllers such as:
+ MAC7100 familly, etc. "
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_freescale_esci.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+}
+
+# EOF ser_freescale_esci_h.cdl
diff --git a/ecos/packages/devs/serial/freescale/esci/hdr/current/include/ser_esci.h b/ecos/packages/devs/serial/freescale/esci/hdr/current/include/ser_esci.h
new file mode 100644
index 0000000..e08afb1
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/esci/hdr/current/include/ser_esci.h
@@ -0,0 +1,162 @@
+#ifndef CYGONCE_DEVS_SERIAL_FREESCALE_ESCI_H
+#define CYGONCE_DEVS_SERIAL_FREESCALE_ESCI_H
+//==========================================================================
+//
+// ser_esci.h
+//
+// Freescale eSCI Serial I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Koco <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2006-04-20
+// Purpose: eSCI Serial I/O definitions.
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// Note: Following macros are platform dependent
+// and have to be defined in var_io.h or plf_io.h
+// Macros referenced by serial driver:
+// CYGADDR_IO_SERIAL_FREESCALE_ESCI_A_BASE
+// CYGADDR_IO_SERIAL_FREESCALE_ESCI_B_BASE
+// CYGADDR_IO_SERIAL_FREESCALE_ESCI_C_BASE
+// CYGADDR_IO_SERIAL_FREESCALE_ESCI_D_BASE
+// CYGNUM_DEV_SER_FREESCALE_ESCI_SYSTEM_CLOCK
+// FREESCALE_ESCI_BAUD(baud_rate)
+
+// Macros not referenced by serial driver
+// but by interrupt controller
+// CYGNUM_IO_SERIAL_FREESCALE_ESCI_A_INT_VECTOR
+// CYGNUM_IO_SERIAL_FREESCALE_ESCI_B_INT_VECTOR
+// CYGNUM_IO_SERIAL_FREESCALE_ESCI_C_INT_VECTOR
+// CYGNUM_IO_SERIAL_FREESCALE_ESCI_D_INT_VECTOR
+// MAC7100_ESCI_A_IV
+// MAC7100_ESCI_B_IV
+// MAC7100_ESCI_C_IV
+// MAC7100_ESCI_D_IV
+//
+
+#define FREESCALE_ESCI_A_BASE (CYGADDR_IO_SERIAL_FREESCALE_ESCI_A_BASE)
+#define FREESCALE_ESCI_B_BASE (CYGADDR_IO_SERIAL_FREESCALE_ESCI_B_BASE)
+#define FREESCALE_ESCI_C_BASE (CYGADDR_IO_SERIAL_FREESCALE_ESCI_C_BASE)
+#define FREESCALE_ESCI_D_BASE (CYGADDR_IO_SERIAL_FREESCALE_ESCI_D_BASE)
+
+#define FREESCALE_ESCI_A_I 0
+#define FREESCALE_ESCI_B_I 1
+#define FREESCALE_ESCI_C_I 2
+#define FREESCALE_ESCI_D_I 3
+
+#define FREESCALE_ESCI_BD(esci_base) \
+ (esci_base + FREESCALE_ESCI_BD_OFFSET) //short
+#define FREESCALE_ESCI_CR12(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR12_OFFSET) //short
+#define FREESCALE_ESCI_CR34(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR34_OFFSET) //short
+#define FREESCALE_ESCI_CR1(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR1_OFFSET) //char
+#define FREESCALE_ESCI_CR2(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR2_OFFSET) //char
+#define FREESCALE_ESCI_CR3(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR3_OFFSET) //char
+#define FREESCALE_ESCI_CR4(esci_base) \
+ (esci_base + FREESCALE_ESCI_CR4_OFFSET) //short
+#define FREESCALE_ESCI_LINCTRL(esci_base) \
+ (esci_base + FREESCALE_ESCI_LINCTRL_OFFSET) //short
+#define FREESCALE_ESCI_LINCRCP(esci_base) \
+ (esci_base + FREESCALE_ESCI_LINCRCP_OFFSET) //short
+#define FREESCALE_ESCI_SR(esci_base) \
+ (esci_base + FREESCALE_ESCI_SR_OFFSET) //short
+#define FREESCALE_ESCI_DRL(esci_base) \
+ (esci_base + FREESCALE_ESCI_DRL_OFFSET) //char
+
+#define FREESCALE_ESCI_BD_OFFSET (0x0000)
+#define FREESCALE_ESCI_CR12_OFFSET (0x0002)
+#define FREESCALE_ESCI_CR34_OFFSET (0x0002)
+#define FREESCALE_ESCI_CR1_OFFSET (0x0002)
+#define FREESCALE_ESCI_CR2_OFFSET (0x0003)
+#define FREESCALE_ESCI_CR3_OFFSET (0x0004)
+#define FREESCALE_ESCI_CR4_OFFSET (0x0005)
+#define FREESCALE_ESCI_DRL_OFFSET (0x0007)
+#define FREESCALE_ESCI_SR_OFFSET (0x0008)
+#define FREESCALE_ESCI_LINSTAT_OFFSET (0x000A)
+#define FREESCALE_ESCI_LINCTRL_OFFSET (0x000C)
+#define FREESCALE_ESCI_LINRX_OFFSET (0x0010)
+#define FREESCALE_ESCI_LINTX_OFFSET (0x0014)
+#define FREESCALE_ESCI_LINCRCP_OFFSET (0x0018)
+
+#define FREESCALE_ESCI_CR12_LOOPS (0x8000)
+#define FREESCALE_ESCI_CR12_SCISDOZ (0x4000)
+#define FREESCALE_ESCI_CR12_RSRC (0x2000)
+#define FREESCALE_ESCI_CR12_M (0x1000)
+#define FREESCALE_ESCI_CR12_WAKE (0x0800)
+#define FREESCALE_ESCI_CR12_ILT (0x0400)
+#define FREESCALE_ESCI_CR12_PE (0x0200)
+#define FREESCALE_ESCI_CR12_PT (0x0100)
+#define FREESCALE_ESCI_CR12_TIE (0x0080)
+#define FREESCALE_ESCI_CR12_TCIE (0x0040)
+#define FREESCALE_ESCI_CR12_RIE (0x0020)
+#define FREESCALE_ESCI_CR12_ILIE (0x0010)
+#define FREESCALE_ESCI_CR12_TE (0x0008)
+#define FREESCALE_ESCI_CR12_RE (0x0004)
+#define FREESCALE_ESCI_CR12_RWU (0x0002)
+#define FREESCALE_ESCI_CR12_SBK (0x0001)
+
+#define FREESCALE_ESCI_CR3_MDIS (0x80)
+#define FREESCALE_ESCI_CR3_FBR (0x40)
+#define FREESCALE_ESCI_CR3_BSTP (0x20)
+#define FREESCALE_ESCI_CR3_IEBERR (0x10)
+#define FREESCALE_ESCI_CR3_RXDMA (0x08)
+#define FREESCALE_ESCI_CR3_TXDMA (0x04)
+#define FREESCALE_ESCI_CR3_BRK13 (0x02)
+#define FREESCALE_ESCI_CR3_TXDIR (0x01)
+
+#define FREESCALE_ESCI_SR_TDRE (0x8000)
+#define FREESCALE_ESCI_SR_TC (0x4000)
+#define FREESCALE_ESCI_SR_RDRF (0x2000)
+#define FREESCALE_ESCI_SR_IDLE (0x1000)
+#define FREESCALE_ESCI_SR_OR (0x0800)
+#define FREESCALE_ESCI_SR_NF (0x0400)
+#define FREESCALE_ESCI_SR_FE (0x0200)
+#define FREESCALE_ESCI_SR_PF (0x0100)
+#define FREESCALE_ESCI_SR_BERR (0x0010)
+#define FREESCALE_ESCI_SR_RAF (0x0001)
+
+#endif // CYGONCE_DEVS_SERIAL_FREESCALE_ESCI_H
+// EOF ser_esci.h
diff --git a/ecos/packages/devs/serial/freescale/uart/drv/current/ChangeLog b/ecos/packages/devs/serial/freescale/uart/drv/current/ChangeLog
new file mode 100644
index 0000000..3b7ea0c
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/uart/drv/current/ChangeLog
@@ -0,0 +1,43 @@
+2013-04-01 Ilija Kocho <ilijak@siva.com.mk>
+
+ * include/ser_freescale_uart_chan.inl. include/ser_freescale_uart.c:
+ Add clock gating enable. [ Bugzilla 1001814 ]
+
+2012-02-07 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/ser_freescale_uart.cdl:
+ Add consolidated Interrupt Priority Scheme [Bugzilla 1001450]
+
+2011-03-26 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/ser_freescale_uart.cdl:
+ * src/ser_freescale_uart.c:
+ * include/ser_freescale_uart_chan.inl:
+ * include/ser_freescale_uart_tty_add.inl:
+ * include/ser_freescale_uart_termiostty_add.inl:
+
+ New package -- Freescale UART driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/freescale/uart/drv/current/cdl/ser_freescale_uart.cdl b/ecos/packages/devs/serial/freescale/uart/drv/current/cdl/ser_freescale_uart.cdl
new file mode 100644
index 0000000..bc29622
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/uart/drv/current/cdl/ser_freescale_uart.cdl
@@ -0,0 +1,269 @@
+# ====================================================================
+#
+# ser_freescale_uart.cdl
+#
+# eCos serial Freescale UART configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Kocho <ilijak@siva.com.mk>
+# Original data:
+# Contributors:
+# Date: 2011-02-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_FREESCALE_UART {
+ display "Freescale UART device driver"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ requires CYGPKG_IO_SERIAL_FREESCALE_UART_HDR
+ requires CYGPKG_ERROR
+
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ Freescale UART, an on-chip serial controller found on some
+ freescale microcontrollers such as Kinetis, etc."
+
+ compile -library=libextras.a ser_freescale_uart.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_freescale_uart.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ # Support up to 6 on-chip UART modules. The number may vary between
+ # processor variants so it is easy to update this here
+ for { set ::channel 0 } { $::channel < 6 } { incr ::channel } {
+
+ cdl_interface CYGINT_IO_SERIAL_FREESCALE_UART[set ::channel] {
+ display "Platform provides UART [set ::channel]"
+ flavor bool
+ description "
+ This interface will be implemented if the specific
+ controller being used has on-chip UART [set ::channel], and if
+ that UART is accessible on the target hardware."
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_UART[set ::channel] {
+ display "Freescale UART port [set ::channel] driver"
+ flavor bool
+ active_if CYGINT_IO_SERIAL_FREESCALE_UART[set ::channel]
+ default_value CYGINT_IO_SERIAL_FREESCALE_UART[set ::channel]
+ implements CYGINT_IO_SERIAL_TTY_TTY[set ::channel]
+ description "
+ This option includes the serial device driver for Freescale
+ UART port [set ::channel]."
+
+ cdl_option CYGDAT_IO_SERIAL_FREESCALE_UART[set ::channel]_NAME {
+ display "Device name for Freescale UART port [set ::channel]"
+ flavor data
+ default_value [ format {"\"/dev/ser%d\""} $::channel ]
+ description "
+ This option specifies the device name for
+ Freescale UART port [set ::channel]."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_UART[set ::channel]_BAUD {
+ display "Baud rate for the Freescale UART port [set ::channel] driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate for the
+ UART port [set ::channel]."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_UART[set ::channel]_BUFSIZE {
+ display "Buffer size for the Freescale UART port [set ::channel] driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for Freescale UART port [set ::channel]."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_FREESCALE_UART[set ::channel]_INT_PRIORITY {
+ display "Freescale UART port [set ::channel] interrupt priority"
+ flavor data
+ default_value CYGNUM_IO_SERIAL_FREESCALE_UART[set ::channel]_INT_PRIORITY_SP
+ description "
+ This option selects the interupt priority for the
+ UART [set ::channel] interrupts."
+ }
+ }
+ }
+
+ cdl_component CYGDAT_IO_SERIAL_TTY_ADD_INL {
+ display "Freescale TTY devices beyond #3"
+ parent CYGPKG_IO_SERIAL
+ active_if CYGPKG_IO_SERIAL_TTY
+ flavor data
+ calculated { "<cyg/io/ser_freescale_uart_tty_add.inl>" }
+
+
+ cdl_component CYGPKG_IO_SERIAL_TTY_TTY4 {
+ display "TTY mode channel #4"
+ flavor bool
+ parent CYGPKG_IO_SERIAL_TTY
+ active_if CYGPKG_IO_SERIAL_TTY
+ default_value 0
+ description "
+ This option causes '/dev/tty4', which is provided by Freescale
+ UART, to be included in the standard drivers."
+
+ cdl_option CYGDAT_IO_SERIAL_TTY_TTY4_DEV {
+ display "TTY mode channel #4 device"
+ flavor data
+ default_value { "\"/dev/ser4\"" }
+ description "
+ This option selects the physical device to use for
+ '/dev/tty4'."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_TTY_TTY5 {
+ display "TTY mode channel #5"
+ flavor bool
+ parent CYGPKG_IO_SERIAL_TTY
+ active_if CYGPKG_IO_SERIAL_TTY
+ default_value 0
+ description "
+ This option causes '/dev/tty5', which is provided by Freescale
+ UART, to be included in the standard drivers."
+
+ cdl_option CYGDAT_IO_SERIAL_TTY_TTY5_DEV {
+ display "TTY mode channel #5 device"
+ flavor data
+ default_value { "\"/dev/ser5\"" }
+ description "
+ This option selects the physical device to use for
+ '/dev/tty5'."
+ }
+ }
+ }
+
+ cdl_component CYGDAT_IO_SERIAL_TERMIOS_ADD_INL {
+ display "Freescale TERMIOS devices beyond #3"
+ parent CYGPKG_IO_SERIAL
+ active_if CYGPKG_IO_SERIAL_TERMIOS
+ flavor data
+ calculated { "<cyg/io/ser_freescale_uart_termiostty_add.inl>" }
+
+ cdl_component CYGPKG_IO_SERIAL_TERMIOS_TERMIOS4 {
+ display "Termios TTY channel #4"
+ flavor bool
+ default_value 0
+ implements CYGINT_IO_SERIAL_TERMIOS_TERMIOS_TTY
+ parent CYGPKG_IO_SERIAL_TERMIOS
+ active_if CYGPKG_IO_SERIAL_TERMIOS
+ description "
+ This option causes '/dev/termios4' to be included in the
+ standard drivers."
+
+ cdl_option CYGDAT_IO_SERIAL_TERMIOS_TERMIOS4_DEV {
+ display "Termios TTY channel #4 device"
+ flavor data
+ default_value {"\"/dev/ser4\""}
+ description "
+ This option selects the physical device to use for
+ '/dev/termios4'."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_TERMIOS_TERMIOS5 {
+ display "Termios TTY channel #5"
+ flavor bool
+ default_value 0
+ implements CYGINT_IO_SERIAL_TERMIOS_TERMIOS_TTY
+ parent CYGPKG_IO_SERIAL_TERMIOS
+ active_if CYGPKG_IO_SERIAL_TERMIOS
+ description "
+ This option causes '/dev/termios5' to be included in the
+ standard drivers."
+
+ cdl_option CYGDAT_IO_SERIAL_TERMIOS_TERMIOS5_DEV {
+ display "Termios TTY channel #5 device"
+ flavor data
+ default_value {"\"/dev/ser5\""}
+ description "
+ This option selects the physical device to use for
+ '/dev/termios5'."
+ }
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_FREESCALE_UART_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_IO_SERIAL_FREESCALE_UART_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_FREESCALE_UART_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_freescale_uart.cdl
diff --git a/ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_chan.inl b/ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_chan.inl
new file mode 100644
index 0000000..6593ef2
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_chan.inl
@@ -0,0 +1,378 @@
+//==========================================================================
+//
+// ser_freescale_uart.inl
+//
+// Freescale UART Serial channel definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Kocho <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2011-02-10
+// Purpose: Freescale UART Serial I/O module (interrupt driven version)
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_UART0
+static const uart_pins_t uart0_pins = {
+ rx : CYGHWR_IO_FREESCALE_UART0_PIN_RX,
+ tx : CYGHWR_IO_FREESCALE_UART0_PIN_TX,
+ rts : CYGHWR_IO_FREESCALE_UART0_PIN_RTS,
+ cts : CYGHWR_IO_FREESCALE_UART0_PIN_CTS
+};
+static uart_serial_info uart_serial_info0 = {
+ uart_base : CYGADDR_IO_SERIAL_FREESCALE_UART0_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_UART0_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_UART0_INT_PRIORITY,
+ clock : CYGHWR_IO_FREESCALE_UART0_CLOCK,
+ pins_p : &uart0_pins
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_UART0_BUFSIZE > 0
+static unsigned char
+ uart_serial_out_buf0[CYGNUM_IO_SERIAL_FREESCALE_UART0_BUFSIZE];
+static unsigned char
+ uart_serial_in_buf0[CYGNUM_IO_SERIAL_FREESCALE_UART0_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(
+ uart_serial_channel0,
+ uart_serial_funs,
+ uart_serial_info0,
+ CYG_SERIAL_BAUD_RATE(
+ CYGNUM_IO_SERIAL_FREESCALE_UART0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &uart_serial_out_buf0[0],
+ sizeof(uart_serial_out_buf0),
+ &uart_serial_in_buf0[0],
+ sizeof(uart_serial_in_buf0));
+#else
+static
+SERIAL_CHANNEL(uart_serial_channel0,
+ uart_serial_funs,
+ uart_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_UART0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(uart_serial_io0,
+ CYGDAT_IO_SERIAL_FREESCALE_UART0_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ uart_serial_init,
+ uart_serial_lookup,
+ &uart_serial_channel0);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_UART0
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_UART1
+static const uart_pins_t uart1_pins = {
+ rx : CYGHWR_IO_FREESCALE_UART1_PIN_RX,
+ tx : CYGHWR_IO_FREESCALE_UART1_PIN_TX,
+ rts : CYGHWR_IO_FREESCALE_UART1_PIN_RTS,
+ cts : CYGHWR_IO_FREESCALE_UART1_PIN_CTS
+};
+static uart_serial_info uart_serial_info1 = {
+ uart_base : CYGADDR_IO_SERIAL_FREESCALE_UART1_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_UART1_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_UART1_INT_PRIORITY,
+ clock : CYGHWR_IO_FREESCALE_UART1_CLOCK,
+ pins_p : &uart1_pins
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_UART1_BUFSIZE > 0
+static unsigned char
+ uart_serial_out_buf1[CYGNUM_IO_SERIAL_FREESCALE_UART1_BUFSIZE];
+static unsigned char
+ uart_serial_in_buf1[CYGNUM_IO_SERIAL_FREESCALE_UART1_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(uart_serial_channel1,
+ uart_serial_funs,
+ uart_serial_info1,
+ CYG_SERIAL_BAUD_RATE(
+ CYGNUM_IO_SERIAL_FREESCALE_UART1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &uart_serial_out_buf1[0],
+ sizeof(uart_serial_out_buf1),
+ &uart_serial_in_buf1[0],
+ sizeof(uart_serial_in_buf1));
+#else
+static
+SERIAL_CHANNEL(uart_serial_channel1,
+ uart_serial_funs,
+ uart_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_UART1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(uart_serial_io1,
+ CYGDAT_IO_SERIAL_FREESCALE_UART1_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ uart_serial_init,
+ uart_serial_lookup,
+ &uart_serial_channel1);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_UART1
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_UART2
+static const uart_pins_t uart2_pins = {
+ rx : CYGHWR_IO_FREESCALE_UART2_PIN_RX,
+ tx : CYGHWR_IO_FREESCALE_UART2_PIN_TX,
+ rts : CYGHWR_IO_FREESCALE_UART2_PIN_RTS,
+ cts : CYGHWR_IO_FREESCALE_UART2_PIN_CTS
+};
+static uart_serial_info uart_serial_info2 = {
+ uart_base : CYGADDR_IO_SERIAL_FREESCALE_UART2_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_UART2_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_UART2_INT_PRIORITY,
+ clock : CYGHWR_IO_FREESCALE_UART2_CLOCK,
+ pins_p : &uart2_pins
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_UART2_BUFSIZE > 0
+static unsigned char
+ uart_serial_out_buf2[CYGNUM_IO_SERIAL_FREESCALE_UART2_BUFSIZE];
+static unsigned char
+ uart_serial_in_buf2[CYGNUM_IO_SERIAL_FREESCALE_UART2_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(uart_serial_channel2,
+ uart_serial_funs,
+ uart_serial_info2,
+ CYG_SERIAL_BAUD_RATE(
+ CYGNUM_IO_SERIAL_FREESCALE_UART2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &uart_serial_out_buf2[0],
+ sizeof(uart_serial_out_buf2),
+ &uart_serial_in_buf2[0],
+ sizeof(uart_serial_in_buf2));
+#else
+static
+SERIAL_CHANNEL(uart_serial_channel2,
+ uart_serial_funs,
+ uart_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_UART2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(uart_serial_io2,
+ CYGDAT_IO_SERIAL_FREESCALE_UART2_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ uart_serial_init,
+ uart_serial_lookup,
+ &uart_serial_channel2);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_UART2
+
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_UART3
+static const uart_pins_t uart3_pins = {
+ rx : CYGHWR_IO_FREESCALE_UART3_PIN_RX,
+ tx : CYGHWR_IO_FREESCALE_UART3_PIN_TX,
+ rts : CYGHWR_IO_FREESCALE_UART3_PIN_RTS,
+ cts : CYGHWR_IO_FREESCALE_UART3_PIN_CTS
+};
+static uart_serial_info uart_serial_info3 = {
+ uart_base : CYGADDR_IO_SERIAL_FREESCALE_UART3_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_UART3_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_UART3_INT_PRIORITY,
+ clock : CYGHWR_IO_FREESCALE_UART3_CLOCK,
+ pins_p : &uart3_pins
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_UART3_BUFSIZE > 0
+static unsigned char
+ uart_serial_out_buf3[CYGNUM_IO_SERIAL_FREESCALE_UART3_BUFSIZE];
+static unsigned char
+ uart_serial_in_buf3[CYGNUM_IO_SERIAL_FREESCALE_UART3_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(uart_serial_channel3,
+ uart_serial_funs,
+ uart_serial_info3,
+ CYG_SERIAL_BAUD_RATE(
+ CYGNUM_IO_SERIAL_FREESCALE_UART3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &uart_serial_out_buf3[0],
+ sizeof(uart_serial_out_buf3),
+ &uart_serial_in_buf3[0],
+ sizeof(uart_serial_in_buf3));
+#else
+static
+SERIAL_CHANNEL(uart_serial_channel3,
+ uart_serial_funs,
+ uart_serial_info3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_UART3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(uart_serial_io3,
+ CYGDAT_IO_SERIAL_FREESCALE_UART3_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ uart_serial_init,
+ uart_serial_lookup,
+ &uart_serial_channel3);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_UART3
+
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_UART4
+static const uart_pins_t uart4_pins = {
+ rx : CYGHWR_IO_FREESCALE_UART4_PIN_RX,
+ tx : CYGHWR_IO_FREESCALE_UART4_PIN_TX,
+ rts : CYGHWR_IO_FREESCALE_UART4_PIN_RTS,
+ cts : CYGHWR_IO_FREESCALE_UART4_PIN_CTS
+};
+static uart_serial_info uart_serial_info4 = {
+ uart_base : CYGADDR_IO_SERIAL_FREESCALE_UART4_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_UART4_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_UART4_INT_PRIORITY,
+ clock : CYGHWR_IO_FREESCALE_UART4_CLOCK,
+ pins_p : &uart4_pins
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_UART4_BUFSIZE > 0
+static unsigned char
+ uart_serial_out_buf4[CYGNUM_IO_SERIAL_FREESCALE_UART4_BUFSIZE];
+static unsigned char
+ uart_serial_in_buf4[CYGNUM_IO_SERIAL_FREESCALE_UART4_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(uart_serial_channel4,
+ uart_serial_funs,
+ uart_serial_info4,
+ CYG_SERIAL_BAUD_RATE(
+ CYGNUM_IO_SERIAL_FREESCALE_UART4_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &uart_serial_out_buf4[0],
+ sizeof(uart_serial_out_buf4),
+ &uart_serial_in_buf4[0],
+ sizeof(uart_serial_in_buf4));
+#else
+static
+SERIAL_CHANNEL(uart_serial_channel4,
+ uart_serial_funs,
+ uart_serial_info4,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_UART4_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(uart_serial_io4,
+ CYGDAT_IO_SERIAL_FREESCALE_UART4_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ uart_serial_init,
+ uart_serial_lookup,
+ &uart_serial_channel4);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_UART4
+
+
+#if defined CYGPKG_IO_SERIAL_FREESCALE_UART5
+static const uart_pins_t uart5_pins = {
+ rx : CYGHWR_IO_FREESCALE_UART5_PIN_RX,
+ tx : CYGHWR_IO_FREESCALE_UART5_PIN_TX,
+ rts : CYGHWR_IO_FREESCALE_UART5_PIN_RTS,
+ cts : CYGHWR_IO_FREESCALE_UART5_PIN_CTS
+};
+static uart_serial_info uart_serial_info5 = {
+ uart_base : CYGADDR_IO_SERIAL_FREESCALE_UART5_BASE,
+ interrupt_num : CYGNUM_IO_SERIAL_FREESCALE_UART5_INT_VECTOR,
+ interrupt_priority : CYGNUM_IO_SERIAL_FREESCALE_UART5_INT_PRIORITY,
+ clock : CYGHWR_IO_FREESCALE_UART5_CLOCK,
+ pins_p : &uart5_pins
+};
+#if CYGNUM_IO_SERIAL_FREESCALE_UART5_BUFSIZE > 0
+static unsigned char
+ uart_serial_out_buf5[CYGNUM_IO_SERIAL_FREESCALE_UART5_BUFSIZE];
+static unsigned char
+ uart_serial_in_buf5[CYGNUM_IO_SERIAL_FREESCALE_UART5_BUFSIZE];
+
+static
+SERIAL_CHANNEL_USING_INTERRUPTS(uart_serial_channel5,
+ uart_serial_funs,
+ uart_serial_info5,
+ CYG_SERIAL_BAUD_RATE(
+ CYGNUM_IO_SERIAL_FREESCALE_UART5_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &uart_serial_out_buf5[0],
+ sizeof(uart_serial_out_buf5),
+ &uart_serial_in_buf5[0],
+ sizeof(uart_serial_in_buf5));
+#else
+static
+SERIAL_CHANNEL(uart_serial_channel5,
+ uart_serial_funs,
+ uart_serial_info5,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_FREESCALE_UART5_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(uart_serial_io5,
+ CYGDAT_IO_SERIAL_FREESCALE_UART5_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ uart_serial_init,
+ uart_serial_lookup,
+ &uart_serial_channel5);
+#endif // ifdef CYGPKG_IO_SERIAL_FREESCALE_UART5
diff --git a/ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_termiostty_add.inl b/ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_termiostty_add.inl
new file mode 100644
index 0000000..309c8f9
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_termiostty_add.inl
@@ -0,0 +1,79 @@
+#ifndef CYGONCE_SER_FREESCALE_UART_TERMIOS_ADD_INL
+#define CYGONCE_SER_FREESCALE_UART_TERMIOS_ADD_INL
+//=============================================================================
+//
+// ser_freescale_uart_termiostty_add.inl
+//
+// Termios definitions beyond #3.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ilijak
+// Contributor(s):
+// Date: 2011-03-28
+// Purpose: Termios definitions beyond #3.
+// Description:
+// Usage: This file is included by pkgconf/io/serial.h
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+
+#ifdef CYGPKG_IO_SERIAL_TERMIOS_TERMIOS4
+static struct termios_private_info termios_private_info4;
+DEVTAB_ENTRY(termios_io4,
+ "/dev/termios4",
+ CYGDAT_IO_SERIAL_TERMIOS_TERMIOS4_DEV,
+ &termios_devio,
+ termios_init,
+ termios_lookup,
+ &termios_private_info4);
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_TERMIOS_TERMIOS5
+static struct termios_private_info termios_private_info5;
+DEVTAB_ENTRY(termios_io5,
+ "/dev/termios5",
+ CYGDAT_IO_SERIAL_TERMIOS_TERMIOS5_DEV,
+ &termios_devio,
+ termios_init,
+ termios_lookup,
+ &termios_private_info5);
+#endif
+//-----------------------------------------------------------------------------
+// end of ser_freescale_uart_termiostty_add.inl
+#endif // CYGONCE_SER_FREESCALE_UART_TERMIOS_ADD_INL
diff --git a/ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_tty_add.inl b/ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_tty_add.inl
new file mode 100644
index 0000000..6587cc9
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/uart/drv/current/include/ser_freescale_uart_tty_add.inl
@@ -0,0 +1,79 @@
+#ifndef CYGONCE_SER_FREESCALE_UART_TTY_ADD_INL
+#define CYGONCE_SER_FREESCALE_UART_TTY_ADD_INL
+//=============================================================================
+//
+// ser_freescale_uart_tty_add.inl
+//
+// TTY definitions beyond #3.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ilijak
+// Contributor(s):
+// Date: 2011-03-28
+// Purpose: TTY definitions beyond 3.
+// Description:
+// Usage: This file is included by pkgconf/io/serial.h
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+
+#ifdef CYGPKG_IO_SERIAL_TTY_TTY4
+static struct tty_private_info tty_private_info4;
+DEVTAB_ENTRY(tty_io4,
+ "/dev/tty4",
+ CYGDAT_IO_SERIAL_TTY_TTY4_DEV,
+ &tty_devio,
+ tty_init,
+ tty_lookup, // Execute this when device is being looked up
+ &tty_private_info4);
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_TTY_TTY5
+static struct tty_private_info tty_private_info5;
+DEVTAB_ENTRY(tty_io5,
+ "/dev/tty5",
+ CYGDAT_IO_SERIAL_TTY_TTY5_DEV,
+ &tty_devio,
+ tty_init,
+ tty_lookup, // Execute this when device is being looked up
+ &tty_private_info5);
+#endif
+//-----------------------------------------------------------------------------
+// end of ser_freescale_uart_tty_add.inl
+#endif // CYGONCE_SER_FREESCALE_UART_TTY_ADD_INL
diff --git a/ecos/packages/devs/serial/freescale/uart/drv/current/src/ser_freescale_uart.c b/ecos/packages/devs/serial/freescale/uart/drv/current/src/ser_freescale_uart.c
new file mode 100644
index 0000000..6c89ae5
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/uart/drv/current/src/ser_freescale_uart.c
@@ -0,0 +1,397 @@
+//==========================================================================
+//
+// ser_freescale_uart.c
+//
+// Freescale UART Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Kocho <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2011-02-10
+// Purpose: Freescale UART Serial I/O module (interrupt driven version)
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arbiter.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+#include <cyg/io/ser_freescale_uart.h>
+
+// Only build this driver for if Freescale UART is needed.
+#ifdef CYGPKG_IO_SERIAL_FREESCALE_UART
+
+typedef struct uart_pins_s {
+ cyg_uint32 rx;
+ cyg_uint32 tx;
+ cyg_uint32 rts;
+ cyg_uint32 cts;
+} uart_pins_t;
+
+
+typedef struct uart_serial_info {
+ CYG_ADDRWORD uart_base; // Base address of the uart port
+ CYG_WORD interrupt_num; // NVIC interrupt vector
+ cyg_priority_t interrupt_priority; // NVIC interupt priority
+ const uart_pins_t *pins_p; // Rx, Tx, etc.
+ cyg_uint32 clock; // Clock gate
+ cyg_bool tx_active;
+ cyg_interrupt interrupt_obj; // Interrupt object
+ cyg_handle_t interrupt_handle; // Interrupt handle
+} uart_serial_info;
+
+static bool uart_serial_init(struct cyg_devtab_entry * tab);
+static bool uart_serial_putc(serial_channel * chan, unsigned char c);
+static Cyg_ErrNo uart_serial_lookup(struct cyg_devtab_entry ** tab,
+ struct cyg_devtab_entry * sub_tab,
+ const char * name);
+static unsigned char uart_serial_getc(serial_channel *chan);
+static Cyg_ErrNo uart_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void uart_serial_start_xmit(serial_channel *chan);
+static void uart_serial_stop_xmit(serial_channel *chan);
+
+// Interrupt servers
+static cyg_uint32 uart_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void uart_serial_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+
+static SERIAL_FUNS(uart_serial_funs,
+ uart_serial_putc,
+ uart_serial_getc,
+ uart_serial_set_config,
+ uart_serial_start_xmit,
+ uart_serial_stop_xmit);
+
+// Available baud rates
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 0, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 230400, // 230400
+};
+
+#include <cyg/io/ser_freescale_uart_chan.inl>
+
+//----------------------------------------------------------------------------
+// Internal function to actually configure the hardware to desired
+// baud rate, etc.
+//----------------------------------------------------------------------------
+static bool
+uart_serial_config_port(serial_channel * chan, cyg_serial_info_t * new_config,
+ bool init)
+{
+ cyg_uint32 regval;
+ uart_serial_info * uart_chan = (uart_serial_info *)(chan->dev_priv);
+ cyg_addrword_t uart_base = uart_chan->uart_base;
+ cyg_uint32 baud_rate = select_baud[new_config->baud];
+
+ if(!baud_rate) return false; // Invalid baud rate selected
+
+ // Bring clock to the sevice
+ CYGHWR_IO_CLOCK_ENABLE(uart_chan->clock);
+ // Configure PORT pins
+ CYGHWR_IO_FREESCALE_UART_PIN(uart_chan->pins_p->rx);
+ CYGHWR_IO_FREESCALE_UART_PIN(uart_chan->pins_p->tx);
+
+ CYGHWR_IO_FREESCALE_UART_BAUD_SET(uart_base, baud_rate);
+
+ if(new_config->word_length != 8)
+ return false;
+
+ switch(new_config->parity) {
+ case CYGNUM_SERIAL_PARITY_NONE:
+ regval = 0;
+ break;
+ case CYGNUM_SERIAL_PARITY_EVEN:
+ regval = CYGHWR_DEV_FREESCALE_UART_C1_PE;
+ break;
+ case CYGNUM_SERIAL_PARITY_ODD:
+ regval = CYGHWR_DEV_FREESCALE_UART_C1_PE |
+ CYGHWR_DEV_FREESCALE_UART_C1_PT;
+ break;
+ default: return false;
+ }
+
+ HAL_WRITE_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_C1, regval);
+
+ if(init) { // Enable the receiver interrupt
+ regval = CYGHWR_DEV_FREESCALE_UART_C2_RIE;
+ } else { // Restore the old interrupt state
+ HAL_READ_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_C2, regval);
+ }
+
+ // Enable the device
+ regval |= CYGHWR_DEV_FREESCALE_UART_C2_TE |
+ CYGHWR_DEV_FREESCALE_UART_C2_RE;
+
+ HAL_WRITE_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_C2, regval);
+
+ uart_chan->tx_active = false;
+
+ if(new_config != &chan->config)
+ chan->config = *new_config;
+
+ return true;
+}
+
+//--------------------------------------------------------------
+// Function to initialize the device. Called at bootstrap time.
+//--------------------------------------------------------------
+static bool
+uart_serial_init(struct cyg_devtab_entry * tab)
+{
+ serial_channel * chan = (serial_channel *)tab->priv;
+ uart_serial_info * uart_chan = (uart_serial_info *)chan->dev_priv;
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ if(chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(uart_chan->interrupt_num,
+ uart_chan->interrupt_priority,
+ // Data item passed to interrupt handler
+ (cyg_addrword_t)chan,
+ uart_serial_ISR,
+ uart_serial_DSR,
+ &uart_chan->interrupt_handle,
+ &uart_chan->interrupt_obj);
+
+ cyg_drv_interrupt_attach(uart_chan->interrupt_handle);
+ cyg_drv_interrupt_unmask(uart_chan->interrupt_num);
+ }
+ return uart_serial_config_port(chan, &chan->config, true);
+}
+
+//----------------------------------------------------------------------
+// This routine is called when the device is "looked" up (i.e. attached)
+//----------------------------------------------------------------------
+static Cyg_ErrNo
+uart_serial_lookup(struct cyg_devtab_entry ** tab,
+ struct cyg_devtab_entry * sub_tab, const char * name)
+{
+ serial_channel * chan = (serial_channel *)(*tab)->priv;
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+
+ return ENOERR;
+}
+
+//-----------------------------------------------------------------
+// Send a character to Tx
+//-----------------------------------------------------------------
+static bool
+uart_serial_putc(serial_channel * chan, unsigned char ch_out)
+{
+ uart_serial_info * uart_chan = (uart_serial_info *)chan->dev_priv;
+ cyg_addrword_t uart_base = uart_chan->uart_base;
+ cyg_uint32 uart_sr;
+
+ HAL_READ_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_S1, uart_sr);
+ if(uart_sr & CYGHWR_DEV_FREESCALE_UART_S1_TDRE) {
+ HAL_WRITE_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_D, ch_out);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+//---------------------------------------------------------------------
+// Fetch a character Rx (for polled operation only)
+//---------------------------------------------------------------------
+static unsigned char
+uart_serial_getc(serial_channel * chan)
+{
+ cyg_uint8 ch_in;
+ uart_serial_info * uart_chan = (uart_serial_info *)chan->dev_priv;
+ cyg_addrword_t uart_base = uart_chan->uart_base;
+
+ cyg_uint32 uart_sr;
+
+ do {
+ HAL_READ_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_S1, uart_sr);
+ } while(uart_sr & CYGHWR_DEV_FREESCALE_UART_S1_RDRF);
+
+ HAL_READ_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_D, ch_in);
+
+ return ch_in;
+}
+
+
+//---------------------------------------------------
+// Set up the device characteristics; baud rate, etc.
+//---------------------------------------------------
+static bool
+uart_serial_set_config(serial_channel * chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 * len)
+{
+ switch(key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO: {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if(*len < sizeof(cyg_serial_info_t)) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if(true != uart_serial_config_port(chan, config, false))
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+//-------------------------------------
+// Enable the transmitter on the device
+//-------------------------------------
+static void uart_serial_start_xmit(serial_channel * chan)
+{
+ uart_serial_info * uart_chan = (uart_serial_info *)chan->dev_priv;
+ cyg_addrword_t uart_base = uart_chan->uart_base;
+ cyg_uint32 uart_cr12;
+
+ if(!uart_chan->tx_active) {
+ uart_chan->tx_active = true;
+ HAL_READ_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_C2, uart_cr12);
+ uart_cr12 |= CYGHWR_DEV_FREESCALE_UART_C2_TIE;
+ HAL_WRITE_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_C2, uart_cr12);
+ }
+}
+
+//--------------------------------------
+// Disable the transmitter on the device
+//--------------------------------------
+static void uart_serial_stop_xmit(serial_channel * chan)
+{
+ uart_serial_info * uart_chan = (uart_serial_info *)chan->dev_priv;
+
+ cyg_addrword_t uart_base = uart_chan->uart_base;
+ cyg_uint32 uart_cr12;
+
+ if(uart_chan->tx_active) {
+ uart_chan->tx_active = false;
+ HAL_READ_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_C2, uart_cr12);
+ uart_cr12 &= ~CYGHWR_DEV_FREESCALE_UART_C2_TIE;
+ HAL_WRITE_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_C2, uart_cr12);
+ }
+}
+
+//-----------------------------------------
+// The low level interrupt handler
+//-----------------------------------------
+static
+cyg_uint32 uart_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel * chan = (serial_channel *)data;
+ uart_serial_info * uart_chan = (uart_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(uart_chan->interrupt_num);
+ cyg_drv_interrupt_acknowledge(uart_chan->interrupt_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+
+//------------------------------------------
+// The high level interrupt handler
+//------------------------------------------
+
+#define CYGHWR_DEV_FREESCALE_UART_S1_ERRORS \
+ (CYGHWR_DEV_FREESCALE_UART_S1_OR | \
+ CYGHWR_DEV_FREESCALE_UART_S1_NF | \
+ CYGHWR_DEV_FREESCALE_UART_S1_FE | \
+ CYGHWR_DEV_FREESCALE_UART_S1_PF)
+
+static void
+uart_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel * chan = (serial_channel *)data;
+ uart_serial_info * uart_chan = (uart_serial_info *)chan->dev_priv;
+ cyg_addrword_t uart_base = uart_chan->uart_base;
+ volatile cyg_uint32 uart_sr;
+ cyg_uint8 uart_dr;
+
+ HAL_READ_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_S1, uart_sr);
+ if(uart_sr & (CYGHWR_DEV_FREESCALE_UART_S1_RDRF |
+ CYGHWR_DEV_FREESCALE_UART_S1_ERRORS)) {
+ // Receiver full or errors
+ HAL_READ_UINT8(uart_base + CYGHWR_DEV_FREESCALE_UART_D, uart_dr);
+ if(uart_sr & CYGHWR_DEV_FREESCALE_UART_S1_ERRORS) {
+ // Check for receive error
+ } else { // No errors, get the character
+ (chan->callbacks->rcv_char)(chan, (cyg_uint8)uart_dr);
+ }
+ }
+
+ if(uart_chan->tx_active && (uart_sr & CYGHWR_DEV_FREESCALE_UART_S1_TDRE)){
+ //Transmitter empty
+ (chan->callbacks->xmt_char)(chan);
+ }
+
+ cyg_drv_interrupt_unmask(uart_chan->interrupt_num);
+}
+
+#endif // CYGPKG_IO_SERIAL_FREESCALE_UART
+// EOF ser_freescale_uart.c
diff --git a/ecos/packages/devs/serial/freescale/uart/hdr/current/ChangeLog b/ecos/packages/devs/serial/freescale/uart/hdr/current/ChangeLog
new file mode 100644
index 0000000..0a2d232
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/uart/hdr/current/ChangeLog
@@ -0,0 +1,34 @@
+2013-04-01 Ilija Kocho <ilijak@siva.com.mk>
+
+ * include/ser_freescale_uart.h: Add clock gating comment.
+ [ Bugzilla 1001814 ]
+
+2011-03-26 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/ser_freescale_uart_hdr.cdl:
+ * include/ser_freescale_uart.h:
+ New package -- Freescale UART header.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/freescale/uart/hdr/current/cdl/ser_freescale_uart_hdr.cdl b/ecos/packages/devs/serial/freescale/uart/hdr/current/cdl/ser_freescale_uart_hdr.cdl
new file mode 100644
index 0000000..e2bac47
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/uart/hdr/current/cdl/ser_freescale_uart_hdr.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# ser_freescale_uart_h.cdl
+#
+# eCos serial Freescale UART configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Ilija Kocho <ilijak@siva.com.mk>
+# Original data:
+# Contributors:
+# Date: 2011-02-05
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_FREESCALE_UART_HDR {
+ display "Freescale UART header"
+
+ include_dir cyg/io
+ description "
+ This pacckage provides header file with definitions and macros for
+ Freescale UART. Same header is used by Freescale UART serial driver
+ as well as by HAL. Freescale UART is on-chip serial controller found
+ on some Freescale micro-controllers such as Kinetis familly, etc."
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HDR_HEADER <pkgconf/io_serial_freescale_uart_hdr.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+}
+
+# EOF ser_freescale_uart_h.cdl
diff --git a/ecos/packages/devs/serial/freescale/uart/hdr/current/include/ser_freescale_uart.h b/ecos/packages/devs/serial/freescale/uart/hdr/current/include/ser_freescale_uart.h
new file mode 100644
index 0000000..4bfc837
--- /dev/null
+++ b/ecos/packages/devs/serial/freescale/uart/hdr/current/include/ser_freescale_uart.h
@@ -0,0 +1,144 @@
+#ifndef CYGONCE_DEVS_SERIAL_FREESCALE_UART_H
+#define CYGONCE_DEVS_SERIAL_FREESCALE_UART_H
+//==========================================================================
+//
+// ser_freescale_uart.h
+//
+// Freescale UART I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Kocho <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2011-02-05
+// Purpose: Freescale UART I/O definitions.
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+enum {
+ CYGHWR_DEV_FREESCALE_UART_BDH, // UART Baud Rate Register High
+ CYGHWR_DEV_FREESCALE_UART_BDL, // UART Baud Rate Register Low
+ CYGHWR_DEV_FREESCALE_UART_C1, // UART Control Register 1
+ CYGHWR_DEV_FREESCALE_UART_C2, // UART Control Register 2
+ CYGHWR_DEV_FREESCALE_UART_S1, // UART Status Register 1
+ CYGHWR_DEV_FREESCALE_UART_S2, // UART Status Register 2
+ CYGHWR_DEV_FREESCALE_UART_C3, // UART Control Register 3
+ CYGHWR_DEV_FREESCALE_UART_D, // UART Data Register
+ CYGHWR_DEV_FREESCALE_UART_MA1, // UART Match Address Registers 1
+ CYGHWR_DEV_FREESCALE_UART_MA2, // UART Match Address Registers 2
+ CYGHWR_DEV_FREESCALE_UART_C4, // UART Control Register 4
+ CYGHWR_DEV_FREESCALE_UART_C5, // UART Control Register 5
+ CYGHWR_DEV_FREESCALE_UART_ED, // UART Extended Data Register
+ CYGHWR_DEV_FREESCALE_UART_MODEM, // UART Modem Register
+ CYGHWR_DEV_FREESCALE_UART_IR, // UART Infrared Register
+ CYGHWR_DEV_FREESCALE_UART_Res_0,
+ CYGHWR_DEV_FREESCALE_UART_PFIFO, // UART FIFO Parameters
+ CYGHWR_DEV_FREESCALE_UART_CFIFO, // UART FIFO Control Register
+ CYGHWR_DEV_FREESCALE_UART_SFIFO, // UART FIFO Status Register
+ CYGHWR_DEV_FREESCALE_UART_TWFIFO, // UART FIFO Transmit Watermark
+ CYGHWR_DEV_FREESCALE_UART_TCFIFO, // UART FIFO Transmit Count
+ CYGHWR_DEV_FREESCALE_UART_RWFIFO, // UART FIFO Receive Watermark
+ CYGHWR_DEV_FREESCALE_UART_RCFIFO, // UART FIFO Receive Count
+ CYGHWR_DEV_FREESCALE_UART_Res_1,
+ CYGHWR_DEV_FREESCALE_UART_C7816, // UART 7816 Control Register
+ CYGHWR_DEV_FREESCALE_UART_IE7816, // UART 7816 Interrupt Enable Register
+ CYGHWR_DEV_FREESCALE_UART_IS7816, // UART 7816 Interrupt Status Register
+ CYGHWR_DEV_FREESCALE_UART_WP7816_T0T1, // UART 7816 Wait Parameter Register
+ CYGHWR_DEV_FREESCALE_UART_WN7816, // UART 7816 Wait N Register
+ CYGHWR_DEV_FREESCALE_UART_WF7816, // UART 7816 Wait FD Register
+ CYGHWR_DEV_FREESCALE_UART_ET7816, // UART 7816 Error Threshold Register
+ CYGHWR_DEV_FREESCALE_UART_TL7816 // UART 7816 Transmit Length Register
+};
+
+// CYGHWR_IO_FREESCALE_UART_BAUD_SET(__uart_p, _baud_) should be provided by HAL.
+// CYGHWR_IO_FREESCALE_UART_PIN(__pin) should be provided by HAL.
+// CYGHWR_IO_FREESCALE_UARTn_CLOCK should be provided by HAL.
+// CYGHWR_IO_FREESCALE_UARTn_PIN_RX should be provided by HAL.
+// CYGHWR_IO_FREESCALE_UARTn_PIN_TX should be provided by HAL.
+// CYGHWR_IO_FREESCALE_UARTn_PIN_RTS should be provided by HAL.
+// CYGHWR_IO_FREESCALE_UARTn_PIN_CTS should be provided by HAL.
+
+
+#define CYGHWR_DEV_FREESCALE_UART_C1_LOOPS (0x80)
+#define CYGHWR_DEV_FREESCALE_UART_C1_UARTSWAI (0x40)
+#define CYGHWR_DEV_FREESCALE_UART_C1_RSRC (0x20)
+#define CYGHWR_DEV_FREESCALE_UART_C1_M (0x10)
+#define CYGHWR_DEV_FREESCALE_UART_C1_WAKE (0x08)
+#define CYGHWR_DEV_FREESCALE_UART_C1_ILT (0x04)
+#define CYGHWR_DEV_FREESCALE_UART_C1_PE (0x02)
+#define CYGHWR_DEV_FREESCALE_UART_C1_PT (0x01)
+
+#define CYGHWR_DEV_FREESCALE_UART_C2_TIE (0x80)
+#define CYGHWR_DEV_FREESCALE_UART_C2_TCIE (0x40)
+#define CYGHWR_DEV_FREESCALE_UART_C2_RIE (0x20)
+#define CYGHWR_DEV_FREESCALE_UART_C2_ILIE (0x10)
+#define CYGHWR_DEV_FREESCALE_UART_C2_TE (0x08)
+#define CYGHWR_DEV_FREESCALE_UART_C2_RE (0x04)
+#define CYGHWR_DEV_FREESCALE_UART_C2_RWU (0x02)
+#define CYGHWR_DEV_FREESCALE_UART_C2_SBK (0x01)
+
+#define CYGHWR_DEV_FREESCALE_UART_S1_TDRE (0x80)
+#define CYGHWR_DEV_FREESCALE_UART_S1_TC (0x40)
+#define CYGHWR_DEV_FREESCALE_UART_S1_RDRF (0x20)
+#define CYGHWR_DEV_FREESCALE_UART_S1_IDLE (0x10)
+#define CYGHWR_DEV_FREESCALE_UART_S1_OR (0x08)
+#define CYGHWR_DEV_FREESCALE_UART_S1_NF (0x04)
+#define CYGHWR_DEV_FREESCALE_UART_S1_FE (0x02)
+#define CYGHWR_DEV_FREESCALE_UART_S1_PF (0x01)
+
+#define CYGHWR_DEV_FREESCALE_UART_S2_LBKDIF (0x80)
+#define CYGHWR_DEV_FREESCALE_UART_S2_RXEDGIF (0x40)
+#define CYGHWR_DEV_FREESCALE_UART_S2_MSBF (0x20)
+#define CYGHWR_DEV_FREESCALE_UART_S2_RXINV (0x10)
+#define CYGHWR_DEV_FREESCALE_UART_S2_RWUID (0x08)
+#define CYGHWR_DEV_FREESCALE_UART_S2_BRK13 (0x04)
+#define CYGHWR_DEV_FREESCALE_UART_S2_LBKDE (0x02)
+#define CYGHWR_DEV_FREESCALE_UART_S2_RAF (0x01)
+
+#define CYGHWR_DEV_FREESCALE_UART_C3_R8 (0x80)
+#define CYGHWR_DEV_FREESCALE_UART_C3_T8 (0x40)
+#define CYGHWR_DEV_FREESCALE_UART_C3_TXDIR (0x20)
+#define CYGHWR_DEV_FREESCALE_UART_C3_TXINV (0x10)
+#define CYGHWR_DEV_FREESCALE_UART_C3_ORIE (0x08)
+#define CYGHWR_DEV_FREESCALE_UART_C3_NEIE (0x04)
+#define CYGHWR_DEV_FREESCALE_UART_C3_FEIE (0x02)
+#define CYGHWR_DEV_FREESCALE_UART_C3_PEIE (0x01)
+
+
+#endif // CYGONCE_DEVS_SERIAL_FREESCALE_UART_H
diff --git a/ecos/packages/devs/serial/generic/16x5x/current/ChangeLog b/ecos/packages/devs/serial/generic/16x5x/current/ChangeLog
new file mode 100644
index 0000000..34e95a1
--- /dev/null
+++ b/ecos/packages/devs/serial/generic/16x5x/current/ChangeLog
@@ -0,0 +1,349 @@
+2012-02-07 Bernard Fouché <bernard.fouche@kuantic.com>
+
+ * src/ser_16x5x.c (serial_config_port): Clear potential Overrun Error
+ condition at init by always reading RHR.
+
+2009-02-17 Rene Schipp von Branitz Nielsen <rbn@vitesse.com>
+
+ * src/ser_16x5x.c:
+ Allow platform code to override the default implementation for
+ writing the LCR register and reading the ISR register by using
+ the SER_16X5X_WRITE_LCR() and SER_16X5X_READ_ISR() macros.
+
+2008-07-08 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/ser_generic_16x5x.cdl
+ (CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO): New interface
+ for devices that support per channel interrupt priorities.
+
+ * src/ser_16x5x.c Added int_prio to pc_serial_info type.
+ serial_config_port(): uses macro
+ CYG_IO_SERIAL_GENERIC_16X5X_CHAN_BAUD_GENERATOR() to get the baud
+ devisor from platform if device suppports per channel baudrate
+ clocks, pc_serial_init(): Use interrupt priority from int_prio
+ data field if device implements
+ CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO
+
+2007-06-22 Alexander Aganichev <aaganichev@gmail.com>
+
+ * cdl/ser_generic_16x5x.cdl
+ (CYGPKG_IO_SERIAL_GENERIC_16X5X_XMIT_REQUIRE_PRIME): New option.
+
+ * src/ser_16x5x.c (pc_serial_start_xmit): Allow platform to define
+ CYGPKG_IO_SERIAL_GENERIC_16X5X_XMIT_REQUIRE_PRIME if enabling THRE
+ interrupt does not generate interrupt unless bytes are posted to the
+ FIFO.
+
+2006-11-27 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/ser_16x5x.c (serial_config_port): Add
+ CYGPRI_IO_SERIAL_GENERIC_16X5X_PLF_INIT_HOOK
+ in case devices need extra initialization.
+
+2006-02-07 Daniel Néri <daniel.neri@sigicom.se>
+
+ * cdl/ser_generic_16x5x.cdl
+ (CYGNUM_IO_SERIAL_GENERIC_16X5X_FIFO_TX_SIZE): New option.
+
+ * src/ser_16x5x.c (serial_config_port, pc_serial_putc,
+ pc_serial_DSR): At TX interrupt, write up to
+ CYGNUM_IO_SERIAL_GENERIC_16X5X_FIFO_TX_SIZE bytes to the transmit
+ FIFO. This makes better use of the FIFO, since the LSR_THE flag
+ resets when the FIFO is non-empty (not when it's full, as this
+ code previously assumed).
+
+2003-09-19 Gary Thomas <gary@mlbassoc.com>
+
+ * src/ser_16x5x.c (pc_serial_init):
+ Allow platform to define CYG_IO_SERIAL_GENERIC_16X5X_BAUD_GENERATOR
+ if the baud rate clock (values) cannot be known at compile time. In
+ this case, the baud rate generator values are provided by platform
+ specific code, computed when the device is first initialized.
+
+2003-07-16 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/ser_16x5x.c (CYG_IO_SERIAL_GENERIC_16X5X_INT_PRIORITY): Add
+ so that the calling hardware-specific drivers can override priorities.
+ Clarify flow control comment.
+
+2003-03-18 Gary Thomas <gary@mlbassoc.com>
+
+ * src/ser_16x5x.c (pc_serial_set_config):
+ Flag for CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE is 32 bits.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_generic_16x5x.cdl: Remove irrelevant doc link.
+
+2001-06-19 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_generic_16x5x.cdl: Only define
+ CYGDAT_IO_SERIAL_DEVICE_HEADER when necessary.
+
+2001-06-18 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/ser_16x5x.c (pc_serial_set_config): Fix length check typo
+
+2001-06-18 Jesper Skov <jskov@masala.cambridge.redhat.com>
+
+ * src/ser_16x5x.c (LCR_PE): Set correct bits (from Boris V. Guzhov)
+
+2001-06-08 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/ser_16x5x.c: Support FIFOs better by detecting what we've got,
+ and only acting if we have a _working_ FIFO.
+ Assert on unhandled serial interrupt type.
+
+2001-03-13 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_generic_16x5x.cdl: Rename
+ CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO_OPTIONS to
+ CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO and make it a boolean. Clarify
+ descriptions a little.
+
+ * src/ser_16x5x.c (serial_config_port): Only program FCR if FIFO
+ support requested.
+ Don't bother with intermediate _fifo_thresh.
+ Detabify.
+
+2001-03-13 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_generic_16x5x.cdl: Removed the default value.
+
+2001-03-09 Julian Smart <julians@redhat.com>
+ Removed default value for flavor none in
+ CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO_OPTIONS since it
+ causes an assert in libcdl
+
+2001-03-05 Jesper Skov <jskov@redhat.com>
+ 2001-02-15 Dave Airlie <airlied@parthus.com>
+
+ * src/ser_16x5x.c (serial_config_port): Add support for setting
+ a FIFO RX Threshold via CDL
+
+ * cdl/ser_generic_16x5x.cdl: Add support for setting a FIFO
+ RX threshold via CDL
+
+2001-01-24 Dave Airlie <airlied@parthus.com>
+
+ * src/ser_16x5x.c (pc_serial_DSR): Allow RX timeouts to be interpreted
+ as RXs.
+
+2000-12-19 Dave Airlie <airlied@parthus.com>
+
+ * src/ser_16x5x.c: Add defines for FIFO control register
+ (serial_config_port): Use these defines.
+
+2000-12-07 Jesper Skov <jskov@redhat.com>
+
+ * src/ser_16x5x.c (ISR_LS): Corrected value. Spotted by Dave Airlie.
+
+2000-09-18 Jesper Skov <jskov@redhat.com>
+
+ * src/ser_16x5x.c: Allow clients to specify register
+ stepping. Rename a type. Fix compile error.
+
+2000-09-14 Jesper Skov <jskov@redhat.com>
+
+ * src/ser_16x5x.c: Moved ARM/PID driver to provide generic 16x5x
+ driver. Rewritten to use HAL IO macros. Still needs some polish
+ and configury to properly support all the various target
+ controllers that may only have a partial set of the features.
+ * cdl/ser_generic_16x5x.cdl: Same.
+
+ * Removed non-PID related ChangeLog entries.
+
+----------------------------------------------------------------------------
+2000-08-24 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/pid_serial_with_ints.c (pid_serial_DSR): Remove accidental
+ OVERRUNERR check duplication
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/pid_serial_with_ints.c: Throughout, add support for line status
+ and modem status callbacks, hardware RTS/CTS and DSR/DTR flow control
+ (pid_serial_set_config): Now use keys to make
+ more flexible.
+
+ * src/pid_serial.h: Add more line status, interrupt status and modem
+ status register definitions
+
+ * cdl/ser_arm_pid.cdl: Implements flow control and line status
+ interfaces
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-06-09 Jesper Skov <jskov@redhat.com>
+
+ * src/pid_serial_with_ints.c:
+ * src/pid_serial.h:
+ Cleaned up defines and made DSR handle all received characters.
+ (Dave Airlie (airlied at parthus dot com))
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_arm_pid.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/arm/pid_serial.h: Added BE support.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv
+ interrupts properly (can't ignore them even with TO bit set).
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ Check for receive interrupt before reading.
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c:
+ Update CDL to follow naming conventions.
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change
+ so that the physical port is not modified unless the provided
+ configuration is valid.
+
+ * src/arm/pid_serial_with_ints.c:
+ Add configury for baud rate and buffer size.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo
+ in comment.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c:
+ Update device names to match CDL.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Add 'CYGDBG_IO_INIT' for control
+ of init messages.
+
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/generic/16x5x/current/cdl/ser_generic_16x5x.cdl b/ecos/packages/devs/serial/generic/16x5x/current/cdl/ser_generic_16x5x.cdl
new file mode 100644
index 0000000..2133603
--- /dev/null
+++ b/ecos/packages/devs/serial/generic/16x5x/current/cdl/ser_generic_16x5x.cdl
@@ -0,0 +1,160 @@
+# ====================================================================
+#
+# ser_generic_16x5x.cdl
+#
+# eCos serial 16x5x configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_GENERIC_16X5X {
+ display "16x5x generic serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+
+ active_if CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ 16x5x compatiple controllers."
+
+ compile -library=libextras.a ser_16x5x.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#ifndef CYGDAT_IO_SERIAL_DEVICE_HEADER"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_generic_16x5x.h>"
+ puts $::cdl_system_header "#endif"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG";
+ }
+
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO {
+ display "Per channel interrupt priority support"
+ flavor bool
+ description "
+ A platform should implement this interface if it supports
+ per channel interrupt priorities. If a platform implements
+ this interface it needs to provide an interrupt priority
+ value for each UART channel it supports."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_GENERIC_16X5X_XMIT_REQUIRE_PRIME {
+ display "Transmission require priming"
+ flavor bool
+ default_value 0
+ description "
+ This option should be switched on when enabling THRE interrupt
+ does not generate interrupt unless bytes are posted to the FIFO."
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO {
+ display "16x5x FIFO support"
+ flavor bool
+ default_value 1
+ description "
+ Options to configure the FIFO on a 16550 (or above) variant."
+
+ cdl_option CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO_RX_THRESHOLD {
+ display "Threshold for RX interrupt on 16550 FIFO"
+ flavor data
+ legal_values { 14 8 4 1 }
+ default_value 1
+ description "
+ This options configures the threshold value at which
+ the RX interrupt occurs when a FIFO is used. (16550 and
+ above only), this may be after 1, 4, 8 or 14 characters."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_GENERIC_16X5X_FIFO_TX_SIZE {
+ display "16x5x TX FIFO size"
+ flavor data
+ default_value 16
+ description "
+ Configures the maximum number of bytes written to the
+ 16x5x UART transmit FIFO when the TX interrupt occurs."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_GENERIC_16X5X_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_GENERIC_16X5X_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_GENERIC_16X5X_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_generic_16x5x.cdl
diff --git a/ecos/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c b/ecos/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c
new file mode 100644
index 0000000..d7cf2df
--- /dev/null
+++ b/ecos/packages/devs/serial/generic/16x5x/current/src/ser_16x5x.c
@@ -0,0 +1,700 @@
+//==========================================================================
+//
+// io/serial/generic/16x5x/ser_16x5x.c
+//
+// Generic 16x5x serial driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas, jlarmour, jskov
+// Date: 1999-02-04
+// Purpose: 16x5x generic serial driver
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_io.h>
+
+// Only compile driver if an inline file with driver details was selected.
+#ifdef CYGDAT_IO_SERIAL_GENERIC_16X5X_INL
+
+#ifndef CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP
+#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 1
+#endif
+
+#define SER_REG(_x_) ((_x_)*CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP)
+
+// Receive control Registers
+#define REG_rhr SER_REG(0) // Receive holding register
+#define REG_isr SER_REG(2) // Interrupt status register
+#define REG_lsr SER_REG(5) // Line status register
+#define REG_msr SER_REG(6) // Modem status register
+#define REG_scr SER_REG(7) // Scratch register
+
+// Transmit control Registers
+#define REG_thr SER_REG(0) // Transmit holding register
+#define REG_ier SER_REG(1) // Interrupt enable register
+#define REG_fcr SER_REG(2) // FIFO control register
+#define REG_lcr SER_REG(3) // Line control register
+#define REG_mcr SER_REG(4) // Modem control register
+#define REG_ldl SER_REG(0) // LSB of baud rate
+#define REG_mdl SER_REG(1) // MSB of baud rate
+
+// Interrupt Enable Register
+#define IER_RCV 0x01
+#define IER_XMT 0x02
+#define IER_LS 0x04
+#define IER_MS 0x08
+
+// Line Control Register
+#define LCR_WL5 0x00 // Word length
+#define LCR_WL6 0x01
+#define LCR_WL7 0x02
+#define LCR_WL8 0x03
+#define LCR_SB1 0x00 // Number of stop bits
+#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words
+#define LCR_SB2 0x04
+#define LCR_PN 0x00 // Parity mode - none
+#define LCR_PE 0x18 // Parity mode - even
+#define LCR_PO 0x08 // Parity mode - odd
+#define LCR_PM 0x28 // Forced "mark" parity
+#define LCR_PS 0x38 // Forced "space" parity
+#define LCR_DL 0x80 // Enable baud rate latch
+
+// Line Status Register
+#define LSR_RSR 0x01
+#define LSR_OE 0x02
+#define LSR_PE 0x04
+#define LSR_FE 0x08
+#define LSR_BI 0x10
+#define LSR_THE 0x20
+#define LSR_TEMT 0x40
+#define LSR_FIE 0x80
+
+// Modem Control Register
+#define MCR_DTR 0x01
+#define MCR_RTS 0x02
+#define MCR_INT 0x08 // Enable interrupts
+#define MCR_LOOP 0x10 // Loopback mode
+
+// Interrupt status Register
+#define ISR_MS 0x00
+#define ISR_nIP 0x01
+#define ISR_Tx 0x02
+#define ISR_Rx 0x04
+#define ISR_LS 0x06
+#define ISR_RxTO 0x0C
+#define ISR_64BFIFO 0x20
+#define ISR_FIFOworks 0x40
+#define ISR_FIFOen 0x80
+
+// Modem Status Register
+#define MSR_DCTS 0x01
+#define MSR_DDSR 0x02
+#define MSR_TERI 0x04
+#define MSR_DDCD 0x08
+#define MSR_CTS 0x10
+#define MSR_DSR 0x20
+#define MSR_RI 0x40
+#define MSR_CD 0x80
+
+// FIFO Control Register
+#define FCR_FE 0x01 // FIFO enable
+#define FCR_CRF 0x02 // Clear receive FIFO
+#define FCR_CTF 0x04 // Clear transmit FIFO
+#define FCR_DMA 0x08 // DMA mode select
+#define FCR_F64 0x20 // Enable 64 byte fifo (16750+)
+#define FCR_RT14 0xC0 // Set Rx trigger at 14
+#define FCR_RT8 0x80 // Set Rx trigger at 8
+#define FCR_RT4 0x40 // Set Rx trigger at 4
+#define FCR_RT1 0x00 // Set Rx trigger at 1
+
+static unsigned char select_word_length[] = {
+ LCR_WL5, // 5 bits / word (char)
+ LCR_WL6,
+ LCR_WL7,
+ LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ LCR_SB1, // 1 stop bit
+ LCR_SB1_5, // 1.5 stop bit
+ LCR_SB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ LCR_PN, // No parity
+ LCR_PE, // Even parity
+ LCR_PO, // Odd parity
+ LCR_PM, // Mark parity
+ LCR_PS, // Space parity
+};
+
+// selec_baud[] must be define by the client
+
+typedef struct pc_serial_info {
+ cyg_addrword_t base;
+ int int_num;
+#ifdef CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO
+ int int_prio;
+#endif // CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
+ enum {
+ sNone = 0,
+ s8250,
+ s16450,
+ s16550,
+ s16550a
+ } deviceType;
+ unsigned tx_fifo_size;
+ volatile unsigned tx_fifo_avail;
+#endif
+} pc_serial_info;
+
+static bool pc_serial_init(struct cyg_devtab_entry *tab);
+static bool pc_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo pc_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char pc_serial_getc(serial_channel *chan);
+static Cyg_ErrNo pc_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void pc_serial_start_xmit(serial_channel *chan);
+static void pc_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 pc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void pc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+
+static SERIAL_FUNS(pc_serial_funs,
+ pc_serial_putc,
+ pc_serial_getc,
+ pc_serial_set_config,
+ pc_serial_start_xmit,
+ pc_serial_stop_xmit
+ );
+
+#include CYGDAT_IO_SERIAL_GENERIC_16X5X_INL
+
+#ifndef CYG_IO_SERIAL_GENERIC_16X5X_INT_PRIORITY
+# define CYG_IO_SERIAL_GENERIC_16X5X_INT_PRIORITY 4
+#endif
+
+// Allow platform code to override the default implementation of
+// a write to the LCR
+#ifndef SER_16X5X_WRITE_LCR
+#define SER_16X5X_WRITE_LCR(_base_, _val_) HAL_WRITE_UINT8((_base_) + REG_lcr, _val_)
+#endif
+
+// Allow platform code to override the default implementation of
+// a read of the ISR
+#ifndef SER_16X5X_READ_ISR
+#define SER_16X5X_READ_ISR(_base_, _val_) HAL_READ_UINT8((_base_) + REG_isr, _val_)
+#endif
+
+// Internal function to actually configure the hardware to desired
+// baud rate, etc.
+static bool
+serial_config_port(serial_channel *chan,
+ cyg_serial_info_t *new_config, bool init)
+{
+ pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
+ cyg_addrword_t base = ser_chan->base;
+ //
+ // If the device supports a dynamic per channel baudrate generator
+ // then we call the CYG_IO_SERIAL_GENERIC_16X5X_CHAN_BAUD_GENERATOR()
+ // macro to get the baud divisor. The macro takes the serial channel data
+ // pointer and the baudrate as parameters and returns the baud divisior
+ //
+#ifdef CYG_IO_SERIAL_GENERIC_16X5X_CHAN_BAUD_GENERATOR
+ unsigned short baud_divisor = CYG_IO_SERIAL_GENERIC_16X5X_CHAN_BAUD_GENERATOR(ser_chan, new_config->baud);
+#else
+ unsigned short baud_divisor = select_baud[new_config->baud];
+#endif
+ unsigned char _lcr, _ier;
+ if (baud_divisor == 0) return false; // Invalid configuration
+
+ // Disable port interrupts while changing hardware
+ HAL_READ_UINT8(base+REG_ier, _ier);
+ HAL_WRITE_UINT8(base+REG_ier, 0);
+
+ _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ SER_16X5X_WRITE_LCR(base, _lcr | LCR_DL);
+ HAL_WRITE_UINT8(base+REG_mdl, baud_divisor >> 8);
+ HAL_WRITE_UINT8(base+REG_ldl, baud_divisor & 0xFF);
+ SER_16X5X_WRITE_LCR(base, _lcr);
+ if (init) {
+#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
+ unsigned char _fcr_thresh;
+ cyg_uint8 b;
+
+ /* First, find out what kind of device it is. */
+ ser_chan->deviceType = sNone;
+ HAL_WRITE_UINT8(base+REG_mcr, MCR_LOOP); // enable loopback mode
+ HAL_READ_UINT8(base+REG_msr, b);
+ if (0 == (b & 0xF0)) { // see if MSR had CD, RI, DSR or CTS set
+ HAL_WRITE_UINT8(base+REG_mcr, MCR_LOOP|MCR_DTR|MCR_RTS);
+ HAL_READ_UINT8(base+REG_msr, b);
+ if (0xF0 != (b & 0xF0)) // check that all of CD,RI,DSR and CTS set
+ ser_chan->deviceType = s8250;
+ }
+ HAL_WRITE_UINT8(base+REG_mcr, 0); // disable loopback mode
+
+ if (ser_chan->deviceType == s8250) {
+ // Check for a scratch register; scratch register
+ // indicates 16450 or above.
+ HAL_WRITE_UINT8(base+REG_scr, 0x55);
+ HAL_READ_UINT8(base+REG_scr, b);
+ if (b == 0x55) {
+ HAL_WRITE_UINT8(base+REG_scr, 0xAA);
+ HAL_READ_UINT8(base+REG_scr, b);
+ if (b == 0xAA)
+ ser_chan->deviceType = s16450;
+ }
+ }
+
+ if (ser_chan->deviceType == s16450) {
+ // Check for a FIFO
+ HAL_WRITE_UINT8(base+REG_fcr, FCR_FE);
+ HAL_READ_UINT8(base+REG_isr, b);
+ if (b & ISR_FIFOen)
+ ser_chan->deviceType = s16550; // but FIFO doesn't
+ // necessarily work
+ if (b & ISR_FIFOworks)
+ ser_chan->deviceType = s16550a; // 16550a FIFOs work
+ }
+
+ if (ser_chan->deviceType == s16550a) {
+ switch(CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO_RX_THRESHOLD) {
+ default:
+ case 1:
+ _fcr_thresh=FCR_RT1; break;
+ case 4:
+ _fcr_thresh=FCR_RT4; break;
+ case 8:
+ _fcr_thresh=FCR_RT8; break;
+ case 14:
+ _fcr_thresh=FCR_RT14; break;
+ }
+ _fcr_thresh|=FCR_FE|FCR_CRF|FCR_CTF;
+ ser_chan->tx_fifo_size =
+ CYGNUM_IO_SERIAL_GENERIC_16X5X_FIFO_TX_SIZE;
+ // Enable and clear FIFO
+ HAL_WRITE_UINT8(base+REG_fcr, _fcr_thresh);
+ // Read RHR to clear potential Overrun Error
+ HAL_READ_UINT8(base+REG_rhr, b);
+ }
+ else {
+ ser_chan->tx_fifo_size = 1;
+ HAL_WRITE_UINT8(base+REG_fcr, 0); // make sure it's disabled
+ }
+
+ ser_chan->tx_fifo_avail = ser_chan->tx_fifo_size;
+#endif
+ if (chan->out_cbuf.len != 0) {
+ _ier = IER_RCV;
+ } else {
+ _ier = 0;
+ }
+ // Master interrupt enable
+ HAL_WRITE_UINT8(base+REG_mcr, MCR_INT|MCR_DTR|MCR_RTS);
+ }
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ _ier |= (IER_LS|IER_MS);
+#endif
+ HAL_WRITE_UINT8(base+REG_ier, _ier);
+
+#ifdef CYGPRI_IO_SERIAL_GENERIC_16X5X_PLF_INIT_HOOK
+ CYGPRI_IO_SERIAL_GENERIC_16X5X_PLF_INIT_HOOK( ser_chan, new_config );
+#endif
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+pc_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
+
+#ifdef CYG_IO_SERIAL_GENERIC_16X5X_BAUD_GENERATOR
+ // Fill in baud rate table - used for platforms where this cannot
+ // be determined statically
+ int baud_idx, baud_val;
+ if (select_baud[0] == 9999) {
+ // Table not yet initialized
+ // Assumes that 'select_baud' looks like this:
+ // static int select_baud[] = {
+ // 9999, -- marker
+ // 50, -- first baud rate
+ // 110, -- second baud rate
+ // etc.
+ for (baud_idx = 1; baud_idx < sizeof(select_baud)/sizeof(select_baud[0]); baud_idx++) {
+ baud_val = CYG_IO_SERIAL_GENERIC_16X5X_BAUD_GENERATOR(select_baud[baud_idx]);
+ select_baud[baud_idx] = baud_val;
+ }
+ select_baud[0] = 0;
+ }
+#endif
+
+#ifdef CYGDBG_IO_INIT
+ diag_printf("16x5x SERIAL init - dev: %x.%d\n",
+ ser_chan->base, ser_chan->int_num);
+#endif
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ //
+ // If the device supports per channel interrupt priorities then
+ // we take the priority from the serial channel data. If it does
+ // not support per channel interrupt priority we fall back to
+ // the old method and use CYG_IO_SERIAL_GENERIC_16X5X_INT_PRIORITY
+ // to define the priority
+ //
+#ifdef CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO
+ cyg_priority_t intprio = ser_chan->int_prio;
+#else
+ cyg_priority_t intprio = CYG_IO_SERIAL_GENERIC_16X5X_INT_PRIORITY;
+#endif // CYGINT_IO_SERIAL_GENERIC_16X5X_CHAN_INTPRIO
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(ser_chan->int_num,
+ intprio,
+ (cyg_addrword_t)chan,
+ pc_serial_ISR,
+ pc_serial_DSR,
+ &ser_chan->serial_interrupt_handle,
+ &ser_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(ser_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(ser_chan->int_num);
+ }
+ serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+pc_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+pc_serial_putc(serial_channel *chan, unsigned char c)
+{
+#ifndef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
+ cyg_uint8 _lsr;
+#endif
+ pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
+ cyg_addrword_t base = ser_chan->base;
+
+#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
+ if (ser_chan->tx_fifo_avail > 0) {
+ HAL_WRITE_UINT8(base+REG_thr, c);
+ --ser_chan->tx_fifo_avail;
+ return true;
+ }
+#else
+ HAL_READ_UINT8(base+REG_lsr, _lsr);
+ if (_lsr & LSR_THE) {
+ // Transmit buffer is empty
+ HAL_WRITE_UINT8(base+REG_thr, c);
+ return true;
+ }
+#endif
+ // No space
+ return false;
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+pc_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ cyg_uint8 _lsr;
+ pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
+ cyg_addrword_t base = ser_chan->base;
+
+ // Wait for char
+ do {
+ HAL_READ_UINT8(base+REG_lsr, _lsr);
+ } while ((_lsr & LSR_RSR) == 0);
+
+ HAL_READ_UINT8(base+REG_rhr, c);
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+pc_serial_set_config(serial_channel *chan, cyg_uint32 key, const void *xbuf,
+ cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+ case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE:
+ {
+ cyg_uint8 _mcr;
+ pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
+ cyg_addrword_t base = ser_chan->base;
+ cyg_uint32 *f = (cyg_uint32 *)xbuf;
+ unsigned char mask=0;
+ if ( *len < sizeof(*f) )
+ return -EINVAL;
+
+ if ( chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX )
+ mask = MCR_RTS;
+ if ( chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_RX )
+ mask |= MCR_DTR;
+ HAL_READ_UINT8(base+REG_mcr, _mcr);
+ if (*f) // we should throttle
+ _mcr &= ~mask;
+ else // we should no longer throttle
+ _mcr |= mask;
+ HAL_WRITE_UINT8(base+REG_mcr, _mcr);
+ }
+ break;
+ case CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG:
+ // Nothing to do because we do support both RTSCTS and DSRDTR flow
+ // control.
+ // Other targets would clear any unsupported flags here and
+ // would then return -ENOSUPP - the higher layer can then query
+ // what flags are set and decide what to do. This is optimised for
+ // the most common case - i.e. that authors know what their hardware
+ // is capable of.
+ // We just return ENOERR.
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+pc_serial_start_xmit(serial_channel *chan)
+{
+ pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
+ cyg_addrword_t base = ser_chan->base;
+ cyg_uint8 _ier;
+
+ HAL_READ_UINT8(base+REG_ier, _ier);
+ _ier |= IER_XMT; // Enable xmit interrupt
+ HAL_WRITE_UINT8(base+REG_ier, _ier);
+#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_XMIT_REQUIRE_PRIME
+ (chan->callbacks->xmt_char)(chan);
+#endif
+}
+
+// Disable the transmitter on the device
+static void
+pc_serial_stop_xmit(serial_channel *chan)
+{
+ pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
+ cyg_addrword_t base = ser_chan->base;
+ cyg_uint8 _ier;
+
+ HAL_READ_UINT8(base+REG_ier, _ier);
+ _ier &= ~IER_XMT; // Disable xmit interrupt
+ HAL_WRITE_UINT8(base+REG_ier, _ier);
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+pc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(ser_chan->int_num);
+ cyg_drv_interrupt_acknowledge(ser_chan->int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+pc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
+ cyg_addrword_t base = ser_chan->base;
+ cyg_uint8 _isr;
+
+ // Check if we have an interrupt pending - note that the interrupt
+ // is pending of the low bit of the isr is *0*, not 1.
+ SER_16X5X_READ_ISR(base, _isr);
+ while ((_isr & ISR_nIP) == 0) {
+ switch (_isr&0xE) {
+ case ISR_Rx:
+ case ISR_RxTO:
+ {
+ cyg_uint8 _lsr;
+ unsigned char c;
+ HAL_READ_UINT8(base+REG_lsr, _lsr);
+ while(_lsr & LSR_RSR) {
+ HAL_READ_UINT8(base+REG_rhr, c);
+ (chan->callbacks->rcv_char)(chan, c);
+ HAL_READ_UINT8(base+REG_lsr, _lsr);
+ }
+ break;
+ }
+ case ISR_Tx:
+#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
+ ser_chan->tx_fifo_avail = ser_chan->tx_fifo_size;
+#endif
+ (chan->callbacks->xmt_char)(chan);
+ break;
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ case ISR_LS:
+ {
+ cyg_serial_line_status_t stat;
+ cyg_uint8 _lsr;
+ HAL_READ_UINT8(base+REG_lsr, _lsr);
+
+ // this might look expensive, but it is rarely the case that
+ // more than one of these is set
+ stat.value = 1;
+ if ( _lsr & LSR_OE ) {
+ stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;
+ (chan->callbacks->indicate_status)(chan, &stat );
+ }
+ if ( _lsr & LSR_PE ) {
+ stat.which = CYGNUM_SERIAL_STATUS_PARITYERR;
+ (chan->callbacks->indicate_status)(chan, &stat );
+ }
+ if ( _lsr & LSR_FE ) {
+ stat.which = CYGNUM_SERIAL_STATUS_FRAMEERR;
+ (chan->callbacks->indicate_status)(chan, &stat );
+ }
+ if ( _lsr & LSR_BI ) {
+ stat.which = CYGNUM_SERIAL_STATUS_BREAK;
+ (chan->callbacks->indicate_status)(chan, &stat );
+ }
+ }
+ break;
+
+ case ISR_MS:
+ {
+ cyg_serial_line_status_t stat;
+ cyg_uint8 _msr;
+
+ HAL_READ_UINT8(base+REG_msr, _msr);
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+ if ( _msr & MSR_DDSR )
+ if ( chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_TX ) {
+ stat.which = CYGNUM_SERIAL_STATUS_FLOW;
+ stat.value = (0 != (_msr & MSR_DSR));
+ (chan->callbacks->indicate_status)(chan, &stat );
+ }
+ if ( _msr & MSR_DCTS )
+ if ( chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX ) {
+ stat.which = CYGNUM_SERIAL_STATUS_FLOW;
+ stat.value = (0 != (_msr & MSR_CTS));
+ (chan->callbacks->indicate_status)(chan, &stat );
+ }
+#endif
+ if ( _msr & MSR_DDCD ) {
+ stat.which = CYGNUM_SERIAL_STATUS_CARRIERDETECT;
+ stat.value = (0 != (_msr & MSR_CD));
+ (chan->callbacks->indicate_status)(chan, &stat );
+ }
+ if ( _msr & MSR_RI ) {
+ stat.which = CYGNUM_SERIAL_STATUS_RINGINDICATOR;
+ stat.value = 1;
+ (chan->callbacks->indicate_status)(chan, &stat );
+ }
+ if ( _msr & MSR_TERI ) {
+ stat.which = CYGNUM_SERIAL_STATUS_RINGINDICATOR;
+ stat.value = 0;
+ (chan->callbacks->indicate_status)(chan, &stat );
+ }
+ }
+ break;
+#endif
+ default:
+ // Yes, this assertion may well not be visible. *But*
+ // if debugging, we may still successfully hit a breakpoint
+ // on cyg_assert_fail, which _is_ useful
+ CYG_FAIL("unhandled serial interrupt state");
+ }
+
+ HAL_READ_UINT8(base+REG_isr, _isr);
+ } // while
+
+ cyg_drv_interrupt_unmask(ser_chan->int_num);
+}
+#endif
+
+// EOF ser_16x5x.c
diff --git a/ecos/packages/devs/serial/h8300/h8300h/current/ChangeLog b/ecos/packages/devs/serial/h8300/h8300h/current/ChangeLog
new file mode 100644
index 0000000..f4f5762
--- /dev/null
+++ b/ecos/packages/devs/serial/h8300/h8300h/current/ChangeLog
@@ -0,0 +1,31 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/serial_h8300.cdl: Remove irrelevant doc link.
+
+2002-04-24 Yoshinori Sato <qzb04471@nifty.ne.jp>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/h8300/h8300h/current/cdl/serial_h8300.cdl b/ecos/packages/devs/serial/h8300/h8300h/current/cdl/serial_h8300.cdl
new file mode 100644
index 0000000..edda67d
--- /dev/null
+++ b/ecos/packages/devs/serial/h8300/h8300h/current/cdl/serial_h8300.cdl
@@ -0,0 +1,112 @@
+# ====================================================================
+#
+# serial_h8300.cdl
+#
+# eCos serial H8/300 SCI configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors:
+# Date: 1999-07-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_H8300_SCI {
+ display "H8/300 SCI serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_H8300
+
+ active_if CYGINT_IO_SERIAL_H8300_SCI_REQUIRED
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ SCI module in Hitachi H8/300 CPUs."
+
+ compile -library=libextras.a h8300_sci_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#ifndef CYGDAT_IO_SERIAL_DEVICE_HEADER"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_h8300_sci.h>"
+ puts $::cdl_system_header "#endif"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_IO_SERIAL_SH_SCI_CFG";
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_SH_SCI_OPTIONS {
+ display "SCI serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_IO_SERIAL_SH_SCI_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_SH_SCI_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+}
+
+# EOF serial_h8300.cdl
diff --git a/ecos/packages/devs/serial/h8300/h8300h/current/src/h8300_sci_serial.c b/ecos/packages/devs/serial/h8300/h8300h/current/src/h8300_sci_serial.c
new file mode 100644
index 0000000..0380f18
--- /dev/null
+++ b/ecos/packages/devs/serial/h8300/h8300h/current/src/h8300_sci_serial.c
@@ -0,0 +1,575 @@
+//==========================================================================
+//
+// h8300_sci_serial.c
+//
+// H8/300 Serial SCI I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:gthomas, jskov
+// Date: 1999-05-24
+// Purpose: H8/300 Serial I/O module (interrupt driven version)
+// Description:
+//
+// Note: Since interrupt sources from the same SCI channel share the same
+// interrupt level, there is no risk of races when altering the
+// channel's control register from ISRs and DSRs. However, when
+// altering the control register from user-level code, interrupts
+// must be disabled while the register is being accessed.
+//
+// FIXME: Receiving in polled mode prevents duplex transfers from working for
+// some reason.
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+// FIXME: This is necessary since the SCIF driver may be overriding
+// CYGDAT_IO_SERIAL_DEVICE_HEADER. Need a better way to include two
+// different drivers.
+#include <pkgconf/io_serial_h8300_sci.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+
+#ifdef CYGDAT_IO_SERIAL_H8300_SCI
+// The SCI controller register layout on the SH3/7708.
+#define SCI_SCSMR 0 // serial mode register
+#define SCI_SCBRR 1 // bit rate register
+#define SCI_SCSCR 2 // serial control register
+#define SCI_SCTDR 3 // transmit data register
+#define SCI_SCSSR 4 // serial status register
+#define SCI_SCRDR 5 // receive data register
+#define SCI_SCSPTR -4 // serial port register
+
+static short select_word_length[] = {
+ -1,
+ -1,
+ CYGARC_REG_SCSMR_CHR, // 7 bits
+ 0 // 8 bits
+};
+
+static short select_stop_bits[] = {
+ -1,
+ 0, // 1 stop bit
+ -1,
+ CYGARC_REG_SCSMR_STOP // 2 stop bits
+};
+
+static short select_parity[] = {
+ 0, // No parity
+ CYGARC_REG_SCSMR_PE, // Even parity
+ CYGARC_REG_SCSMR_PE|CYGARC_REG_SCSMR_OE, // Odd parity
+ -1,
+ -1
+};
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ CYGARC_SCBRR_CKSx(50)<<8 | CYGARC_SCBRR_N(50),
+ CYGARC_SCBRR_CKSx(75)<<8 | CYGARC_SCBRR_N(75),
+ CYGARC_SCBRR_CKSx(110)<<8 | CYGARC_SCBRR_N(110),
+ CYGARC_SCBRR_CKSx(134)<<8 | CYGARC_SCBRR_N(134),
+ CYGARC_SCBRR_CKSx(150)<<8 | CYGARC_SCBRR_N(150),
+ CYGARC_SCBRR_CKSx(200)<<8 | CYGARC_SCBRR_N(200),
+ CYGARC_SCBRR_CKSx(300)<<8 | CYGARC_SCBRR_N(300),
+ CYGARC_SCBRR_CKSx(600)<<8 | CYGARC_SCBRR_N(600),
+ CYGARC_SCBRR_CKSx(1200)<<8 | CYGARC_SCBRR_N(1200),
+ CYGARC_SCBRR_CKSx(1800)<<8 | CYGARC_SCBRR_N(1800),
+ CYGARC_SCBRR_CKSx(2400)<<8 | CYGARC_SCBRR_N(2400),
+ CYGARC_SCBRR_CKSx(3600)<<8 | CYGARC_SCBRR_N(3600),
+ CYGARC_SCBRR_CKSx(4800)<<8 | CYGARC_SCBRR_N(4800),
+ CYGARC_SCBRR_CKSx(7200)<<8 | CYGARC_SCBRR_N(7200),
+ CYGARC_SCBRR_CKSx(9600)<<8 | CYGARC_SCBRR_N(9600),
+ CYGARC_SCBRR_CKSx(14400)<<8 | CYGARC_SCBRR_N(14400),
+ CYGARC_SCBRR_CKSx(19200)<<8 | CYGARC_SCBRR_N(19200),
+ CYGARC_SCBRR_CKSx(38400)<<8 | CYGARC_SCBRR_N(38400),
+ CYGARC_SCBRR_CKSx(57600)<<8 | CYGARC_SCBRR_N(57600),
+ CYGARC_SCBRR_CKSx(115200)<<8 | CYGARC_SCBRR_N(115200),
+ CYGARC_SCBRR_CKSx(230400)<<8 | CYGARC_SCBRR_N(230400)
+};
+
+
+typedef struct h8300_sci_info {
+ CYG_ADDRWORD data; // Pointer to data register
+
+ CYG_WORD er_int_num, // Error interrupt number
+ rx_int_num, // Receive interrupt number
+ tx_int_num; // Transmit interrupt number
+
+ CYG_ADDRWORD ctrl_base; // Base address of SCI controller
+
+ cyg_interrupt serial_er_interrupt,
+ serial_rx_interrupt,
+ serial_tx_interrupt;
+ cyg_handle_t serial_er_interrupt_handle,
+ serial_rx_interrupt_handle,
+ serial_tx_interrupt_handle;
+
+ bool tx_enabled;
+} sh_sci_info;
+
+static bool h8300_serial_init(struct cyg_devtab_entry *tab);
+static bool h8300_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo h8300_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char h8300_serial_getc(serial_channel *chan);
+static Cyg_ErrNo h8300_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void h8300_serial_start_xmit(serial_channel *chan);
+static void h8300_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 h8300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void h8300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+static cyg_uint32 h8300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void h8300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+static cyg_uint32 h8300_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void h8300_serial_er_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+
+static SERIAL_FUNS(h8300_serial_funs,
+ h8300_serial_putc,
+ h8300_serial_getc,
+ h8300_serial_set_config,
+ h8300_serial_start_xmit,
+ h8300_serial_stop_xmit
+ );
+
+
+static h8300_sci_info h8300_serial_info =
+{
+ NULL,
+ CYGNUM_HAL_INTERRUPT_ERI0,
+ CYGNUM_HAL_INTERRUPT_RXI0,
+ CYGNUM_HAL_INTERRUPT_TXI0,
+ CYGARC_REG_SMR0
+};
+
+#if CYGNUM_IO_SERIAL_H8300_H8300H_SERIAL1_BUFSIZE > 0
+static unsigned char h8300_serial_out_buf[CYGNUM_IO_SERIAL_H8300_CQ7708_SERIAL1_BUFSIZE];
+static unsigned char h8300_serial_in_buf[CYGNUM_IO_SERIAL_H8300_CQ7708_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(h8300_serial_channel,
+ h8300_serial_funs,
+ h8300_serial_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_H8300_H8300H_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &h8300_serial_out_buf[0],
+ sizeof(h8300_serial_out_buf),
+ &h8300_serial_in_buf[0],
+ sizeof(h8300_serial_in_buf)
+ );
+#else
+static SERIAL_CHANNEL(h8300_serial_channel,
+ h8300_serial_funs,
+ h8300_serial_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_H8300_H8300H_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(h8300_serial_io,
+ CYGDAT_IO_SERIAL_H8300_H8300H_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ h8300_serial_init,
+ h8300_serial_lookup, // Serial driver may need initializing
+ &h8300_serial_channel
+ );
+
+// Internal function to actually configure the hardware to desired baud rate,
+// etc.
+static bool
+h8300_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config,
+ bool init)
+{
+ cyg_uint16 baud_divisor = select_baud[new_config->baud];
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+ cyg_uint8 _scr, _smr;
+
+ // Check configuration request
+ if ((-1 == select_word_length[(new_config->word_length -
+ CYGNUM_SERIAL_WORD_LENGTH_5)])
+ || -1 == select_stop_bits[new_config->stop]
+ || -1 == select_parity[new_config->parity]
+ || baud_divisor == 0)
+ return false;
+
+ // Disable SCI interrupts while changing hardware
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, 0);
+
+ // Set databits, stopbits and parity.
+ _smr = select_word_length[(new_config->word_length -
+ CYGNUM_SERIAL_WORD_LENGTH_5)] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSMR, _smr);
+
+ // Set baud rate.
+ _smr &= ~CYGARC_REG_SCSMR_CKSx_MASK;
+ _smr |= baud_divisor >> 8;
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSMR, _smr);
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCBRR, baud_divisor & 0xff);
+
+ // Clear the status register.
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSSR, 0);
+
+ if (init) {
+ // Always enable transmitter and receiver.
+ _scr = CYGARC_REG_SCSCR_TE | CYGARC_REG_SCSCR_RE;
+
+ if (chan->out_cbuf.len != 0)
+ _scr |= CYGARC_REG_SCSCR_TIE; // enable tx interrupts
+
+ if (chan->in_cbuf.len != 0)
+ _scr |= CYGARC_REG_SCSCR_RIE; // enable rx interrupts
+ }
+
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+h8300_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("SH SERIAL init - dev: %x.%d\n",
+ h8300_chan->data, h8300_chan->rx_int_num);
+#endif
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(h8300_chan->tx_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ h8300_serial_tx_ISR,
+ h8300_serial_tx_DSR,
+ &h8300_chan->serial_tx_interrupt_handle,
+ &h8300_chan->serial_tx_interrupt);
+ cyg_drv_interrupt_attach(h8300_chan->serial_tx_interrupt_handle);
+ cyg_drv_interrupt_unmask(h8300_chan->tx_int_num);
+ h8300_chan->tx_enabled = false;
+ }
+ if (chan->in_cbuf.len != 0) {
+ // Receive interrupt
+ cyg_drv_interrupt_create(h8300_chan->rx_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ h8300_serial_rx_ISR,
+ h8300_serial_rx_DSR,
+ &h8300_chan->serial_rx_interrupt_handle,
+ &h8300_chan->serial_rx_interrupt);
+ cyg_drv_interrupt_attach(h8300_chan->serial_rx_interrupt_handle);
+ // Receive error interrupt
+ cyg_drv_interrupt_create(h8300_chan->er_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ h8300_serial_er_ISR,
+ h8300_serial_er_DSR,
+ &h8300_chan->serial_er_interrupt_handle,
+ &h8300_chan->serial_er_interrupt);
+ cyg_drv_interrupt_attach(h8300_chan->serial_er_interrupt_handle);
+ // This unmasks both interrupt sources.
+ cyg_drv_interrupt_unmask(h8300_chan->rx_int_num);
+ }
+ h8300_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+h8300_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+h8300_serial_putc(serial_channel *chan, unsigned char c)
+{
+ cyg_uint8 _ssr;
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSSR, _ssr);
+ if (_ssr & CYGARC_REG_SCSSR_TDRE) {
+// Transmit buffer is empty
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCTDR, c);
+ // Clear empty flag.
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSSR,
+ CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_TDRE);
+ return true;
+ } else {
+// No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+h8300_serial_getc(serial_channel *chan)
+{
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+ unsigned char c;
+ cyg_uint8 _ssr;
+
+ do {
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSSR, _ssr);
+ } while ((_ssr & CYGARC_REG_SCSSR_RDRF) == 0);
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCRDR, c);
+
+ // Clear buffer full flag.
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSSR,
+ CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF);
+
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+h8300_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != h8300_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+h8300_serial_start_xmit(serial_channel *chan)
+{
+ cyg_uint8 _scr;
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+
+ h8300_chan->tx_enabled = true;
+
+ // Mask the interrupts (all sources of the unit) while changing
+ // the CR since a rx interrupt in the middle of this would result
+ // in a bad CR state.
+ cyg_drv_interrupt_mask(h8300_chan->rx_int_num);
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCSCR_TIE; // Enable xmit interrupt
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+
+ cyg_drv_interrupt_unmask(h8300_chan->rx_int_num);
+}
+
+// Disable the transmitter on the device
+static void
+h8300_serial_stop_xmit(serial_channel *chan)
+{
+ cyg_uint8 _scr;
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+
+ h8300_chan->tx_enabled = false;
+
+ // Mask the interrupts (all sources of the unit) while changing
+ // the CR since a rx interrupt in the middle of this would result
+ // in a bad CR state.
+ cyg_drv_interrupt_mask(h8300_chan->rx_int_num);
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCSCR_TIE; // Disable xmit interrupt
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+
+ cyg_drv_interrupt_unmask(h8300_chan->rx_int_num);
+}
+
+// Serial I/O - low level tx interrupt handler (ISR)
+static cyg_uint32
+h8300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+ cyg_uint8 _scr;
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCSCR_TIE; // mask out tx interrupts
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level tx interrupt handler (DSR)
+static void
+h8300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+
+ (chan->callbacks->xmt_char)(chan);
+
+ if (h8300_chan->tx_enabled) {
+ cyg_uint8 _scr;
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCSCR_TIE; // unmask tx interrupts
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ }
+}
+
+// Serial I/O - low level RX interrupt handler (ISR)
+static cyg_uint32
+h8300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+ cyg_uint8 _scr;
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCSCR_RIE; // mask rx interrupts
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level rx interrupt handler (DSR)
+static void
+h8300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+ cyg_uint8 _ssr, _scr;
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSSR, _ssr);
+ if (_ssr & CYGARC_REG_SCSSR_RDRF) {
+ cyg_uint8 _c;
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCRDR, _c);
+ // Clear buffer full flag.
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSSR,
+ CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF);
+
+ (chan->callbacks->rcv_char)(chan, _c);
+ }
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCSCR_RIE; // unmask rx interrupts
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+}
+
+static volatile int h8300_serial_error_orer = 0;
+static volatile int h8300_serial_error_fer = 0;
+static volatile int h8300_serial_error_per = 0;
+
+// Serial I/O - low level error interrupt handler (ISR)
+static cyg_uint32
+h8300_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+ cyg_uint8 _scr;
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCSCR_RIE; // mask rx interrupts
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level error interrupt handler (DSR)
+static void
+h8300_serial_er_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ h8300_sci_info *h8300_chan = (h8300_sci_info *)chan->dev_priv;
+ cyg_uint8 _ssr, _ssr2, _scr;
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSSR, _ssr);
+ _ssr2 = CYGARC_REG_SCSSR_CLEARMASK;
+
+ if (_ssr & CYGARC_REG_SCSSR_ORER) {
+ _ssr2 &= ~CYGARC_REG_SCSSR_ORER;
+ h8300_serial_error_orer++;
+ }
+ if (_ssr & CYGARC_REG_SCSSR_FER) {
+ _ssr2 &= ~CYGARC_REG_SCSSR_FER;
+ h8300_serial_error_fer++;
+ }
+ if (_ssr & CYGARC_REG_SCSSR_PER) {
+ _ssr2 &= ~CYGARC_REG_SCSSR_PER;
+ h8300_serial_error_per++;
+ }
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSSR, _ssr2);
+
+ HAL_READ_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCSCR_RIE; // unmask rx interrupts
+ HAL_WRITE_UINT8(h8300_chan->ctrl_base+SCI_SCSCR, _scr);
+}
+
+#endif // ifdef CYGDAT_IO_SERIAL_H8300_SCI
diff --git a/ecos/packages/devs/serial/i386/pc/current/ChangeLog b/ecos/packages/devs/serial/i386/pc/current/ChangeLog
new file mode 100644
index 0000000..e42ba5d
--- /dev/null
+++ b/ecos/packages/devs/serial/i386/pc/current/ChangeLog
@@ -0,0 +1,1196 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_i386_pc.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_i386_pc.cdl:
+ Fix 234000->230400 typo.
+
+2001-06-08 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/i386_pc_ser.inl: Use generic 16x5x driver now.
+
+ * cdl/ser_i386_pc.cdl: Define necessary options to use generic
+ 16x5x driver.
+ Fix IRQ->INT in CDL display strings.
+
+ * src/pc_serial.c: Removed in favour of generic driver.
+ * src/pc_serial.h: Ditto.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_i386_pc.cdl: Moved testing parameters here.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/pc_serial.c (pc_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_i386_pc.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/i386/pc/current/cdl/ser_i386_pc.cdl b/ecos/packages/devs/serial/i386/pc/current/cdl/ser_i386_pc.cdl
new file mode 100644
index 0000000..94e0e3d
--- /dev/null
+++ b/ecos/packages/devs/serial/i386/pc/current/cdl/ser_i386_pc.cdl
@@ -0,0 +1,268 @@
+# ====================================================================
+#
+# ser_i386_pc.cdl
+#
+# eCos serial PC configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jlarmour, nickg, gthomas, pjo
+# Original data:
+# Contributors: jskov
+# Date: 2001-06-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_I386_PC {
+ display "PC serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_I386_PCMB
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ description "
+ This option enables the serial device drivers for the
+ PC."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/i386_pc_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_i386_pc.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_I386_PC_SERIAL0 {
+ display "PC serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for port 0 on the
+ PC."
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ cdl_option CYGDAT_IO_SERIAL_I386_PC_SERIAL0_NAME {
+ display "Device name for PC serial port 0"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the device name port 0 on the PC."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BAUD {
+ display "Baud rate for the PC serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PC port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE {
+ display "Buffer size for the PC serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the PC port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IOBASE {
+ display "I/O base address for the i386-PC serial port 0"
+ flavor data
+ legal_values 0 to 0xFF8
+ default_value 0x3F8
+ description "
+ This option specifies the I/O address of the 8250 or 16550 for serial port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IRQ {
+ display "IRQ for the i386-PC serial port 0"
+ flavor data
+ legal_values 0 to 15
+ default_value 4
+ description "
+ This option specifies the IRQ of the 8250 or 16550 for serial port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_INT {
+ display "INT for the i386-PC serial port 0"
+ flavor data
+ legal_values 32 to 47
+ default_value { CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IRQ + 32 }
+ description "
+ This option specifies the interrupt vector of the 8250 or 16550 for serial port 0."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_I386_PC_SERIAL1 {
+ display "PC serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for port 1 on
+ the PC."
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ cdl_option CYGDAT_IO_SERIAL_I386_PC_SERIAL1_NAME {
+ display "Device name for PC serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name port 1 on the PC."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BAUD {
+ display "Baud rate for the PC serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE {
+ display "Buffer size for the PC serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the PC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IOBASE {
+ display "I/O base address for the i386-PC serial port 1"
+ flavor data
+ legal_values 0 to 0xFF8
+ default_value 0x2F8
+ description "
+ This option specifies the I/O address of the 8250 or 16550 for serial port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IRQ {
+ display "IRQ for the i386-PC serial port 1"
+ flavor data
+ legal_values 0 to 15
+ default_value 3
+ description "
+ This option specifies the IRQ of the 8250 or 16550 for serial port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_INT {
+ display "INT for the i386-PC serial port 1"
+ flavor data
+ legal_values 32 to 47
+ default_value { CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IRQ + 32 }
+ description "
+ This option specifies the interrupt vector of the 8250 or 16550 for serial port 1."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_I386_PC_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_I386_PC_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_I386_PC_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_I386_PC_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_I386_PC_SERIAL0
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_I386_PC_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"i386pc\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_i386_pc.cdl
diff --git a/ecos/packages/devs/serial/i386/pc/current/include/i386_pc_ser.inl b/ecos/packages/devs/serial/i386/pc/current/include/i386_pc_ser.inl
new file mode 100644
index 0000000..8219cb4
--- /dev/null
+++ b/ecos/packages/devs/serial/i386/pc/current/include/i386_pc_ser.inl
@@ -0,0 +1,163 @@
+//==========================================================================
+//
+// io/serial/i386/pc/i386_pc_ser.inl
+//
+// i386 PC Serial I/O Interface Module (interrupt driven)
+// for use with 8250s or 16550s.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2001-06-08
+// Purpose: PC Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification, based on raw 24MHz clock
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 2304, // 50
+ 1536, // 75
+ 1047, // 110
+ 857, // 134.5
+ 768, // 150
+ 576, // 200
+ 384, // 300
+ 192, // 600
+ 96, // 1200
+ 64, // 1800
+ 48, // 2400
+ 32, // 3600
+ 24, // 4800
+ 16, // 7200
+ 12, // 9600
+ 8, // 14400
+ 6, // 19200
+ 3, // 38400
+ 2, // 57600
+ 1, // 115200
+ 0, // 230400
+};
+
+#ifdef CYGPKG_IO_SERIAL_I386_PC_SERIAL0
+static pc_serial_info pc_serial_info0 = {CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IOBASE,
+ CYGNUM_IO_SERIAL_I386_PC_SERIAL0_INT};
+#if CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE > 0
+static unsigned char pc_serial_out_buf0[CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE];
+static unsigned char pc_serial_in_buf0[CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(pc_serial_channel0,
+ pc_serial_funs,
+ pc_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &pc_serial_out_buf0[0], sizeof(pc_serial_out_buf0),
+ &pc_serial_in_buf0[0], sizeof(pc_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(pc_serial_channel0,
+ pc_serial_funs,
+ pc_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(pc_serial_io0,
+ CYGDAT_IO_SERIAL_I386_PC_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &pc_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_I386_PC_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_I386_PC_SERIAL1
+static pc_serial_info pc_serial_info1 = {CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IOBASE,
+ CYGNUM_IO_SERIAL_I386_PC_SERIAL1_INT};
+#if CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE > 0
+static unsigned char pc_serial_out_buf1[CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE];
+static unsigned char pc_serial_in_buf1[CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(pc_serial_channel1,
+ pc_serial_funs,
+ pc_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &pc_serial_out_buf1[0], sizeof(pc_serial_out_buf1),
+ &pc_serial_in_buf1[0], sizeof(pc_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(pc_serial_channel1,
+ pc_serial_funs,
+ pc_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(pc_serial_io1,
+ CYGDAT_IO_SERIAL_I386_PC_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &pc_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_I386_PC_SERIAL1
+
+// EOF i386_pc_ser.inl
diff --git a/ecos/packages/devs/serial/loop/current/ChangeLog b/ecos/packages/devs/serial/loop/current/ChangeLog
new file mode 100644
index 0000000..c049490
--- /dev/null
+++ b/ecos/packages/devs/serial/loop/current/ChangeLog
@@ -0,0 +1,53 @@
+2009-10-09 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/ser_loop.cdl: Remove irrelevant testing parameters which
+ prevent the loading of this package in the presence of other serial
+ device drivers.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_loop.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_loop.cdl:
+ Fix 234000->230400 typo.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_loop.cdl: Moved testing parameters here.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/loop_serial.c (loop_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-15 Nick Garnett <nickg@cygnus.co.uk>
+
+ * cdl/ser_loop.cdl:
+ * src/loop/loop_serial.c:
+ Added loopback serial driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/loop/current/cdl/ser_loop.cdl b/ecos/packages/devs/serial/loop/current/cdl/ser_loop.cdl
new file mode 100644
index 0000000..4bed65b
--- /dev/null
+++ b/ecos/packages/devs/serial/loop/current/cdl/ser_loop.cdl
@@ -0,0 +1,188 @@
+# ====================================================================
+#
+# ser_loop.cdl
+#
+# eCos serial LOOP configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_LOOP {
+ display "Loop serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+
+ description "
+ This package contains the loop serial device driver."
+
+ compile -library=libextras.a loop_serial.c
+
+ # FIXME: Bad name
+ cdl_option CYGPKG_IO_SERIAL_LOOP_POLLED_MODE {
+ display "LOOP polled mode serial drivers"
+ flavor bool
+ default_value 0
+ description "
+ If asserted, this option specifies that the serial loop device
+ drivers for the should be polled-mode instead of
+ interrupt driven."
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_LOOP_SERIAL0 {
+ display "LOOP serial port 0 driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial loop device driver for port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_LOOP_SERIAL0_NAME {
+ display "Device name for LOOP serial port 0"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the first loop device name."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_LOOP_SERIAL0_BAUD {
+ display "Baud rate for the LOOP serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800
+ 2400 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ LOOP port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_LOOP_SERIAL0_BUFSIZE {
+ display "Buffer size for the LOOP serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the LOOP port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_LOOP_SERIAL1 {
+ display "LOOP serial port 1 driver"
+ flavor bool
+ default_value 0
+ description "
+ This option includes the serial device driver for port 1 on
+ the LOOP."
+
+ cdl_option CYGDAT_IO_SERIAL_LOOP_SERIAL1_NAME {
+ display "Device name for LOOP serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name port 1 on the LOOP."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_LOOP_SERIAL1_BAUD {
+ display "Baud rate for the LOOP serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800
+ 2400 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ LOOP port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_LOOP_SERIAL1_BUFSIZE {
+ display "Buffer size for the LOOP serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the LOOP port 1."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_LOOP_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_LOOP_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags
+ are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_LOOP_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_loop.cdl
diff --git a/ecos/packages/devs/serial/loop/current/src/loop_serial.c b/ecos/packages/devs/serial/loop/current/src/loop_serial.c
new file mode 100644
index 0000000..be5ea46
--- /dev/null
+++ b/ecos/packages/devs/serial/loop/current/src/loop_serial.c
@@ -0,0 +1,456 @@
+//==========================================================================
+//
+// loop_serial.c
+//
+// Loopback serial device driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1999-02-25
+// Purpose: Loopback serial device driver
+// Description: This device driver implements a pair of serial lines that are
+// connected back-to-back. Data output to one will appear as
+// input on the other. This process in in part driven by an alarm
+// object which provides a degree of separation between the two
+// channels.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io_serial_loop.h>
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/kernel/kapi.h>
+
+#ifdef CYGPKG_IO_SERIAL_LOOP
+
+//-------------------------------------------------------------------------
+
+extern void diag_printf(const char *fmt, ...);
+
+//-------------------------------------------------------------------------
+// Forward definitions
+
+static bool loop_serial_init(struct cyg_devtab_entry *tab);
+static bool loop_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo loop_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char loop_serial_getc(serial_channel *chan);
+static Cyg_ErrNo loop_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void loop_serial_start_xmit(serial_channel *chan);
+static void loop_serial_stop_xmit(serial_channel *chan);
+
+#ifndef CYGPKG_IO_SERIAL_LOOP_POLLED_MODE
+static void alarm_handler(cyg_handle_t alarm, cyg_addrword_t data);
+#endif
+
+//-------------------------------------------------------------------------
+// Alarm object for feeding data back into serial channels
+
+static cyg_alarm alarm_obj;
+
+static cyg_handle_t alarm_handle;
+
+//-------------------------------------------------------------------------
+// Transfer FIFOs
+
+#define FIFO_SIZE 16
+
+struct fifo
+{
+ cyg_bool tx_enable;
+ volatile int head;
+ volatile int tail;
+ volatile int num;
+ volatile char buf[FIFO_SIZE+1];
+};
+
+static struct fifo fifo0 = { false, 0, 0, 0 }; // from serial0 to serial1
+static struct fifo fifo1 = { false, 0, 0, 0 }; // from serial1 to serial0
+
+//-------------------------------------------------------------------------
+
+#define BUFSIZE 128
+
+//-------------------------------------------------------------------------
+// Info for each serial device controlled
+
+typedef struct loop_serial_info {
+ struct fifo *write_fifo;
+ struct fifo *read_fifo;
+} loop_serial_info;
+
+//-------------------------------------------------------------------------
+// Callback functions exported by this driver
+
+static SERIAL_FUNS(loop_serial_funs,
+ loop_serial_putc,
+ loop_serial_getc,
+ loop_serial_set_config,
+ loop_serial_start_xmit,
+ loop_serial_stop_xmit
+ );
+
+//-------------------------------------------------------------------------
+// Hardware info for each serial line
+
+#ifdef CYGPKG_IO_SERIAL_LOOP_SERIAL0
+static loop_serial_info loop_serial_info0 = {
+ &fifo0,
+ &fifo1
+};
+#if CYGNUM_IO_SERIAL_LOOP_SERIAL0_BUFSIZE > 0
+static unsigned char loop_serial_out_buf0[CYGNUM_IO_SERIAL_LOOP_SERIAL0_BUFSIZE];
+static unsigned char loop_serial_in_buf0[CYGNUM_IO_SERIAL_LOOP_SERIAL0_BUFSIZE];
+#endif
+#endif // CYGPKG_IO_SERIAL_LOOP_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_LOOP_SERIAL1
+static loop_serial_info loop_serial_info1 = {
+ &fifo1,
+ &fifo0
+};
+#if CYGNUM_IO_SERIAL_LOOP_SERIAL1_BUFSIZE > 0
+static unsigned char loop_serial_out_buf1[CYGNUM_IO_SERIAL_LOOP_SERIAL1_BUFSIZE];
+static unsigned char loop_serial_in_buf1[CYGNUM_IO_SERIAL_LOOP_SERIAL1_BUFSIZE];
+#endif
+#endif // CYGPKG_IO_SERIAL_LOOP_SERIAL1
+
+//-------------------------------------------------------------------------
+// Channel descriptions:
+
+#ifdef CYGPKG_IO_SERIAL_LOOP_POLLED_MODE
+#define SIZEOF_BUF(_x_) 0
+#else
+#define SIZEOF_BUF(_x_) sizeof(_x_)
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_LOOP_SERIAL0
+#if CYGNUM_IO_SERIAL_LOOP_SERIAL0_BUFSIZE > 0
+static SERIAL_CHANNEL_USING_INTERRUPTS(loop_serial_channel0,
+ loop_serial_funs,
+ loop_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_LOOP_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &loop_serial_out_buf0[0],
+ SIZEOF_BUF(loop_serial_out_buf0),
+ &loop_serial_in_buf0[0],
+ SIZEOF_BUF(loop_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(loop_serial_channel0,
+ loop_serial_funs,
+ loop_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_LOOP_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+#endif // CYGPKG_IO_SERIAL_LOOP_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_LOOP_SERIAL1
+#if CYGNUM_IO_SERIAL_LOOP_SERIAL1_BUFSIZE > 0
+static SERIAL_CHANNEL_USING_INTERRUPTS(loop_serial_channel1,
+ loop_serial_funs,
+ loop_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_LOOP_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &loop_serial_out_buf1[0],
+ SIZEOF_BUF(loop_serial_out_buf1),
+ &loop_serial_in_buf1[0],
+ SIZEOF_BUF(loop_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(loop_serial_channel1,
+ loop_serial_funs,
+ loop_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_LOOP_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+#endif // CYGPKG_IO_SERIAL_LOOP_SERIAL1
+
+//-------------------------------------------------------------------------
+// And finally, the device table entries:
+
+#ifdef CYGPKG_IO_SERIAL_LOOP_SERIAL0
+DEVTAB_ENTRY(loop_serial_io0,
+ CYGDAT_IO_SERIAL_LOOP_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ loop_serial_init,
+ loop_serial_lookup, // Serial driver may need initializing
+ &loop_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_LOOP_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_LOOP_SERIAL1
+DEVTAB_ENTRY(loop_serial_io1,
+ CYGDAT_IO_SERIAL_LOOP_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ loop_serial_init,
+ loop_serial_lookup, // Serial driver may need initializing
+ &loop_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_LOOP_SERIAL1
+
+//-------------------------------------------------------------------------
+
+static bool
+loop_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+// loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+//-------------------------------------------------------------------------
+// Function to initialize the device. Called at bootstrap time.
+
+bool loop_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+// loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;
+
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+
+#ifndef CYGPKG_IO_SERIAL_LOOP_POLLED_MODE
+
+ // Set up alarm for feeding data back into channels
+
+ cyg_alarm_create( cyg_real_time_clock(),
+ alarm_handler,
+ 0,
+ &alarm_handle,
+ &alarm_obj);
+
+ cyg_alarm_initialize( alarm_handle, 1, 1 );
+
+#endif
+
+ loop_serial_config_port(chan, &chan->config, true);
+
+ return true;
+}
+
+//-------------------------------------------------------------------------
+// This routine is called when the device is "looked" up (i.e. attached)
+
+static Cyg_ErrNo
+loop_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+//-------------------------------------------------------------------------
+// Return 'true' if character is sent to device
+
+bool
+loop_serial_putc(serial_channel *chan, unsigned char c)
+{
+ loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;
+
+ struct fifo *f = loop_chan->write_fifo;
+
+ if( f->num == FIFO_SIZE )
+ return false;
+
+ f->buf[f->tail] = c;
+ f->num++;
+ f->tail++;
+ if( f->tail == sizeof(f->buf) )
+ f->tail = 0;
+
+ return true;
+}
+
+//-------------------------------------------------------------------------
+
+unsigned char
+loop_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;
+
+ struct fifo *f = loop_chan->read_fifo;
+
+ while( f->num == 0 )
+ continue;
+
+ c = f->buf[f->head];
+ f->num--;
+ f->head++;
+ if( f->head == sizeof(f->buf) )
+ f->head = 0;
+
+ return c;
+}
+
+//-------------------------------------------------------------------------
+
+static Cyg_ErrNo
+loop_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != loop_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+//-------------------------------------------------------------------------
+// Enable the transmitter on the device
+
+static void
+loop_serial_start_xmit(serial_channel *chan)
+{
+#ifndef CYGPKG_IO_SERIAL_LOOP_POLLED_MODE
+ loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;
+
+ loop_chan->write_fifo->tx_enable = true;
+
+ (chan->callbacks->xmt_char)(chan);
+#endif
+}
+
+//-------------------------------------------------------------------------
+// Disable the transmitter on the device
+
+static void
+loop_serial_stop_xmit(serial_channel *chan)
+{
+#ifndef CYGPKG_IO_SERIAL_LOOP_POLLED_MODE
+ loop_serial_info *loop_chan = (loop_serial_info *)chan->dev_priv;
+
+ loop_chan->write_fifo->tx_enable = false;
+
+#endif
+}
+
+//-------------------------------------------------------------------------
+
+static void alarm_handler(cyg_handle_t alarm, cyg_addrword_t data)
+{
+ serial_channel *chan0 = &loop_serial_channel0;
+ serial_channel *chan1 = &loop_serial_channel1;
+
+ while( fifo0.num )
+ {
+ // Data ready for delivery to serial1
+
+ struct fifo *f = &fifo0;
+ char c;
+
+ c = f->buf[f->head];
+ f->num--;
+ f->head++;
+ if( f->head == sizeof(f->buf) )
+ f->head = 0;
+
+ (chan1->callbacks->rcv_char)(chan1, c);
+ if( f->tx_enable )
+ (chan0->callbacks->xmt_char)(chan0);
+ }
+
+ while( fifo1.num )
+ {
+ // Data ready for delivery to serial0
+
+ struct fifo *f = &fifo1;
+ char c;
+
+ c = f->buf[f->head];
+ f->num--;
+ f->head++;
+ if( f->head == sizeof(f->buf) )
+ f->head = 0;
+
+ (chan0->callbacks->rcv_char)(chan0, c);
+ if( f->tx_enable )
+ (chan1->callbacks->xmt_char)(chan1);
+ }
+
+
+
+}
+
+
+#endif // CYGPKG_IO_SERIAL_LOOP
+
+//-------------------------------------------------------------------------
+// EOF loop.c
diff --git a/ecos/packages/devs/serial/m68k/mcf52xx/current/ChangeLog b/ecos/packages/devs/serial/m68k/mcf52xx/current/ChangeLog
new file mode 100644
index 0000000..dea863b
--- /dev/null
+++ b/ecos/packages/devs/serial/m68k/mcf52xx/current/ChangeLog
@@ -0,0 +1,115 @@
+2008-11-17 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/ser_mcf52xx.cdl, doc/mcf52xx_ser.sgml, src/ser_mcf52xx.c:
+ minor clean-ups.
+
+2008-05-26 Bart Veer <bartv@ecoscentric.com>
+
+ * src/ser_mcf52xx.c: provide more flow control capability
+ information to higher levels.
+
+2006-09-25 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/mcf52xx_ser.sgml: update docs to reflect changes in the
+ hal/m68k hierarchy.
+
+ * src/ser_mcf52xx.c: Motorola -> Freescale.
+
+2006-09-08 Bart Veer <bartv@ecoscentric.com>
+
+ * src/ser_mcf52xx.c: update to use new var_io.h definitions.
+
+2006-09-05 Bart Veer <bartv@ecoscentric.com>
+
+ * src/ser_mcf52xx.c, cdl/ser_mcf52xx.cdl:
+ Trigger off options/components in the processor HAL rather than
+ on interfaces in the device driver. The latter were essentially
+ duplicates of the former so no longer served a purpose.
+
+2006-07-10 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/ser_mcf52xx.cdl, src/ser_mcf52xx.c: separate out RTS/CTS
+ handling. Cope with various changes in the mcf52xx variant HAL for
+ better support of the ColdFire range of processors.
+
+2006-03-10 John Dallaway <jld@ecoscentric.com>
+
+ * cdl/ser_mcf52xx.cdl: Add reference to package documentation.
+
+2004-08-03 John Dallaway <jld@ecoscentric.com>
+
+ * cdl/ser_mcf52xx.cdl: Use any port for serial testing.
+
+2004-08-02 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/ser_mcf52xx.cdl, src/ser_mcf52xx.c, doc/mcf52xx_ser.sgml:
+ Make it easier for platform HALs to control what functionality is
+ enabled, e.g. whether or not RTS/CTS are connected.
+
+2004-03-17 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/mcf52xx_ser.sgml: update following port to mcf5282
+
+2004-03-08 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/ser_mcf52xx.cdl: look for default ISR priorities supplied by
+ the HAL.
+
+2004-02-11 Bart Veer <bartv@ecoscentric.com>
+
+ * src/ser_mcf52xx.c, cdl/ser_mcf52xx.cdl: add support for an
+ optional third UART.
+
+2003-08-01 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/mcf52xx_ser.sgml: Document use of rx fifo
+
+ * src/ser_mcf52xx.c:
+ Use rx fifo where available. Add some statistics gathering.
+
+2003-07-22 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/mcf52xx_ser.sgml: fix various typos etc.
+
+2003-07-18 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/mcf52xx_ser.sgml: Add documentation.
+
+2003-07-10 Bart Veer <bartv@ecoscentric.com>
+
+ * src/ser_mcf52xx.c (mcf52xx_serial_set_config):
+ Reject DSR/DTR flow control more gracefully.
+
+2003-07-08 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/ser_mcf52xx.cdl, src/ser_mcf52xx.c:
+ Add support for hardware handshaking.
+ Make better use of the fifos to reduce interrupts.
+
+2003-06-04 Bart Veer <bartv@ecoscentric.com>
+
+ * New version of the M68K support
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004, 2006, 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/m68k/mcf52xx/current/cdl/ser_mcf52xx.cdl b/ecos/packages/devs/serial/m68k/mcf52xx/current/cdl/ser_mcf52xx.cdl
new file mode 100644
index 0000000..e6db120
--- /dev/null
+++ b/ecos/packages/devs/serial/m68k/mcf52xx/current/cdl/ser_mcf52xx.cdl
@@ -0,0 +1,186 @@
+# ====================================================================
+#
+# ser_mcfxxxx.cdl
+#
+# Serial driver for mcfxxxx coldfire processors
+#
+# ====================================================================
+# ####ECOSGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2003, 2004, 2006, 2008 Free Software Foundation, Inc.
+#
+# eCos is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 or (at your option) any later
+# version.
+#
+# eCos is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with eCos; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered by
+# the GNU General Public License. However the source code for this file
+# must still be made available in accordance with section (3) of the GNU
+# General Public License v2.
+#
+# This exception does not invalidate any other reasons why a work based
+# on this file might be covered by the GNU General Public License.
+# -------------------------------------------
+# ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Contributors:
+# Date: 2003-06-4
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_SERIAL_MCFxxxx {
+ display "Serial driver for the coldfire mcfxxxx family"
+ doc ref/devs-ser-m68k-mcfxxxx-part.html
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_M68K_MCFxxxx
+
+ requires CYGPKG_ERROR
+
+ description "
+ This package provides a serial device driver for the on-chip
+ UART's in MCFxxxx ColdFire processors."
+ compile -library=libextras.a ser_mcf52xx.c
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/devs_serial_mcfxxxx.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ # Support up to three on-chip UART's. The number varies between
+ # processor variants, and on some platforms some of the UART's
+ # may not be connected to save board space or to obtain more
+ # GPIO lines. Also h/w handshake lines may or may not be connected.
+ for { set ::uart 0 } { $::uart < 3 } { incr ::uart } {
+
+ cdl_component CYGPKG_DEVS_SERIAL_MCFxxxx_SERIAL[set ::uart] {
+ display "Allow access to the on-chip uart[set ::uart] via a serial driver"
+ flavor bool
+ active_if CYGHWR_HAL_M68K_MCFxxxx_UART[set ::uart]
+ default_value 1
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ If the application needs to access the on-chip uart[set ::uart]
+ via an eCos serial driver then this option should be enabled."
+
+ cdl_option CYGDAT_DEVS_SERIAL_MCFxxxx_SERIAL[set ::uart]_NAME {
+ display "Device name for uart [set ::uart]"
+ flavor data
+ default_value [format {"\"/dev/ser%d\""} $::uart]
+ description "
+ This option controls the name that an eCos application
+ should use to access this device via cyg_io_lookup(),
+ open(), or similar calls."
+ }
+
+ cdl_option CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL[set ::uart]_ISR_PRIORITY {
+ display "Interrupt priority for this device"
+ flavor data
+ default_value is_loaded(CYGNUM_HAL_M68K_MCFxxxx_ISR_DEFAULT_PRIORITY_UART[set ::uart]) ? \
+ CYGNUM_HAL_M68K_MCFxxxx_ISR_DEFAULT_PRIORITY_UART[set ::uart] : \
+ CYGNUM_HAL_M68K_MCFxxxx_ISR_PRIORITY_MIN
+ legal_values CYGNUM_HAL_M68K_MCFxxxx_ISR_PRIORITY_MIN to CYGNUM_HAL_M68K_MCFxxxx_ISR_PRIORITY_MAX
+ description "
+ By default uart [set ::uart] is given an interrupt priority of 1,
+ in other words it will interrupt at IPL level 1. The device can
+ be made to interrupt at a higher priority but this is rarely
+ useful since nearly all processing happens at DSR level rather
+ than ISR level."
+ }
+
+ cdl_option CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL[set ::uart]_BAUD {
+ display "Default baud rate for uart [set ::uart]"
+ flavor data
+ default_value 38400
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ description "This option determines the initial baud rate for uart [set ::uart]"
+ }
+
+ cdl_option CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL[set ::uart]_BUFSIZE {
+ display "Buffer size for the uart [set ::uart] serial driver"
+ flavor booldata
+ default_value 128
+ legal_values 16 to 8192
+ description "
+ Typically the device driver will run in interrupt mode and will
+ perform some buffering of both incoming and outgoing data. This
+ option controls the size of both input and output buffer. If
+ the device will be used only in polled mode then this option
+ can be disabled."
+ }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_SERIAL_MCFxxxx_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVS_SERIAL_MCFxxxx_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_SERIAL_MCFxxxx_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_SERIAL_MCFxxxx_TESTING {
+ display "Testing parameters"
+ flavor none
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"mcfxxxx\""
+ }
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { "\"/dev/ser0\"" }
+ }
+ cdl_option CYGPRI_SER_TEST_TTY_DEV {
+ display "TTY device used for testing"
+ flavor data
+ default_value { "\"/dev/tty0\"" }
+ }
+ }
+}
diff --git a/ecos/packages/devs/serial/m68k/mcf52xx/current/doc/mcf52xx_ser.sgml b/ecos/packages/devs/serial/m68k/mcf52xx/current/doc/mcf52xx_ser.sgml
new file mode 100644
index 0000000..62483ca
--- /dev/null
+++ b/ecos/packages/devs/serial/m68k/mcf52xx/current/doc/mcf52xx_ser.sgml
@@ -0,0 +1,208 @@
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- mcfxxxx_ser.sgml -->
+<!-- -->
+<!-- mcfxxxx serial driver documentation. -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2003, 2004, 2006, 2008 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2003/07/15 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-ser-m68k-mcfxxxx-part"><title>Freescale MCFxxxx Serial Driver</title>
+
+<refentry id="devs-ser-m68k-mcfxxxx">
+ <refmeta>
+ <refentrytitle>MCFxxxx Serial Driver</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname><varname>CYGPKG_DEVS_SERIAL_MCFxxxx</varname></refname>
+ <refpurpose>eCos Support for the MCFxxxx On-chip Serial Devices</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="devs-ser-m68k-mcfxxxx-description"><title>Description</title>
+ <para>
+All members of the Freescale MCFxxxx ColdFire family of processors
+contain a number of on-chip UARTs for serial communication. They all
+use very similar hardware. There are some variations such as different
+fifo sizes, and some processors contain extra functionality such as
+autobaud detection, but a single eCos device driver can cope with most
+of these differences. The
+<varname>CYGPKG_DEVS_SERIAL_MCFxxxx</varname> package provides this
+driver. It will use definitions provided by the variant HAL
+<varname>CYGPKG_HAL_M68K_MCFxxxx</varname>, the processor HAL and the
+platform HAL.
+ </para>
+ <para>
+The driver provides partial support for hardware flow control and for
+serial line status. Only CTS/RTS hardware flow control is supported
+since the UART does not provide DTR/DSR lines. Similarly only line
+breaks, and certain communication errors are supported for line status
+since the UART does not provide other lines such as DCD or RI. On some
+platforms it should be possible to emulate these lines using GPIO
+pins, but currently there is no support for this.
+ </para>
+ <para>
+Once application code accesses a UART through the serial driver, for
+example by opening a device <literal>/dev/ser0</literal>, the driver
+assumes that it has sole access to the hardware. This means that the
+UART should not be used for any other purpose, for example HAL
+diagnostics or gdb debug traffic. Instead such traffic has to go via
+another communication channel such as ethernet.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-ser-m68k-mcfxxxx-config"><title>Configuration Options</title>
+ <para>
+ The MCFxxxx serial driver should be loaded automatically when
+selecting a platform containing a suitable processor, and it should
+never be necessary to load it explicitly. The driver as a whole is
+inactive unless the generic serial support,
+<varname>CYGPKG_IO_SERIAL_DEVICES</varname>, is enabled. Exactly which
+UART or UARTs are accessible on a given platform is determined by the
+platform because even if the processor contains a UART the platform
+may not provide a connector. Support for a given UART, say uart0, is
+controlled by a configuration option
+<varname>CYGPKG_DEVS_SERIAL_MCFxxxx_SERIAL0</varname>. The device
+driver configuration option in turn depends on a HAL configuration
+option <varname>CYGHWR_HAL_M68K_MCFxxxx_UART0</varname> to indicate
+that the UART is actually present and connected on the target
+hardware. If a given UART is of no interest to an application
+developer then it is possible to save some memory by disabling this
+option.
+ </para>
+ <para>
+For every enabled UART there are a further four configuration options:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><varname>CYGDAT_DEVS_SERIAL_MCFxxxx_SERIAL0_NAME</varname></term>
+ <listitem><para>
+Each serial device should have a unique name so that application code
+can open it. The default device names are <literal>/dev/ser0</literal>,
+<literal>/dev/ser1</literal>, and so on. It is only necessary to change
+these if the platform contains additional off-chip UARTs with clashing
+names.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_ISR_PRIORITY</varname></term>
+ <listitem><para>
+By default the driver arranges for the UARTs to interrupt at a low
+interrupt priority. Usually there will be no need to change this
+because the driver does not actually do very much processing at ISR
+level, and anyway UARTs are not especially fast devices so do not
+require immediate attention. On some Coldfires with MCF5282-compatible
+interrupt controllers care has to be taken that all interrupt
+priorities are unique.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_BAUD</varname></term>
+ <listitem><para>
+Each UART will be initialized to a given baud rate. The default baud
+rate is 38400 because in most scenarios this is fast enough yet
+does not suffer from excess data corruption. Lower baud rates can be
+used if the application will operate in an electrically noisy
+environment, or higher baud rates up to 230400 can be used if
+38400 does not provide sufficient throughput.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_BUFSIZE</varname></term>
+ <listitem><para>
+The serial driver will maintain software buffers for incoming and
+outgoing data. The former allows data to continue to arrive even if
+the application is still busy processing the previous transfer, and
+thus potentially improves throughput. The latter allows the
+application to transmit data without immediately blocking until the
+transfer is complete, often eliminating the need for a separate
+thread. The size of these buffers can be controlled via this
+configuration option, or alternatively these buffers can be disabled
+completely to save memory.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+There are additional options in the generic serial I/O package
+<varname>CYGPKG_IO_SERIAL</varname> which will affect this driver. For
+example <varname>CYGPKG_IO_SERIAL_FLOW_CONTROL</varname> and its
+sub-options determine what flow control mechanism (if any) should be
+used.
+ </para>
+ <para>
+This package also defines some configuration options related to
+testing. Usually these options are of no interest to application
+developers and can be ignored.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-ser-m68k-mcfxxxx-porting"><title>Porting</title>
+ <para>
+The generic driver needs some information from other packages about
+the exact hardware, for example how many UARTs are available and where
+in memory they can be accessed.
+ </para>
+ <orderedlist>
+ <listitem><para>
+Another package, usually the processor HAL, should provide one or more
+options <varname>CYGHWR_HAL_M68K_MCFxxxx_UART0</varname>,
+<varname>CYGHWR_HAL_M68K_MCFxxxx_UART1</varname> or
+<varname>CYGHWR_HAL_M68K_MCFxxxx_UART2</varname>. These may be
+calculated or user-configurable depending on the processor.
+ </para></listitem>
+ <listitem><para>
+The device driver will also look for symbol definitions
+<varname>CYGHWR_HAL_M68K_MCFxxxx_UART0_RTS</varname> and
+<varname>CYGHWR_HAL_M68K_MCFxxxx_UART0_CTS</varname>, and the
+equivalents for the other UARTs, to determine whether or not these
+handshake lines are connected. These may be configuration options or
+they may be statically defined in a HAL I/O header file. The platform
+HAL should also implement the generic serial package's interface
+<varname>CYGINT_IO_SERIAL_FLOW_CONTROL_HW</varname> if appropriate.
+ </para></listitem>
+ <listitem><para>
+If RTS is connected then the driver will also look for a symbol
+<varname>CYGHWR_HAL_M68K_MCFxxxx_UART0_RS485_RTS</varname>. This
+enables partial support for RS485 communication in that the device
+driver will arrange for the RTS line to be asserted during a transmit.
+The driver has no support for more advanced RS485 functionality such
+as multidrop.
+ </para></listitem>
+ </orderedlist>
+ <para>
+In addition the driver assumes the standard MCFxxxx HAL macros are
+defined for the UART base addresses and the registers. The driver
+primarily targets MCF5282-compatible UARTs but there is also some
+support for functionality available on other members of the Coldfire
+range, for example the MCF5272's fractional baud rate support.
+ </para>
+ </refsect1>
+
+</refentry>
+</part>
diff --git a/ecos/packages/devs/serial/m68k/mcf52xx/current/src/ser_mcf52xx.c b/ecos/packages/devs/serial/m68k/mcf52xx/current/src/ser_mcf52xx.c
new file mode 100644
index 0000000..2a0e7e3
--- /dev/null
+++ b/ecos/packages/devs/serial/m68k/mcf52xx/current/src/ser_mcf52xx.c
@@ -0,0 +1,850 @@
+//==========================================================================
+//
+// ser_mcfxxxx.c
+//
+// Serial driver for Freescale coldfire processors
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004, 2006, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors: bartv
+// Date: 2003-06-04
+// Purpose: support coldfire on-chip uart's
+// Description: The various coldfire mcfxxxx processors all use the same
+// basic UART. There are some variations, e.g. different
+// fifo sizes, autobaud capability, and calculating baud
+// rates requires platform-specific knowledge such as the
+// cpu speed. Also there is no standardization of base
+// addresses or interrupt vectors. Never the less a single
+// driver should be able to support most devices, with
+// various processor-specific or platform-specific #define's
+// and other support.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// NOTE: some platforms may use GPIO pins for other modem lines such as
+// ring and DSR/DTR/DCD. This code could check for #ifdef HAL_MCF52xx_UART_SET_DCD()
+// and incorporate support from the platform HAL.
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include CYGBLD_HAL_VARIANT_H
+#include CYGBLD_HAL_PROC_H
+#include CYGBLD_HAL_PLATFORM_H
+#include <pkgconf/devs_serial_mcfxxxx.h>
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_io.h>
+
+//#define MCFxxxx_SERIAL_STATS 1
+#undef MCFxxxx_SERIAL_STATS
+
+#ifdef MCFxxxx_SERIAL_STATS
+# define INCR_STAT(_info_, _field_, _amount_) \
+ CYG_MACRO_START \
+ (_info_)->_field_ += _amount_; \
+ CYG_MACRO_END
+#else
+# define INCR_STAT(_info_, _field_, _amount_) \
+ CYG_MACRO_START \
+ CYG_MACRO_END
+#endif
+
+// ----------------------------------------------------------------------------
+// devtab entries for the supported devices.
+
+static bool mcfxxxx_serial_init(struct cyg_devtab_entry*);
+static Cyg_ErrNo mcfxxxx_serial_lookup(struct cyg_devtab_entry**, struct cyg_devtab_entry*, const char*);
+static Cyg_ErrNo mcfxxxx_serial_set_config(serial_channel*, cyg_uint32, const void*, cyg_uint32*);
+static bool mcfxxxx_serial_putc(serial_channel*, unsigned char);
+static unsigned char mcfxxxx_serial_getc(serial_channel*);
+static void mcfxxxx_serial_start_xmit(serial_channel*);
+static void mcfxxxx_serial_stop_xmit(serial_channel*);
+static cyg_uint32 mcfxxxx_serial_isr(cyg_vector_t, cyg_addrword_t);
+static void mcfxxxx_serial_dsr(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
+
+typedef struct mcfxxxx_serial_info {
+ cyg_uint8* base;
+ cyg_vector_t isr_vec;
+ int isr_priority;
+ cyg_uint8 uimr_shadow;
+ cyg_uint8 umr1_shadow;
+ cyg_uint8 umr2_shadow;
+ cyg_uint8 flags;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+#ifdef MCFxxxx_SERIAL_STATS
+ cyg_uint32 isr_count;
+ cyg_uint32 dsr_count;
+ cyg_uint32 rx_bytes;
+ cyg_uint32 tx_bytes;
+ cyg_uint32 rx_errors;
+#endif
+} mcfxxxx_serial_info;
+
+#define MCFxxxx_SERIAL_RTS (0x01 << 0)
+#define MCFxxxx_SERIAL_CTS (0x01 << 1)
+#define MCFxxxx_SERIAL_RS485_RTS (0x01 << 2)
+
+static SERIAL_FUNS(mcfxxxx_serial_funs,
+ mcfxxxx_serial_putc,
+ mcfxxxx_serial_getc,
+ mcfxxxx_serial_set_config,
+ mcfxxxx_serial_start_xmit,
+ mcfxxxx_serial_stop_xmit
+ );
+
+
+#ifdef CYGPKG_DEVS_SERIAL_MCFxxxx_SERIAL0
+static mcfxxxx_serial_info mcfxxxx_serial0_info = {
+ base: (cyg_uint8*)HAL_MCFxxxx_UART0_BASE,
+ isr_vec: CYGNUM_HAL_ISR_UART0,
+ isr_priority: CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_ISR_PRIORITY,
+#ifdef MCFxxxx_SERIAL_STATS
+ isr_count: 0,
+ dsr_count: 0,
+ rx_bytes: 0,
+ tx_bytes: 0,
+ rx_errors: 0,
+#endif
+ flags:
+#if defined(CYGHWR_HAL_M68K_MCFxxxx_UART0_RS485_RTS)
+ MCFxxxx_SERIAL_RS485_RTS |
+#elif defined(CYGHWR_HAL_M68K_MCFxxxx_UART0_RTS)
+ MCFxxxx_SERIAL_RTS |
+#endif
+#if defined(CYGHWR_HAL_M68K_MCFxxxx_UART0_CTS)
+ MCFxxxx_SERIAL_CTS |
+#endif
+ 0x00
+};
+
+# ifdef CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_BUFSIZE
+static unsigned char mcfxxxx_serial0_tx_buf[CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_BUFSIZE];
+static unsigned char mcfxxxx_serial0_rx_buf[CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mcfxxxx_serial0_chan,
+ mcfxxxx_serial_funs,
+ mcfxxxx_serial0_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ mcfxxxx_serial0_tx_buf, CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_BUFSIZE,
+ mcfxxxx_serial0_rx_buf, CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_BUFSIZE
+ );
+#else
+static SERIAL_CHANNEL(mcfxxxx_serial0_chan,
+ mcfxxxx_serial_funs,
+ mcfxxxx_serial0_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+# endif
+
+DEVTAB_ENTRY(mcfxxxx_serial0_devtab,
+ CYGDAT_DEVS_SERIAL_MCFxxxx_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mcfxxxx_serial_init,
+ mcfxxxx_serial_lookup, // Serial driver may need initializing
+ &mcfxxxx_serial0_chan
+ );
+#endif
+
+#ifdef CYGPKG_DEVS_SERIAL_MCFxxxx_SERIAL1
+static mcfxxxx_serial_info mcfxxxx_serial1_info = {
+ base: (cyg_uint8*)HAL_MCFxxxx_UART1_BASE,
+ isr_vec: CYGNUM_HAL_ISR_UART1,
+ isr_priority: CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL1_ISR_PRIORITY,
+#ifdef MCFxxxx_SERIAL_STATS
+ isr_count: 0,
+ dsr_count: 0,
+ rx_bytes: 0,
+ tx_bytes: 0,
+ rx_errors: 0,
+#endif
+ flags:
+#if defined(CYGHWR_HAL_M68K_MCFxxxx_UART1_RS485_RTS)
+ MCFxxxx_SERIAL_RS485_RTS |
+#elif defined(CYGHWR_HAL_M68K_MCFxxxx_UART1_RTS)
+ MCFxxxx_SERIAL_RTS |
+#endif
+#if defined(CYGHWR_HAL_M68K_MCFxxxx_UART1_CTS)
+ MCFxxxx_SERIAL_CTS |
+#endif
+ 0x00
+};
+
+# ifdef CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL1_BUFSIZE
+static unsigned char mcfxxxx_serial1_tx_buf[CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL1_BUFSIZE];
+static unsigned char mcfxxxx_serial1_rx_buf[CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mcfxxxx_serial1_chan,
+ mcfxxxx_serial_funs,
+ mcfxxxx_serial1_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ mcfxxxx_serial1_tx_buf, CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL1_BUFSIZE,
+ mcfxxxx_serial1_rx_buf, CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL1_BUFSIZE
+ );
+#else
+static SERIAL_CHANNEL(mcfxxxx_serial1_chan,
+ mcfxxxx_serial_funs,
+ mcfxxxx_serial1_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+# endif
+
+DEVTAB_ENTRY(mcfxxxx_serial1_devtab,
+ CYGDAT_DEVS_SERIAL_MCFxxxx_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mcfxxxx_serial_init,
+ mcfxxxx_serial_lookup, // Serial driver may need initializing
+ &mcfxxxx_serial1_chan
+ );
+#endif
+
+#ifdef CYGPKG_DEVS_SERIAL_MCFxxxx_SERIAL2
+static mcfxxxx_serial_info mcfxxxx_serial2_info = {
+ base: (cyg_uint8*)HAL_MCFxxxx_UART2_BASE,
+ isr_vec: CYGNUM_HAL_ISR_UART2,
+ isr_priority: CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL2_ISR_PRIORITY,
+#ifdef MCFxxxx_SERIAL_STATS
+ isr_count: 0,
+ dsr_count: 0,
+ rx_bytes: 0,
+ tx_bytes: 0,
+ rx_errors: 0,
+#endif
+ flags:
+#if defined(CYGHWR_HAL_M68K_MCFxxxx_UART2_RS485_RTS)
+ MCFxxxx_SERIAL_RS485_RTS |
+#elif defined(CYGHWR_HAL_M68K_MCFxxxx_UART2_RTS)
+ MCFxxxx_SERIAL_RTS |
+#endif
+#if defined(CYGHWR_HAL_M68K_MCFxxxx_UART2_CTS)
+ MCFxxxx_SERIAL_CTS |
+#endif
+ 0x00
+};
+
+# ifdef CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL2_BUFSIZE
+static unsigned char mcfxxxx_serial2_tx_buf[CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL2_BUFSIZE];
+static unsigned char mcfxxxx_serial2_rx_buf[CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mcfxxxx_serial2_chan,
+ mcfxxxx_serial_funs,
+ mcfxxxx_serial2_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ mcfxxxx_serial2_tx_buf, CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL2_BUFSIZE,
+ mcfxxxx_serial2_rx_buf, CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL2_BUFSIZE
+ );
+#else
+static SERIAL_CHANNEL(mcfxxxx_serial2_chan,
+ mcfxxxx_serial_funs,
+ mcfxxxx_serial2_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_DEVS_SERIAL_MCFxxxx_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+# endif
+
+DEVTAB_ENTRY(mcfxxxx_serial2_devtab,
+ CYGDAT_DEVS_SERIAL_MCFxxxx_SERIAL2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mcfxxxx_serial_init,
+ mcfxxxx_serial_lookup, // Serial driver may need initializing
+ &mcfxxxx_serial2_chan
+ );
+#endif
+
+// ----------------------------------------------------------------------------
+
+static cyg_uint32 mcfxxxx_baud_rates[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 134, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 230400 // 230400
+};
+
+static bool
+mcfxxxx_serial_config(serial_channel* chan, cyg_serial_info_t* config, cyg_bool init)
+{
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+ cyg_uint8* base = info->base;
+
+ if (init) {
+#if defined(CYGPKG_DEVS_SERIAL_MCFxxxx_SERIAL0) && defined(HAL_MCFxxxx_UART0_PROC_INIT)
+ if (info == &mcfxxxx_serial0_info) {
+ HAL_MCFxxxx_UART0_PROC_INIT();
+ }
+#endif
+#if defined(CYGPKG_DEVS_SERIAL_MCFxxxx_SERIAL1) && defined(HAL_MCFxxxx_UART1_PROC_INIT)
+ if (info == &mcfxxxx_serial1_info) {
+ HAL_MCFxxxx_UART1_PROC_INIT();
+ }
+#endif
+#if defined(CYGPKG_DEVS_SERIAL_MCFxxxx_SERIAL2) && defined(HAL_MCFxxxx_UART2_PROC_INIT)
+ if (info == &mcfxxxx_serial2_info) {
+ HAL_MCFxxxx_UART2_PROC_INIT();
+ }
+#endif
+ // Various resets to get the UART in a known good state
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UCR]), HAL_MCFxxxx_UARTx_UCR_MISC_RR);
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UCR]), HAL_MCFxxxx_UARTx_UCR_MISC_RT);
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UCR]), HAL_MCFxxxx_UARTx_UCR_MISC_RES);
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UCR]), HAL_MCFxxxx_UARTx_UCR_MISC_RBCI);
+
+ // Initialize the interrupt mask register. We want to trigger on rxrdy() and
+ // optionally on breaks. Tx interrupts are not enabled by default, only
+ // when a transmit is in progress.
+ //
+ // Some processors may define HAL_MCFxxxx_UARTx_UIMR_RXFTO which can be
+ // used instead of RXRDY, getting an interrupt only when the fifo is full
+ // or when 64 bit times have elapsed without new data. This reduces the
+ // number of rx interrupts by e.g. a factor of 12. It is not without
+ // penalty: if higher-level code could start processing data before the
+ // fifo has filled up then the latency is increased significantly; even
+ // if a whole packet needs to be received first, unless the packet size
+ // maps cleanly on to fifo boundaries the latency is increased by the
+ // timeout; if software flow control is in use then this side may not
+ // respond to XON/XOFF bytes for a while. For now rx fifos are used
+ // by default if available, although this should probably be made configurable.
+ info->uimr_shadow = 0;
+ if (chan->out_cbuf.len != 0) {
+# if defined(HAL_MCFxxxx_UARTx_UIMR_RXFIFO) && defined(HAL_MCFxxxx_UARTx_UIMR_RXFTO) && defined(HAL_MCFxxxx_UARTx_URF)
+ info->uimr_shadow = HAL_MCFxxxx_UARTx_UIMR_RXFTO | HAL_MCFxxxx_UARTx_UIMR_RXFIFO;
+# else
+ info->uimr_shadow = HAL_MCFxxxx_UARTx_UIMR_RXRDY;
+#endif
+ }
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ info->uimr_shadow |= HAL_MCFxxxx_UARTx_UIMR_DB;
+#endif
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UIMR]), info->uimr_shadow);
+
+ // If the hardware supports tx fifo control, set it up so that
+ // interrupts only occur when the fifo is more than 75% empty.
+ // That cuts down on the number of interrupts without
+ // affecting performance. The processor should service the interrupt
+ // and replenish the fifo before the remaining bytes go out.
+#ifdef HAL_MCFxxxx_UARTx_UTF
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UTF]), HAL_MCFxxxx_UARTx_UTF_TXS_75);
+#endif
+ // Ditto for rx fifo, but trigger on 50%. That is a compromise between
+ // latency and efficiency.
+#ifdef HAL_MCFxxxx_UARTx_URF
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_URF]), HAL_MCFxxxx_UARTx_URF_RXS_50);
+#endif
+ // Always use the internal prescaled CLKIN.
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UCSR]), HAL_MCFxxxx_UARTx_UCSR_RCS_CLKIN | HAL_MCFxxxx_UARTx_UCSR_TCS_CLKIN);
+
+ // Hardware flow control.
+ //
+ // Default: no TXRTS, no TXCTS, no RXRTS, no configurable RTS fifo level
+ info->umr1_shadow = 0x00;
+ info->umr2_shadow = 0x00;
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UACR]), 0x00);
+
+ // CTS, used to throttle the transmitter automatically. This involves
+ // setting the TXCTS bit. However it is not the default, h/w flow control
+ // has to be explicitly enabled by a set_config() call.
+
+ // RTS. This may not be connected at all, or it may be used
+ // for h/w control of an RS485 transceiver, or it may be used
+ // for RS232 handshaking. If the latter then the uart provides
+ // automatic support for throttling the other side when the
+ // fifo starts filling up.
+ if (info->flags & MCFxxxx_SERIAL_RS485_RTS) {
+ info->umr2_shadow = HAL_MCFxxxx_UARTx_UMR2_TXRTS;
+ } else if (info->flags & MCFxxxx_SERIAL_RTS) {
+ // RS232 h/w flow control.
+ // See if the processor supports configurable RTS levels.
+# ifdef HAL_MCFxxxx_UARTx_UACR_RTSL_25
+ // Set up RTS to change when the fifo is 25% full. This means the
+ // processor can accept another 18 bytes, more than the 16-byte
+ // transmit fifo in a typical PC uart. Increasing the RTS level to
+ // any more than this may cause overruns.
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UACR]), HAL_MCFxxxx_UARTx_UACR_RTSL_25);
+# else
+ // Only RxRTS mode is supported, so use it.
+ info->umr1_shadow = HAL_MCFxxxx_UARTx_UMR1_RXRTS;
+# endif
+ // If RTS is connected assert it here, allowing the other side to transmit
+ // data. This may be too early since the h/w is not fully set up yet, but
+ // we only want to do this during init.
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UOP1]), HAL_MCFxxxx_UARTx_UOP_RTS);
+ } else {
+ // RTS is not connected at all.
+ }
+
+ // Enable both RX and TX
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UCR]), HAL_MCFxxxx_UARTx_UCR_TC_TE | HAL_MCFxxxx_UARTx_UCR_RC_RE);
+ }
+
+ info->umr1_shadow &= ~(HAL_MCFxxxx_UARTx_UMR1_BC_MASK | HAL_MCFxxxx_UARTx_UMR1_PM_MASK);
+ switch (config->word_length) {
+ case CYGNUM_SERIAL_WORD_LENGTH_5:
+ info->umr1_shadow |= HAL_MCFxxxx_UARTx_UMR1_BC_5;
+ break;
+ case CYGNUM_SERIAL_WORD_LENGTH_6:
+ info->umr1_shadow |= HAL_MCFxxxx_UARTx_UMR1_BC_6;
+ break;
+ case CYGNUM_SERIAL_WORD_LENGTH_7:
+ info->umr1_shadow |= HAL_MCFxxxx_UARTx_UMR1_BC_7;
+ break;
+ case CYGNUM_SERIAL_WORD_LENGTH_8:
+ default:
+ info->umr1_shadow |= HAL_MCFxxxx_UARTx_UMR1_BC_8;
+ break;
+ }
+ switch (config->parity) {
+ case CYGNUM_SERIAL_PARITY_EVEN:
+ info->umr1_shadow |= HAL_MCFxxxx_UARTx_UMR1_PM_WITH;
+ break;
+ case CYGNUM_SERIAL_PARITY_ODD:
+ info->umr1_shadow |= HAL_MCFxxxx_UARTx_UMR1_PM_WITH | HAL_MCFxxxx_UARTx_UMR1_PT;
+ break;
+ case CYGNUM_SERIAL_PARITY_MARK:
+ info->umr1_shadow |= HAL_MCFxxxx_UARTx_UMR1_PM_FORCE | HAL_MCFxxxx_UARTx_UMR1_PT;
+ break;
+ case CYGNUM_SERIAL_PARITY_SPACE:
+ info->umr1_shadow |= HAL_MCFxxxx_UARTx_UMR1_PM_FORCE;
+ break;
+ case CYGNUM_SERIAL_PARITY_NONE:
+ default:
+ info->umr1_shadow |= HAL_MCFxxxx_UARTx_UMR1_PM_NO;
+ break;
+ }
+ info->umr2_shadow &= ~HAL_MCFxxxx_UARTx_UMR2_SB_MASK;
+ switch (config->stop) {
+ case CYGNUM_SERIAL_STOP_2:
+ info->umr2_shadow |= HAL_MCFxxxx_UARTx_UMR2_SB_2;
+ break;
+ case CYGNUM_SERIAL_STOP_1_5:
+ info->umr2_shadow |= (CYGNUM_SERIAL_WORD_LENGTH_5 == config->word_length) ? 0x07 : 0x08;
+ break;
+ case CYGNUM_SERIAL_STOP_1:
+ default:
+ info->umr2_shadow |= (CYGNUM_SERIAL_WORD_LENGTH_5 == config->word_length) ? 0x00 : HAL_MCFxxxx_UARTx_UMR2_SB_1;
+ break;
+ }
+
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UCR]), HAL_MCFxxxx_UARTx_UCR_MISC_RMRP);
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UMR]), info->umr1_shadow);
+ HAL_WRITE_UINT8(&(base[HAL_MCFxxxx_UARTx_UMR]), info->umr2_shadow);
+
+ // Set the baud rate, using a processor or platform macro. That way the
+ // calculation can depend on the clock speed.
+ HAL_MCFxxxx_UARTx_SET_BAUD(base, mcfxxxx_baud_rates[config->baud]);
+
+ if (config != &chan->config) {
+ chan->config = *config;
+ }
+
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+static bool
+mcfxxxx_serial_init(struct cyg_devtab_entry* devtab_entry)
+{
+ serial_channel* chan = (serial_channel*) devtab_entry->priv;
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+
+ mcfxxxx_serial_config(chan, &(chan->config), true);
+
+ if (0 != chan->out_cbuf.len) {
+ cyg_drv_interrupt_create(info->isr_vec,
+ info->isr_priority,
+ (cyg_addrword_t) chan,
+ &mcfxxxx_serial_isr,
+ &mcfxxxx_serial_dsr,
+ &(info->serial_interrupt_handle),
+ &(info->serial_interrupt));
+ cyg_drv_interrupt_attach(info->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(info->isr_vec);
+ }
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+static Cyg_ErrNo
+mcfxxxx_serial_lookup(struct cyg_devtab_entry** tab, struct cyg_devtab_entry* sub_tab, const char* name)
+{
+ serial_channel* chan = (serial_channel*) (*tab)->priv;
+ (chan->callbacks->serial_init)(chan);
+ return ENOERR;
+}
+
+// ----------------------------------------------------------------------------
+static Cyg_ErrNo
+mcfxxxx_serial_set_config(serial_channel* chan, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ Cyg_ErrNo result = ENOERR;
+
+ switch(key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+ cyg_serial_info_t* config = (cyg_serial_info_t*) buf;
+ if (*len < sizeof(cyg_serial_info_t)) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ // DSR/DTR is never supported.
+ if (config->flags & (CYGNUM_SERIAL_FLOW_DSRDTR_RX | CYGNUM_SERIAL_FLOW_DSRDTR_TX)) {
+ result = -ENOSUPP;
+ config->flags &= ~(CYGNUM_SERIAL_FLOW_DSRDTR_RX | CYGNUM_SERIAL_FLOW_DSRDTR_TX);
+ }
+ // RTS/CTS may be supported, if the appropriate pins are connected.
+ if ((config->flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX) && !(info->flags & MCFxxxx_SERIAL_RTS)) {
+ result = -ENOSUPP;
+ config->flags &= ~CYGNUM_SERIAL_FLOW_RTSCTS_RX;
+ }
+ if ((config->flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX) && !(info->flags & MCFxxxx_SERIAL_CTS)) {
+ result = -ENOSUPP;
+ config->flags &= ~CYGNUM_SERIAL_FLOW_RTSCTS_TX;
+ }
+ if (ENOERR == result) {
+ if (! mcfxxxx_serial_config(chan, config, false)) {
+ result = -EINVAL;
+ }
+ }
+ break;
+ }
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+ case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE:
+ {
+ // RX flow control involves just the RTS line. Most of the
+ // work is done by the hardware depending on the state of
+ // the fifo. This option serves mainly to drop RTS if
+ // higher-level code is running out of buffer space, even
+ // if the fifo is not yet full.
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+ cyg_uint32* flag = (cyg_uint32*) buf;
+ if (! (info->flags & MCFxxxx_SERIAL_RTS)) {
+ return -ENOSUPP;
+ }
+ if (*flag) {
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UOP0, HAL_MCFxxxx_UARTx_UOP_RTS);
+ } else {
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UOP1, HAL_MCFxxxx_UARTx_UOP_RTS);
+ }
+ }
+ break;
+
+ case CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG:
+ {
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+
+ // DSR/DTR is never supported.
+ if (chan->config.flags & (CYGNUM_SERIAL_FLOW_DSRDTR_RX | CYGNUM_SERIAL_FLOW_DSRDTR_TX)) {
+ result = -ENOSUPP;
+ chan->config.flags &= ~(CYGNUM_SERIAL_FLOW_DSRDTR_RX | CYGNUM_SERIAL_FLOW_DSRDTR_TX);
+ }
+ // RTS/CTS may be supported, if the appropriate pins are connected.
+ if ((chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX) && !(info->flags & MCFxxxx_SERIAL_RTS)) {
+ result = -ENOSUPP;
+ chan->config.flags &= ~CYGNUM_SERIAL_FLOW_RTSCTS_RX;
+ }
+ if ((chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX) && !(info->flags & MCFxxxx_SERIAL_CTS)) {
+ result = -ENOSUPP;
+ chan->config.flags &= ~CYGNUM_SERIAL_FLOW_RTSCTS_TX;
+ }
+
+ // RTS flow control for RX. Either UMR1 RxRTS or a UACR RTS trigger
+ // level has been set during initialization. There is little point
+ // changing either of these. If h/w flow control is being disabled
+ // then the other side should start ignoring the RTS signal, even
+ // if this side still thinks it is a good idea to change it depending
+ // on the fifo level.
+
+ // CTS flow control for TX just involves the UMR2 TxCTS bit.
+ if (0 != (chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX)) {
+ info->umr2_shadow |= HAL_MCFxxxx_UARTx_UMR2_TXCTS;
+ } else {
+ info->umr2_shadow &= ~HAL_MCFxxxx_UARTx_UMR2_TXCTS;
+ }
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UCR, HAL_MCFxxxx_UARTx_UCR_MISC_RMRP);
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UMR, info->umr1_shadow);
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UMR, info->umr2_shadow);
+ }
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
+
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// Non-blocking send, returning true if the character was consumed. This can
+// be called in both interrupt and polled mode.
+
+static bool
+mcfxxxx_serial_putc(serial_channel* chan, unsigned char ch)
+{
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+ cyg_uint8 usr;
+
+ HAL_READ_UINT8(info->base + HAL_MCFxxxx_UARTx_USR, usr);
+ if (usr & HAL_MCFxxxx_UARTx_USR_TXRDY) {
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UTB, ch);
+ INCR_STAT(info, tx_bytes, 1);
+ return true;
+ }
+ return false;
+}
+
+// Blocking receive, only called in polled mode.
+
+static unsigned char
+mcfxxxx_serial_getc(serial_channel* chan)
+{
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+ cyg_uint8 usr, data;
+
+ do {
+ HAL_READ_UINT8(info->base + HAL_MCFxxxx_UARTx_USR, usr);
+ } while (! (usr & HAL_MCFxxxx_UARTx_USR_RXRDY));
+ HAL_READ_UINT8(info->base + HAL_MCFxxxx_UARTx_URB, data);
+ INCR_STAT(info, rx_bytes, 1);
+ return data;
+}
+
+// Start transmitting, only called in interrupt mode. This just requires
+// unmasking tx interrupts, with the interrupt handling code doing the
+// rest. The UIMR register is write-only so this has to go via a shadow
+// copy.
+//
+// If the processor supports interrupting on TXFIFO then that is used
+// instead, raising interrupts only if the fifo >= 75% empty.
+//
+// In RS485 mode it is necessary to enable RTS here so that the transceiver
+// is no longer tristated. RTS will be dropped automatically at the end of the
+// transmit. It is assumed that the fifo will be refilled quickly enough
+// that RTS does not get dropped too soon. Arguably RTS should be raised
+// in the fifo fill code, but that would introduce problems if another node
+// has decided a timeout has occurred and it should start transmitting now.
+
+static void
+mcfxxxx_serial_start_xmit(serial_channel* chan)
+{
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+ CYG_INTERRUPT_STATE saved_state;
+
+ if (info->flags & MCFxxxx_SERIAL_RS485_RTS) {
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UOP1, HAL_MCFxxxx_UARTx_UOP_RTS);
+ }
+
+ HAL_DISABLE_INTERRUPTS(saved_state);
+#ifdef HAL_MCFxxxx_UARTx_UIMR_TXFIFO
+ info->uimr_shadow |= HAL_MCFxxxx_UARTx_UIMR_TXFIFO;
+#else
+ info->uimr_shadow |= HAL_MCFxxxx_UARTx_UIMR_TXRDY;
+#endif
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UIMR, info->uimr_shadow);
+ HAL_RESTORE_INTERRUPTS(saved_state);
+}
+
+// Stop transmitting, only called in interrupt mode.
+static void
+mcfxxxx_serial_stop_xmit(serial_channel* chan)
+{
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+ CYG_INTERRUPT_STATE saved_state;
+
+ HAL_DISABLE_INTERRUPTS(saved_state);
+#ifdef HAL_MCFxxxx_UARTx_UIMR_TXFIFO
+ info->uimr_shadow &= ~HAL_MCFxxxx_UARTx_UIMR_TXFIFO;
+#else
+ info->uimr_shadow &= ~HAL_MCFxxxx_UARTx_UIMR_TXRDY;
+#endif
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UIMR, info->uimr_shadow);
+ HAL_RESTORE_INTERRUPTS(saved_state);
+}
+
+// ----------------------------------------------------------------------------
+// The main serial I/O callbacks expect to be called in DSR context, not
+// ISR context, so it is not possible to do much processing in the ISR.
+// Instead everything is deferred to the DSR.
+
+static cyg_uint32
+mcfxxxx_serial_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ serial_channel* chan = (serial_channel*) data;
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UIMR, 0);
+
+ INCR_STAT(info, isr_count, 1);
+
+ return CYG_ISR_CALL_DSR;
+}
+
+// ----------------------------------------------------------------------------
+static void
+mcfxxxx_serial_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel* chan = (serial_channel*) data;
+ mcfxxxx_serial_info* info = (mcfxxxx_serial_info*) chan->dev_priv;
+ cyg_uint8 uisr;
+
+ INCR_STAT(info, dsr_count, 1);
+
+ HAL_READ_UINT8(info->base + HAL_MCFxxxx_UARTx_UISR, uisr);
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ // This is not quite right, it will report a break event instead of a delta-break,
+ // so higher-level code will see two breaks instead of start-break and end-break.
+ // In practice that should be good enough.
+ //
+ // There is also a received-break bit in the usr register, indicating that a
+ // break occurred in the middle of a character.
+ if (uisr & HAL_MCFxxxx_UARTx_UISR_DB) {
+ cyg_serial_line_status_t stat;
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UCR, HAL_MCFxxxx_UARTx_UCR_MISC_RBCI);
+ stat.value = 1;
+ stat.which = CYGNUM_SERIAL_STATUS_BREAK;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+
+ // Do not report CTS changes to higher-level code. There is no point since flow
+ // control should be handled by the hardware.
+
+ if (uisr & HAL_MCFxxxx_UARTx_UISR_RXRDY) {
+ cyg_uint8 usr, data;
+ while (1) {
+ HAL_READ_UINT8(info->base + HAL_MCFxxxx_UARTx_USR, usr);
+
+ if (! (usr & HAL_MCFxxxx_UARTx_USR_RXRDY)) {
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ // Now check for an overrun, so that the error is
+ // reported in approximately the right place in the
+ // data stream. It is possible that an extra byte
+ // or so has come in after the overrun, but that
+ // cannot be detected.
+ if (usr & HAL_MCFxxxx_UARTx_USR_OE) {
+ cyg_serial_line_status_t stat;
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UCR, HAL_MCFxxxx_UARTx_UCR_MISC_RES);
+ stat.value = 1;
+ stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ INCR_STAT(info, rx_errors, 1);
+ }
+#endif
+ // There is no more data in the fifo, so look for transmits.
+ break;
+ }
+
+ // RXRDY is set, so we have either a valid or a corrupted byte
+ // in the current fifo position. First pass the byte up the stack,
+ // then report the error.
+ HAL_READ_UINT8(info->base + HAL_MCFxxxx_UARTx_URB, data);
+ (chan->callbacks->rcv_char)(chan, data);
+ INCR_STAT(info, rx_bytes, 1);
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ if (usr & HAL_MCFxxxx_UARTx_USR_FE) {
+ cyg_serial_line_status_t stat;
+ stat.value = 1;
+ stat.which = CYGNUM_SERIAL_STATUS_FRAMEERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ INCR_STAT(info, rx_errors, 1);
+ }
+ if (usr & HAL_MCFxxxx_UARTx_USR_PE) {
+ cyg_serial_line_status_t stat;
+ stat.value = 1;
+ stat.which = CYGNUM_SERIAL_STATUS_PARITYERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ INCR_STAT(info, rx_errors, 1);
+ }
+#endif
+ }
+ }
+
+ if (uisr & HAL_MCFxxxx_UARTx_UISR_TXRDY) {
+ (chan->callbacks->xmt_char)(chan);
+ }
+
+ // Re-enable UART interrupts
+ HAL_WRITE_UINT8(info->base + HAL_MCFxxxx_UARTx_UIMR, info->uimr_shadow);
+}
diff --git a/ecos/packages/devs/serial/mcf52xx/mcf5272/current/ChangeLog b/ecos/packages/devs/serial/mcf52xx/mcf5272/current/ChangeLog
new file mode 100644
index 0000000..a89edc0
--- /dev/null
+++ b/ecos/packages/devs/serial/mcf52xx/mcf5272/current/ChangeLog
@@ -0,0 +1,27 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_mcf5272_uart.cdl: Remove irrelevant doc link.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/mcf52xx/mcf5272/current/cdl/ser_mcf5272_uart.cdl b/ecos/packages/devs/serial/mcf52xx/mcf5272/current/cdl/ser_mcf5272_uart.cdl
new file mode 100644
index 0000000..282bd17
--- /dev/null
+++ b/ecos/packages/devs/serial/mcf52xx/mcf5272/current/cdl/ser_mcf5272_uart.cdl
@@ -0,0 +1,141 @@
+# ====================================================================
+#
+# ser_MCF5272_uart.cdl
+#
+# eCos serial driver for MCF5272 UART
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_MCF5272_UART {
+ display "Serial driver for MCF5272 UART"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ description "
+ This option enables the serial device drivers for the
+ GMPU boards."
+
+ compile -library=libextras.a ser_mcf5272_uart.c
+
+ #define_proc {
+ # puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ # puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_MCF52xx_ser_MFC5272_uart.h>"
+ # puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ #}
+
+
+ cdl_component CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0 {
+ display "MCF5272 UART serial port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "This option includes the serial device driver for the MCF5272 UART port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL0_NAME {
+ display "Device name for the MCF5272 UART serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of serial device for the
+ MCF5272 UART port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD {
+ display "Baud rate for the MCF5272 UART serial port 0 driver"
+ flavor data
+ legal_values {1200 2400 4800 9600 14400 19200 38400 115200}
+ default_value 9600
+ description "
+ This option specifies the default baud rate (speed) for the
+ MCF5272 UART port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE {
+ display "Buffer size for the MCF5272 UART serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the MCF5272 UART port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1 {
+ display "MCF5272 UART serial port 1 driver"
+ flavor bool
+ default_value 0
+
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "This option includes the serial device driver for the MCF5272 UART port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL1_NAME {
+ display "Device name for the MCF5272 UART serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for the
+ MCF5272 UART port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BAUD {
+ display "Baud rate for the MCF5272 UART serial port 1 driver"
+ flavor data
+ legal_values {1200 2400 4800 9600 14400 19200 38400 115200}
+ default_value 9600
+ description "
+ This option specifies the default baud rate (speed) for the
+ MCF5272 UART port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE {
+ display "Buffer size for the MCF5272 UART serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the MCF5272 UART port 1."
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/serial/mcf52xx/mcf5272/current/include/ser_mcf5272_uart.h b/ecos/packages/devs/serial/mcf52xx/mcf5272/current/include/ser_mcf5272_uart.h
new file mode 100644
index 0000000..6aa055c
--- /dev/null
+++ b/ecos/packages/devs/serial/mcf52xx/mcf5272/current/include/ser_mcf5272_uart.h
@@ -0,0 +1,129 @@
+#ifndef _SER_MCF5272_H_
+#define _SER_MCF5272_H_
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+#include <pkgconf/io_serial_mcf5272_uart.h>
+
+/* Bit level definitions and macros */
+#define MCF5272_UART_UMR1_RXRTS (0x80)
+#define MCF5272_UART_UMR1_RXIRQ (0x40)
+#define MCF5272_UART_UMR1_ERR (0x20)
+#define MCF5272_UART_UMR1_PM_MULTI_ADDR (0x1C)
+#define MCF5272_UART_UMR1_PM_MULTI_DATA (0x18)
+#define MCF5272_UART_UMR1_PM_NONE (0x10)
+#define MCF5272_UART_UMR1_PM_FORCE_HI (0x0C)
+#define MCF5272_UART_UMR1_PM_FORCE_LO (0x08)
+#define MCF5272_UART_UMR1_PM_ODD (0x04)
+#define MCF5272_UART_UMR1_PM_EVEN (0x00)
+#define MCF5272_UART_UMR1_BC_5 (0x00)
+#define MCF5272_UART_UMR1_BC_6 (0x01)
+#define MCF5272_UART_UMR1_BC_7 (0x02)
+#define MCF5272_UART_UMR1_BC_8 (0x03)
+
+#define MCF5272_UART_UMR2_CM_NORMAL (0x00)
+#define MCF5272_UART_UMR2_CM_ECHO (0x40)
+#define MCF5272_UART_UMR2_CM_LOCAL_LOOP (0x80)
+#define MCF5272_UART_UMR2_CM_REMOTE_LOOP (0xC0)
+#define MCF5272_UART_UMR2_TXRTS (0x20)
+#define MCF5272_UART_UMR2_TXCTS (0x10)
+#define MCF5272_UART_UMR2_STOP_BITS_1 (0x07)
+#define MCF5272_UART_UMR2_STOP_BITS_15 (0x08)
+#define MCF5272_UART_UMR2_STOP_BITS_2 (0x0F)
+#define MCF5272_UART_UMR2_STOP_BITS(a) ((a)&0x0f) /* Stop Bit Length */
+
+//#define MCF5272_UART_USR_RB (0x80)
+//#define MCF5272_UART_USR_FE (0x40)
+//#define MCF5272_UART_USR_PE (0x20)
+//#define MCF5272_UART_USR_OE (0x10)
+//#define MCF5272_UART_USR_TXEMP (0x08)
+//#define MCF5272_UART_USR_TXRDY (0x04)
+#define MCF5272_UART_USR_FFULL (0x02)
+#define MCF5272_UART_USR_RXRDY (0x01)
+
+#define MCF5272_UART_UCSR_RCS(a) (((a)&0x0f)<<4) /* Rx Clk Select */
+#define MCF5272_UART_UCSR_TCS(a) ((a)&0x0f) /* Tx Clk Select */
+
+
+#define MCF5272_UART_UCR_NONE (0x00)
+#define MCF5272_UART_UCR_ENAB (0x80)
+#define MCF5272_UART_UCR_STOP_BREAK (0x70)
+#define MCF5272_UART_UCR_START_BREAK (0x60)
+#define MCF5272_UART_UCR_RESET_BKCHGINT (0x50)
+#define MCF5272_UART_UCR_RESET_ERROR (0x40)
+#define MCF5272_UART_UCR_RESET_TX (0x30)
+#define MCF5272_UART_UCR_RESET_RX (0x20)
+#define MCF5272_UART_UCR_RESET_MR (0x10)
+#define MCF5272_UART_UCR_TX_DISABLED (0x08)
+#define MCF5272_UART_UCR_TX_ENABLED (0x04)
+#define MCF5272_UART_UCR_RX_DISABLED (0x02)
+#define MCF5272_UART_UCR_RX_ENABLED (0x01)
+
+#define MCF5272_UART_UCCR_COS (0x10)
+#define MCF5272_UART_UCCR_CTS (0x01)
+
+#define MCF5272_UART_UACR_BRG (0x80)
+#define MCF5272_UART_UACR_CTMS_TIMER (0x60)
+#define MCF5272_UART_UACR_IEC (0x01)
+
+#define MCF5272_UART_UISR_COS (0x80)
+#define MCF5272_UART_UISR_ABC (0x40)
+#define MCF5272_UART_UISR_DB (0x04)
+#define MCF5272_UART_UISR_RXRDY (0x02)
+#define MCF5272_UART_UISR_TXRDY (0x01)
+
+#define MCF5272_UART_UIMR_COS (0x80)
+#define MCF5272_UART_UIMR_ABC (0x40)
+#define MCF5272_UART_UIMR_DB (0x04)
+#define MCF5272_UART_UIMR_FFULL (0x02)
+#define MCF5272_UART_UIMR_TXRDY (0x01)
+
+typedef unsigned char uint8; /* 8 bits */
+typedef unsigned short int uint16; /* 16 bits */
+typedef unsigned long int uint32; /* 32 bits */
+
+typedef signed char int8; /* 8 bits */
+typedef signed short int int16; /* 16 bits */
+typedef signed long int int32; /* 32 bits */
+
+#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
+unsigned long MCF5272_uart_get_channel_0_baud_rate(void);
+#endif /* CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0 */
+
+#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
+unsigned long MCF5272_uart_get_channel_1_baud_rate(void);
+#endif /* CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1 */
+
+#endif /* _SER_MCF5272_H_ */
+
diff --git a/ecos/packages/devs/serial/mcf52xx/mcf5272/current/src/ser_mcf5272_uart.c b/ecos/packages/devs/serial/mcf52xx/mcf5272/current/src/ser_mcf5272_uart.c
new file mode 100644
index 0000000..4d30a87
--- /dev/null
+++ b/ecos/packages/devs/serial/mcf52xx/mcf5272/current/src/ser_mcf5272_uart.c
@@ -0,0 +1,945 @@
+//==========================================================================
+//
+// devs/serial/MCF52xx/MCF5282
+//
+// MCF5272 UART Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_memmap.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <pkgconf/io_serial_mcf5272_uart.h>
+#include <cyg/io/ser_mcf5272_uart.h>
+
+
+/* The UART priority level */
+#define MCF5272_UART_PRIORITY_LEVEL 2
+
+
+/* Autobaud states */
+typedef enum autobaud_states_t
+{
+ AB_IDLE = 0, /* Normal state. Autobaud process hasn't been initiated yet. */
+ AB_BEGIN_BREAK, /* Detected a start of the break */
+ AB_BEGIN, /* Detected the end of the break and has set up the autobaud.*/
+
+}autobaud_states_t;
+
+#define FIELD_OFFSET(type,field) (cyg_uint32)(&(((type*)0)->field))
+
+typedef struct MCF5272_uart_info_t
+{
+
+ volatile mcf5272_sim_uart_t* base; // Base address of the UART registers
+ uint32 uart_vector; // UART interrupt vector number
+
+ cyg_interrupt serial_interrupt; // Interrupt context
+ cyg_handle_t serial_interrupt_handle; // Interrupt handle
+
+ volatile uint8 imr_mirror; // Interrupt mask register mirror
+
+ cyg_serial_info_t config; // The channel configuration
+
+ autobaud_states_t autobaud_state; // The autobaud state
+
+
+} MCF5272_uart_info_t;
+
+/* Function prtoftyps for the MCF5272 UART ISR and DSR. */
+static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+
+/* Function prototypes for the serial functions. */
+static bool MCF5272_uart_init(struct cyg_devtab_entry * tab);
+static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c);
+static unsigned char MCF5272_uart_getc(serial_channel *chan);
+Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void MCF5272_uart_start_xmit(serial_channel *chan);
+static void MCF5272_uart_stop_xmit(serial_channel * chan);
+
+
+/* Declare the serial functions that are called by the common serial driver layer. */
+static SERIAL_FUNS
+(
+ MCF5272_uart_funs,
+ MCF5272_uart_putc,
+ MCF5272_uart_getc,
+ MCF5272_uart_set_config,
+ MCF5272_uart_start_xmit,
+ MCF5272_uart_stop_xmit
+);
+
+
+/* Definition for channel 0 UART configuration. */
+/************************************************/
+#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
+
+/* Data structure contains
+ channel informtion.
+ */
+static MCF5272_uart_info_t MCF5272_uart_channel_info_0;
+
+/* If the channel buffer size is zero, do not include interrupt UART processing */
+#if CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE > 0
+
+/* Allocated receive and transmit buffer. The size of the buffer is */
+/* configured by the configtool. */
+
+static unsigned char MCF5272_uart_out_buf0[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE];
+static unsigned char MCF5272_uart_in_buf0[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BUFSIZE];
+
+/* Channel function table. We register the UART functions here so */
+/* that uppper serial drivers can call the serial driver's routines. */
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(
+ MCF5272_uart_channel_0,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ MCF5272_uart_out_buf0, sizeof(MCF5272_uart_out_buf0),
+ MCF5272_uart_in_buf0, sizeof(MCF5272_uart_in_buf0)
+);
+#else
+/* Don't use interrupt processing for the UART. */
+static SERIAL_CHANNEL(
+ MCF5272_uart_channel_0,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+);
+#endif
+
+DEVTAB_ENTRY(
+ MCF5272_uart_io0,
+ CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio, // The table of I/O functions.
+ MCF5272_uart_init, // UART initialization function.
+ MCF5272_uart_lookup, // The UART lookup function. This function typically sets
+ // up the device for actual use, turing on interrupts, configuring the port, etc.
+ &MCF5272_uart_channel_0
+);
+#endif // CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0
+
+/* Definition for channel 1 UART configuration. */
+/************************************************/
+
+#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
+
+
+/* Data structure contains
+ channel informtion.
+ */
+static MCF5272_uart_info_t MCF5272_uart_channel_info_1;
+
+/* If the channel buffer size is zero, do not include interrupt UART processing */
+#if CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE > 0
+
+/* Allocated receive and transmit buffer. The size of the buffer is */
+/* configured by the configtool. */
+
+static unsigned char MCF5272_uart_out_buf1[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE];
+static unsigned char MCF5272_uart_in_buf1[CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BUFSIZE];
+
+/* Channel function table. We register the UART functions here so */
+/* that uppper serial drivers can call the serial driver's routines. */
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(
+ MCF5272_uart_channel_1,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ MCF5272_uart_out_buf1, sizeof(MCF5272_uart_out_buf1),
+ MCF5272_uart_in_buf1, sizeof(MCF5272_uart_in_buf1)
+);
+
+#else
+static SERIAL_CHANNEL(MCF5272_uart_channel_1,
+ MCF5272_uart_funs,
+ MCF5272_uart_channel_info_1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+DEVTAB_ENTRY(
+ MCF5272_uart_io1,
+ CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio, // The table of I/O functions.
+ MCF5272_uart_init, // UART initialization function.
+ MCF5272_uart_lookup, // The UART lookup function. This function typically sets
+ // up the device for actual use, turing on interrupts, configuring the port, etc.
+ &MCF5272_uart_channel_1
+);
+#endif // CYGNUM_IO_SERIAL_MCF5272_UART_CHANNEL1
+
+
+
+/* Definition of macros that access the UART's SIM registers */
+/* Read from a register */
+
+#define MCF5272_UART_WRITE(_addr_,_value_) \
+ *((volatile CYG_BYTE*)&(_addr_)) = (CYG_BYTE)(_value_)
+/* Write to a register */
+#define MCF5272_UART_READ(_addr_) \
+ *(volatile CYG_BYTE*)&(_addr_)
+
+
+/* Function Prototypes */
+/* =================== */
+/* Internal function to actually configure the hardware to desired baud rate, etc. */
+static bool MCF5272_uart_config_port(serial_channel*, cyg_serial_info_t*);
+static void MCF5272_uart_start_xmit(serial_channel*);
+
+
+/* Baudrate conversion table. */
+static unsigned long baud_rates_table[]=
+{
+ 0,
+ 50, // CYGNUM_SERIAL_BAUD_50 = 1
+ 75, // CYGNUM_SERIAL_BAUD_75
+ 110, // CYGNUM_SERIAL_BAUD_110
+ 134, // CYGNUM_SERIAL_BAUD_134_5
+ 150, // CYGNUM_SERIAL_BAUD_150
+ 200, // CYGNUM_SERIAL_BAUD_200
+ 300, // CYGNUM_SERIAL_BAUD_300
+ 600, // CYGNUM_SERIAL_BAUD_600
+ 1200, // CYGNUM_SERIAL_BAUD_1200
+ 1800, // CYGNUM_SERIAL_BAUD_1800
+ 2400, // CYGNUM_SERIAL_BAUD_2400
+ 3600, // CYGNUM_SERIAL_BAUD_3600
+ 4800, // CYGNUM_SERIAL_BAUD_4800
+ 7200, // CYGNUM_SERIAL_BAUD_7200
+ 9600, // CYGNUM_SERIAL_BAUD_9600
+ 14400, // CYGNUM_SERIAL_BAUD_14400
+ 19200, // CYGNUM_SERIAL_BAUD_19200
+ 38400, // CYGNUM_SERIAL_BAUD_38400
+ 57600, // CYGNUM_SERIAL_BAUD_57600
+ 115200, // CYGNUM_SERIAL_BAUD_115200
+ 230400 // CYGNUM_SERIAL_BAUD_230400
+};
+
+/* The table contains divers to divide the clock to configre a */
+/* approppriate for the UART. */
+
+static unsigned long dividers_table[]=
+{
+ 0,
+ 46080, // 50
+ 30720, // 75
+ 20945, // 110
+ 17130, // 134_5
+ 15360, // 150
+ 11520, // 200
+ 7680, // 300
+ 3840, // 600
+ 1920, // 1200
+ 1280, // 1800
+ 960, // 2400
+ 640, // 3600
+ 480, // 4800
+ 320, // 7200
+ 240, // 9600
+ 160, // 14400
+ 120, // 19200
+ 60, // 38400
+ 40, // 57600
+ 20, // 115200
+ 10 // 230400
+};
+
+/*******************************************************************************
+ MCF5272_uart_init() - This routine is called during bootstrap to set up the
+ UART driver.
+
+ INPUT:
+ Pointer to the the device table.
+
+ RETURN:
+ Returns true if the initialization is successful. Otherwise, it retuns false
+*/
+static bool MCF5272_uart_init(struct cyg_devtab_entry * tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ MCF5272_uart_info_t *MCF5272_uart_chan = (MCF5272_uart_info_t *)chan->dev_priv;
+
+ #ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
+
+ /* Instantiation of the UART channel 0 data strucutre. This data */
+ /* structure contains channel information. */
+
+ if (strcmp(tab->name, CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL0_NAME) == 0)
+ {
+
+ /* Initiliaze the UART information data to all zeros. */
+
+ memset(MCF5272_uart_chan, sizeof(MCF5272_uart_info_t), 0);
+
+ /* Set the base address of the UART registers to differentiate */
+ /* itself from the different regusters for the other UART port. */
+
+ MCF5272_uart_chan->base = (mcf5272_sim_uart_t*)&MCF5272_SIM->uart[0];
+
+ /* Set the UART interrupt vector number. */
+
+ MCF5272_uart_chan->uart_vector = CYGNUM_HAL_VECTOR_UART1;
+
+ /* Set the autobaud state to idle. */
+
+ MCF5272_uart_chan->autobaud_state = AB_IDLE;
+
+ /* Initilize the UART 0 output pins */
+
+ MCF5272_SIM->gpio.pbcnt = MCF5272_GPIO_PBCNT_URT0_EN |
+ ((MCF5272_SIM->gpio.pbcnt) & ~MCF5272_GPIO_PBCNT_URT0_MSK);
+ }
+ #endif
+
+ #ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
+
+ /* Instantiation of the UART channel 1 data strucutre. This data structure contains
+ channel information.
+ */
+ if (strcmp(tab->name, CYGDAT_IO_SERIAL_MCF5272_UART_CHANNEL1_NAME) == 0)
+ {
+
+ /* Initiliaze the UART information data to all zeros. */
+
+ memset(MCF5272_uart_chan, sizeof(MCF5272_uart_info_t), 0);
+
+ /* Set the base address of the UART registers to differentiate */
+ /* itself from the different regusters for the other UART port. */
+
+ MCF5272_uart_chan->base = (mcf5272_sim_uart_t*)&MCF5272_SIM->uart[1];
+
+ /* Set the UART interrupt vector number. */
+
+ MCF5272_uart_chan->uart_vector = CYGNUM_HAL_VECTOR_UART2;
+
+ /* Set the autobaud state to idle. */
+
+ MCF5272_uart_chan->autobaud_state = AB_IDLE;
+
+ /* Initilize the UART 1 output pins */
+
+ MCF5272_SIM->gpio.pdcnt = MCF5272_GPIO_PDCNT_URT1_EN |
+ ((MCF5272_SIM->gpio.pdcnt) & ~MCF5272_GPIO_PDCNT_URT1_MSK);
+
+ }
+ #endif
+
+
+ if (chan->out_cbuf.len > 0) {
+
+ /* If the the buffer is greater than zero, then the driver will */
+ /* use interrupt driven I/O. Hence, the driver creates an */
+ /* interrupt context for the UART device. */
+
+ cyg_drv_interrupt_create(MCF5272_uart_chan->uart_vector,
+ MCF5272_UART_PRIORITY_LEVEL, // Priority - Level 2
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ MCF5272_uart_ISR,
+ MCF5272_uart_DSR,
+ &MCF5272_uart_chan->serial_interrupt_handle,
+ &MCF5272_uart_chan->serial_interrupt);
+
+ cyg_drv_interrupt_attach(MCF5272_uart_chan->serial_interrupt_handle);
+
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ }
+
+ // Configure Serial device.
+ return(MCF5272_uart_config_port(chan, &chan->config));
+}
+
+/******************************************************************************************************
+ MCF5272_uart_config_port() - Configure the UART port.
+
+ Internal function to actually configure the hardware to desired baud rate, etc.
+
+ INPUT:
+ chan - The channel information
+ new_confg - The port configuration which include the desired baud rate, etc.
+
+ RETURN:
+ Returns true if the port configuration is successful. Otherwise, it retuns false
+
+ */
+static bool MCF5272_uart_config_port(serial_channel *chan,
+ cyg_serial_info_t *new_config)
+{
+ MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
+ uint8 mode_reg = 0;
+ uint32 ubgs;
+ unsigned int baud_divisor;
+
+
+ /* Get the divisor from the baudrate table which will use to */
+ /* configure the port's baud rate. */
+
+ baud_divisor = baud_rates_table[new_config->baud];
+
+ /* If the divisor is zeor, we dont' configure the port. */
+
+ if (baud_divisor == 0) return false;
+
+ /* Save the configuration value for later use. */
+
+ port->config = *new_config;
+
+ /* We first write the reset values into the device and then configure */
+ /* the device the we way we want to use it. */
+
+ /* Reset Transmitter */
+
+ MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_TX);
+
+ /* Reset Receiver */
+
+ MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_RX);
+
+ /* Reset Mode Register */
+
+ MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_MR);
+
+ /* Translate the parity configuration to UART mode bits. */
+
+ switch(port->config.parity)
+ {
+ default:
+ case CYGNUM_SERIAL_PARITY_NONE:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_NONE;
+ break;
+ case CYGNUM_SERIAL_PARITY_EVEN:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_EVEN;
+ break;
+ case CYGNUM_SERIAL_PARITY_ODD:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_ODD;
+ break;
+ case CYGNUM_SERIAL_PARITY_MARK:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_HI;
+ break;
+ case CYGNUM_SERIAL_PARITY_SPACE:
+ mode_reg = 0 | MCF5272_UART_UMR1_PM_FORCE_LO;
+ break;
+ }
+
+ /* Translate the number of bits per character configuration to UART mode bits. */
+
+ switch(port->config.word_length)
+ {
+
+ case CYGNUM_SERIAL_WORD_LENGTH_5:
+ mode_reg |= MCF5272_UART_UMR1_BC_5;
+ break;
+ case CYGNUM_SERIAL_WORD_LENGTH_6:
+ mode_reg |= MCF5272_UART_UMR1_BC_6;
+ break;
+ case CYGNUM_SERIAL_WORD_LENGTH_7:
+ mode_reg |= MCF5272_UART_UMR1_BC_7;
+ break;
+ default:
+ case CYGNUM_SERIAL_WORD_LENGTH_8:
+ mode_reg |= MCF5272_UART_UMR1_BC_8;
+ break;
+ }
+
+ /* Configure the parity and the bits per character */
+
+ MCF5272_UART_WRITE(port->base->umr, mode_reg);
+
+ /* Translate the stop bit length to UART mode bits. */
+
+ switch(port->config.stop)
+ {
+ default:
+ case CYGNUM_SERIAL_STOP_1:
+ mode_reg = MCF5272_UART_UMR2_STOP_BITS_1;
+ break;
+ case CYGNUM_SERIAL_STOP_1_5:
+ mode_reg = MCF5272_UART_UMR2_STOP_BITS_15;
+ break;
+ case CYGNUM_SERIAL_STOP_2:
+ mode_reg = MCF5272_UART_UMR2_STOP_BITS_2;
+ break;
+ }
+
+ /* No echo or loopback */
+
+ MCF5272_UART_WRITE(port->base->umr, 0 | MCF5272_UART_UMR2_CM_NORMAL | mode_reg);
+
+ /* Set Rx and Tx baud by timer */
+
+ MCF5272_UART_WRITE(port->base->ucr, 0 | MCF5272_UART_UCSR_RCS(0xD) |
+ MCF5272_UART_UCSR_TCS(0xD));
+
+ /* Mask all USART interrupts */
+
+ MCF5272_UART_WRITE(port->base->uisr_uimr, 0);
+
+ /* Calculate baud settings */
+
+ ubgs = (uint16)((CYGHWR_HAL_SYSTEM_CLOCK_MHZ*1000000)/
+ (baud_divisor * 32));
+
+ /* Program the baud settings to the device. */
+
+ MCF5272_UART_WRITE(port->base->udu, (uint8)((ubgs & 0xFF00) >> 8));
+ MCF5272_UART_WRITE(port->base->udl, (uint8)(ubgs & 0x00FF));
+
+ /* Enable receiver and transmitter */
+
+ MCF5272_UART_WRITE(port->base->ucr, 0 | MCF5272_UART_UCR_TXRXEN);
+
+ /* Enable both transmit and receive interrupt. */
+
+ port->imr_mirror = MCF5272_UART_UIMR_TXRDY | MCF5272_UART_UIMR_FFULL |
+ MCF5272_UART_UIMR_DB;
+ MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
+
+ return true; /* Returns true to indicate a successful configuration */
+
+}
+
+/*******************************************************************************
+ MCF5272_uart_lookup() - This routine is called when the device is "looked" up
+ (i.e. attached)
+
+ INPUT:
+ tab - pointer to a pointer of the device table
+ sub_tab - Pointer to the sub device table.
+ name - name of the device
+
+ RETURN:
+ always return ENOERR
+
+*/
+static Cyg_ErrNo MCF5272_uart_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+/*******************************************************************************
+ MCF5272_uart_putc() - Send a character to the device output buffer.
+
+ INPUT:
+ chan - pointer to the serial private data.
+ c - the character to output
+
+ RETURN:
+ 'true' if character is sent to device, return 'false' when we've
+ ran out of buffer space in the device itself.
+
+*/
+
+static bool MCF5272_uart_putc(serial_channel *chan, unsigned char c)
+{
+ CYG_INTERRUPT_STATE int_state;
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *)chan->dev_priv;
+
+ /* Make sure the transmitter is not full. If it is full, return false. */
+ if (!(MCF5272_UART_READ(port->base->usr_ucsr) & MCF5272_UART_USR_TXRDY))
+ return false;
+
+ /* Enable transmit interrupt. */
+ HAL_DISABLE_INTERRUPTS(int_state);
+ port->imr_mirror |= MCF5272_UART_UIMR_TXRDY;
+ MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
+ HAL_RESTORE_INTERRUPTS(int_state);
+
+ /* Enable the UART transmit. */
+ MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXRXEN);
+
+ /* Send the character */
+ MCF5272_UART_WRITE(port->base->urb_utb, c);
+
+ return true ;
+}
+
+
+/******************************************************************************************************
+ MCF5272_uart_getc() - Fetch a character from the device input bufferand return it to the alling
+ routine. Wait until there is a character ready.
+
+ INPUT:
+ chan - pointer to the serial private data.
+
+ RETURN:
+ the character read from the UART.
+
+ */
+static unsigned char MCF5272_uart_getc(serial_channel *chan)
+{
+ MCF5272_uart_info_t * port = (MCF5272_uart_info_t *)chan->dev_priv;
+
+ /* Wait until character has been received */
+
+ while (!(MCF5272_UART_READ(port->base->usr_ucsr) & MCF5272_UART_USR_RXRDY))
+ {
+ diag_printf("ready poll");
+ }
+
+ /* Read the character from the FIFO queue. */
+
+ return MCF5272_UART_READ(port->base->urf);
+
+}
+
+
+/*******************************************************************************
+ MCF5272_uart_set_config() - Set up the device characteristics; baud rate, etc.
+
+ INPUT:
+ chan - pointer to the serial private data.
+ key - configuration key (command).
+ xbuf - pointer to the configuration buffer
+ len - the length of the configuration buffer
+
+ RETURN:
+ NOERR - If the configuration is successful
+ EINVAL - If the argument is invalid
+
+*/
+
+Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ /* Set serial configuration. */
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+
+ if (!MCF5272_uart_config_port(chan, config))
+ return EINVAL;
+ }
+ break;
+
+ case CYG_IO_GET_CONFIG_SERIAL_INFO:
+ // Retrieve UART configuration
+ *config = port->config;
+ break;
+
+ default:
+ return EINVAL;
+ }
+ return ENOERR;
+}
+
+
+/*******************************************************************************
+ MCF5272_uart_start_xmit() - Enable the transmitter on the device.
+
+ INPUT:
+ chan - pointer to the serial private data.
+
+*/
+static void MCF5272_uart_start_xmit(serial_channel *chan)
+{
+ CYG_INTERRUPT_STATE int_state;
+ MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+ /* Enable the UART transmit. */
+ MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXEN);
+
+ /* Enable transmit interrupt */
+ HAL_DISABLE_INTERRUPTS(int_state);
+ port->imr_mirror |= MCF5272_UART_UIMR_TXRDY;
+ MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
+ HAL_RESTORE_INTERRUPTS(int_state);
+
+
+}
+
+
+/******************************************************************************************************
+ MCF5272_uart_stop_xmit() - Disable the transmitter on the device
+
+ INPUT:
+ chan - pointer to the serial private data.
+
+*/
+static void MCF5272_uart_stop_xmit(serial_channel * chan)
+{
+ CYG_INTERRUPT_STATE int_state;
+ MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+ /* Disable transmit interrupt */
+ HAL_DISABLE_INTERRUPTS(int_state);
+ port->imr_mirror &= ~MCF5272_UART_UIMR_TXRDY;
+ MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
+ HAL_RESTORE_INTERRUPTS(int_state);
+
+ /* Disable the UART transmit.
+ !!!!!!!!!!!!!
+ !!!WARNING!!!
+ !!!!!!!!!!!!!
+ If the transmit the disabe
+ the diag_printf routines will poll forever to transmit the
+ a character. Hence, don't ever disable the transmit if
+ we want it to work with diag_printf.
+ */
+ //MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXDE);
+
+
+}
+
+
+/******************************************************************************************************
+ MCF5272_uart_ISR() - UART I/O interrupt interrupt service routine (ISR).
+
+ INPUT:
+ vector - the interrupt vector number
+ data - user parameter.
+
+
+ RETURN:
+ returns CYG_ISR_CALL_DSR to call the DSR.
+
+ */
+static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *) data;
+ MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
+
+
+ /* Write the value in the interrupt status register back
+ to the mask register to disable the interrupt temporarily.
+ */
+
+ MCF5272_UART_WRITE(port->base->uisr_uimr, 0);
+
+ return CYG_ISR_CALL_DSR; // Cause DSR to run
+}
+
+
+
+/******************************************************************************************************
+ MCF5272_uart_DSR() - Defered Service Routine (DSR) - This routine processes the interrupt
+ from the device.
+
+ INPUT:
+ vector - The interrupt vector number
+ count - The nunber of DSR requests.
+ data - Device specific information
+
+*/
+
+static void MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ MCF5272_uart_info_t *port = (MCF5272_uart_info_t *)chan->dev_priv;
+ volatile u8_t isr;
+
+
+ /* Retrieve the interrupt status bits. We use these status bits to figure out
+ what process shouled we perform: read from the UART or inform of a completion
+ of a data transmission.
+ */
+
+ /* Retrieve the interrupt status register so
+ * the DSR can look it up.
+ */
+
+
+ while((isr = (MCF5272_UART_READ(port->base->uisr_uimr) & port->imr_mirror)))
+ {
+ switch (port->autobaud_state)
+ {
+ default:
+ case AB_IDLE:
+ if (isr & MCF5272_UART_UISR_DB)
+ {
+ /* Detected the begin of a break, set the state to AB_BEGIN_BREAK
+ */
+ port->autobaud_state = AB_BEGIN_BREAK;
+
+ /* Reset the Delta Break bit in the UISR */
+ MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_BKCHGINT);
+
+ }
+ break;
+ case AB_BEGIN_BREAK:
+ if (isr & MCF5272_UART_UISR_DB)
+ {
+ /* Detected the end of a break, set the state to AB_BEGIN, and
+ setup autobaud detection.
+ */
+ port->autobaud_state = AB_BEGIN;
+
+ /* Reset the Delta Break bit in the UISR and Enable autobaud */
+ MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_BKCHGINT |
+ MCF5272_UART_UCR_ENAB);
+
+ /* Enable autobaud completion interrupt */
+ port->imr_mirror |= MCF5272_UART_UIMR_ABC;
+ /* Disable the delta break interrupt so we can't receive
+ anymore break interrupt.
+ */
+ port->imr_mirror &= ~MCF5272_UART_UIMR_DB;
+
+ }
+ break;
+
+ case AB_BEGIN:
+ if (isr & MCF5272_UART_UISR_ABC)
+ {
+ int count;
+ // Retrieve the baudrate that we're using now.
+ u16_t divider = (port->base->uabu << 8) + port->base->uabl;
+ // Search in the list to find a match.
+ for (count = sizeof(dividers_table)/sizeof(unsigned long) - 1;
+ count >= 0;
+ count--)
+ {
+ if (divider < dividers_table[count]) break;
+ }
+
+ // Set the baud.
+ port->config.baud = count;
+
+ /* Autobaud completion */
+ port->autobaud_state = AB_IDLE;
+
+ /* Disable autobaud */
+ MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_NONE);
+
+ /* Ignore autobaud completion interrupt. */
+ port->imr_mirror &= ~MCF5272_UART_UIMR_ABC;
+
+ /* Reenable begin break change and receive interrupt. */
+ port->imr_mirror |= MCF5272_UART_UIMR_DB;
+
+ }
+ break;
+
+ }
+
+
+ /* Receive character interrupt */
+ if ((isr & MCF5272_UART_UISR_RXRDY))
+ /* Ignore all receive interrupt when we're autobauding. */
+ {
+ // Read all the characters in the fifo.
+ while ((MCF5272_UART_READ(port->base->uisr_uimr) & MCF5272_UART_UISR_RXRDY))
+ {
+ char c;
+ /* Read the character from the UART. */
+ c = MCF5272_UART_READ(port->base->urb_utb);
+ /* Pass the read character to the upper layer. */
+ (chan->callbacks->rcv_char)(chan, c);
+ }
+ }
+
+ /* Transmit complete interrupt */
+
+ if ((isr & MCF5272_UART_UISR_TXRDY))
+ {
+
+ /* Transmit holding register is empty */
+ (chan->callbacks->xmt_char)(chan);
+
+ }
+
+ }
+
+ /* Unmask all the DUART interrupts that were masked in the ISR, so */
+ /* that we can receive the next interrupt. */
+
+ MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
+
+}
+
+#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
+unsigned long MCF5272_uart_get_channel_0_baud_rate()
+{
+ /* return the baud rate for the first serial port */
+
+ return baud_rates_table[MCF5272_uart_channel_info_0.config.baud];
+}
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
+unsigned long MCF5272_uart_get_channel_1_baud_rate()
+{
+ /* return the baud rate for the second serial port */
+
+ return baud_rates_table[MCF5272_uart_channel_info_1.config.baud];
+}
+#endif
+
+
diff --git a/ecos/packages/devs/serial/mips/atlas/current/ChangeLog b/ecos/packages/devs/serial/mips/atlas/current/ChangeLog
new file mode 100644
index 0000000..7c6ef46
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/atlas/current/ChangeLog
@@ -0,0 +1,43 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_mips_atlas.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_mips_atlas.cdl:
+ Fix 234000->230400 typo.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/atlas_serial.c (atlas_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-07-14 Drew Moseley <dmoseley@redhat.com>
+
+ * cdl/ser_mips_atlas.cdl: New file. Implement a serial driver for the mips Atlas board
+ * src/atlas_serial.c: Ditto.
+ * src/atlas_serial.h: Ditto.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/mips/atlas/current/cdl/ser_mips_atlas.cdl b/ecos/packages/devs/serial/mips/atlas/current/cdl/ser_mips_atlas.cdl
new file mode 100644
index 0000000..68d5d0e
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/atlas/current/cdl/ser_mips_atlas.cdl
@@ -0,0 +1,157 @@
+# ====================================================================
+#
+# ser_mips_atlas.cdl
+#
+# eCos serial MIPS/ATLAS configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): dmoseley
+# Original data: gthomas
+# Contributors:
+# Date: 2000-06-23
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_MIPS_ATLAS {
+ display "MIPS ATLAS serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_MIPS_ATLAS
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+# include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ MIPS ATLAS."
+
+ compile -library=libextras.a atlas_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_mips_atlas.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+# FIXME: Bad name
+cdl_option CYGPKG_IO_SERIAL_MIPS_ATLAS_POLLED_MODE {
+ display "MIPS ATLAS polled mode serial drivers"
+ flavor bool
+ default_value 0
+ description "
+ If asserted, this option specifies that the serial device
+ drivers for the MIPS ATLAS should be polled-mode instead of
+ interrupt driven."
+}
+
+cdl_component CYGPKG_IO_SERIAL_MIPS_ATLAS_SERIAL_A {
+ display "MIPS ATLAS serial port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the 16C550C on the
+ MIPS ATLAS."
+
+ cdl_option CYGDAT_IO_SERIAL_MIPS_ATLAS_SERIAL_A_NAME {
+ display "Device name for MIPS ATLAS serial port"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the device name on the MIPS ATLAS."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_ATLAS_SERIAL_A_BAUD {
+ display "Baud rate for the MIPS ATLAS serial port driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ MIPS ATLAS 16c550c port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_ATLAS_SERIAL_A_BUFSIZE {
+ display "Buffer size for the MIPS ATLAS serial port driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 512
+ description "
+ This option specifies the size of the internal buffers used
+ for the MIPS ATLAS 16c550c port."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_MIPS_ATLAS_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_MIPS_ATLAS_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_MIPS_ATLAS_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_mips_atlas.cdl
diff --git a/ecos/packages/devs/serial/mips/atlas/current/src/atlas_serial.c b/ecos/packages/devs/serial/mips/atlas/current/src/atlas_serial.c
new file mode 100644
index 0000000..df264ed
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/atlas/current/src/atlas_serial.c
@@ -0,0 +1,372 @@
+//==========================================================================
+//
+// atlas_serial.c
+//
+// Serial device driver for ATLAS on-chip serial devices
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dmoseley, based on POWERPC driver by jskov
+// Contributors: gthomas, jskov, dmoseley
+// Date: 2000-06-23
+// Purpose: ATLAS serial device driver
+// Description: ATLAS serial device driver
+//
+// To Do:
+// Put in magic to effectively use the FIFOs. Transmitter FIFO fill is a
+// problem, and setting receiver FIFO interrupts to happen only after
+// n chars may conflict with hal diag.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+
+#ifdef CYGPKG_IO_SERIAL_MIPS_ATLAS
+
+#include "atlas_serial.h"
+
+typedef struct atlas_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+ cyg_uint8 iir;
+} atlas_serial_info;
+
+static bool atlas_serial_init(struct cyg_devtab_entry *tab);
+static bool atlas_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo atlas_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char atlas_serial_getc(serial_channel *chan);
+static Cyg_ErrNo atlas_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void atlas_serial_start_xmit(serial_channel *chan);
+static void atlas_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 atlas_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void atlas_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(atlas_serial_funs,
+ atlas_serial_putc,
+ atlas_serial_getc,
+ atlas_serial_set_config,
+ atlas_serial_start_xmit,
+ atlas_serial_stop_xmit
+ );
+
+static atlas_serial_info atlas_serial_info0 ={ATLAS_SER_16550_BASE_A,
+ CYGNUM_HAL_INTERRUPT_SER};
+
+#if CYGNUM_IO_SERIAL_MIPS_ATLAS_SERIAL_A_BUFSIZE > 0
+static unsigned char atlas_serial_out_buf0[CYGNUM_IO_SERIAL_MIPS_ATLAS_SERIAL_A_BUFSIZE];
+static unsigned char atlas_serial_in_buf0[CYGNUM_IO_SERIAL_MIPS_ATLAS_SERIAL_A_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(atlas_serial_channel0,
+ atlas_serial_funs,
+ atlas_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_ATLAS_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &atlas_serial_out_buf0[0],
+ sizeof(atlas_serial_out_buf0),
+ &atlas_serial_in_buf0[0],
+ sizeof(atlas_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(atlas_serial_channel0,
+ atlas_serial_funs,
+ atlas_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_ATLAS_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(atlas_serial_io0,
+ CYGDAT_IO_SERIAL_MIPS_ATLAS_SERIAL_A_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ atlas_serial_init,
+ atlas_serial_lookup, // Serial driver may need initializing
+ &atlas_serial_channel0
+ );
+
+
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+atlas_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ atlas_serial_info *atlas_chan = (atlas_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = atlas_chan->base;
+ cyg_uint16 baud_divisor = select_baud[new_config->baud];
+ cyg_uint8 _lcr, _ier;
+
+ if (baud_divisor == 0)
+ return false; // Invalid baud rate selected
+
+ //
+ // We may need to increase the timeout before causing a break reset.
+ // According to the Atlas Users Manual (Document MD00005) The BRKRES
+ // register will need to be programmed with a value larger that 0xA (the default)
+ // if we are going to use a baud rate lower than 2400.
+ //
+ if (new_config->baud <= CYGNUM_SERIAL_BAUD_2400)
+ {
+ // For now, just disable the break reset entirely.
+ HAL_WRITE_UINT32(HAL_ATLAS_BRKRES, 0);
+ } else {
+ // Put the break reset state back to the default
+ HAL_WRITE_UINT32(HAL_ATLAS_BRKRES, HAL_ATLAS_BRKRES_DEFAULT_VALUE);
+ }
+
+ // Disable port interrupts while changing hardware
+ HAL_READ_UINT8(port+SER_16550_IER, _ier);
+ HAL_WRITE_UINT8(port+SER_16550_IER, 0);
+
+ // Set databits, stopbits and parity.
+ _lcr = select_word_length[(new_config->word_length -
+ CYGNUM_SERIAL_WORD_LENGTH_5)] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr);
+
+ // Set baud rate.
+ _lcr |= LCR_DL;
+ HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr);
+ HAL_WRITE_UINT8(port+SER_16550_DLM, baud_divisor >> 8);
+ HAL_WRITE_UINT8(port+SER_16550_DLL, baud_divisor & 0xff);
+ _lcr &= ~LCR_DL;
+ HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr);
+
+ if (init) {
+ // Enable and clear FIFO
+ HAL_WRITE_UINT8(port+SER_16550_FCR,
+ (FCR_ENABLE | FCR_CLEAR_RCVR | FCR_CLEAR_XMIT));
+
+ if (chan->out_cbuf.len != 0) {
+ HAL_WRITE_UINT8(port+SER_16550_IER, SIO_IER_ERDAI);
+ } else {
+ HAL_WRITE_UINT8(port+SER_16550_IER, 0);
+ }
+ } else {
+ HAL_WRITE_UINT8(port+SER_16550_IER, _ier);
+ }
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+atlas_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ atlas_serial_info *atlas_chan = (atlas_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("ATLAS SERIAL init - dev: %x.%d\n", atlas_chan->base, atlas_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(atlas_chan->int_num,
+ 0, // can change IRQ0 priority
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ atlas_serial_ISR,
+ atlas_serial_DSR,
+ &atlas_chan->serial_interrupt_handle,
+ &atlas_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(atlas_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(atlas_chan->int_num);
+ }
+ atlas_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+atlas_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+atlas_serial_putc(serial_channel *chan, unsigned char c)
+{
+ atlas_serial_info *atlas_chan = (atlas_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = atlas_chan->base;
+ cyg_uint8 _lsr;
+
+ HAL_READ_UINT8(port+SER_16550_LSR, _lsr);
+ if (_lsr & SIO_LSR_THRE) {
+ // Transmit buffer is empty
+ HAL_WRITE_UINT8(port+SER_16550_THR, c);
+ return true;
+ } else {
+ // No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+atlas_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ atlas_serial_info *atlas_chan = (atlas_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = atlas_chan->base;
+ cyg_uint8 _lsr;
+
+ do {
+ HAL_READ_UINT8(port+SER_16550_LSR, _lsr);
+ } while ((_lsr & SIO_LSR_DR) == 0);
+ HAL_READ_UINT8(port+SER_16550_RBR, c);
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+atlas_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != atlas_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+atlas_serial_start_xmit(serial_channel *chan)
+{
+ atlas_serial_info *atlas_chan = (atlas_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = atlas_chan->base;
+ cyg_uint8 _ier;
+
+ HAL_READ_UINT8(port+SER_16550_IER, _ier);
+ _ier |= IER_XMT; // Enable xmit interrupt
+ HAL_WRITE_UINT8(port+SER_16550_IER, _ier);
+
+ // We should not need to call this here. THRE Interrupts are enabled, and the DSR
+ // below calls this function. However, sometimes we get called with Master Interrupts
+ // disabled, and thus the DSR never runs. This is unfortunate because it means we
+ // will be doing multiple processing steps for the same thing.
+ (chan->callbacks->xmt_char)(chan);
+}
+
+// Disable the transmitter on the device
+static void
+atlas_serial_stop_xmit(serial_channel *chan)
+{
+ atlas_serial_info *atlas_chan = (atlas_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = atlas_chan->base;
+ cyg_uint8 _ier;
+
+ HAL_READ_UINT8(port+SER_16550_IER, _ier);
+ _ier &= ~IER_XMT; // Disable xmit interrupt
+ HAL_WRITE_UINT8(port+SER_16550_IER, _ier);
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+atlas_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ atlas_serial_info *atlas_chan = (atlas_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(atlas_chan->int_num);
+ cyg_drv_interrupt_acknowledge(atlas_chan->int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+atlas_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ atlas_serial_info *atlas_chan = (atlas_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = atlas_chan->base;
+ cyg_uint8 _iir;
+
+ HAL_READ_UINT8(port+SER_16550_IIR, _iir);
+ _iir &= SIO_IIR_ID_MASK;
+ if ( ISR_Tx_Empty == _iir ) {
+ (chan->callbacks->xmt_char)(chan);
+ } else if (( ISR_Rx_Avail == _iir ) || ( ISR_Rx_Char_Timeout == _iir )) {
+ cyg_uint8 _c;
+ HAL_READ_UINT8(port+SER_16550_RBR, _c);
+ (chan->callbacks->rcv_char)(chan, _c);
+ }
+
+ cyg_drv_interrupt_unmask(atlas_chan->int_num);
+}
+
+#endif
+
+//-------------------------------------------------------------------------
+// EOF atlas_serial.c
diff --git a/ecos/packages/devs/serial/mips/atlas/current/src/atlas_serial.h b/ecos/packages/devs/serial/mips/atlas/current/src/atlas_serial.h
new file mode 100644
index 0000000..1b78b9d
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/atlas/current/src/atlas_serial.h
@@ -0,0 +1,213 @@
+//==========================================================================
+//
+// io/serial/mips/atlas/atlas_serial.h
+//
+// MIPS Atlas Serial I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dmoseley, based on PowerPC driver by jskov
+// Contributors:gthomas, jskov, dmoseley
+// Date: 2000-06-23
+// Purpose: Atlas Serial definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// Description of serial ports on Atlas board
+
+// Interrupt Enable Register
+#define IER_RCV 0x01
+#define IER_XMT 0x02
+#define IER_LS 0x04
+#define IER_MS 0x08
+
+// Line Control Register
+#define LCR_WL5 0x00 // Word length
+#define LCR_WL6 0x01
+#define LCR_WL7 0x02
+#define LCR_WL8 0x03
+#define LCR_SB1 0x00 // Number of stop bits
+#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words
+#define LCR_SB2 0x04
+#define LCR_PN 0x00 // Parity mode - none
+#define LCR_PE 0x0C // Parity mode - even
+#define LCR_PO 0x08 // Parity mode - odd
+#define LCR_PM 0x28 // Forced "mark" parity
+#define LCR_PS 0x38 // Forced "space" parity
+#define LCR_DL 0x80 // Enable baud rate latch
+
+// Line Status Register
+#define LSR_RSR 0x01
+#define LSR_THE 0x20
+
+// Modem Control Register
+#define MCR_DTR 0x01
+#define MCR_RTS 0x02
+#define MCR_INT 0x08 // Enable interrupts
+
+// Interrupt status register
+#define ISR_None 0x01
+#define ISR_Rx_Line_Status 0x06
+#define ISR_Rx_Avail 0x04
+#define ISR_Rx_Char_Timeout 0x0C
+#define ISR_Tx_Empty 0x02
+#define IRS_Modem_Status 0x00
+
+// FIFO control register
+#define FCR_ENABLE 0x01
+#define FCR_CLEAR_RCVR 0x02
+#define FCR_CLEAR_XMIT 0x04
+
+
+////////////////////////////////////////////////////////////
+// Clean this up.
+
+#define ATLAS_SER_16550_BASE_A 0xBF000900
+#define SER_16550_BASE ATLAS_SER_16550_BASE_A
+
+//-----------------------------------------------------------------------------
+// Define the serial registers. The Atlas board is equipped with a 16550C
+// serial chip.
+#define SER_16550_RBR 0x00 // receiver buffer register, read, dlab = 0
+#define SER_16550_THR 0x00 // transmitter holding register, write, dlab = 0
+#define SER_16550_DLL 0x00 // divisor latch (LS), read/write, dlab = 1
+#define SER_16550_IER 0x08 // interrupt enable register, read/write, dlab = 0
+#define SER_16550_DLM 0x08 // divisor latch (MS), read/write, dlab = 1
+#define SER_16550_IIR 0x10 // interrupt identification reg, read, dlab = 0
+#define SER_16550_FCR 0x10 // fifo control register, write, dlab = 0
+#define SER_16550_AFR 0x10 // alternate function reg, read/write, dlab = 1
+#define SER_16550_LCR 0x18 // line control register, read/write
+#define SER_16550_MCR 0x20 // modem control register, read/write
+#define SER_16550_LSR 0x28 // line status register, read
+#define SER_16550_MSR 0x30 // modem status register, read
+#define SER_16550_SCR 0x38 // scratch pad register
+
+// The interrupt enable register bits.
+#define SIO_IER_ERDAI 0x01 // enable received data available irq
+#define SIO_IER_ETHREI 0x02 // enable THR empty interrupt
+#define SIO_IER_ELSI 0x04 // enable receiver line status irq
+#define SIO_IER_EMSI 0x08 // enable modem status interrupt
+
+// The interrupt identification register bits.
+#define SIO_IIR_IP 0x01 // 0 if interrupt pending
+#define SIO_IIR_ID_MASK 0x0e // mask for interrupt ID bits
+
+// The line status register bits.
+#define SIO_LSR_DR 0x01 // data ready
+#define SIO_LSR_OE 0x02 // overrun error
+#define SIO_LSR_PE 0x04 // parity error
+#define SIO_LSR_FE 0x08 // framing error
+#define SIO_LSR_BI 0x10 // break interrupt
+#define SIO_LSR_THRE 0x20 // transmitter holding register empty
+#define SIO_LSR_TEMT 0x40 // transmitter register empty
+#define SIO_LSR_ERR 0x80 // any error condition
+
+// The modem status register bits.
+#define SIO_MSR_DCTS 0x01 // delta clear to send
+#define SIO_MSR_DDSR 0x02 // delta data set ready
+#define SIO_MSR_TERI 0x04 // trailing edge ring indicator
+#define SIO_MSR_DDCD 0x08 // delta data carrier detect
+#define SIO_MSR_CTS 0x10 // clear to send
+#define SIO_MSR_DSR 0x20 // data set ready
+#define SIO_MSR_RI 0x40 // ring indicator
+#define SIO_MSR_DCD 0x80 // data carrier detect
+
+// The line control register bits.
+#define SIO_LCR_WLS0 0x01 // word length select bit 0
+#define SIO_LCR_WLS1 0x02 // word length select bit 1
+#define SIO_LCR_STB 0x04 // number of stop bits
+#define SIO_LCR_PEN 0x08 // parity enable
+#define SIO_LCR_EPS 0x10 // even parity select
+#define SIO_LCR_SP 0x20 // stick parity
+#define SIO_LCR_SB 0x40 // set break
+#define SIO_LCR_DLAB 0x80 // divisor latch access bit
+
+// The FIFO control register
+#define SIO_FCR_FCR0 0x01 // enable xmit and rcvr fifos
+#define SIO_FCR_FCR1 0x02 // clear RCVR FIFO
+#define SIO_FCR_FCR2 0x04 // clear XMIT FIFO
+/////////////////////////////////////////
+
+
+static unsigned char select_word_length[] = {
+ LCR_WL5, // 5 bits / word (char)
+ LCR_WL6,
+ LCR_WL7,
+ LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ LCR_SB1, // 1 stop bit
+ LCR_SB1_5, // 1.5 stop bit
+ LCR_SB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ LCR_PN, // No parity
+ LCR_PE, // Even parity
+ LCR_PO, // Odd parity
+ LCR_PM, // Mark parity
+ LCR_PS, // Space parity
+};
+
+// FIXME: calc all properly
+// The Atlas board has a 3.6864 MHz crystal
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 2094, // 110
+ 0, // 134.5
+ 1536, // 150
+ 0, // 200
+ 768, // 300
+ 384, // 600
+ 192, // 1200
+ 0, // 1800
+ 96, // 2400
+ 0, // 3600
+ 48, // 4800
+ 32, // 7200
+ 24, // 9600
+ 16, // 14400
+ 12, // 19200
+ 6, // 38400
+ 4, // 57600
+ 2, // 115200
+ 1, // 230400
+};
+
diff --git a/ecos/packages/devs/serial/mips/idt79s334a/current/ChangeLog b/ecos/packages/devs/serial/mips/idt79s334a/current/ChangeLog
new file mode 100644
index 0000000..01c0c41
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/idt79s334a/current/ChangeLog
@@ -0,0 +1,38 @@
+2003-03-09 Tim Michals <t.michals@attbi.com>
+
+ * cdl/ser_mipsidt_334a.cdl: Add configuration for second serial port.
+ * src/mipsidt_serial.c: Updated support for dual serial ports
+ * src/mipsidt_serial.h: Add some helpful extra defines for debug.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_mipsidt_334a.cdl: Remove irrelevant doc link.
+
+2003-02-13 Tim Michals <t.michals@attbi.com>
+2003-02-13 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * New package - support for MIPS IDT 79s334a board.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/mips/idt79s334a/current/cdl/ser_mipsidt_334a.cdl b/ecos/packages/devs/serial/mips/idt79s334a/current/cdl/ser_mipsidt_334a.cdl
new file mode 100644
index 0000000..b3748d5
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/idt79s334a/current/cdl/ser_mipsidt_334a.cdl
@@ -0,0 +1,196 @@
+# ====================================================================
+#
+# ser_mipsidt_334a.cdl
+#
+# eCos serial MIPS/IDT 334a reference platform configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): tmichals
+# Original data: dmoseley
+# Contributors:
+# Date: 2003-02-13
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_MIPS_IDT79S334A {
+ display "MIPS IDT79RC32344 reference platform serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_MIPS_IDT32334
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+# include_files ; # none _exported_ whatsoever
+ description "
+ This package contains the serial device drivers for the
+ MIPS IDT79RC32334 reference platform."
+
+ compile -library=libextras.a mipsidt_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_mips_idt79s334a.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+
+cdl_option CYGPKG_IO_SERIAL_MIPS_POLLED_MODE {
+ display "MIPS IDT polled mode serial drivers"
+ flavor bool
+ default_value 0
+ description "
+ If asserted, this option specifies that the serial device
+ drivers for the MIPS should be polled-mode instead of
+ interrupt driven."
+}
+
+cdl_component CYGPKG_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A {
+ display "MIPS IDT79S334A serial port driver 0"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the 16C550 on the
+ MIPS IDT79S334A."
+
+ cdl_option CYGDAT_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A_NAME {
+ display "Device name for MIPS IDT79S334A serial port 0"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the device name on the MIPS IDT79S334A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A_BAUD {
+ display "Baud rate for the MIPS IDT79S334A serial port driver 0"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 115200
+ description "
+ This option specifies the default baud rate (speed) for the
+ MIPS 16c550 port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A_BUFSIZE {
+ display "Buffer size for the MIPS IDT79S334A serial port driver 0"
+ flavor data
+ legal_values 0 to 8192
+ default_value 512
+ description "
+ This option specifies the size of the internal buffers used
+ for the MIPS IDT79S334A 16c550c port."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B {
+ display "MIPS IDT79S334A serial port driver 1"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the 16C550 on the
+ MIPS IDT79S334A."
+
+ cdl_option CYGDAT_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B_NAME {
+ display "Device name for MIPS IDT79S334A serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name on the MIPS IDT79S334A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B_BAUD {
+ display "Baud rate for the MIPS IDT79S334A serial port driver 1"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 115200
+ description "
+ This option specifies the default baud rate (speed) for the
+ MIPS 16c550 port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B_BUFSIZE {
+ display "Buffer size for the MIPS IDT79S334A serial port driver 1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 512
+ description "
+ This option specifies the size of the internal buffers used
+ for the MIPS IDT79S334A 16c550c port."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_MIPS_IDT79S334A_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_MIPS_IDT79S334A_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_MIPS_IDT79S334A_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_mipsidt_334A.cdl
diff --git a/ecos/packages/devs/serial/mips/idt79s334a/current/src/mipsidt_serial.c b/ecos/packages/devs/serial/mips/idt79s334a/current/src/mipsidt_serial.c
new file mode 100755
index 0000000..6943c64
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/idt79s334a/current/src/mipsidt_serial.c
@@ -0,0 +1,409 @@
+//==========================================================================
+//
+// mipsidt_serial.c
+//
+// Serial device driver for MIPS IDT79s334a reference platform on-chip serial devices
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): tmichals based on driver by dmoseley, based on POWERPC driver by jskov
+// Contributors: gthomas, jskov, dmoseley, tmichals
+// Date: 2003-02-13
+// Purpose: MIPS IDT79s334a reference platform serial device driver
+// Description: IDT MIPS serial device driver
+//
+// To Do:
+// Put in magic to effectively use the FIFOs. Transmitter FIFO fill is a
+// problem, and setting receiver FIFO interrupts to happen only after
+// n chars may conflict with hal diag.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+
+#ifdef CYGPKG_IO_SERIAL_MIPS_IDT79S334A
+
+#include "mipsidt_serial.h"
+
+typedef struct mipsidt_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+ cyg_uint8 iir;
+} mipsidt_serial_info;
+
+static bool mipsidt_serial_init(struct cyg_devtab_entry *tab);
+static bool mipsidt_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo mipsidt_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char mipsidt_serial_getc(serial_channel *chan);
+static Cyg_ErrNo mipsidt_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void mipsidt_serial_start_xmit(serial_channel *chan);
+static void mipsidt_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 mipsidt_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void mipsidt_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(mipsidt_serial_funs,
+ mipsidt_serial_putc,
+ mipsidt_serial_getc,
+ mipsidt_serial_set_config,
+ mipsidt_serial_start_xmit,
+ mipsidt_serial_stop_xmit
+ );
+
+
+#ifdef CYGPKG_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A
+static mipsidt_serial_info mipsidt_serial_info0 ={IDTMIPS_SER_16550_BASE_A,
+ CYGNUM_HAL_INTERRUPT_SIO_0};
+
+#if CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A_BUFSIZE > 0
+static unsigned char mipsidt_serial_out_buf0[CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A_BUFSIZE];
+static unsigned char mipsidt_serial_in_buf0[CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mipsidt_serial_channel0,
+ mipsidt_serial_funs,
+ mipsidt_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mipsidt_serial_out_buf0[0],
+ sizeof(mipsidt_serial_out_buf0),
+ &mipsidt_serial_in_buf0[0],
+ sizeof(mipsidt_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(mipsidt_serial_channel0,
+ mipsidt_serial_funs,
+ mipsidt_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(mipsidt_serial_io0,
+ CYGDAT_IO_SERIAL_MIPS_IDT79S334A_SERIAL_A_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mipsidt_serial_init,
+ mipsidt_serial_lookup, // Serial driver may need initializing
+ &mipsidt_serial_channel0
+ );
+
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B
+static mipsidt_serial_info mipsidt_serial_info1 ={IDTMIPS_SER_16550_BASE_B,
+ CYGNUM_HAL_INTERRUPT_SIO_1};
+
+#if CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B_BUFSIZE > 0
+static unsigned char mipsidt_serial_out_buf1[CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B_BUFSIZE];
+static unsigned char mipsidt_serial_in_buf1[CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mipsidt_serial_channel1,
+ mipsidt_serial_funs,
+ mipsidt_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mipsidt_serial_out_buf1[0],
+ sizeof(mipsidt_serial_out_buf1),
+ &mipsidt_serial_in_buf1[0],
+ sizeof(mipsidt_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(mipsidt_serial_channel1,
+ mipsidt_serial_funs,
+ mipsidt_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(mipsidt_serial_io1,
+ CYGDAT_IO_SERIAL_MIPS_IDT79S334A_SERIAL_B_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mipsidt_serial_init,
+ mipsidt_serial_lookup, // Serial driver may need initializing
+ &mipsidt_serial_channel1
+ );
+
+#endif
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+mipsidt_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ mipsidt_serial_info *mipsidt_chan = (mipsidt_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mipsidt_chan->base;
+ cyg_uint32 baud_divisor = select_baud[new_config->baud]; ;
+ cyg_uint8 _lcr, _ier;
+
+ if (baud_divisor == 0)
+ return false; // Invalid baud rate selected
+
+ baud_divisor = (CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL * 10) / (16 * select_baud[new_config->baud]);
+
+ baud_divisor +=5;
+ baud_divisor = ((cyg_int32)baud_divisor) / 10;
+
+
+ // Disable port interrupts while changing hardware
+ HAL_READ_UINT8(port+SER_16550_IER, _ier);
+ HAL_WRITE_UINT8(port+SER_16550_IER, 0);
+
+ // Set databits, stopbits and parity.
+ _lcr = select_word_length[(new_config->word_length -
+ CYGNUM_SERIAL_WORD_LENGTH_5)] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr);
+
+ // Set baud rate.
+ _lcr |= LCR_DL;
+ HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr);
+ HAL_WRITE_UINT8(port+SER_16550_DLM, baud_divisor >> 8);
+ HAL_WRITE_UINT8(port+SER_16550_DLL, baud_divisor & 0xff);
+ _lcr &= ~LCR_DL;
+ HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr);
+
+ if (init) {
+ // Enable and clear FIFO
+ HAL_WRITE_UINT8(port+SER_16550_FCR,
+ (FCR_ENABLE | FCR_CLEAR_RCVR | FCR_CLEAR_XMIT));
+
+ if (chan->out_cbuf.len != 0) {
+ HAL_WRITE_UINT8(port+SER_16550_IER, SIO_IER_ERDAI);
+ } else {
+ HAL_WRITE_UINT8(port+SER_16550_IER, 0);
+ }
+ } else {
+ HAL_WRITE_UINT8(port+SER_16550_IER, _ier);
+ }
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+mipsidt_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ mipsidt_serial_info *mipsidt_chan = (mipsidt_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("IDT SERIAL init - dev: %x.%d\n", mipsidt_chan->base, mipsidt_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(mipsidt_chan->int_num,
+ 0, // can change IRQ0 priority
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ mipsidt_serial_ISR,
+ mipsidt_serial_DSR,
+ &mipsidt_chan->serial_interrupt_handle,
+ &mipsidt_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(mipsidt_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(mipsidt_chan->int_num);
+ }
+ mipsidt_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+mipsidt_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+mipsidt_serial_putc(serial_channel *chan, unsigned char c)
+{
+ mipsidt_serial_info *mipsidt_chan = (mipsidt_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mipsidt_chan->base;
+ cyg_uint8 _lsr;
+
+ HAL_READ_UINT8(port+SER_16550_LSR, _lsr);
+ if (((_lsr & (SIO_LSR_THRE | SIO_LSR_TEMT)) == 0x60)) {
+ // Transmit buffer is empty
+ HAL_WRITE_UINT8(port+SER_16550_THR, c);
+ return true;
+ } else {
+ // No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+mipsidt_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ mipsidt_serial_info *mipsidt_chan = (mipsidt_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mipsidt_chan->base;
+ cyg_uint8 _lsr;
+
+ do {
+ HAL_READ_UINT8(port+SER_16550_LSR, _lsr);
+ } while ((_lsr & SIO_LSR_DR) == 0);
+ HAL_READ_UINT8(port+SER_16550_RBR, c);
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+mipsidt_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != mipsidt_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+mipsidt_serial_start_xmit(serial_channel *chan)
+{
+ mipsidt_serial_info *mipsidt_chan = (mipsidt_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mipsidt_chan->base;
+ cyg_uint8 _ier;
+
+ HAL_READ_UINT8(port+SER_16550_IER, _ier);
+ _ier |= IER_XMT; // Enable xmit interrupt
+ HAL_WRITE_UINT8(port+SER_16550_IER, _ier);
+
+ // We should not need to call this here. THRE Interrupts are enabled, and the DSR
+ // below calls this function. However, sometimes we get called with Master Interrupts
+ // disabled, and thus the DSR never runs. This is unfortunate because it means we
+ // will be doing multiple processing steps for the same thing.
+ (chan->callbacks->xmt_char)(chan);
+}
+
+// Disable the transmitter on the device
+static void
+mipsidt_serial_stop_xmit(serial_channel *chan)
+{
+ mipsidt_serial_info *mipsidt_chan = (mipsidt_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mipsidt_chan->base;
+ cyg_uint8 _ier;
+
+ HAL_READ_UINT8(port+SER_16550_IER, _ier);
+ _ier &= ~IER_XMT; // Disable xmit interrupt
+ HAL_WRITE_UINT8(port+SER_16550_IER, _ier);
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+mipsidt_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mipsidt_serial_info *mipsidt_chan = (mipsidt_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mipsidt_chan->int_num);
+ cyg_drv_interrupt_acknowledge(mipsidt_chan->int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+mipsidt_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mipsidt_serial_info *mipsidt_chan = (mipsidt_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mipsidt_chan->base;
+ cyg_uint8 _iir;
+
+ HAL_READ_UINT8(port+SER_16550_IIR, _iir);
+ _iir &= SIO_IIR_ID_MASK;
+ if ( ISR_Tx_Empty == _iir ) {
+ (chan->callbacks->xmt_char)(chan);
+ } else if (( ISR_Rx_Avail == _iir ) || ( ISR_Rx_Char_Timeout == _iir )) {
+ cyg_uint8 _c;
+ HAL_READ_UINT8(port+SER_16550_RBR, _c);
+ (chan->callbacks->rcv_char)(chan, _c);
+ }
+
+ cyg_drv_interrupt_unmask(mipsidt_chan->int_num);
+}
+
+#endif
+
+//-------------------------------------------------------------------------
+// EOF mipsidt_serial.c
diff --git a/ecos/packages/devs/serial/mips/idt79s334a/current/src/mipsidt_serial.h b/ecos/packages/devs/serial/mips/idt79s334a/current/src/mipsidt_serial.h
new file mode 100755
index 0000000..7975d78
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/idt79s334a/current/src/mipsidt_serial.h
@@ -0,0 +1,218 @@
+//==========================================================================
+//
+// io/serial/mips/idt79s334a/mipsidt_serial.h
+//
+// MIPS IDT79S334A Serial I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): tmichals based on driver by dmoseley, based on POWERPC driver by jskov
+// Contributors: gthomas, jskov, dmoseley, tmichals
+// Date: 2003-02-13
+// Date: 2003-02-13
+// Purpose: MIPS IDT79s334a reference platform serial device driver definitions.
+// Description: IDT MIPS serial device driver definitions.
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// Description of serial ports on IDT board
+
+// Interrupt Enable Register
+#define IER_RCV 0x01
+#define IER_XMT 0x02
+#define IER_LS 0x04
+#define IER_MS 0x08
+
+// Line Control Register
+#define LCR_WL5 0x00 // Word length
+#define LCR_WL6 0x01
+#define LCR_WL7 0x02
+#define LCR_WL8 0x03
+#define LCR_SB1 0x00 // Number of stop bits
+#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words
+#define LCR_SB2 0x04
+#define LCR_PN 0x00 // Parity mode - none
+#define LCR_PE 0x0C // Parity mode - even
+#define LCR_PO 0x08 // Parity mode - odd
+#define LCR_PM 0x28 // Forced "mark" parity
+#define LCR_PS 0x38 // Forced "space" parity
+#define LCR_DL 0x80 // Enable baud rate latch
+
+// Line Status Register
+#define LSR_RSR 0x01
+#define LSR_THE 0x20
+
+// Modem Control Register
+#define MCR_DTR 0x01
+#define MCR_RTS 0x02
+#define MCR_INT 0x08 // Enable interrupts
+
+// Interrupt status register
+#define ISR_None 0x01
+#define ISR_Rx_Line_Status 0x06
+#define ISR_Rx_Avail 0x04
+#define ISR_Rx_Char_Timeout 0x0C
+#define ISR_Tx_Empty 0x02
+#define IRS_Modem_Status 0x00
+
+// FIFO control register
+#define FCR_ENABLE 0x01
+#define FCR_CLEAR_RCVR 0x02
+#define FCR_CLEAR_XMIT 0x04
+
+
+////////////////////////////////////////////////////////////
+// Clean this up.
+
+#define IDTMIPS_SER_16550_BASE_A 0xB8000803
+#define IDTMIPS_SER_16550_BASE_B 0xB8000823
+#define SER_16550_BASE IDTMIPS_SER_16550_BASE_A
+#define INTR_COM0_REG 0xB8000554
+#define INTR_COM1_REG 0xB8000564
+
+//-----------------------------------------------------------------------------
+// Define the serial registers. The IDT board is equipped with a 16550C
+// serial chip.
+#define SER_16550_RBR 0x00 // receiver buffer register, read, dlab = 0
+#define SER_16550_THR 0x00 // transmitter holding register, write, dlab = 0
+#define SER_16550_DLL 0x00 // divisor latch (LS), read/write, dlab = 1
+#define SER_16550_IER 0x04 // interrupt enable register, read/write, dlab = 0
+#define SER_16550_DLM 0x04 // divisor latch (MS), read/write, dlab = 1
+#define SER_16550_IIR 0x08 // interrupt identification reg, read, dlab = 0
+#define SER_16550_FCR 0x08 // fifo control register, write, dlab = 0
+#define SER_16550_AFR 0x08 // alternate function reg, read/write, dlab = 1
+#define SER_16550_LCR 0x0c // line control register, read/write
+#define SER_16550_MCR 0x10 // modem control register, read/write
+#define SER_16550_LSR 0x14 // line status register, read
+#define SER_16550_MSR 0x18 // modem status register, read
+#define SER_16550_SCR 0x1c // scratch pad register
+
+// The interrupt enable register bits.
+#define SIO_IER_ERDAI 0x01 // enable received data available irq
+#define SIO_IER_ETHREI 0x02 // enable THR empty interrupt
+#define SIO_IER_ELSI 0x04 // enable receiver line status irq
+#define SIO_IER_EMSI 0x08 // enable modem status interrupt
+
+// The interrupt identification register bits.
+#define SIO_IIR_IP 0x01 // 0 if interrupt pending
+#define SIO_IIR_ID_MASK 0x0e // mask for interrupt ID bits
+
+// The line status register bits.
+#define SIO_LSR_DR 0x01 // data ready
+#define SIO_LSR_OE 0x02 // overrun error
+#define SIO_LSR_PE 0x04 // parity error
+#define SIO_LSR_FE 0x08 // framing error
+#define SIO_LSR_BI 0x10 // break interrupt
+#define SIO_LSR_THRE 0x20 // transmitter holding register empty
+#define SIO_LSR_TEMT 0x40 // transmitter register empty
+#define SIO_LSR_ERR 0x80 // any error condition
+
+// The modem status register bits.
+#define SIO_MSR_DCTS 0x01 // delta clear to send
+#define SIO_MSR_DDSR 0x02 // delta data set ready
+#define SIO_MSR_TERI 0x04 // trailing edge ring indicator
+#define SIO_MSR_DDCD 0x08 // delta data carrier detect
+#define SIO_MSR_CTS 0x10 // clear to send
+#define SIO_MSR_DSR 0x20 // data set ready
+#define SIO_MSR_RI 0x40 // ring indicator
+#define SIO_MSR_DCD 0x80 // data carrier detect
+
+// The line control register bits.
+#define SIO_LCR_WLS0 0x01 // word length select bit 0
+#define SIO_LCR_WLS1 0x02 // word length select bit 1
+#define SIO_LCR_STB 0x04 // number of stop bits
+#define SIO_LCR_PEN 0x08 // parity enable
+#define SIO_LCR_EPS 0x10 // even parity select
+#define SIO_LCR_SP 0x20 // stick parity
+#define SIO_LCR_SB 0x40 // set break
+#define SIO_LCR_DLAB 0x80 // divisor latch access bit
+
+// The FIFO control register
+#define SIO_FCR_FCR0 0x01 // enable xmit and rcvr fifos
+#define SIO_FCR_FCR1 0x02 // clear RCVR FIFO
+#define SIO_FCR_FCR2 0x04 // clear XMIT FIFO
+/////////////////////////////////////////
+
+
+static unsigned char select_word_length[] = {
+ LCR_WL5, // 5 bits / word (char)
+ LCR_WL6,
+ LCR_WL7,
+ LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ LCR_SB1, // 1 stop bit
+ LCR_SB1_5, // 1.5 stop bit
+ LCR_SB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ LCR_PN, // No parity
+ LCR_PE, // Even parity
+ LCR_PO, // Odd parity
+ LCR_PM, // Mark parity
+ LCR_PS, // Space parity
+};
+
+
+static unsigned int select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 134, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 230400, // 230400
+};
+
+// EOF mipsidt_serial.h
diff --git a/ecos/packages/devs/serial/mips/jmr3904/current/ChangeLog b/ecos/packages/devs/serial/mips/jmr3904/current/ChangeLog
new file mode 100644
index 0000000..91f4a29
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/jmr3904/current/ChangeLog
@@ -0,0 +1,1185 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl:
+ Fix 234000->230400 typo.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Moved testing parameters here.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/tx3904_serial.c (tx3904_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_mips_jmr3904.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/mips/jmr3904/current/cdl/ser_mips_jmr3904.cdl b/ecos/packages/devs/serial/mips/jmr3904/current/cdl/ser_mips_jmr3904.cdl
new file mode 100644
index 0000000..cf922eb
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/jmr3904/current/cdl/ser_mips_jmr3904.cdl
@@ -0,0 +1,219 @@
+# ====================================================================
+#
+# ser_mips_jmr3904.cdl
+#
+# eCos serial MIPS/JMR3904 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-14
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_TX39_JMR3904 {
+ display "TX39 JMR3904 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_MIPS_TX39_JMR3904
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ TX39 JMR3904."
+
+ compile -library=libextras.a tx3904_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_tx39_jmr3904.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+# FIXME: Bad name
+cdl_option CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE {
+ display "TX39 JMR3904 polled mode serial drivers"
+ flavor bool
+ default_value 0
+ description "
+ If asserted, this option specifies that the serial device
+ drivers for the TX39 JMR3904 should be polled-mode instead of
+ interrupt driven."
+}
+
+cdl_component CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 {
+ display "TX39 JMR3904 serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for port 0 on the
+ TX39 JMR3904."
+
+ cdl_option CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL0_NAME {
+ display "Device name for TX39 JMR3904 serial port 0"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the device name port 0 on the TX39 JMR3904."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BAUD {
+ display "Baud rate for the TX39 JMR3904 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ TX39 JMR3904 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE {
+ display "Buffer size for the TX39 JMR3904 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the TX39 JMR3904 port 0."
+ }
+}
+cdl_component CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 {
+ display "TX39 JMR3904 serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for port 1 on
+ the TX39 JMR3904."
+
+ cdl_option CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL1_NAME {
+ display "Device name for TX39 JMR3904 serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name port 1 on the TX39 JMR3904."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BAUD {
+ display "Baud rate for the TX39 JMR3904 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ TX39 JMR3904 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE {
+ display "Buffer size for the TX39 JMR3904 serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the TX39 JMR3904 port 1."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_TX39_JMR3904_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_TX39_JMR3904_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_TX39_JMR3904_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_TX39_JMR3904_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_9600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_57600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+ implements CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN
+ implements CYGINT_IO_SERIAL_TEST_SKIP_STOP_2
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"tx39jmr\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_mips_jmr3904.cdl
diff --git a/ecos/packages/devs/serial/mips/jmr3904/current/src/tx3904_serial.c b/ecos/packages/devs/serial/mips/jmr3904/current/src/tx3904_serial.c
new file mode 100644
index 0000000..0552d65
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/jmr3904/current/src/tx3904_serial.c
@@ -0,0 +1,756 @@
+//==========================================================================
+//
+// tx3904_serial.c
+//
+// Serial device driver for TX3904 on-chip serial devices
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1999-03-3
+// Purpose: TX3904 serial device driver
+// Description: TX3904 serial device driver
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_serial.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+
+#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904
+
+cyg_bool cyg_hal_is_break(char *buf, int size);
+void cyg_hal_user_break( CYG_ADDRWORD *regs );
+
+//-------------------------------------------------------------------------
+
+extern void diag_printf(const char *fmt, ...);
+
+//-------------------------------------------------------------------------
+// Forward definitions
+
+static bool tx3904_serial_init(struct cyg_devtab_entry *tab);
+static bool tx3904_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo tx3904_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char tx3904_serial_getc(serial_channel *chan);
+static Cyg_ErrNo tx3904_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void tx3904_serial_start_xmit(serial_channel *chan);
+static void tx3904_serial_stop_xmit(serial_channel *chan);
+
+#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE
+static cyg_uint32 tx3904_serial_ISR(cyg_vector_t vector, cyg_addrword_t data, cyg_addrword_t *regs);
+static void tx3904_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+#endif
+
+
+//-------------------------------------------------------------------------
+// TX3904 serial line control register values:
+
+// Offsets to serial control registers from base
+#define SERIAL_CR 0x00
+#define SERIAL_SR 0x04
+#define SERIAL_ICR 0x08
+#define SERIAL_ISR 0x0C
+#define SERIAL_FCR 0x10
+#define SERIAL_BRG 0x14
+#define SERIAL_TXB 0x20
+#define SERIAL_RXB 0x30
+
+// Status register bits
+#define ISR_RXRDY 0x01
+#define ISR_TXRDY 0x02
+#define ISR_ERROR 0x04
+
+// Control register bits
+#define LCR_SB1 0x0000
+#define LCR_SB1_5 0x0000
+#define LCR_SB2 0x0004
+#define LCR_PN 0x0000 // Parity mode - none
+#define LCR_PS 0x0000 // Forced "space" parity
+#define LCR_PM 0x0000 // Forced "mark" parity
+#define LCR_PE 0x0018 // Parity mode - even
+#define LCR_PO 0x0010 // Parity mode - odd
+#define LCR_WL5 0x0001 // not supported - use 7bit
+#define LCR_WL6 0x0001 // not supported - use 7bit
+#define LCR_WL7 0x0001 // 7 bit chars
+#define LCR_WL8 0x0000 // 8 bit chars
+
+#define LCR_BRG 0x0020 // Select baud rate generator
+
+#define ICR_RXE 0x0001 // receive enable
+#define ICR_TXE 0x0002 // transmit enable
+
+//-------------------------------------------------------------------------
+// Tables to map input values to hardware settings
+
+static unsigned char select_word_length[] = {
+ LCR_WL5, // 5 bits / word (char)
+ LCR_WL6,
+ LCR_WL7,
+ LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ LCR_SB1, // 1 stop bit
+ LCR_SB1_5, // 1.5 stop bit
+ LCR_SB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ LCR_PN, // No parity
+ LCR_PE, // Even parity
+ LCR_PO, // Odd parity
+ LCR_PM, // Mark parity
+ LCR_PS, // Space parity
+};
+
+// The values in this table plug straight into the BRG register
+// in the serial driver hardware. They comprise a baud rate divisor
+// in the bottom 8 bits and a clock selector in the top 8 bits.
+// These figures all come from Toshiba.
+
+#if (CYGHWR_HAL_MIPS_CPU_FREQ == 50)
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 0, // 110
+ 0, // 134.5
+ 0, // 150
+ 0, // 200
+ 0, // 300
+ 0x0300|20, // 600
+ 0x0300|10, // 1200
+ 0, // 1800
+ 0x0300|05, // 2400
+ 0, // 3600
+ 0x0300|10, // 4800
+ 0, // 7200
+ 0x0200|05, // 9600
+ 0, // 14400
+ 0x0100|10, // 19200
+ 0x0100|05, // 38400
+ 0, // 57600
+ 0, // 115200
+ 0, // 230400
+};
+
+#elif (CYGHWR_HAL_MIPS_CPU_FREQ == 66)
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 0, // 110
+ 0, // 134.5
+ 0, // 150
+ 0, // 200
+ 0, // 300
+ 0x0300|27, // 600
+ 0x0200|54, // 1200
+ 0, // 1800
+ 0x0200|27, // 2400
+ 0, // 3600
+ 0x0100|54, // 4800
+ 0, // 7200
+ 0x0100|27, // 9600
+ 0, // 14400
+ 0x0000|54, // 19200
+ 0x0000|27, // 38400
+ 0, // 57600
+ 0, // 115200
+ 0, // 230400
+};
+
+#else
+
+#error Unsupported CPU frequency
+
+#endif
+
+//-------------------------------------------------------------------------
+// Info for each serial device controlled
+
+typedef struct tx3904_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt interrupt;
+ cyg_handle_t interrupt_handle;
+ cyg_uint8 input_char;
+ cyg_bool input_char_valid;
+ cyg_bool output_ready;
+ cyg_uint16 cur_baud;
+} tx3904_serial_info;
+
+//-------------------------------------------------------------------------
+// Callback functions exported by this driver
+
+static SERIAL_FUNS(tx3904_serial_funs,
+ tx3904_serial_putc,
+ tx3904_serial_getc,
+ tx3904_serial_set_config,
+ tx3904_serial_start_xmit,
+ tx3904_serial_stop_xmit
+ );
+
+//-------------------------------------------------------------------------
+// Hardware info for each serial line
+
+#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0
+static tx3904_serial_info tx3904_serial_info0 = {
+ 0xFFFFF300,
+ CYGNUM_HAL_INTERRUPT_SIO_0
+};
+#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE > 0
+static unsigned char tx3904_serial_out_buf0[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE];
+static unsigned char tx3904_serial_in_buf0[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE];
+#endif
+#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1
+static tx3904_serial_info tx3904_serial_info1 = {
+ 0xFFFFF400,
+ CYGNUM_HAL_INTERRUPT_SIO_1
+};
+#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE > 0
+static unsigned char tx3904_serial_out_buf1[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE];
+static unsigned char tx3904_serial_in_buf1[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE];
+#endif
+#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1
+
+//-------------------------------------------------------------------------
+// Channel descriptions:
+
+#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE
+#define SIZEOF_BUF(_x_) 0
+#else
+#define SIZEOF_BUF(_x_) sizeof(_x_)
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0
+#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE > 0
+static SERIAL_CHANNEL_USING_INTERRUPTS(tx3904_serial_channel0,
+ tx3904_serial_funs,
+ tx3904_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &tx3904_serial_out_buf0[0],
+ SIZEOF_BUF(tx3904_serial_out_buf0),
+ &tx3904_serial_in_buf0[0],
+ SIZEOF_BUF(tx3904_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(tx3904_serial_channel0,
+ tx3904_serial_funs,
+ tx3904_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1
+#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE > 0
+static SERIAL_CHANNEL_USING_INTERRUPTS(tx3904_serial_channel1,
+ tx3904_serial_funs,
+ tx3904_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &tx3904_serial_out_buf1[0],
+ SIZEOF_BUF(tx3904_serial_out_buf1),
+ &tx3904_serial_in_buf1[0],
+ SIZEOF_BUF(tx3904_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(tx3904_serial_channel1,
+ tx3904_serial_funs,
+ tx3904_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1
+
+//-------------------------------------------------------------------------
+// And finally, the device table entries:
+
+#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0
+DEVTAB_ENTRY(tx3904_serial_io0,
+ CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ tx3904_serial_init,
+ tx3904_serial_lookup, // Serial driver may need initializing
+ &tx3904_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1
+DEVTAB_ENTRY(tx3904_serial_io1,
+ CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ tx3904_serial_init,
+ tx3904_serial_lookup, // Serial driver may need initializing
+ &tx3904_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1
+
+// ------------------------------------------------------------------------
+// Delay for some number of character times. This is based on the baud
+// rate currently set. We use the numbers that plug in to the BRG
+// clock select and divider to control two loops. The innermost delay
+// loop uses a count that is derived from dividing the CPU frequency
+// by the BRG granularity (and we then add 1 to compensate for any
+// rounding). This gives the number of cycles that the innermost loop
+// must consume. For the sake of simplicity we assume that this loop
+// will take 1 cycle per loop, which is roughly true in optimized
+// code.
+
+void delay_char_time(tx3904_serial_info *tx3904_chan, int n)
+{
+ static cyg_uint16 clock_val[4] = { 4, 16, 64, 256 };
+ cyg_uint16 baud_val = select_baud[tx3904_chan->cur_baud];
+ cyg_count32 clock_loop = clock_val[baud_val>>8];
+ cyg_count32 div_loop = baud_val & 0xFF;
+ cyg_count32 bit_time = ((CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL)/(2457600)) + 1;
+
+ n *= 11; // allow for start and stop bits and 8 data bits
+
+ while( n-- )
+ {
+ cyg_count32 i,j,k;
+
+ for( i = 0; i < clock_loop; i++ )
+ for( j = 0; j < div_loop; j++ )
+ for( k = 0; k < bit_time; k++ )
+ continue;
+ }
+}
+
+//-------------------------------------------------------------------------
+
+static bool
+tx3904_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;
+ cyg_uint16 cr = 0;
+ cyg_uint16 icr = 0;
+ cyg_uint16 baud_divisor = select_baud[new_config->baud];
+
+ if (baud_divisor == 0)
+ return false; // Invalid baud rate selected
+
+ // set up other config values:
+
+ cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];
+ cr |= select_stop_bits[new_config->stop];
+ cr |= select_parity[new_config->parity];
+
+ // Source transfer clock from BRG
+ cr |= LCR_BRG;
+
+#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE
+ // Enable RX interrupts only at present
+#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0
+ if ((chan->out_cbuf.len != 0) || (chan == &tx3904_serial_channel0)) {
+#else
+ if (chan->out_cbuf.len != 0) {
+#endif
+ icr |= ICR_RXE;
+ }
+#endif
+
+ // Avoid any interrupts while we are fiddling with the line parameters.
+ cyg_drv_interrupt_mask(tx3904_chan->int_num);
+
+
+ // In theory we should wait here for the transmitter to drain the
+ // FIFO so we dont change the line parameters with characters
+ // unsent. Unfortunately the TX39 serial devices do not allow us
+ // to discover when the FIFO is empty.
+
+ delay_char_time(tx3904_chan, 8);
+
+ // Disable device entirely.
+// HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_CR, 0);
+// HAL_WRITE_UINT8(tx3904_chan->base+SERIAL_ICR, 0);
+
+ // Reset the FIFOs
+
+ HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_FCR, 7);
+ HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_FCR, 0);
+
+ // Set up baud rate
+
+ HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_BRG, baud_divisor );
+
+ // Write CR into hardware
+ HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_CR, cr);
+
+ // Write ICR into hardware
+ HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_ICR, icr);
+
+ // Re-enable interrupts.
+ cyg_drv_interrupt_unmask(tx3904_chan->int_num);
+
+ // Save current baud rate
+ tx3904_chan->cur_baud = new_config->baud;
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+//-------------------------------------------------------------------------
+// Function to initialize the device. Called at bootstrap time.
+
+bool tx3904_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;
+
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+
+ tx3904_chan->cur_baud = CYGNUM_SERIAL_BAUD_38400;
+
+#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE
+ if (chan->out_cbuf.len != 0) {
+ // Install and enable the interrupt
+ cyg_drv_interrupt_create(tx3904_chan->int_num,
+ 4, // Priority
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ (cyg_ISR_t *)tx3904_serial_ISR,
+ tx3904_serial_DSR,
+ &tx3904_chan->interrupt_handle,
+ &tx3904_chan->interrupt);
+ cyg_drv_interrupt_attach(tx3904_chan->interrupt_handle);
+ cyg_drv_interrupt_unmask(tx3904_chan->int_num);
+ }
+#endif
+
+ tx3904_serial_config_port(chan, &chan->config, true);
+
+ return true;
+}
+
+//-------------------------------------------------------------------------
+// This routine is called when the device is "looked" up (i.e. attached)
+
+static Cyg_ErrNo
+tx3904_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+//-------------------------------------------------------------------------
+// Return 'true' if character is sent to device
+
+bool
+tx3904_serial_putc(serial_channel *chan, unsigned char c)
+{
+ tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;
+ cyg_uint16 isr;
+
+ HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+
+ if( isr & ISR_TXRDY )
+ {
+ HAL_WRITE_UINT8( tx3904_chan->base+SERIAL_TXB, c );
+
+ isr &= ~ISR_TXRDY;
+
+ HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+
+ return true;
+ }
+ else return false;
+}
+
+//-------------------------------------------------------------------------
+
+unsigned char
+tx3904_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;
+ cyg_uint16 isr;
+
+ do
+ {
+ HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+
+ // Eliminate any RX errors
+ if( isr & ISR_ERROR )
+ {
+ cyg_uint16 sr = 0;
+
+ isr &= ISR_ERROR;
+
+// HAL_READ_UINT16( tx3904_chan->base+SERIAL_SR, sr );
+
+ HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_SR, sr );
+ HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+ }
+
+ } while( (isr & ISR_RXRDY) != ISR_RXRDY );
+
+ HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, c );
+
+ isr &= ~ISR_RXRDY;
+
+ HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+
+ return c;
+}
+
+//-------------------------------------------------------------------------
+
+static Cyg_ErrNo
+tx3904_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != tx3904_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+//-------------------------------------------------------------------------
+// Enable the transmitter on the device
+
+static void
+tx3904_serial_start_xmit(serial_channel *chan)
+{
+#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE
+ tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;
+ cyg_uint16 icr;
+
+ HAL_READ_UINT16( tx3904_chan->base+SERIAL_ICR, icr );
+
+ icr |= ICR_TXE;
+
+ HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ICR, icr );
+#endif
+}
+
+//-------------------------------------------------------------------------
+// Disable the transmitter on the device
+
+static void
+tx3904_serial_stop_xmit(serial_channel *chan)
+{
+#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE
+ tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;
+ cyg_uint16 icr;
+
+ HAL_READ_UINT16( tx3904_chan->base+SERIAL_ICR, icr );
+
+ icr &= ~ICR_TXE;
+
+ HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ICR, icr );
+#endif
+}
+
+//-------------------------------------------------------------------------
+// Serial I/O - low level interrupt handlers (ISR)
+
+#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE
+
+static cyg_uint32
+tx3904_serial_ISR(cyg_vector_t vector, cyg_addrword_t data, cyg_addrword_t *regs)
+{
+ serial_channel *chan = (serial_channel *)data;
+ tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;
+ cyg_uint8 isr;
+ cyg_uint32 result = 0;
+
+ cyg_drv_interrupt_mask(tx3904_chan->int_num);
+ cyg_drv_interrupt_acknowledge(tx3904_chan->int_num);
+
+ HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+
+ // Eliminate any RX errors
+ if( isr & ISR_ERROR )
+ {
+ cyg_uint16 sr = 0;
+
+ isr &= ~ISR_ERROR;
+
+ HAL_READ_UINT16( tx3904_chan->base+SERIAL_SR, sr );
+
+ HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_SR, 0 );
+ }
+
+ // Check for a TX interrupt and set the flag if so.
+ if( isr & ISR_TXRDY )
+ {
+ isr &= ~ISR_TXRDY;
+
+ tx3904_chan->output_ready = true;
+
+ result |= CYG_ISR_CALL_DSR; // Cause DSR to be run
+ }
+
+
+ // Check here for an RX interrupt and fetch the character. If it
+ // is a ^C then call into GDB stub to handle it.
+
+ if( isr & ISR_RXRDY )
+ {
+ cyg_uint8 rxb;
+ HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, rxb );
+
+ isr &= ~ISR_RXRDY;
+
+ if( cyg_hal_is_break( &rxb , 1 ) )
+ cyg_hal_user_break( regs );
+ else
+ {
+ tx3904_chan->input_char = rxb;
+ tx3904_chan->input_char_valid = true;
+ result |= CYG_ISR_CALL_DSR; // Cause DSR to be run
+ }
+
+ }
+
+ HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+
+ return result;
+}
+
+
+#endif
+
+//-------------------------------------------------------------------------
+// Serial I/O - high level interrupt handler (DSR)
+
+#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE
+
+static void
+tx3904_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;
+ cyg_uint8 isr;
+
+ HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+
+ if( tx3904_chan->input_char_valid )
+ {
+ (chan->callbacks->rcv_char)(chan, tx3904_chan->input_char);
+
+ tx3904_chan->input_char_valid = false;
+
+#if 0
+ // And while we are here, pull any further characters out of the
+ // FIFO. This should help to reduce the interrupt rate.
+
+ HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+
+ while( isr & ISR_RXRDY )
+ {
+ cyg_uint8 rxb;
+ HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, rxb );
+
+ (chan->callbacks->rcv_char)(chan, rxb);
+
+ isr &= ~ISR_RXRDY;
+
+ HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+ HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );
+ }
+#endif
+
+ }
+
+ if( tx3904_chan->output_ready )
+ {
+ (chan->callbacks->xmt_char)(chan);
+
+ tx3904_chan->output_ready = false;
+ }
+
+ cyg_drv_interrupt_unmask(tx3904_chan->int_num);
+}
+
+#endif
+#endif // CYGPKG_IO_SERIAL_TX39_JMR3904
+
+//-------------------------------------------------------------------------
+// EOF tx3904_serial.c
diff --git a/ecos/packages/devs/serial/mips/ref4955/current/ChangeLog b/ecos/packages/devs/serial/mips/ref4955/current/ChangeLog
new file mode 100644
index 0000000..fbaff46
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/ref4955/current/ChangeLog
@@ -0,0 +1,60 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_mips_ref4955.cdl: Remove irrelevant doc link.
+
+2000-09-18 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_ref4955.cdl: Use CDL to specify testing parameters.
+
+ * include/mips_tx49_ref4955_ser.inl: Follow type naming changes in
+ generic driver.
+
+2000-09-14 Jesper Skov <jskov@redhat.com>
+
+ * include/mips_tx49_ref4955_ser.inl: Use with generic 16x5x serial
+ driver.
+ * src/ref4955_serial.c: Deleted.
+ * src/ref4955_serial.h: Deleted.
+ * cdl/ser_mips_ref4955.cdl: Changed accordingly.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/ref4955_serial.c (pc_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-05-25 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_ref4955.cdl:
+ * src/ref4955_serial.h:
+ * src/ref4955_serial.c:
+ REF4955 serial driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/mips/ref4955/current/cdl/ser_mips_ref4955.cdl b/ecos/packages/devs/serial/mips/ref4955/current/cdl/ser_mips_ref4955.cdl
new file mode 100644
index 0000000..4570fe3
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/ref4955/current/cdl/ser_mips_ref4955.cdl
@@ -0,0 +1,182 @@
+# ====================================================================
+#
+# ser_mips_ref4955.cdl
+#
+# eCos serial MIPS/REF4955 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 2000-05-24
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_MIPS_REF4955 {
+ display "REF4955 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_MIPS_TX49_REF4955
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ REF4955."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/mips_tx49_ref4955_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_mips_ref4955.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_MIPS_REF4955_SERIAL0 {
+ display "REF4955 serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the
+ REF4955 port 0."
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+# implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+# implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ cdl_option CYGDAT_IO_SERIAL_MIPS_REF4955_SERIAL0_NAME {
+ display "Device name for the REF4955 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option sets the name of the serial device for the
+ REF4955 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL0_BAUD {
+ display "Baud rate for the REF4955 serial port 0 driver"
+ flavor data
+ legal_values { 1200 2400 4800 9600 14400 19200 38400 57600 115200}
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the REF4955 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL0_BUFSIZE {
+ display "Buffer size for the REF4955 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the REF4955 port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_MIPS_REF4955_SERIAL1 {
+ display "REF4955 serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the
+ REF4955 port 1."
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+# implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+# implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ cdl_option CYGDAT_IO_SERIAL_MIPS_REF4955_SERIAL1_NAME {
+ display "Device name for the REF4955 serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for
+ the REF4955 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL1_BAUD {
+ display "Baud rate for the REF4955 serial port 1 driver"
+ flavor data
+ legal_values { 1200 2400 4800 9600 14400 19200 38400 57600 115200}
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the REF4955 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL1_BUFSIZE {
+ display "Buffer size for the REF4955 serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the REF4955 port 1."
+ }
+ }
+
+
+ cdl_component CYGPKG_IO_SERIAL_MIPS_REF4955_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_MIPS_REF4955_SERIAL0
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_MIPS_REF4955_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"ref4955\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_mips_ref4955.cdl
diff --git a/ecos/packages/devs/serial/mips/ref4955/current/include/mips_tx49_ref4955_ser.inl b/ecos/packages/devs/serial/mips/ref4955/current/include/mips_tx49_ref4955_ser.inl
new file mode 100644
index 0000000..ea514f3
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/ref4955/current/include/mips_tx49_ref4955_ser.inl
@@ -0,0 +1,176 @@
+//==========================================================================
+//
+// devs/serial/mips/ref4955/src/mips_tx49_ref4955_ser.inl
+//
+// REF4955 Serial I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:gthomas, jskov
+// Date: 2000-05-24
+// Purpose: REF4955 Serial definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+//-----------------------------------------------------------------------------
+// There are two serial ports.
+#define CYG_DEVICE_SERIAL_SCC1 0xb40003f8 // port 1
+#define CYG_DEVICE_SERIAL_SCC2 0xb40002f8 // port 2
+
+//-----------------------------------------------------------------------------
+// The REF4955 board has a 14.318 MHz crystal, but the PC87338 part
+// uses a 24MHz internal clock for baud rate calculation.
+#define BAUD_DIVISOR(_x_) 24000000/13/16/(_x_)
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 0, // 110
+ 0, // 134.5
+ 0, // 150
+ 0, // 200
+ 0, // 300
+ 0, // 600
+ BAUD_DIVISOR(1200),
+ 0, // 1800
+ BAUD_DIVISOR(2400),
+ 0, // 3600
+ BAUD_DIVISOR(4800),
+ 0 , // 7200
+ BAUD_DIVISOR(9600),
+ BAUD_DIVISOR(14400),
+ BAUD_DIVISOR(19200),
+ BAUD_DIVISOR(38400),
+ BAUD_DIVISOR(57600),
+ BAUD_DIVISOR(115200),
+ 0, // 230400
+};
+
+//-----------------------------------------------------------------------------
+// Port 0 descriptors
+
+#ifdef CYGPKG_IO_SERIAL_MIPS_REF4955_SERIAL0
+static pc_serial_info pc_serial_info0 = {CYG_DEVICE_SERIAL_SCC1,
+ CYGNUM_HAL_INTERRUPT_DEBUG_UART};
+#if CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL0_BUFSIZE > 0
+static unsigned char pc_serial_out_buf0[CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL0_BUFSIZE];
+static unsigned char pc_serial_in_buf0[CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(pc_serial_channel0,
+ pc_serial_funs,
+ pc_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &pc_serial_out_buf0[0],
+ sizeof(pc_serial_out_buf0),
+ &pc_serial_in_buf0[0],
+ sizeof(pc_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(pc_serial_channel0,
+ pc_serial_funs,
+ pc_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(pc_serial_io0,
+ CYGDAT_IO_SERIAL_MIPS_REF4955_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &pc_serial_channel0
+ );
+#endif
+
+//-----------------------------------------------------------------------------
+// Port 1 descriptors
+
+#ifdef CYGPKG_IO_SERIAL_MIPS_REF4955_SERIAL1
+static pc_serial_info pc_serial_info1 = {CYG_DEVICE_SERIAL_SCC2,
+ CYGNUM_HAL_INTERRUPT_USER_UART};
+#if CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL1_BUFSIZE > 0
+static unsigned char pc_serial_out_buf1[CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL1_BUFSIZE];
+static unsigned char pc_serial_in_buf1[CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(pc_serial_channel1,
+ pc_serial_funs,
+ pc_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &pc_serial_out_buf1[0],
+ sizeof(pc_serial_out_buf1),
+ &pc_serial_in_buf1[0],
+ sizeof(pc_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(pc_serial_channel1,
+ pc_serial_funs,
+ pc_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_REF4955_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(pc_serial_io1,
+ CYGDAT_IO_SERIAL_MIPS_REF4955_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &pc_serial_channel1
+ );
+#endif
+
+// EOF mips_tx49_ref4955_ser.inl
diff --git a/ecos/packages/devs/serial/mips/upd985xx/current/ChangeLog b/ecos/packages/devs/serial/mips/upd985xx/current/ChangeLog
new file mode 100644
index 0000000..4b52d82
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/upd985xx/current/ChangeLog
@@ -0,0 +1,43 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_mips_upd985xx.cdl: Remove irrelevant doc link.
+
+2002-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/upd985xx_serial.c (upd985xx_serial_init): Fix compile error.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_mips_upd985xx.cdl:
+ Fix 234000->230400 typo.
+
+2001-07-18 Hugo Tyson <hmt@redhat.com>
+
+ * src/upd985xx_serial.c:
+ * src/upd985xx_serial.h:
+ * cdl/ser_mips_upd985xx.cdl:
+ New files; implement asynchronous serial device for uPD985xx.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/mips/upd985xx/current/cdl/ser_mips_upd985xx.cdl b/ecos/packages/devs/serial/mips/upd985xx/current/cdl/ser_mips_upd985xx.cdl
new file mode 100644
index 0000000..6669288
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/upd985xx/current/cdl/ser_mips_upd985xx.cdl
@@ -0,0 +1,164 @@
+# ====================================================================
+#
+# ser_mips_upd985xx.cdl
+#
+# eCos serial MIPS/Upd985xx configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): hmt
+# Contributors: gthomas
+# Date: 2001-07-17
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_MIPS_UPD985XX {
+ display "NEC uPD985xx serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_MIPS_UPD985XX
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ NEC MIPS uPD985xx system-on-chip device."
+
+ compile -library=libextras.a upd985xx_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_mips_upd985xx.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_MIPS_UPD985XX_SERIAL0 {
+ display "MIPS UPD985XX serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the MIPS UPD985XX
+ serial port."
+
+ cdl_option CYGDAT_IO_SERIAL_MIPS_UPD985XX_SERIAL0_NAME {
+ display "Device name for MIPS UPD985XX serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device for the
+ MIPS UPD985XX port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_UPD985XX_SERIAL0_BAUD {
+ display "Baud rate for the MIPS UPD985XX serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ MIPS UPD985XX port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_UPD985XX_SERIAL0_BUFSIZE {
+ display "Buffer size for the MIPS UPD985XX serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the MIPS UPD985XX port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_MIPS_UPD985XX_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_MIPS_UPD985XX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_MIPS_UPD985XX_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_MIPS_UPD985XX_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_MIPS_UPD985XX_SERIAL0
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_MIPS_UPD985XX_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"upd985xx\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_mips_upd985xx.cdl
diff --git a/ecos/packages/devs/serial/mips/upd985xx/current/src/upd985xx_serial.c b/ecos/packages/devs/serial/mips/upd985xx/current/src/upd985xx_serial.c
new file mode 100644
index 0000000..402ea9c
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/upd985xx/current/src/upd985xx_serial.c
@@ -0,0 +1,312 @@
+//==========================================================================
+//
+// io/serial/mips/upd985xx/upd985xx_serial.c
+//
+// NEC MIPS uPD985xx Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: gthomas
+// Date: 2001-07-17
+// Purpose: NEC MIPS uPD985xx Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#include "upd985xx_serial.h"
+
+typedef struct upd985xx_serial_info {
+// CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} upd985xx_serial_info;
+
+static bool upd985xx_serial_init(struct cyg_devtab_entry *tab);
+static bool upd985xx_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo upd985xx_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char upd985xx_serial_getc(serial_channel *chan);
+static Cyg_ErrNo upd985xx_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void upd985xx_serial_start_xmit(serial_channel *chan);
+static void upd985xx_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 upd985xx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void upd985xx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(upd985xx_serial_funs,
+ upd985xx_serial_putc,
+ upd985xx_serial_getc,
+ upd985xx_serial_set_config,
+ upd985xx_serial_start_xmit,
+ upd985xx_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_MIPS_UPD985XX_SERIAL0
+static upd985xx_serial_info upd985xx_serial_info0 = {
+ // base: (CYG_ADDRWORD)UPD985XX_UART3_CONTROL0,
+ int_num: CYGNUM_HAL_INTERRUPT_UART,
+};
+#if CYGNUM_IO_SERIAL_MIPS_UPD985XX_SERIAL0_BUFSIZE > 0
+static unsigned char upd985xx_serial_out_buf0[CYGNUM_IO_SERIAL_MIPS_UPD985XX_SERIAL0_BUFSIZE];
+static unsigned char upd985xx_serial_in_buf0[CYGNUM_IO_SERIAL_MIPS_UPD985XX_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(
+ upd985xx_serial_channel0,
+ upd985xx_serial_funs,
+ upd985xx_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_UPD985XX_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &upd985xx_serial_out_buf0[0], sizeof(upd985xx_serial_out_buf0),
+ &upd985xx_serial_in_buf0[0], sizeof(upd985xx_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(
+ upd985xx_serial_channel0,
+ upd985xx_serial_funs,
+ upd985xx_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_UPD985XX_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(upd985xx_serial_io0,
+ CYGDAT_IO_SERIAL_MIPS_UPD985XX_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ upd985xx_serial_init,
+ upd985xx_serial_lookup, // Serial driver may need initializing
+ &upd985xx_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_MIPS_UPD985XX_SERIAL1
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+upd985xx_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ unsigned char parity;
+ unsigned char word_length;
+ unsigned char stop_bits;
+ int baud;
+
+ parity = select_parity[new_config->parity];
+ word_length = select_word_length[new_config->word_length-CYGNUM_SERIAL_WORD_LENGTH_5];
+ stop_bits = select_stop_bits[new_config->stop];
+ baud = select_baud[new_config->baud];
+
+ if ((word_length == 0xFF) ||
+ (parity == 0xFF) ||
+ (stop_bits == 0xFF)) {
+ return false; // Unsupported configuration
+ }
+
+ // First ensure we are accessing the right registers.
+ // Clear the divisor latch access bit
+ *UARTLCR &=~UARTLCR_DLAB;
+
+ // Disable Receiver and Transmitter
+ // No such thing in uPD985xx - but we can mask interrupts:
+ *UARTIER = 0;
+
+ // Clear sticky (writable) status bits.
+ // Ensure it's in 16550 mode at least:
+ *UARTFCR = UARTFCR_16550_MODE;
+
+ // Set parity, word length, stop bits (keep DLAB clear)
+ *UARTLCR = word_length | parity | stop_bits;
+
+ // Set the desired baud rate.
+ *UARTLCR |= UARTLCR_DLAB;
+ *UARTDLM = (baud >> 8) & 0xff;
+ *UARTDLL = baud & 0xff;
+ *UARTLCR &=~UARTLCR_DLAB;
+
+ // Enable the receiver (with interrupts) and the transmitter.
+ *UARTIER = UARTIER_ERBFI;
+
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+upd985xx_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ upd985xx_serial_info *upd985xx_chan = (upd985xx_serial_info *)chan->dev_priv;
+ int res;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("UPD985XX SERIAL init - dev: %x.%d\n", 0 /* upd985xx_chan->base */,
+ upd985xx_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(upd985xx_chan->int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ upd985xx_serial_ISR,
+ upd985xx_serial_DSR,
+ &upd985xx_chan->serial_interrupt_handle,
+ &upd985xx_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(upd985xx_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(upd985xx_chan->int_num);
+ }
+ res = upd985xx_serial_config_port(chan, &chan->config, true);
+ return res;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+upd985xx_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+upd985xx_serial_putc(serial_channel *chan, unsigned char c)
+{
+ if ( 0 == (UARTLSR_THRE & *UARTLSR) )
+ return false;
+ *UARTTHR = (unsigned int)c;
+ return true;
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+upd985xx_serial_getc(serial_channel *chan)
+{
+ while ( 0 == (UARTLSR_DR & *UARTLSR) )
+ /* do nothing */ ;
+
+ return (char)*UARTRBR;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+upd985xx_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != upd985xx_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+upd985xx_serial_start_xmit(serial_channel *chan)
+{
+ (chan->callbacks->xmt_char)(chan); // Kick transmitter (if necessary)
+ *UARTIER |= UARTIER_ERBEI; // enable interrupts
+}
+
+// Disable the transmitter on the device
+static void
+upd985xx_serial_stop_xmit(serial_channel *chan)
+{
+ *UARTIER &=~UARTIER_ERBEI; // disable interrupts
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+upd985xx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_drv_interrupt_mask(vector);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+upd985xx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+
+ int stat = *UARTIIR;
+
+ stat &= UARTIIR_UIID_MASK;
+
+ if (stat == UARTIIR_TX_EMPTY) {
+ (chan->callbacks->xmt_char)(chan);
+ }
+ if (stat == UARTIIR_RXD_AVAIL) {
+ while (0 != (UARTLSR_DR & *UARTLSR)) {
+ (chan->callbacks->rcv_char)(chan, (char)*UARTRBR);
+ }
+ }
+ cyg_drv_interrupt_acknowledge(vector);
+ cyg_drv_interrupt_unmask(vector);
+}
+
+// ------------------------------------------------------------------------
+// EOF upd985xx_serial.c
diff --git a/ecos/packages/devs/serial/mips/upd985xx/current/src/upd985xx_serial.h b/ecos/packages/devs/serial/mips/upd985xx/current/src/upd985xx_serial.h
new file mode 100644
index 0000000..ad9f96c
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/upd985xx/current/src/upd985xx_serial.h
@@ -0,0 +1,108 @@
+#ifndef CYGONCE_MIPS_UPD985XX_SERIAL_H
+#define CYGONCE_MIPS_UPD985XX_SERIAL_H
+// ====================================================================
+//
+// upd985xx_serial.h
+//
+// Device I/O - Description of NEC MIPS uPD985xx serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: gthomas
+// Date: 2001-07-17
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports on NEC MIPS uPD985xx
+
+#include <cyg/hal/hal_arch.h> // Register definitions
+
+static unsigned char select_word_length[] = {
+ 0xFF, // 5 bits / word (char)
+ 0xFF, // 6
+ UARTLCR_7, // 7
+ UARTLCR_8 // 8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0xFF, // N/A
+ UARTLCR_STB1, // 1 stop bit
+ 0xFF, // 1.5 stop bit
+ UARTLCR_STB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ UARTLCR_NOP, // No parity
+ UARTLCR_EP, // Even parity
+ UARTLCR_OP, // Odd parity
+ 0xFF, // Mark parity
+ 0xFF, // Space parity
+};
+
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ UARTDLL_VAL( 50 ), // 50
+ UARTDLL_VAL( 75 ), // 75
+ UARTDLL_VAL( 110 ), // 110
+ 0, // 134.5
+ UARTDLL_VAL( 150 ), // 150
+ UARTDLL_VAL( 200 ), // 200
+ UARTDLL_VAL( 300 ), // 300
+ UARTDLL_VAL( 600 ), // 600
+ UARTDLL_VAL( 1200 ), // 1200
+ UARTDLL_VAL( 1800 ), // 1800
+ UARTDLL_VAL( 2400 ), // 2400
+ UARTDLL_VAL( 3600 ), // 3600
+ UARTDLL_VAL( 4800 ), // 4800
+ UARTDLL_VAL( 7200 ), // 7200
+ UARTDLL_VAL( 9600 ), // 9600
+ UARTDLL_VAL( 14400 ), // 14400
+ UARTDLL_VAL( 19200 ), // 19200
+ UARTDLL_VAL( 38400 ), // 38400
+ UARTDLL_VAL( 57600 ), // 57600
+ UARTDLL_VAL( 115200 ), // 115200
+ UARTDLL_VAL( 230400 ), // 230400
+};
+
+#endif // CYGONCE_MIPS_UPD985XX_SERIAL_H
+
+// ------------------------------------------------------------------------
+// EOF upd985xx_serial.h
diff --git a/ecos/packages/devs/serial/mips/vrc437x/current/ChangeLog b/ecos/packages/devs/serial/mips/vrc437x/current/ChangeLog
new file mode 100644
index 0000000..88678cc
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/vrc437x/current/ChangeLog
@@ -0,0 +1,1206 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_mips_vrc437x.cdl: Remove irrelevant doc link.
+
+2001-09-18 Nick Garnett <nickg@redhat.com>
+
+ * cdl/ser_mips_vrc437x.cdl:
+ * src/vrc437x_serial.h:
+ * src/vrc437x_serial.c:
+ Fixed VRC4373 -> VRC437X conversions that were missed.
+ Also made default baud rates 38400 rather than 9600.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_mips_vrc437x.cdl:
+ Fix 234000->230400 typo.
+
+2001-09-07 Nick Garnett <nickg@redhat.com>
+
+ * cdl/ser_mips_vrc437x.cdl:
+ * src/vrc437x_serial.h:
+ * src/vrc437x_serial.c:
+ Moved this entire tree over to vrc437x from vrc4373 to make it
+ generic to both kinds of board.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_vrc4373.cdl: Moved testing parameters here.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/vrc4373_serial.c (vrc4373_serial_set_config): Now use keys
+ to make more flexible.
+
+2000-07-22 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/vrc4373_serial.c (vrc4373_serial_init): Add comment about broken
+ interrupt handling
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_mips_vrc4373.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/mips/vrc437x/current/cdl/ser_mips_vrc437x.cdl b/ecos/packages/devs/serial/mips/vrc437x/current/cdl/ser_mips_vrc437x.cdl
new file mode 100644
index 0000000..fb459a0
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/vrc437x/current/cdl/ser_mips_vrc437x.cdl
@@ -0,0 +1,202 @@
+# ====================================================================
+#
+# ser_mips_vrc437x.cdl
+#
+# eCos serial MIPS/VRC437X configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-14
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_MIPS_VRC437X {
+ display "VRC437X serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_MIPS_VR4300_VRC437X
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ VRC437X."
+
+ compile -library=libextras.a vrc437x_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_mips_vrc437x.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_MIPS_VRC437X_SERIAL0 {
+ display "VRC437X serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the VRC437X port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_MIPS_VRC437X_SERIAL0_NAME {
+ display "Device name for the VRC437X serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option sets the name of the serial device for the VRC437X
+ port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL0_BAUD {
+ display "Baud rate for the VRC437X serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ VRC437X port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL0_BUFSIZE {
+ display "Buffer size for the VRC437X serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the VRC437X port 0."
+ }
+}
+cdl_component CYGPKG_IO_SERIAL_MIPS_VRC437X_SERIAL1 {
+ display "VRC437X serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the VRC437X port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_MIPS_VRC437X_SERIAL1_NAME {
+ display "Device name for the VRC437X serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of serial device for the
+ VRC437X port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL1_BAUD {
+ display "Baud rate for the VRC437X serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ VRC437X port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL1_BUFSIZE {
+ display "Buffer size for the VRC437X serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the VRC437X port 1."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_MIPS_VRC437X_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_MIPS_VRC437X_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_MIPS_VRC437X_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_MIPS_VRC437X_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_MIPS_VRC437X_SERIAL0
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_MIPS_VRC437X_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"vrc437X\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+}
+
+# EOF ser_mips_vrc437x.cdl
diff --git a/ecos/packages/devs/serial/mips/vrc437x/current/src/vrc437x_serial.c b/ecos/packages/devs/serial/mips/vrc437x/current/src/vrc437x_serial.c
new file mode 100644
index 0000000..96dc6d3
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/vrc437x/current/src/vrc437x_serial.c
@@ -0,0 +1,493 @@
+//==========================================================================
+//
+// io/serial/mips/vrc437x_serial.c
+//
+// Mips VRC437X Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-04-15
+// Purpose: VRC437X Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+
+#ifdef CYGPKG_IO_SERIAL_MIPS_VRC437X
+
+#include "vrc437x_serial.h"
+
+#if defined(CYGPKG_HAL_MIPS_LSBFIRST)
+#define VRC437X_SCC_BASE 0xC1000000
+#elif defined(CYGPKG_HAL_MIPS_MSBFIRST)
+#define VRC437X_SCC_BASE 0xC1000003
+#else
+#error MIPS endianness not defined by configuration
+#endif
+
+#define VRC437X_SCC_INT CYGNUM_HAL_INTERRUPT_DUART
+#define SCC_CHANNEL_A 4
+#define SCC_CHANNEL_B 0
+
+extern void diag_printf(const char *fmt, ...);
+
+typedef struct vrc437x_serial_info {
+ CYG_ADDRWORD base;
+ unsigned char regs[16]; // Known register state (since hardware is write-only!)
+} vrc437x_serial_info;
+
+static bool vrc437x_serial_init(struct cyg_devtab_entry *tab);
+static bool vrc437x_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo vrc437x_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char vrc437x_serial_getc(serial_channel *chan);
+static Cyg_ErrNo vrc437x_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void vrc437x_serial_start_xmit(serial_channel *chan);
+static void vrc437x_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 vrc437x_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void vrc437x_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(vrc437x_serial_funs,
+ vrc437x_serial_putc,
+ vrc437x_serial_getc,
+ vrc437x_serial_set_config,
+ vrc437x_serial_start_xmit,
+ vrc437x_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_MIPS_VRC437X_SERIAL0
+static vrc437x_serial_info vrc437x_serial_info0 = {VRC437X_SCC_BASE+SCC_CHANNEL_A};
+#if CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL0_BUFSIZE > 0
+static unsigned char vrc437x_serial_out_buf0[CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL0_BUFSIZE];
+static unsigned char vrc437x_serial_in_buf0[CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(vrc437x_serial_channel0,
+ vrc437x_serial_funs,
+ vrc437x_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &vrc437x_serial_out_buf0[0], sizeof(vrc437x_serial_out_buf0),
+ &vrc437x_serial_in_buf0[0], sizeof(vrc437x_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(vrc437x_serial_channel0,
+ vrc437x_serial_funs,
+ vrc437x_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(vrc437x_serial_io0,
+ CYGDAT_IO_SERIAL_MIPS_VRC437X_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ vrc437x_serial_init,
+ vrc437x_serial_lookup, // Serial driver may need initializing
+ &vrc437x_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_MIPS_VRC437X_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_MIPS_VRC437X_SERIAL1
+static vrc437x_serial_info vrc437x_serial_info1 = {VRC437X_SCC_BASE+SCC_CHANNEL_B};
+#if CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL1_BUFSIZE > 0
+static unsigned char vrc437x_serial_out_buf1[CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL1_BUFSIZE];
+static unsigned char vrc437x_serial_in_buf1[CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(vrc437x_serial_channel1,
+ vrc437x_serial_funs,
+ vrc437x_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &vrc437x_serial_out_buf1[0], sizeof(vrc437x_serial_out_buf1),
+ &vrc437x_serial_in_buf1[0], sizeof(vrc437x_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(vrc437x_serial_channel1,
+ vrc437x_serial_funs,
+ vrc437x_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC437X_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(vrc437x_serial_io1,
+ CYGDAT_IO_SERIAL_MIPS_VRC437X_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ vrc437x_serial_init,
+ vrc437x_serial_lookup, // Serial driver may need initializing
+ &vrc437x_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_MIPS_VRC437X_SERIAL1
+
+static cyg_interrupt vrc437x_serial_interrupt;
+static cyg_handle_t vrc437x_serial_interrupt_handle;
+
+// Table which maps hardware channels (A,B) to software ones
+struct serial_channel *vrc437x_chans[] = {
+#ifdef CYGPKG_IO_SERIAL_MIPS_VRC437X_SERIAL0 // Hardware channel A
+ &vrc437x_serial_channel0,
+#else
+ 0,
+#endif
+#ifdef CYGPKG_IO_SERIAL_MIPS_VRC437X_SERIAL1 // Hardware channel B
+ &vrc437x_serial_channel1,
+#else
+ 0,
+#endif
+};
+
+// Support functions which access the serial device. Note that this chip requires
+// a substantial delay after each access.
+
+#define SCC_DELAY 100
+inline static void
+scc_delay(void)
+{
+ int i;
+ for (i = 0; i < SCC_DELAY; i++) ;
+}
+
+inline static void
+scc_write_reg(volatile unsigned char *reg, unsigned char val)
+{
+ scc_delay();
+ *reg = val;
+}
+
+inline static unsigned char
+scc_read_reg(volatile unsigned char *reg)
+{
+ unsigned char val;
+ scc_delay();
+ val = *reg;
+ return (val);
+}
+
+inline static unsigned char
+scc_read_ctl(volatile struct serial_port *port, int reg)
+{
+ if (reg != 0) {
+ scc_write_reg(&port->scc_ctl, reg);
+ }
+ return (scc_read_reg(&port->scc_ctl));
+}
+
+inline static void
+scc_write_ctl(volatile struct serial_port *port, int reg, unsigned char val)
+{
+ if (reg != 0) {
+ scc_write_reg(&port->scc_ctl, reg);
+ }
+ scc_write_reg(&port->scc_ctl, val);
+}
+
+inline static unsigned char
+scc_read_dat(volatile struct serial_port *port)
+{
+ return (scc_read_reg(&port->scc_dat));
+}
+
+inline static void
+scc_write_dat(volatile struct serial_port *port, unsigned char val)
+{
+ scc_write_reg(&port->scc_dat, val);
+}
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+vrc437x_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ vrc437x_serial_info *vrc437x_chan = (vrc437x_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)vrc437x_chan->base;
+ cyg_int32 baud_rate = select_baud[new_config->baud];
+ cyg_int32 baud_divisor;
+ unsigned char *regs = &vrc437x_chan->regs[0];
+ if (baud_rate == 0) return false;
+ // Compute state of registers. The register/control state needs to be kept in
+ // the shadow variable 'regs' because the hardware registers can only be written,
+ // not read (in general).
+ if (init) {
+ // Insert appropriate resets?
+ if (chan->out_cbuf.len != 0) {
+ regs[R1] = WR1_IntAllRx;
+ regs[R9] = WR9_MIE | WR9_NoVector;
+ } else {
+ regs[R1] = 0;
+ regs[R9] = 0;
+ }
+ // Clocks are from the baud rate generator
+ regs[R11] = WR11_TRxCBR | WR11_TRxCOI | WR11_TxCBR | WR11_RxCBR;
+ regs[R14] = WR14_BRenable | WR14_BRSRC;
+ regs[R10] = 0; // Unused in this [async] mode
+ regs[R15] = 0;
+ }
+ regs[R3] = WR3_RxEnable | select_word_length_WR3[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];
+ regs[R4] = WR4_X16CLK | select_stop_bits[new_config->stop] | select_parity[new_config->parity];
+ regs[R5] = WR5_TxEnable | select_word_length_WR5[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];
+ baud_divisor = BRTC(baud_rate);
+ regs[R12] = baud_divisor & 0xFF;
+ regs[R13] = baud_divisor >> 8;
+ // Now load the registers
+ scc_write_ctl(port, R4, regs[R4]);
+ scc_write_ctl(port, R10, regs[R10]);
+ scc_write_ctl(port, R3, regs[R3] & ~WR3_RxEnable);
+ scc_write_ctl(port, R5, regs[R5] & ~WR5_TxEnable);
+ scc_write_ctl(port, R1, regs[R1]);
+ scc_write_ctl(port, R9, regs[R9]);
+ scc_write_ctl(port, R11, regs[R11]);
+ scc_write_ctl(port, R12, regs[R12]);
+ scc_write_ctl(port, R13, regs[R13]);
+ scc_write_ctl(port, R14, regs[R14]);
+ scc_write_ctl(port, R15, regs[R15]);
+ scc_write_ctl(port, R3, regs[R3]);
+ scc_write_ctl(port, R5, regs[R5]);
+ // Update configuration
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+vrc437x_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ vrc437x_serial_info *vrc437x_chan = (vrc437x_serial_info *)chan->dev_priv;
+ static bool init = false;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("VRC437X SERIAL init '%s' - dev: %x\n", tab->name, vrc437x_chan->base);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (!init && chan->out_cbuf.len != 0) {
+ init = true;
+// Note that the hardware is rather broken. The interrupt status needs to
+// be read using only channel A
+ cyg_drv_interrupt_create(VRC437X_SCC_INT,
+ 99,
+ (cyg_addrword_t)VRC437X_SCC_BASE+SCC_CHANNEL_A,
+ vrc437x_serial_ISR,
+ vrc437x_serial_DSR,
+ &vrc437x_serial_interrupt_handle,
+ &vrc437x_serial_interrupt);
+ cyg_drv_interrupt_attach(vrc437x_serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(VRC437X_SCC_INT);
+ }
+ vrc437x_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+vrc437x_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+vrc437x_serial_putc(serial_channel *chan, unsigned char c)
+{
+ vrc437x_serial_info *vrc437x_chan = (vrc437x_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)vrc437x_chan->base;
+ if (scc_read_ctl(port, R0) & RR0_TxEmpty) {
+// Transmit buffer is empty
+ scc_write_dat(port, c);
+ return true;
+ } else {
+// No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+vrc437x_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ vrc437x_serial_info *vrc437x_chan = (vrc437x_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)vrc437x_chan->base;
+ while ((scc_read_ctl(port, R0) & RR0_RxAvail) == 0) ; // Wait for char
+ c = scc_read_dat(port);
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+vrc437x_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != vrc437x_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+vrc437x_serial_start_xmit(serial_channel *chan)
+{
+ vrc437x_serial_info *vrc437x_chan = (vrc437x_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)vrc437x_chan->base;
+ if ((vrc437x_chan->regs[R1] & WR1_TxIntEnab) == 0) {
+ CYG_INTERRUPT_STATE old;
+ HAL_DISABLE_INTERRUPTS(old);
+ vrc437x_chan->regs[R1] |= WR1_TxIntEnab; // Enable Tx interrupt
+ scc_write_ctl(port, R1, vrc437x_chan->regs[R1]);
+ (chan->callbacks->xmt_char)(chan); // Send first character to start xmitter
+ HAL_RESTORE_INTERRUPTS(old);
+ }
+}
+
+// Disable the transmitter on the device
+static void
+vrc437x_serial_stop_xmit(serial_channel *chan)
+{
+ vrc437x_serial_info *vrc437x_chan = (vrc437x_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)vrc437x_chan->base;
+ if ((vrc437x_chan->regs[R1] & WR1_TxIntEnab) != 0) {
+ CYG_INTERRUPT_STATE old;
+ HAL_DISABLE_INTERRUPTS(old);
+ vrc437x_chan->regs[R1] &= ~WR1_TxIntEnab; // Disable Tx interrupt
+ scc_write_ctl(port, R1, vrc437x_chan->regs[R1]);
+ HAL_RESTORE_INTERRUPTS(old);
+ }
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+vrc437x_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_drv_interrupt_mask(VRC437X_SCC_INT);
+ cyg_drv_interrupt_acknowledge(VRC437X_SCC_INT);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+inline static void
+vrc437x_int(serial_channel *chan, unsigned char stat)
+{
+ vrc437x_serial_info *vrc437x_chan = (vrc437x_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)vrc437x_chan->base;
+ // Note: 'stat' value is interrupt status register, shifted into "B" position
+ if (stat & RR3_BRxIP) {
+ // Receive interrupt
+ unsigned char c;
+ c = scc_read_dat(port);
+ (chan->callbacks->rcv_char)(chan, c);
+ }
+ if (stat & RR3_BTxIP) {
+ // Transmit interrupt
+ (chan->callbacks->xmt_char)(chan);
+ }
+ if (stat & RR3_BExt) {
+ // Status interrupt (parity error, framing error, etc)
+ }
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+// Note: This device presents a single interrupt for both channels. Thus the
+// interrupt handler has to query the device and decide which channel needs service.
+// Additionally, more than one interrupt condition may be present so this needs to
+// be done in a loop until all interrupt requests have been handled.
+// Also note that the hardware is rather broken. The interrupt status needs to
+// be read using only channel A (pointed to by 'data')
+static void
+vrc437x_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan;
+ volatile struct serial_port *port = (volatile struct serial_port *)data;
+ unsigned char stat;
+ while (true) {
+ stat = scc_read_ctl(port, R3);
+ if (stat & (RR3_AExt | RR3_ATxIP | RR3_ARxIP)) {
+ chan = vrc437x_chans[0]; // Hardware channel A
+ vrc437x_int(chan, stat>>3); // Handle interrupt
+ } else if (stat & (RR3_BExt | RR3_BTxIP | RR3_BRxIP)) {
+ chan = vrc437x_chans[1]; // Hardware channel B
+ vrc437x_int(chan, stat); // Handle interrupt
+ } else {
+ // No more interrupts, all done
+ break;
+ }
+ }
+ cyg_drv_interrupt_unmask(VRC437X_SCC_INT);
+}
+#endif
diff --git a/ecos/packages/devs/serial/mips/vrc437x/current/src/vrc437x_serial.h b/ecos/packages/devs/serial/mips/vrc437x/current/src/vrc437x_serial.h
new file mode 100644
index 0000000..23e4127
--- /dev/null
+++ b/ecos/packages/devs/serial/mips/vrc437x/current/src/vrc437x_serial.h
@@ -0,0 +1,343 @@
+#ifndef CYGONCE_MIPS_VRC437X_SERIAL_H
+#define CYGONCE_MIPS_VRC437X_SERIAL_H
+
+// ====================================================================
+//
+// vrc437x_serial.h
+//
+// Device I/O - Description of Mips VRC437X serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-04-15
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports on Mips VRC437X
+// Based on Zilog 85C30 SCC
+
+struct serial_port {
+ unsigned char _byte[16];
+};
+
+#define scc_ctl _byte[0]
+#define scc_dat _byte[8]
+
+#define R0 0 /* Register selects */
+#define R1 1
+#define R2 2
+#define R3 3
+#define R4 4
+#define R5 5
+#define R6 6
+#define R7 7
+#define R8 8
+#define R9 9
+#define R10 10
+#define R11 11
+#define R12 12
+#define R13 13
+#define R14 14
+#define R15 15
+
+/* Write Register 0 */
+#define WR0_NullCode 0x00 /* Null Code */
+#define WR0_PointHigh 0x08 /* Select upper half of registers */
+#define WR0_ResExtInt 0x10 /* Reset Ext. Status Interrupts */
+#define WR0_SendAbort 0x18 /* HDLC Abort */
+#define WR0_ResRxIntFC 0x20 /* Reset RxINT on First Character */
+#define WR0_ResTxP 0x28 /* Reset TxINT Pending */
+#define WR0_ErrReset 0x30 /* Error Reset */
+#define WR0_ResHiIUS 0x38 /* Reset highest IUS */
+
+#define WR0_ResRxCRC 0x40 /* Reset Rx CRC Checker */
+#define WR0_ResTxCRC 0x80 /* Reset Tx CRC Checker */
+#define WR0_ResEOMlatch 0xC0 /* Reset EOM latch */
+
+/* Write Register 1 */
+
+#define WR1_ExtIntEnab 0x01 /* Ext Int Enable */
+#define WR1_TxIntEnab 0x02 /* Tx Int Enable */
+#define WR1_ParSpec 0x04 /* Parity is special condition */
+
+#define WR1_RxIntDisab 0x00 /* Rx Int Disable */
+#define WR1_RxIntFCE 0x08 /* Rx Int on First Character Only or Error */
+#define WR1_IntAllRx 0x10 /* Int on all Rx Characters or error */
+#define WR1_IntErrRx 0x18 /* Int on error only */
+
+#define WR1_WtRdyRT 0x20 /* Wait/Ready on R/T */
+#define WR1_WtFnRdyFn 0x40 /* Wait/FN/Ready FN */
+#define WR1_WtRdyEnab 0x80 /* Wait/Ready Enable */
+
+/* Write Register #2 (Interrupt Vector) */
+
+/* Write Register 3 */
+
+#define WR3_RxEnable 0x01 /* Rx Enable */
+#define WR3_SyncInhibit 0x02 /* Sync Character Load Inhibit */
+#define WR3_AddrSearch 0x04 /* Address Search Mode (SDLC) */
+#define WR3_RxCRC_ENAB 0x08 /* Rx CRC Enable */
+#define WR3_EntHuntMode 0x10 /* Enter Hunt Mode */
+#define WR3_AutoEnab 0x20 /* Auto Enables */
+#define WR3_Rx5 0x00 /* Rx 5 Bits/Character */
+#define WR3_Rx7 0x40 /* Rx 7 Bits/Character */
+#define WR3_Rx6 0x80 /* Rx 6 Bits/Character */
+#define WR3_Rx8 0xc0 /* Rx 8 Bits/Character */
+#define WR3_RxNbitsMask 0xc0
+
+/* Write Register 4 */
+
+#define WR4_ParityEn 0x01 /* Parity Enable */
+#define WR4_ParityEven 0x02 /* Parity Even/Odd* */
+
+#define WR4_SyncEnable 0x00 /* Sync Modes Enable */
+#define WR4_SB1 0x04 /* 1 stop bit/char */
+#define WR4_SB15 0x08 /* 1.5 stop bits/char */
+#define WR4_SB2 0x0c /* 2 stop bits/char */
+#define WR4_SB_MASK 0x0c
+
+#define WR4_Monsync 0x00 /* 8 Bit Sync character */
+#define WR4_Bisync 0x10 /* 16 bit sync character */
+#define WR4_SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */
+#define WR4_EXtSync 0x30 /* External Sync Mode */
+
+#define WR4_X1CLK 0x00 /* x1 clock mode */
+#define WR4_X16CLK 0x40 /* x16 clock mode */
+#define WR4_X32CLK 0x80 /* x32 clock mode */
+#define WR4_X64CLK 0xC0 /* x64 clock mode */
+#define WR4_XCLK_MASK 0xC0
+
+/* Write Register 5 */
+
+#define WR5_TxCRCEnab 0x01 /* Tx CRC Enable */
+#define WR5_RTS 0x02 /* RTS */
+#define WR5_SDLC_CRC 0x04 /* SDLC/CRC-16 */
+#define WR5_TxEnable 0x08 /* Tx Enable */
+#define WR5_SendBreak 0x10 /* Send Break */
+#define WR5_Tx5 0x00 /* Tx 5 bits (or less)/character */
+#define WR5_Tx7 0x20 /* Tx 7 bits/character */
+#define WR5_Tx6 0x40 /* Tx 6 bits/character */
+#define WR5_Tx8 0x60 /* Tx 8 bits/character */
+#define WR5_TxNbitsMask 0x60
+#define WR5_DTR 0x80 /* DTR */
+
+/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */
+
+/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
+
+/* Write Register 8 (transmit buffer) */
+
+/* Write Register 9 (Master interrupt control) */
+#define WR9_VIS 0x01 /* Vector Includes Status */
+#define WR9_NoVector 0x02 /* No Vector */
+#define WR9_DLC 0x04 /* Disable Lower Chain */
+#define WR9_MIE 0x08 /* Master Interrupt Enable */
+#define WR9_StatHi 0x10 /* Status high */
+#define WR9_NoReset 0x00 /* No reset on write to R9 */
+#define WR9_ResetB 0x40 /* Reset channel B */
+#define WR9_ResetA 0x80 /* Reset channel A */
+#define WR9_HwReset 0xc0 /* Force hardware reset */
+
+/* Write Register 10 (misc control bits) */
+#define WR10_Bit6 0x01 /* 6 bit/8bit sync */
+#define WR10_LoopMode 0x02 /* SDLC Loop mode */
+#define WR10_AbrtUnder 0x04 /* Abort/flag on SDLC xmit underrun */
+#define WR10_MarkIdle 0x08 /* Mark/flag on idle */
+#define WR10_GAOP 0x10 /* Go active on poll */
+#define WR10_NRZ 0x00 /* NRZ mode */
+#define WR10_NRZI 0x20 /* NRZI mode */
+#define WR10_FM1 0x40 /* FM1 (transition = 1) */
+#define WR10_FM0 0x60 /* FM0 (transition = 0) */
+#define WR10_CRCPS 0x80 /* CRC Preset I/O */
+
+/* Write Register 11 (Clock Mode control) */
+#define WR11_TRxCXT 0x00 /* TRxC = Xtal output */
+#define WR11_TRxCTC 0x01 /* TRxC = Transmit clock */
+#define WR11_TRxCBR 0x02 /* TRxC = BR Generator Output */
+#define WR11_TRxCDP 0x03 /* TRxC = DPLL output */
+#define WR11_TRxCOI 0x04 /* TRxC O/I */
+#define WR11_TxCRTxCP 0x00 /* Transmit clock = RTxC pin */
+#define WR11_TxCTRxCP 0x08 /* Transmit clock = TRxC pin */
+#define WR11_TxCBR 0x10 /* Transmit clock = BR Generator output */
+#define WR11_TxCDPLL 0x18 /* Transmit clock = DPLL output */
+#define WR11_RxCRTxCP 0x00 /* Receive clock = RTxC pin */
+#define WR11_RxCTRxCP 0x20 /* Receive clock = TRxC pin */
+#define WR11_RxCBR 0x40 /* Receive clock = BR Generator output */
+#define WR11_RxCDPLL 0x60 /* Receive clock = DPLL output */
+#define WR11_RTxCX 0x80 /* RTxC Xtal/No Xtal */
+
+/* Write Register 12 (lower byte of baud rate generator time constant) */
+
+/* Write Register 13 (upper byte of baud rate generator time constant) */
+
+/* Write Register 14 (Misc control bits) */
+#define WR14_BRenable 0x01 /* Baud rate generator enable */
+#define WR14_BRSRC 0x02 /* Baud rate generator source */
+#define WR14_DTRreq 0x04 /* DTR/Request function */
+#define WR14_AutoEcho 0x08 /* Auto Echo */
+#define WR14_LoopBack 0x10 /* Local loopback */
+#define WR14_Search 0x20 /* Enter search mode */
+#define WR14_RMC 0x40 /* Reset missing clock */
+#define WR14_NoDPLL 0x60 /* Disable DPLL */
+#define WR14_SSBR 0x80 /* Set DPLL source = BR generator */
+#define WR14_SSRTxC 0xa0 /* Set DPLL source = RTxC */
+#define WR14_SFMM 0xc0 /* Set FM mode */
+#define WR14_SNRZI 0xe0 /* Set NRZI mode */
+
+/* Write Register 15 (external/status interrupt control) */
+#define WR15_ZCIE 0x02 /* Zero count IE */
+#define WR15_DCDIE 0x08 /* DCD IE */
+#define WR15_SYNCIE 0x10 /* Sync/hunt IE */
+#define WR15_CTSIE 0x20 /* CTS IE */
+#define WR15_TxUIE 0x40 /* Tx Underrun/EOM IE */
+#define WR15_BRKIE 0x80 /* Break/Abort IE */
+
+/* Read Register 0 */
+#define RR0_RxAvail 0x01 /* Rx Character Available */
+#define RR0_Zcount 0x02 /* Zero count */
+#define RR0_TxEmpty 0x04 /* Tx Buffer empty */
+#define RR0_DCD 0x08 /* DCD */
+#define RR0_SyncHunt 0x10 /* Sync/hunt */
+#define RR0_CTS 0x20 /* CTS */
+#define RR0_TxEOM 0x40 /* Tx underrun */
+#define RR0_BrkAbort 0x80 /* Break/Abort */
+
+/* Read Register 1 */
+#define RR1_AllSent 0x01 /* All sent */
+/* Residue Data for 8 Rx bits/char programmed */
+#define RR1_RES3 0x08 /* 0/3 */
+#define RR1_RES4 0x04 /* 0/4 */
+#define RR1_RES5 0x0c /* 0/5 */
+#define RR1_RES6 0x02 /* 0/6 */
+#define RR1_RES7 0x0a /* 0/7 */
+#define RR1_RES8 0x06 /* 0/8 */
+#define RR1_RES18 0x0e /* 1/8 */
+#define RR1_RES28 0x00 /* 2/8 */
+/* Special Rx Condition Interrupts */
+#define RR1_PariryError 0x10 /* Parity error */
+#define RR1_RxOverrun 0x20 /* Rx Overrun Error */
+#define RR1_FrameError 0x40 /* CRC/Framing Error */
+#define RR1_EndOfFrame 0x80 /* End of Frame (SDLC) */
+
+/* Read Register 2 (channel b only) - Interrupt vector */
+
+/* Read Register 3 (interrupt pending register) ch a only */
+#define RR3_BExt 0x01 /* Channel B Ext/Stat IP */
+#define RR3_BTxIP 0x02 /* Channel B Tx IP */
+#define RR3_BRxIP 0x04 /* Channel B Rx IP */
+#define RR3_AExt 0x08 /* Channel A Ext/Stat IP */
+#define RR3_ATxIP 0x10 /* Channel A Tx IP */
+#define RR3_ARxIP 0x20 /* Channel A Rx IP */
+
+/* Read Register 8 (receive data register) */
+
+/* Read Register 10 (misc status bits) */
+#define RR10_OnLoop 0x02 /* On loop */
+#define RR10_LoopSend 0x10 /* Loop sending */
+#define RR10_Clk2Mis 0x40 /* Two clocks missing */
+#define RR10_Clk1Mis 0x80 /* One clock missing */
+
+/* Read Register 12 (lower byte of baud rate generator constant) */
+
+/* Read Register 13 (upper byte of baud rate generator constant) */
+
+/* Read Register 15 (value of WR 15) */
+
+#define BRTC(brate) (( ((unsigned) DUART_CLOCK) / (2*(brate)*SCC_CLKMODE_TC)) - 2)
+#define DUART_CLOCK 4915200 /* Z8530 duart */
+#define SCC_CLKMODE_TC 16 /* Always run x16 clock for async modes */
+
+static unsigned char select_word_length_WR3[] = {
+ WR3_Rx5, // 5 bits / word (char)
+ WR3_Rx6,
+ WR3_Rx7,
+ WR3_Rx8
+};
+
+static unsigned char select_word_length_WR5[] = {
+ WR5_Tx5, // 5 bits / word (char)
+ WR5_Tx6,
+ WR5_Tx7,
+ WR5_Tx8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ WR4_SB1, // 1 stop bit
+ WR4_SB15, // 1.5 stop bit
+ WR4_SB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ 0, // No parity
+ WR4_ParityEn | WR4_ParityEven, // Even parity
+ WR4_ParityEn, // Odd parity
+ 0xFF, // Mark parity
+ 0xFF, // Space parity
+};
+
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 0, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 0, // 57600
+ 0, // 115200
+ 0, // 230400
+};
+
+#endif // CYGONCE_MIPS_VRC437X_SERIAL_H
diff --git a/ecos/packages/devs/serial/mn10300/mn10300/current/ChangeLog b/ecos/packages/devs/serial/mn10300/mn10300/current/ChangeLog
new file mode 100644
index 0000000..7414cf2
--- /dev/null
+++ b/ecos/packages/devs/serial/mn10300/mn10300/current/ChangeLog
@@ -0,0 +1,1181 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_mn10300.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_mn10300.cdl:
+ Fix 234000->230400 typo.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300_serial.c (mn10300_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_mn10300.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/mn10300/mn10300/current/cdl/ser_mn10300.cdl b/ecos/packages/devs/serial/mn10300/mn10300/current/cdl/ser_mn10300.cdl
new file mode 100644
index 0000000..6d2f192
--- /dev/null
+++ b/ecos/packages/devs/serial/mn10300/mn10300/current/cdl/ser_mn10300.cdl
@@ -0,0 +1,237 @@
+# ====================================================================
+#
+# ser_mn10300.cdl
+#
+# eCos serial MN10300 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_MN10300 {
+ display "MN10300 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_MN10300
+
+ # Note: this is not currently tied to a specific board since the
+ # ports are "on chip"
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ MN10300."
+
+ compile -library=libextras.a mn10300_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_mn10300.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+# FIXME: Bad name
+cdl_option CYGPKG_IO_SERIAL_MN10300_POLLED_MODE {
+ display "MN10300 polled mode serial drivers"
+ flavor bool
+ default_value 0
+ description "
+ If asserted, this option specifies that the serial device
+ drivers for the MN10300 should be polled-mode instead of
+ interrupt driven."
+}
+
+cdl_component CYGPKG_IO_SERIAL_MN10300_SERIAL0 {
+ display "MN10300 serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for port 0 on the
+ MN10300."
+
+ cdl_option CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME {
+ display "Device name for MN10300 serial port 0"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the device name port 0 on the MN10300."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD {
+ display "Baud rate for the MN10300 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ MN10300 port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE {
+ display "Buffer size for the MN10300 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the MN10300 port 0."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_MN10300_SERIAL1 {
+ display "MN10300 serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for port 1 on
+ the MN10300."
+
+ cdl_option CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME {
+ display "Device name for MN10300 serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name port 1 on the MN10300."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD {
+ display "Baud rate for the MN10300 serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ MN10300 port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE {
+ display "Buffer size for the MN10300 serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the MN10300 port 1."
+ }
+}
+cdl_component CYGPKG_IO_SERIAL_MN10300_SERIAL2 {
+ display "MN10300 serial port 2 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for port 2 on the
+ MN10300."
+
+ cdl_option CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME {
+ display "Device name for MN10300 serial port 2"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name port 2 on the MN10300."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD {
+ display "Baud rate for the MN10300 serial port 2 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ MN10300 port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE {
+ display "Buffer size for the MN10300 serial port 2 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the MN10300 port 2."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_MN10300_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_MN10300_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_MN10300_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_mn10300.cdl
diff --git a/ecos/packages/devs/serial/mn10300/mn10300/current/src/mn10300_serial.c b/ecos/packages/devs/serial/mn10300/mn10300/current/src/mn10300_serial.c
new file mode 100644
index 0000000..0a81cbd
--- /dev/null
+++ b/ecos/packages/devs/serial/mn10300/mn10300/current/src/mn10300_serial.c
@@ -0,0 +1,1035 @@
+//==========================================================================
+//
+// mn10300_serial.c
+//
+// Serial device driver for mn10300 on-chip serial devices
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1999-02-25
+// Purpose: MN10300 serial device driver
+// Description: MN10300 serial device driver
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_serial.h>
+#include <cyg/hal/hal_io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/hal/hal_intr.h>
+
+#ifdef CYGPKG_IO_SERIAL_MN10300
+
+#define CYG_HAL_MN10300_SERIAL_RX_FIFO
+
+//-------------------------------------------------------------------------
+
+extern void diag_printf(const char *fmt, ...);
+
+//-------------------------------------------------------------------------
+// Forward definitions
+
+static bool mn10300_serial_init(struct cyg_devtab_entry *tab);
+static bool mn10300_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo mn10300_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char mn10300_serial_getc(serial_channel *chan);
+static Cyg_ErrNo mn10300_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void mn10300_serial_start_xmit(serial_channel *chan);
+static void mn10300_serial_stop_xmit(serial_channel *chan);
+
+#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
+static cyg_uint32 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static cyg_uint32 mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static void mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+#endif
+
+//-------------------------------------------------------------------------
+
+#define BUFSIZE 128
+
+//-------------------------------------------------------------------------
+// MN10300 serial line control register values:
+
+// Offsets to serial control registers from base
+#define SERIAL_CTR 0x0
+#define SERIAL_ICR 0x4
+#define SERIAL_TXB 0x8
+#define SERIAL_RXB 0x9
+#define SERIAL_STR 0xc
+#define SERIAL_TIM 0xd
+
+// Status register bits
+#define SR_RBF 0x10
+#define SR_TBF 0x20
+#define SR_RXF 0x40
+#define SR_TXF 0x80
+
+// Control register bits
+#define LCR_SB1 0x00
+#define LCR_SB1_5 0x00
+#define LCR_SB2 0x04
+#define LCR_PN 0x00 // Parity mode - none
+#define LCR_PS 0x40 // Forced "space" parity
+#define LCR_PM 0x50 // Forced "mark" parity
+#define LCR_PE 0x60 // Parity mode - even
+#define LCR_PO 0x70 // Parity mode - odd
+#define LCR_WL5 0x00 // not supported - use 7bit
+#define LCR_WL6 0x00 // not supported - use 7bit
+#define LCR_WL7 0x00 // 7 bit chars
+#define LCR_WL8 0x80 // 8 bit chars
+#define LCR_RXE 0x4000 // receive enable
+#define LCR_TXE 0x8000 // transmit enable
+
+#if defined(CYGPKG_HAL_MN10300_AM31)
+#define LCR_TWE 0x0100 // interrupt enable (only on serial2/AM31)
+#else
+#define LCR_TWE 0x0000 // Bit does not exist in other variants
+#endif
+
+//-------------------------------------------------------------------------
+// MN10300 timer registers:
+
+#undef TIMER_BR
+#undef TIMER_MD
+#define TIMER_MD 0x00
+#define TIMER_BR 0x10
+
+//-------------------------------------------------------------------------
+// Serial and timer base registers:
+
+#if defined(CYGPKG_HAL_MN10300_AM31)
+
+#define SERIAL0_BASE 0x34000800
+#define SERIAL1_BASE 0x34000810
+#define SERIAL2_BASE 0x34000820
+
+#define TIMER0_BASE 0x34001000
+#define TIMER1_BASE 0x34001001
+#define TIMER2_BASE 0x34001002
+
+#define SERIAL0_TIMER_SELECT 0x0004 // timer 0
+#define SERIAL1_TIMER_SELECT 0x0004 // timer 1
+#define SERIAL2_TIMER_SELECT 0x0001 // timer 2
+
+#ifdef CYGPKG_HAL_MN10300_AM31_STDEVAL1
+// The use of PORT3 to provide CTS/CTR is specific to
+// the STDEVAL1 board only.
+#define PORT3_MD 0x36008025
+#endif
+
+#define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan) \
+CYG_MACRO_START \
+ if( mn10300_chan->is_serial2 ) \
+ cr |= LCR_TWE; \
+ else \
+ cr |= LCR_TXE; \
+CYG_MACRO_END
+
+#define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan) \
+CYG_MACRO_START \
+ if( mn10300_chan->is_serial2 ) \
+ cr &= ~LCR_TWE; \
+ else \
+ cr &= ~LCR_TXE; \
+CYG_MACRO_END
+
+#elif defined(CYGPKG_HAL_MN10300_AM33)
+
+#define SERIAL0_BASE 0xd4002000
+#define SERIAL1_BASE 0xd4002010
+#define SERIAL2_BASE 0xd4002020
+
+#define TIMER0_BASE 0xd4003002
+#define TIMER1_BASE 0xd4003001
+#define TIMER2_BASE 0xd4003003
+
+#define SERIAL0_TIMER_SELECT 0x0005 // timer 2
+#define SERIAL1_TIMER_SELECT 0x0004 // timer 1
+#define SERIAL2_TIMER_SELECT 0x0003 // timer 3
+
+#define HW_TIMER0 0xd4003000
+
+#define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan)
+
+#define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan)
+
+#else
+
+#error Unsupported MN10300 variant
+
+#endif
+
+//-------------------------------------------------------------------------
+// Tables to map input values to hardware settings
+
+static unsigned char select_word_length[] = {
+ LCR_WL5, // 5 bits / word (char)
+ LCR_WL6,
+ LCR_WL7,
+ LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ LCR_SB1, // 1 stop bit
+ LCR_SB1_5, // 1.5 stop bit
+ LCR_SB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ LCR_PN, // No parity
+ LCR_PE, // Even parity
+ LCR_PO, // Odd parity
+ LCR_PM, // Mark parity
+ LCR_PS, // Space parity
+};
+
+#if defined(CYGPKG_HAL_MN10300_AM31)
+
+static unsigned short select_baud_01[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 0, // 110
+ 0, // 134.5
+ 0, // 150
+ 0, // 200
+ 0, // 300
+ 0, // 600
+ 0, // 1200
+ 0, // 1800
+ 0, // 2400
+ 0, // 3600
+ 0, // 4800
+ 0, // 7200
+ 195, // 9600
+ 130, // 14400
+ 98, // 19200
+ 48, // 38400
+ 32, // 57600
+ 16, // 115200
+ 8, // 230400
+};
+
+// Serial 2 has its own timer register in addition to using timer 2 to
+// supply the baud rate generator. Both of these must be proframmed to
+// get the right baud rate. The following values come from Matsushita
+// with some modifications from Cygmon.
+static struct
+{
+ cyg_uint8 serial2_val;
+ cyg_uint8 timer2_val;
+} select_baud_2[] = {
+ { 0, 0 }, // Unused
+ { 0, 0 }, // 50
+ { 0, 0 }, // 75
+ { 0, 0 }, // 110
+ { 0, 0 }, // 134.5
+ { 0, 0 }, // 150
+ { 0, 0 }, // 200
+ { 0, 0 }, // 300
+ { 126, 196 }, // 600
+ { 125, 98 }, // 1200
+ { 0, 0 }, // 1800
+ { 124, 49 }, // 2400
+ { 0, 0 }, // 3600
+ { 124, 24 }, // 4800
+ { 0, 0 }, // 7200
+ { 70, 21 }, // 9600
+ { 0, 0 }, // 14400
+ { 70, 10 }, // 19200
+ { 22, 16 }, // 38400
+ { 88, 2 }, // 57600
+ { 64, 1 }, // 115200
+ { 62, 0 }, // 230400
+};
+
+#elif defined(CYGPKG_HAL_MN10300_AM33)
+
+// The AM33 runs at a different clock rate and therefore has a
+// different set of dividers for the baud rate.
+
+static unsigned short select_baud_01[] = {
+ 0, // Unused
+ 0, // 50
+ 0, // 75
+ 0, // 110
+ 0, // 134.5
+ 0, // 150
+ 0, // 200
+ 0, // 300
+ 0, // 600
+ 3168, // 1200
+ 0, // 1800
+ 1584, // 2400
+ 0, // 3600
+ 792, // 4800
+ 0, // 7200
+ 396, // 9600
+ 0, // 14400
+ 198, // 19200
+ 99, // 38400
+ 0, // 57600
+ 33, // 115200
+ 16, // 230400
+};
+
+// Serial 2 has its own timer register in addition to using timer 2 to
+// supply the baud rate generator. Both of these must be proframmed to
+// get the right baud rate. The following values come from Matsushita
+// with some modifications from Cygmon.
+
+// The values in the following table differ significantly from those
+// given in the Matsushita documentation. These have been determined
+// by (somewhat exhaustive) experiment, the values in the documentation
+// do not appear to work at all.
+
+static struct
+{
+ cyg_uint8 serial2_val;
+ cyg_uint8 timer2_val;
+} select_baud_2[] = {
+ { 0, 0 }, // Unused
+ { 0, 0 }, // 50
+ { 0, 0 }, // 75
+ { 0, 0 }, // 110
+ { 0, 0 }, // 134.5
+ { 0, 0 }, // 150
+ { 0, 0 }, // 200
+ { 0, 0 }, // 300
+ { 0, 0 }, // 600
+ { 0, 0 }, // 1200
+ { 0, 0 }, // 1800
+ { 0, 0 }, // 2400
+ { 0, 0 }, // 3600
+ { 110, 56 }, // 4800
+ { 0, 0 }, // 7200
+ { 110, 28 }, // 9600
+ { 0, 0 }, // 14400
+ { 71, 21 }, // 19200
+ { 102, 7 }, // 38400
+ { 0, 0 }, // 57600
+ { 9, 26 }, // 115200
+ { 0, 0 }, // 230400
+};
+
+#else
+
+#error Unsupported MN10300 variant
+
+#endif
+
+//-------------------------------------------------------------------------
+// Info for each serial device controlled
+
+typedef struct mn10300_serial_info {
+ CYG_ADDRWORD base;
+ CYG_ADDRWORD timer_base;
+ CYG_WORD timer_select;
+ CYG_WORD rx_int;
+ CYG_WORD tx_int;
+ cyg_bool is_serial2;
+ cyg_interrupt rx_interrupt;
+ cyg_interrupt tx_interrupt;
+ cyg_handle_t rx_interrupt_handle;
+ cyg_handle_t tx_interrupt_handle;
+#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO
+ volatile cyg_int32 fifo_head;
+ volatile cyg_int32 fifo_tail;
+ volatile cyg_uint8 fifo[16];
+#endif
+} mn10300_serial_info;
+
+//-------------------------------------------------------------------------
+// Callback functions exported by this driver
+
+static SERIAL_FUNS(mn10300_serial_funs,
+ mn10300_serial_putc,
+ mn10300_serial_getc,
+ mn10300_serial_set_config,
+ mn10300_serial_start_xmit,
+ mn10300_serial_stop_xmit
+ );
+
+//-------------------------------------------------------------------------
+// Hardware info for each serial line
+
+#ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1
+#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0
+static mn10300_serial_info mn10300_serial_info0 = {
+ SERIAL0_BASE,
+ TIMER0_BASE,
+ SERIAL0_TIMER_SELECT,
+ CYGNUM_HAL_INTERRUPT_SERIAL_0_RX,
+ CYGNUM_HAL_INTERRUPT_SERIAL_0_TX,
+ false
+};
+#if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0
+static unsigned char mn10300_serial_out_buf0[CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE];
+static unsigned char mn10300_serial_in_buf0[CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE];
+#endif
+#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1
+static mn10300_serial_info mn10300_serial_info1 = {
+ SERIAL1_BASE,
+ TIMER1_BASE,
+ SERIAL1_TIMER_SELECT,
+ CYGNUM_HAL_INTERRUPT_SERIAL_1_RX,
+ CYGNUM_HAL_INTERRUPT_SERIAL_1_TX,
+ false
+};
+#if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0
+static unsigned char mn10300_serial_out_buf1[CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE];
+static unsigned char mn10300_serial_in_buf1[CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE];
+#endif
+#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1
+
+#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2
+static mn10300_serial_info mn10300_serial_info2 = {
+ SERIAL2_BASE,
+ TIMER2_BASE,
+ SERIAL2_TIMER_SELECT,
+ CYGNUM_HAL_INTERRUPT_SERIAL_2_RX,
+ CYGNUM_HAL_INTERRUPT_SERIAL_2_TX,
+ true
+};
+#if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0
+static unsigned char mn10300_serial_out_buf2[CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE];
+static unsigned char mn10300_serial_in_buf2[CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE];
+#endif
+#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2
+
+
+//-------------------------------------------------------------------------
+// Channel descriptions:
+
+#ifdef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
+#define SIZEOF_BUF(_x_) 0
+#else
+#define SIZEOF_BUF(_x_) sizeof(_x_)
+#endif
+
+#ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1
+#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0
+#if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0
+static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel0,
+ mn10300_serial_funs,
+ mn10300_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mn10300_serial_out_buf0[0],
+ SIZEOF_BUF(mn10300_serial_out_buf0),
+ &mn10300_serial_in_buf0[0],
+ SIZEOF_BUF(mn10300_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(mn10300_serial_channel0,
+ mn10300_serial_funs,
+ mn10300_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1
+#if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0
+static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel1,
+ mn10300_serial_funs,
+ mn10300_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mn10300_serial_out_buf1[0],
+ SIZEOF_BUF(mn10300_serial_out_buf1),
+ &mn10300_serial_in_buf1[0],
+ SIZEOF_BUF(mn10300_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(mn10300_serial_channel1,
+ mn10300_serial_funs,
+ mn10300_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1
+
+#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2
+#if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0
+static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel2,
+ mn10300_serial_funs,
+ mn10300_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mn10300_serial_out_buf2[0],
+ SIZEOF_BUF(mn10300_serial_out_buf2),
+ &mn10300_serial_in_buf2[0],
+ SIZEOF_BUF(mn10300_serial_in_buf2)
+ );
+#else
+static SERIAL_CHANNEL(mn10300_serial_channel2,
+ mn10300_serial_funs,
+ mn10300_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2
+
+//-------------------------------------------------------------------------
+// And finally, the device table entries:
+
+#ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1
+#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0
+// On the standard eval board serial0 is not connected. If enabled, it
+// generates continuous frame error and overrun interrupts. Hence we do
+// not touch it.
+DEVTAB_ENTRY(mn10300_serial_io0,
+ CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mn10300_serial_init,
+ mn10300_serial_lookup, // Serial driver may need initializing
+ &mn10300_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1
+DEVTAB_ENTRY(mn10300_serial_io1,
+ CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mn10300_serial_init,
+ mn10300_serial_lookup, // Serial driver may need initializing
+ &mn10300_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1
+
+#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2
+DEVTAB_ENTRY(mn10300_serial_io2,
+ CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mn10300_serial_init,
+ mn10300_serial_lookup, // Serial driver may need initializing
+ &mn10300_serial_channel2
+ );
+#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2
+
+//-------------------------------------------------------------------------
+// Read the serial line's status register. Serial 2 has an 8 bit status
+// register while serials 0 and 1 have 16 bit registers. This function
+// uses the correct size access, but passes back a 16 bit quantity for
+// both.
+
+static cyg_uint16 mn10300_read_sr( mn10300_serial_info *mn10300_chan )
+{
+ cyg_uint16 sr = 0;
+ if( mn10300_chan->is_serial2 )
+ {
+ cyg_uint8 sr8;
+ HAL_READ_UINT8(mn10300_chan->base+SERIAL_STR, sr8);
+ sr = sr8;
+ }
+ else
+ {
+ HAL_READ_UINT16(mn10300_chan->base+SERIAL_STR, sr);
+ }
+
+ return sr;
+}
+
+//-------------------------------------------------------------------------
+
+static bool
+mn10300_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+ cyg_uint16 cr = 0;
+ cyg_uint16 sr;
+
+ // wait for the device to become quiescent. This could take some time
+ // if the device had been transmitting at a low baud rate.
+ do {
+ sr = mn10300_read_sr(mn10300_chan);
+ } while (sr & (SR_RXF|SR_TXF));
+
+ // Disable device entirely.
+ HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, 0);
+
+ // Set up the Interrupt Mode Register
+ HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_ICR, 0);
+
+ // Set up baud rate
+ if( mn10300_chan->is_serial2 )
+ {
+ // Serial 2 is a bit different from 0 and 1 in the way that the
+ // baud rate is controlled.
+
+ cyg_uint8 baud_divisor = select_baud_2[new_config->baud].timer2_val;
+
+ if (baud_divisor == 0)
+ return false; // Invalid baud rate selected
+
+ HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor);
+
+ HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, 0x80 );
+
+ baud_divisor = select_baud_2[new_config->baud].serial2_val;
+
+ HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_TIM, baud_divisor);
+
+ cr |= mn10300_chan->timer_select;
+ }
+ else
+ {
+ cyg_uint16 baud_divisor = select_baud_01[new_config->baud];
+ cyg_uint8 timer_mode = 0x80;
+
+ if (baud_divisor == 0)
+ return false; // Invalid baud rate selected
+
+#if defined(CYGPKG_HAL_MN10300_AM33)
+ if( baud_divisor > 255 )
+ {
+ // The AM33 runs at a higher clock rate than the AM31 and
+ // needs a bigger divisor for low baud rates. We do this by
+ // using timer 0 as a prescaler. We set it to 198 so we can then
+ // use it to prescale for both serial0 and serial1 if they need
+ // it.
+ static int timer0_initialized = 0;
+ baud_divisor /= 198;
+ baud_divisor--;
+ timer_mode = 0x84;
+ if( !timer0_initialized )
+ {
+ timer0_initialized = 1;
+ HAL_WRITE_UINT8(HW_TIMER0+TIMER_BR, 198 );
+ HAL_WRITE_UINT8(HW_TIMER0+TIMER_MD, 0x80 );
+ }
+ }
+#endif
+
+ HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor);
+
+ HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, timer_mode );
+
+ cr |= mn10300_chan->timer_select;
+ }
+
+#ifdef PORT3_MD
+ HAL_WRITE_UINT8( PORT3_MD, 0x01 );
+#endif
+
+ // set up other config values:
+
+ cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];
+ cr |= select_stop_bits[new_config->stop];
+ cr |= select_parity[new_config->parity];
+
+ cr |= LCR_RXE | LCR_TXE; // enable Rx and Tx
+
+#ifdef CYGPKG_HAL_MN10300_AM31
+ if( mn10300_chan->is_serial2 )
+ {
+ // AM31 has an extra TX interrupt enable bit for serial 2.
+ DISABLE_TRANSMIT_INTERRUPT(mn10300_chan);
+ }
+#endif
+
+ // Write CR into hardware
+ HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, cr);
+
+ sr = mn10300_read_sr(mn10300_chan);
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+//-------------------------------------------------------------------------
+// Function to initialize the device. Called at bootstrap time.
+
+bool mn10300_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+
+#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
+ if (chan->out_cbuf.len != 0) {
+ // Install and enable the receive interrupt
+ cyg_drv_interrupt_create(mn10300_chan->rx_int,
+ 4, // Priority - what goes here?
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ mn10300_serial_rx_ISR,
+ mn10300_serial_rx_DSR,
+ &mn10300_chan->rx_interrupt_handle,
+ &mn10300_chan->rx_interrupt);
+ cyg_drv_interrupt_attach(mn10300_chan->rx_interrupt_handle);
+ cyg_drv_interrupt_unmask(mn10300_chan->rx_int);
+
+ // Install and enable the transmit interrupt
+ cyg_drv_interrupt_create(mn10300_chan->tx_int,
+ 4, // Priority - what goes here?
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ mn10300_serial_tx_ISR,
+ mn10300_serial_tx_DSR,
+ &mn10300_chan->tx_interrupt_handle,
+ &mn10300_chan->tx_interrupt);
+ cyg_drv_interrupt_attach(mn10300_chan->tx_interrupt_handle);
+ cyg_drv_interrupt_mask(mn10300_chan->tx_int);
+ }
+#endif
+
+ mn10300_serial_config_port(chan, &chan->config, true);
+
+ return true;
+}
+
+//-------------------------------------------------------------------------
+// This routine is called when the device is "looked" up (i.e. attached)
+
+static Cyg_ErrNo
+mn10300_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+//-------------------------------------------------------------------------
+// Return 'true' if character is sent to device
+
+bool
+mn10300_serial_putc(serial_channel *chan, unsigned char c)
+{
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+ cyg_uint8 sr = mn10300_read_sr( mn10300_chan);
+
+ if( (sr & SR_TBF) == 0 )
+ {
+ HAL_WRITE_UINT8( mn10300_chan->base+SERIAL_TXB, c );
+
+ return true;
+ }
+ else return false;
+}
+
+//-------------------------------------------------------------------------
+
+unsigned char
+mn10300_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+ do
+ {
+ cyg_uint8 sr = mn10300_read_sr( mn10300_chan );
+
+ if( (sr & SR_RBF) != 0 )
+ {
+ HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c );
+
+ break;
+ }
+
+ } while(1);
+
+ return c;
+}
+
+//-------------------------------------------------------------------------
+
+static Cyg_ErrNo
+mn10300_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != mn10300_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+//-------------------------------------------------------------------------
+// Enable the transmitter on the device
+
+static void
+mn10300_serial_start_xmit(serial_channel *chan)
+{
+#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+ cyg_uint16 cr;
+
+ HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
+
+ ENABLE_TRANSMIT_INTERRUPT(mn10300_chan);
+
+ HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
+
+ cyg_drv_interrupt_unmask(mn10300_chan->tx_int);
+
+ (chan->callbacks->xmt_char)(chan);
+#endif
+}
+
+//-------------------------------------------------------------------------
+// Disable the transmitter on the device
+
+static void
+mn10300_serial_stop_xmit(serial_channel *chan)
+{
+#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+ cyg_uint16 cr;
+ cyg_uint16 sr;
+
+ // Wait until the transmitter has actually stopped before turning it off.
+
+ do
+ {
+ sr = mn10300_read_sr( mn10300_chan );
+
+ } while( sr & SR_TXF );
+
+ HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
+
+ DISABLE_TRANSMIT_INTERRUPT(mn10300_chan);
+
+ HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
+
+ cyg_drv_interrupt_mask(mn10300_chan->tx_int);
+
+#endif
+}
+
+//-------------------------------------------------------------------------
+// Serial I/O - low level interrupt handlers (ISR)
+
+#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
+
+#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO
+
+// This version of the RX ISR implements a simple receive FIFO. The
+// MN10300 serial devices do not have hardware FIFOs (as found in
+// 16550s for example), and it can be difficult at times to keep up
+// with higher baud rates without overrunning. This ISR implements a
+// software equivalent of the hardware FIFO, placing recieved
+// characters into the FIFO as soon as they arrive. Whenever the DSR
+// is run, it collects all the pending characters from the FIFO for
+// delivery to the application. Neither the ISR or DSR disable
+// interrupts, instead we rely on being able to write the head and
+// tail pointers atomically, to implement lock-free synchronization.
+
+static cyg_uint32
+mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+ cyg_uint8 sr = mn10300_read_sr( mn10300_chan);
+
+ while( (sr & SR_RBF) != 0 )
+ {
+ register cyg_int32 head = mn10300_chan->fifo_head;
+ cyg_uint8 c;
+ int i;
+ HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c );
+
+ mn10300_chan->fifo[head++] = c;
+
+ if( head >= sizeof(mn10300_chan->fifo) )
+ head = 0;
+
+ mn10300_chan->fifo_head = head;
+
+ sr = mn10300_read_sr( mn10300_chan);
+
+ }
+
+ cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int);
+
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+#else
+
+static cyg_uint32
+mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mn10300_chan->rx_int);
+ cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int);
+
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+#endif
+
+static cyg_uint32
+mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mn10300_chan->tx_int);
+ cyg_drv_interrupt_acknowledge(mn10300_chan->tx_int);
+
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+#endif
+
+//-------------------------------------------------------------------------
+// Serial I/O - high level interrupt handler (DSR)
+
+#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE
+
+#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO
+
+static void
+mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+ register cyg_int32 head = mn10300_chan->fifo_head;
+ register cyg_int32 tail = mn10300_chan->fifo_tail;
+
+ while( head != tail )
+ {
+ cyg_uint8 c = mn10300_chan->fifo[tail++];
+
+ if( tail >= sizeof(mn10300_chan->fifo) ) tail = 0;
+
+ (chan->callbacks->rcv_char)(chan, c);
+ }
+
+ mn10300_chan->fifo_tail = tail;
+}
+
+#else
+
+static void
+mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+ cyg_uint8 sr = mn10300_read_sr( mn10300_chan);
+
+ if( (sr & SR_RBF) != 0 )
+ {
+ cyg_uint8 rxb;
+ HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, rxb );
+
+ (chan->callbacks->rcv_char)(chan, rxb);
+ }
+
+ cyg_drv_interrupt_unmask(mn10300_chan->rx_int);
+}
+
+#endif
+
+static void
+mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
+ cyg_uint8 sr = mn10300_read_sr( mn10300_chan);
+
+ if( (sr & SR_TBF) == 0 )
+ {
+ (chan->callbacks->xmt_char)(chan);
+ }
+
+ cyg_drv_interrupt_unmask(mn10300_chan->tx_int);
+}
+
+#endif
+
+#endif // CYGPKG_IO_SERIAL_MN10300
+
+//-------------------------------------------------------------------------
+// EOF mn10300.c
diff --git a/ecos/packages/devs/serial/powerpc/cogent/current/ChangeLog b/ecos/packages/devs/serial/powerpc/cogent/current/ChangeLog
new file mode 100644
index 0000000..b47655e
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/cogent/current/ChangeLog
@@ -0,0 +1,1185 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_powerpc_cogent.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_powerpc_cogent.cdl:
+ Fix 234000->230400 typo.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_powerpc_cogent.cdl: Moved testing parameters here.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/cogent_serial_with_ints.c (cogent_serial_set_config): Now use
+ keys to make more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/powerpc/cogent/current/cdl/ser_powerpc_cogent.cdl b/ecos/packages/devs/serial/powerpc/cogent/current/cdl/ser_powerpc_cogent.cdl
new file mode 100644
index 0000000..8659afa
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/cogent/current/cdl/ser_powerpc_cogent.cdl
@@ -0,0 +1,206 @@
+# ====================================================================
+#
+# ser_powerpc_cogent.cdl
+#
+# eCos serial PowerPC/Cogent configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-14
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_POWERPC_COGENT {
+ display "Cogent PowerPC serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_POWERPC_COGENT
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ Cogent PowerPC."
+
+ compile -library=libextras.a cogent_serial_with_ints.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_powerpc_cogent.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_A {
+ display "Cogent PowerPC serial port A driver"
+ flavor bool
+ default_value 0
+ requires (CYGIMP_KERNEL_INTERRUPTS_CHAIN || \
+ !CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B)
+ description "
+ This option includes the serial device driver for the Cogent
+ PowerPC port A. If both drivers need to be enabled, interrupt
+ chaining must be enabled in the kernel configuration."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_A_NAME {
+ display "Device name for Cogent PowerPC serial port A"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the Cogent PowerPC
+ port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BAUD {
+ display "Baud rate for the Cogent PowerPC serial port A driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ Cogent PowerPC port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE {
+ display "Buffer size for the Cogent PowerPC serial port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the Cogent PowerPC port A."
+ }
+}
+cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B {
+ display "Cogent PowerPC serial port B driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the Cogent
+ PowerPC port B."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME {
+ display "Device name for Cogent PowerPC serial port B"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the Cogent PowerPC
+ port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BAUD {
+ display "Baud rate for the Cogent PowerPC serial port B driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ Cogent PowerPC port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE {
+ display "Buffer size for the Cogent PowerPC serial port B driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the Cogent PowerPC port B."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_COGENT_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_COGENT_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"ppccog\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty2\""
+ }
+ }
+}
+
+# EOF ser_powerpc_cogent.cdl
diff --git a/ecos/packages/devs/serial/powerpc/cogent/current/src/cogent_serial.h b/ecos/packages/devs/serial/powerpc/cogent/current/src/cogent_serial.h
new file mode 100644
index 0000000..40a39cd
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/cogent/current/src/cogent_serial.h
@@ -0,0 +1,212 @@
+//==========================================================================
+//
+// io/serial/powerpc/cogent_serial.h
+//
+// PowerPC Cogent Serial I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, based on ARM driver by gthomas
+// Contributors:gthomas, jskov
+// Date: 1999-03-02
+// Purpose: Cogent Serial definitions
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// Description of serial ports on Cogent board
+
+// Interrupt Enable Register
+#define IER_RCV 0x01
+#define IER_XMT 0x02
+#define IER_LS 0x04
+#define IER_MS 0x08
+
+// Line Control Register
+#define LCR_WL5 0x00 // Word length
+#define LCR_WL6 0x01
+#define LCR_WL7 0x02
+#define LCR_WL8 0x03
+#define LCR_SB1 0x00 // Number of stop bits
+#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words
+#define LCR_SB2 0x04
+#define LCR_PN 0x00 // Parity mode - none
+#define LCR_PE 0x0C // Parity mode - even
+#define LCR_PO 0x08 // Parity mode - odd
+#define LCR_PM 0x28 // Forced "mark" parity
+#define LCR_PS 0x38 // Forced "space" parity
+#define LCR_DL 0x80 // Enable baud rate latch
+
+// Line Status Register
+#define LSR_RSR 0x01
+#define LSR_THE 0x20
+
+// Modem Control Register
+#define MCR_DTR 0x01
+#define MCR_RTS 0x02
+#define MCR_INT 0x08 // Enable interrupts
+
+// Interrupt status register
+#define ISR_Tx 0x02
+#define ISR_Rx 0x04
+
+// FIFO control register
+#define FCR_ENABLE 0x01
+#define FCR_CLEAR_RCVR 0x02
+#define FCR_CLEAR_XMIT 0x04
+
+
+////////////////////////////////////////////////////////////
+// Clean this up.
+
+//-----------------------------------------------------------------------------
+// There are two serial ports.
+#define CMA_SER_16550_BASE_A 0xe900047 // port A
+#define CMA_SER_16550_BASE_B 0xe900007 // port B
+#define SER_16550_BASE CMA_SER_16550_BASE_B
+
+//-----------------------------------------------------------------------------
+// Define the serial registers. The Cogent board is equipped with a 16552
+// serial chip.
+#define SER_16550_RBR 0x00 // receiver buffer register, read, dlab = 0
+#define SER_16550_THR 0x00 // transmitter holding register, write, dlab = 0
+#define SER_16550_DLL 0x00 // divisor latch (LS), read/write, dlab = 1
+#define SER_16550_IER 0x08 // interrupt enable register, read/write, dlab = 0
+#define SER_16550_DLM 0x08 // divisor latch (MS), read/write, dlab = 1
+#define SER_16550_IIR 0x10 // interrupt identification reg, read, dlab = 0
+#define SER_16550_FCR 0x10 // fifo control register, write, dlab = 0
+#define SER_16550_AFR 0x10 // alternate function reg, read/write, dlab = 1
+#define SER_16550_LCR 0x18 // line control register, read/write
+#define SER_16550_MCR 0x20 // modem control register, read/write
+#define SER_16550_LSR 0x28 // line status register, read
+#define SER_16550_MSR 0x30 // modem status register, read
+#define SER_16550_SCR 0x38 // scratch pad register
+
+// The interrupt enable register bits.
+#define SIO_IER_ERDAI 0x01 // enable received data available irq
+#define SIO_IER_ETHREI 0x02 // enable THR empty interrupt
+#define SIO_IER_ELSI 0x04 // enable receiver line status irq
+#define SIO_IER_EMSI 0x08 // enable modem status interrupt
+
+// The interrupt identification register bits.
+#define SIO_IIR_IP 0x01 // 0 if interrupt pending
+#define SIO_IIR_ID_MASK 0x0e // mask for interrupt ID bits
+
+// The line status register bits.
+#define SIO_LSR_DR 0x01 // data ready
+#define SIO_LSR_OE 0x02 // overrun error
+#define SIO_LSR_PE 0x04 // parity error
+#define SIO_LSR_FE 0x08 // framing error
+#define SIO_LSR_BI 0x10 // break interrupt
+#define SIO_LSR_THRE 0x20 // transmitter holding register empty
+#define SIO_LSR_TEMT 0x40 // transmitter register empty
+#define SIO_LSR_ERR 0x80 // any error condition
+
+// The modem status register bits.
+#define SIO_MSR_DCTS 0x01 // delta clear to send
+#define SIO_MSR_DDSR 0x02 // delta data set ready
+#define SIO_MSR_TERI 0x04 // trailing edge ring indicator
+#define SIO_MSR_DDCD 0x08 // delta data carrier detect
+#define SIO_MSR_CTS 0x10 // clear to send
+#define SIO_MSR_DSR 0x20 // data set ready
+#define SIO_MSR_RI 0x40 // ring indicator
+#define SIO_MSR_DCD 0x80 // data carrier detect
+
+// The line control register bits.
+#define SIO_LCR_WLS0 0x01 // word length select bit 0
+#define SIO_LCR_WLS1 0x02 // word length select bit 1
+#define SIO_LCR_STB 0x04 // number of stop bits
+#define SIO_LCR_PEN 0x08 // parity enable
+#define SIO_LCR_EPS 0x10 // even parity select
+#define SIO_LCR_SP 0x20 // stick parity
+#define SIO_LCR_SB 0x40 // set break
+#define SIO_LCR_DLAB 0x80 // divisor latch access bit
+
+// The FIFO control register
+#define SIO_FCR_FCR0 0x01 // enable xmit and rcvr fifos
+#define SIO_FCR_FCR1 0x02 // clear RCVR FIFO
+#define SIO_FCR_FCR2 0x04 // clear XMIT FIFO
+/////////////////////////////////////////
+
+
+static unsigned char select_word_length[] = {
+ LCR_WL5, // 5 bits / word (char)
+ LCR_WL6,
+ LCR_WL7,
+ LCR_WL8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ LCR_SB1, // 1 stop bit
+ LCR_SB1_5, // 1.5 stop bit
+ LCR_SB2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ LCR_PN, // No parity
+ LCR_PE, // Even parity
+ LCR_PO, // Odd parity
+ LCR_PM, // Mark parity
+ LCR_PS, // Space parity
+};
+
+// FIXME: calc all properly
+// The Cogent board has a 3.6864 MHz crystal
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 4608, // 50
+ 0, // 75
+ 2094, // 110
+ 0, // 134.5
+ 1536, // 150
+ 0, // 200
+ 768, // 300
+ 384, // 600
+ 182, // 1200
+ 0, // 1800
+ 96, // 2400
+ 0, // 3600
+ 48, // 4800
+ 32, // 7200
+ 24, // 9600
+ 16, // 14400
+ 12, // 19200
+ 6, // 38400
+ 4, // 57600
+ 2, // 115200
+ 0, // 230400
+};
+
diff --git a/ecos/packages/devs/serial/powerpc/cogent/current/src/cogent_serial_with_ints.c b/ecos/packages/devs/serial/powerpc/cogent/current/src/cogent_serial_with_ints.c
new file mode 100644
index 0000000..30d7376
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/cogent/current/src/cogent_serial_with_ints.c
@@ -0,0 +1,412 @@
+//==========================================================================
+//
+// io/serial/powerpc/cogent_serial_with_ints.c
+//
+// PowerPC Cogent Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov, based on ARM driver by gthomas
+// Contributors:gthomas, jskov
+// Date: 1999-03-02
+// Purpose: Cogent Serial I/O module (interrupt driven version)
+// Description:
+//
+// To Do:
+// Put in magic to effectively use the FIFOs. Transmitter FIFO fill is a
+// problem, and setting receiver FIFO interrupts to happen only after
+// n chars may conflict with hal diag.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_COGENT
+
+#include "cogent_serial.h"
+
+// Make sure the configuration is sane.
+#if defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_A) && \
+ defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B) && \
+ !defined(CYGIMP_KERNEL_INTERRUPTS_CHAIN)
+#error "Need CYGIMP_KERNEL_INTERRUPTS_CHAIN to support both ports"
+#endif
+
+
+#define BUFSIZE 128
+
+typedef struct cogent_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} cogent_serial_info;
+
+static bool cogent_serial_init(struct cyg_devtab_entry *tab);
+static bool cogent_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo cogent_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char cogent_serial_getc(serial_channel *chan);
+static Cyg_ErrNo cogent_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void cogent_serial_start_xmit(serial_channel *chan);
+static void cogent_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 cogent_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void cogent_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(cogent_serial_funs,
+ cogent_serial_putc,
+ cogent_serial_getc,
+ cogent_serial_set_config,
+ cogent_serial_start_xmit,
+ cogent_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_A
+static cogent_serial_info cogent_serial_info0 ={CMA_SER_16550_BASE_A,
+ CYGNUM_HAL_INTERRUPT_SIU_IRQ1};
+#if CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE > 0
+static unsigned char cogent_serial_out_buf0[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE];
+static unsigned char cogent_serial_in_buf0[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(cogent_serial_channel0,
+ cogent_serial_funs,
+ cogent_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &cogent_serial_out_buf0[0],
+ sizeof(cogent_serial_out_buf0),
+ &cogent_serial_in_buf0[0],
+ sizeof(cogent_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(cogent_serial_channel0,
+ cogent_serial_funs,
+ cogent_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(cogent_serial_io0,
+ CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_A_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ cogent_serial_init,
+ cogent_serial_lookup, // Serial driver may need initializing
+ &cogent_serial_channel0
+ );
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B
+static cogent_serial_info cogent_serial_info1 ={CMA_SER_16550_BASE_B,
+ CYGNUM_HAL_INTERRUPT_SIU_IRQ1};
+#if CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE > 0
+static unsigned char cogent_serial_out_buf1[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE];
+static unsigned char cogent_serial_in_buf1[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(cogent_serial_channel1,
+ cogent_serial_funs,
+ cogent_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &cogent_serial_out_buf1[0],
+ sizeof(cogent_serial_out_buf1),
+ &cogent_serial_in_buf1[0],
+ sizeof(cogent_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(cogent_serial_channel1,
+ cogent_serial_funs,
+ cogent_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(cogent_serial_io1,
+ CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ cogent_serial_init,
+ cogent_serial_lookup, // Serial driver may need initializing
+ &cogent_serial_channel1
+ );
+#endif
+
+
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+cogent_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = cogent_chan->base;
+ cyg_uint16 baud_divisor = select_baud[new_config->baud];
+ cyg_uint8 _lcr, _ier;
+
+ if (baud_divisor == 0)
+ return false; // Invalid baud rate selected
+
+ // Disable port interrupts while changing hardware
+ HAL_READ_UINT8(port+SER_16550_IER, _ier);
+ HAL_WRITE_UINT8(port+SER_16550_IER, 0);
+
+ // Set databits, stopbits and parity.
+ _lcr = select_word_length[(new_config->word_length -
+ CYGNUM_SERIAL_WORD_LENGTH_5)] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr);
+
+ // Set baud rate.
+ _lcr |= LCR_DL;
+ HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr);
+ HAL_WRITE_UINT8(port+SER_16550_DLM, baud_divisor >> 8);
+ HAL_WRITE_UINT8(port+SER_16550_DLL, baud_divisor & 0xff);
+ _lcr &= ~LCR_DL;
+ HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr);
+
+ if (init) {
+ // Enable and clear FIFO
+ HAL_WRITE_UINT8(port+SER_16550_FCR,
+ (FCR_ENABLE | FCR_CLEAR_RCVR | FCR_CLEAR_XMIT));
+
+ if (chan->out_cbuf.len != 0) {
+ HAL_WRITE_UINT8(port+SER_16550_IER, SIO_IER_ERDAI);
+ } else {
+ HAL_WRITE_UINT8(port+SER_16550_IER, 0);
+ }
+
+ {
+ // Special initialization for ST16C552 on CMA102
+ cyg_uint8 mcr;
+
+ HAL_READ_UINT8(CMA_SER_16550_BASE_A+SER_16550_MCR, mcr);
+ mcr |= 8;
+ HAL_WRITE_UINT8(CMA_SER_16550_BASE_A+SER_16550_MCR, mcr);
+
+ HAL_READ_UINT8(CMA_SER_16550_BASE_B+SER_16550_MCR, mcr);
+ mcr |= 8;
+ HAL_WRITE_UINT8(CMA_SER_16550_BASE_B+SER_16550_MCR, mcr);
+ }
+ } else {
+ HAL_WRITE_UINT8(port+SER_16550_IER, _ier);
+ }
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+cogent_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("COGENT SERIAL init - dev: %x.%d\n", cogent_chan->base, cogent_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(cogent_chan->int_num,
+ 0, // can change IRQ0 priority
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ cogent_serial_ISR,
+ cogent_serial_DSR,
+ &cogent_chan->serial_interrupt_handle,
+ &cogent_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(cogent_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(cogent_chan->int_num);
+ }
+ cogent_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+cogent_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+cogent_serial_putc(serial_channel *chan, unsigned char c)
+{
+ cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = cogent_chan->base;
+ cyg_uint8 _lsr;
+
+ HAL_READ_UINT8(port+SER_16550_LSR, _lsr);
+ if (_lsr & SIO_LSR_THRE) {
+// Transmit buffer is empty
+ HAL_WRITE_UINT8(port+SER_16550_THR, c);
+ return true;
+ } else {
+// No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+cogent_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = cogent_chan->base;
+ cyg_uint8 _lsr;
+
+ do {
+ HAL_READ_UINT8(port+SER_16550_LSR, _lsr);
+ } while ((_lsr & SIO_LSR_DR) == 0);
+
+ HAL_READ_UINT8(port+SER_16550_RBR, c);
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+cogent_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != cogent_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+cogent_serial_start_xmit(serial_channel *chan)
+{
+ cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = cogent_chan->base;
+ cyg_uint8 _ier;
+
+ HAL_READ_UINT8(port+SER_16550_IER, _ier);
+ _ier |= IER_XMT; // Enable xmit interrupt
+ HAL_WRITE_UINT8(port+SER_16550_IER, _ier);
+
+ (chan->callbacks->xmt_char)(chan);
+}
+
+// Disable the transmitter on the device
+static void
+cogent_serial_stop_xmit(serial_channel *chan)
+{
+ cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = cogent_chan->base;
+ cyg_uint8 _ier;
+
+ HAL_READ_UINT8(port+SER_16550_IER, _ier);
+ _ier &= ~IER_XMT; // Disable xmit interrupt
+ HAL_WRITE_UINT8(port+SER_16550_IER, _ier);
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+cogent_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(cogent_chan->int_num);
+ cyg_drv_interrupt_acknowledge(cogent_chan->int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+cogent_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = cogent_chan->base;
+ cyg_uint8 _iir;
+
+ HAL_READ_UINT8(port+SER_16550_IIR, _iir);
+ _iir &= SIO_IIR_ID_MASK;
+ if ( ISR_Tx == _iir ) {
+ (chan->callbacks->xmt_char)(chan);
+ } else if ( ISR_Rx == _iir ) {
+ cyg_uint8 _c;
+ HAL_READ_UINT8(port+SER_16550_RBR, _c);
+ (chan->callbacks->rcv_char)(chan, _c);
+ }
+ cyg_drv_interrupt_unmask(cogent_chan->int_num);
+}
+#endif
diff --git a/ecos/packages/devs/serial/powerpc/mpc555/current/ChangeLog b/ecos/packages/devs/serial/powerpc/mpc555/current/ChangeLog
new file mode 100644
index 0000000..750cd75
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/mpc555/current/ChangeLog
@@ -0,0 +1,59 @@
+2008-12-23 Steven Clugston <steven.clugston@ncl.ac.uk>
+
+ * cdl/ser_powerpc_mpc555.cdl: Add HW queue option
+ * src/mpc555_serial_with_ints.c:
+ To help resolve an issue of characters being lost a software buffer
+ has been added between the Rx ISR and DSR when no hardware queue is
+ being used.
+ A cdl option to enable support the hardware queue on the first serial
+ port has been added. This enables 16 character hardware Tx and Rx
+ buffers to be used which allows continuous transmission and reception
+ of serial data and significantly improves performance.
+
+2008-05-13 Steven Clugston <steven.clugston@ncl.ac.uk>
+
+ * cdl/ser_powerpc_mpc555.cdl: Add line status
+ * src/mpc555_serial_with_ints.c:
+ Fixed exception caused by attempt to clear scsr bits.
+ Add line status callbacks
+
+2008-04-06 Steven Clugston <steven.clugston@ncl.ac.uk>
+
+ * Refactored package to more generic mpc555
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_powerpc_cme555.cdl: Remove irrelevant doc link.
+
+2002-11-11 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * src/cme555_serial_with_ints.c:
+ interrupt arbiter slightly modified to make GDB CTRL-C work
+
+2002-04-24 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/powerpc/mpc555/current/cdl/ser_powerpc_mpc555.cdl b/ecos/packages/devs/serial/powerpc/mpc555/current/cdl/ser_powerpc_mpc555.cdl
new file mode 100644
index 0000000..f25a447
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/mpc555/current/cdl/ser_powerpc_mpc555.cdl
@@ -0,0 +1,196 @@
+# ====================================================================
+#
+# ser_powerpc_mpc555.cdl
+#
+# eCos serial PowerPC/mpc555 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Bob Koninckx
+# Original data:
+# Contributors:
+# Date: 1999-07-14
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_POWERPC_MPC555 {
+ display "mpc555 PowerPC serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_POWERPC_MPC555
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ mpc555 mpc555 development board."
+
+ compile -library=libextras.a mpc555_serial_with_ints.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_powerpc_mpc555.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A {
+ display "mpc555 PowerPC serial port A driver"
+ flavor bool
+ default_value 0
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+ implements CYGINT_IO_SERIAL_BLOCK_TRANSFER
+ description "
+ This option includes the serial device driver for the mpc555
+ PowerPC port A."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_NAME {
+ display "Device name for mpc555 PowerPC serial port A"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the mpc555 PowerPC
+ port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BAUD {
+ display "Baud rate for the mpc555 PowerPC serial port A driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ mpc555 PowerPC port A."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE {
+ display "Buffer size for the mpc555 PowerPC serial port A driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the mpc555 PowerPC port A."
+ }
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_USE_HWARE_QUEUE {
+ display "Use hardware queue for mpc555 PowerPC serial port A"
+ flavor bool
+ default_value 1
+ description "
+ This option specifies if the QSCI 16-byte hardware queue
+ is used for the mpc555 PowerPC port A. Using the queue
+ makes block transfers possible. Select this option
+ if you need to support continuous transmission and reception
+ without buffer overruns occurring."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B {
+ display "mpc555 PowerPC serial port B driver"
+ flavor bool
+ default_value 1
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+ description "
+ This option includes the serial device driver for the mpc555
+ PowerPC port B."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_B_NAME {
+ display "Device name for mpc555 PowerPC serial port B"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the mpc555 PowerPC
+ port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BAUD {
+ display "Baud rate for the mpc555 PowerPC serial port B driver"
+ flavor data
+ legal_values { 300 600 1200 2400 4800 9600 14400 19200 38400 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ mpc555 PowerPC port B."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BUFSIZE {
+ display "Buffer size for the mpc555 PowerPC serial port B driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the mpc555 PowerPC port B."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC555_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_MPC555_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_MPC555_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_powerpc_mpc555.cdl
diff --git a/ecos/packages/devs/serial/powerpc/mpc555/current/src/mpc555_serial.h b/ecos/packages/devs/serial/powerpc/mpc555/current/src/mpc555_serial.h
new file mode 100644
index 0000000..8c0044b
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/mpc555/current/src/mpc555_serial.h
@@ -0,0 +1,156 @@
+#ifndef CYGONCE_DEVS_SERIAL_POWERPC_MPC555_SERIAL_H
+#define CYGONCE_DEVS_SERIAL_POWERPC_MPC555_SERIAL_H
+//==========================================================================
+//
+// mpc555_serial.h
+//
+// PowerPC 5xx MPC555 Serial I/O definitions.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bob Koninckx
+// Contributors:
+// Date: 2002-04-25
+// Purpose: MPC555 Serial I/O definitions.
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+//----------------------------------
+// Includes and forward declarations
+//----------------------------------
+
+//----------------------
+// Constants definitions
+//----------------------
+// Base addresses for the two serial ports
+#define MPC555_SERIAL_BASE_A 0x305008
+#define MPC555_SERIAL_BASE_B 0x305020
+
+// The offset from the base for all serial registers
+#define MPC555_SERIAL_SCCxR0 0
+#define MPC555_SERIAL_SCCxR1 2
+#define MPC555_SERIAL_SCxSR 4
+#define MPC555_SERIAL_SCxDR 6
+
+// The bits in the serial registers
+#define MPC555_SERIAL_SCCxR0_OTHR 0x8000
+#define MPC555_SERIAL_SCCxR0_LINKBD 0x4000
+#define MPC555_SERIAL_SCCxR0_SCxBR 0x1fff
+
+#define MPC555_SERIAL_SCCxR1_LOOPS 0x4000
+#define MPC555_SERIAL_SCCxR1_WOMS 0x2000
+#define MPC555_SERIAL_SCCxR1_ILT 0x1000
+#define MPC555_SERIAL_SCCxR1_PT 0x0800
+#define MPC555_SERIAL_SCCxR1_PE 0x0400
+#define MPC555_SERIAL_SCCxR1_M 0x0200
+#define MPC555_SERIAL_SCCxR1_WAKE 0x0100
+#define MPC555_SERIAL_SCCxR1_TIE 0x0080
+#define MPC555_SERIAL_SCCxR1_TCIE 0x0040
+#define MPC555_SERIAL_SCCxR1_RIE 0x0020
+#define MPC555_SERIAL_SCCxR1_ILIE 0x0010
+#define MPC555_SERIAL_SCCxR1_TE 0x0008
+#define MPC555_SERIAL_SCCxR1_RE 0x0004
+#define MPC555_SERIAL_SCCxR1_RWU 0x0002
+#define MPC555_SERIAL_SCCxR1_SBK 0x0001
+
+#define MPC555_SERIAL_SCxSR_TDRE 0x0100
+#define MPC555_SERIAL_SCxSR_TC 0x0080
+#define MPC555_SERIAL_SCxSR_RDRF 0x0040
+#define MPC555_SERIAL_SCxSR_RAF 0x0020
+#define MPC555_SERIAL_SCxSR_IDLE 0x0010
+#define MPC555_SERIAL_SCxSR_OR 0x0008
+#define MPC555_SERIAL_SCxSR_NF 0x0004
+#define MPC555_SERIAL_SCxSR_FE 0x0002
+#define MPC555_SERIAL_SCxSR_PF 0x0001
+
+// The available baud rates
+// These are calculated for a busclock of 40 MHz
+// It is not necessary to let the compiler calculate these
+// values, we did not provide clockfrequency as a configuarion
+// option anyway.
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 0, // 50 bps unsupported
+ 0, // 75 bps unsupported
+ 0, // 110 bps unsupported
+ 0, // 134_5 bps unsupported
+ 0, // 150 bps unsupported
+ 0, // 200 bps unsupported
+ 4167, // 300 bps
+ 2083, // 600 bps
+ 1042, // 1200 bps
+ 0, // 1800 bps unsupported
+ 521, // 2400 bps
+ 0, // 3600 bps unsupported
+ 260, // 4800 bps
+ 0, // 7200 bps unsupported
+ 130, // 9600 bps
+ 87, // 14400 bps
+ 65, // 19200 bps
+ 33, // 38400 bps
+ 22, // 57600 bps
+ 11, // 115200 bps
+ 0 // 230400 bps unsupported
+};
+
+static unsigned char select_word_length[] = {
+ 0, // 5 bits / word (char) not supported
+ 0, // 6 bits / word (char) not supported
+ 7, // 7 bits / word (char) ->> 7 bits per frame
+ 8 // 8 bits / word (char) ->> 8 bits per frame
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ 1, // 1 stop bit ->> 1 bit per frame
+ 0, // 1.5 stop bit not supported
+ 2 // 2 stop bits ->> 2 bits per frame
+};
+
+static unsigned char select_parity[] = {
+ 0, // No parity ->> 0 bits per frame
+ 1, // Even parity ->> 1 bit per frame
+ 1, // Odd parityv ->> 1 bit per frame
+ 0, // Mark parity not supported
+ 0, // Space parity not supported
+};
+
+#endif // CYGONCE_DEVS_SERIAL_POWERPC_MPC555_SERIAL_H
+
+// EOF mpc555_serial.h
diff --git a/ecos/packages/devs/serial/powerpc/mpc555/current/src/mpc555_serial_with_ints.c b/ecos/packages/devs/serial/powerpc/mpc555/current/src/mpc555_serial_with_ints.c
new file mode 100644
index 0000000..6571356
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/mpc555/current/src/mpc555_serial_with_ints.c
@@ -0,0 +1,1290 @@
+//==========================================================================
+//
+// mpc555_serial_with_ints.c
+//
+// PowerPC 5xx MPC555 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bob Koninckx
+// Contributors:
+// Date: 2002-04-25
+// Purpose: MPC555 Serial I/O module (interrupt driven version)
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+//----------------------------------
+// Includes and forward declarations
+//----------------------------------
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_arbiter.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+
+// Only build this driver for the MPC555 based boards
+#if defined (CYGPKG_IO_SERIAL_POWERPC_MPC555) && \
+ (defined (CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A) || \
+ defined (CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B))
+
+#include "mpc555_serial.h"
+
+//---------------------------------------------------------------------------
+// Type definitions
+//---------------------------------------------------------------------------
+#define MPC555_SCI_RX_BUFF_SIZE 256
+typedef struct st_sci_circbuf {
+ cyg_uint8 buf[MPC555_SCI_RX_BUFF_SIZE];
+ cyg_uint16 scsr[MPC555_SCI_RX_BUFF_SIZE];
+ cyg_uint8 fill_pos;
+ cyg_uint8 read_pos;
+} mpc555_sci_circbuf_t;
+
+typedef struct mpc555_serial_info {
+ CYG_ADDRWORD base; // The base address of the serial port
+ CYG_WORD tx_interrupt_num; // trivial
+ CYG_WORD rx_interrupt_num; // trivial
+ cyg_priority_t tx_interrupt_priority;// trivial
+ cyg_priority_t rx_interrupt_priority;// trivial
+ bool tx_interrupt_enable; // can the tx interrupt be re-enabled?
+ mpc555_sci_circbuf_t* rx_circbuf; // rx buff for ISR to DSR data exchange
+ bool use_queue; // Use the queue when available?
+ CYG_WORD rx_last_queue_pointer;// Keep track where queue read is upto
+ CYG_WORD rx_interrupt_idle_line_num; // trivial
+ CYG_WORD tx_interrupt_queue_top_empty_num; // trivial
+ CYG_WORD tx_interrupt_queue_bot_empty_num; // trivial
+ CYG_WORD rx_interrupt_queue_top_full_num; // trivial
+ CYG_WORD rx_interrupt_queue_bot_full_num; // trivial
+ cyg_priority_t rx_interrupt_idle_line_priority; // trivial
+ cyg_priority_t tx_interrupt_queue_top_empty_priority; // trivial
+ cyg_priority_t tx_interrupt_queue_bot_empty_priority; // trivial
+ cyg_priority_t rx_interrupt_queue_top_full_priority; // trivial
+ cyg_priority_t rx_interrupt_queue_bot_full_priority; // trivial
+ cyg_interrupt tx_interrupt; // the tx interrupt object
+ cyg_handle_t tx_interrupt_handle; // the tx interrupt handle
+ cyg_interrupt rx_interrupt; // the rx interrupt object
+ cyg_handle_t rx_interrupt_handle; // the rx interrupt handle
+ cyg_interrupt rx_idle_interrupt; // the rx idle line isr object
+ cyg_handle_t rx_idle_interrupt_handle; // the rx idle line isr handle
+ cyg_interrupt tx_queue_top_interrupt; // the tx interrupt object
+ cyg_handle_t tx_queue_top_interrupt_handle;// the tx interrupt handle
+ cyg_interrupt tx_queue_bot_interrupt; // the tx interrupt object
+ cyg_handle_t tx_queue_bot_interrupt_handle;// the tx interrupt handle
+ cyg_interrupt rx_queue_top_interrupt; // the tx interrupt object
+ cyg_handle_t rx_queue_top_interrupt_handle;// the tx interrupt handle
+ cyg_interrupt rx_queue_bot_interrupt; // the tx interrupt object
+ cyg_handle_t rx_queue_bot_interrupt_handle;// the tx interrupt handle
+} mpc555_serial_info;
+
+//--------------------
+// Function prototypes
+//--------------------
+static bool mpc555_serial_putc(serial_channel * chan, unsigned char c);
+static unsigned char mpc555_serial_getc(serial_channel *chan);
+static Cyg_ErrNo mpc555_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void mpc555_serial_start_xmit(serial_channel *chan);
+static void mpc555_serial_stop_xmit(serial_channel *chan);
+static Cyg_ErrNo mpc555_serial_lookup(struct cyg_devtab_entry ** tab,
+ struct cyg_devtab_entry * sub_tab,
+ const char * name);
+static bool mpc555_serial_init(struct cyg_devtab_entry * tab);
+
+// The interrupt servers
+static cyg_uint32 mpc555_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static cyg_uint32 mpc555_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void mpc555_serial_tx_DSR(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+static void mpc555_serial_rx_DSR(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A
+static cyg_uint32 mpc555_serial_tx_queue_top_ISR(cyg_vector_t vector,
+ cyg_addrword_t data);
+static cyg_uint32 mpc555_serial_tx_queue_bot_ISR(cyg_vector_t vector,
+ cyg_addrword_t data);
+static cyg_uint32 mpc555_serial_rx_queue_top_ISR(cyg_vector_t vector,
+ cyg_addrword_t data);
+static cyg_uint32 mpc555_serial_rx_queue_bot_ISR(cyg_vector_t vector,
+ cyg_addrword_t data);
+static cyg_uint32 mpc555_serial_rx_idle_line_ISR(cyg_vector_t vector,
+ cyg_addrword_t data);
+
+static void mpc555_serial_tx_queue_DSR(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+static void mpc555_serial_rx_queue_DSR(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+
+static int mpc555_serial_read_queue(serial_channel* chan, int start, int end);
+#endif
+
+//------------------------------------------------------------------------------
+// Register the device driver with the kernel
+//------------------------------------------------------------------------------
+static SERIAL_FUNS(mpc555_serial_funs,
+ mpc555_serial_putc,
+ mpc555_serial_getc,
+ mpc555_serial_set_config,
+ mpc555_serial_start_xmit,
+ mpc555_serial_stop_xmit);
+
+//------------------------------------------------------------------------------
+// Device driver data
+//------------------------------------------------------------------------------
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A
+#ifdef CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_USE_HWARE_QUEUE
+//static mpc555_sci_circbuf_t mpc555_serial_isr_to_dsr_buf0;
+
+static mpc555_serial_info mpc555_serial_info0 = {
+ MPC555_SERIAL_BASE_A,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX_PRIORITY,
+ false,
+ NULL, // Don't need software buffer
+ true, // Use queue
+ 0, // init queue pointer
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_IDLE,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TXQTHE,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TXQBHE,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RXQTHF,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RXQBHF,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_IDLE_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TXQTHE_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TXQBHE_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RXQTHF_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RXQBHF_PRIORITY};
+
+static unsigned char mpc555_serial_out_buf0[CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE];
+static unsigned char mpc555_serial_in_buf0[CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(
+ mpc555_serial_channel0,
+ mpc555_serial_funs,
+ mpc555_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc555_serial_out_buf0[0],
+ sizeof(mpc555_serial_out_buf0),
+ &mpc555_serial_in_buf0[0],
+ sizeof(mpc555_serial_in_buf0));
+
+#elif CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE > 0
+static mpc555_sci_circbuf_t mpc555_serial_isr_to_dsr_buf0;
+
+static mpc555_serial_info mpc555_serial_info0 = {
+ MPC555_SERIAL_BASE_A,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX_PRIORITY,
+ false,
+ &mpc555_serial_isr_to_dsr_buf0,
+ false};
+
+static unsigned char mpc555_serial_out_buf0[CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE];
+static unsigned char mpc555_serial_in_buf0[CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(
+ mpc555_serial_channel0,
+ mpc555_serial_funs,
+ mpc555_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc555_serial_out_buf0[0],
+ sizeof(mpc555_serial_out_buf0),
+ &mpc555_serial_in_buf0[0],
+ sizeof(mpc555_serial_in_buf0));
+#else
+static mpc555_serial_info mpc555_serial_info0 = {
+ MPC555_SERIAL_BASE_A,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX_PRIORITY,
+ false,
+ NULL,
+ false};
+
+static SERIAL_CHANNEL(
+ mpc555_serial_channel0,
+ mpc555_serial_funs,
+ mpc555_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_A_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(mpc555_serial_io0,
+ CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ mpc555_serial_init,
+ mpc555_serial_lookup,
+ &mpc555_serial_channel0);
+#endif // ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B
+
+#if CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BUFSIZE > 0
+static mpc555_sci_circbuf_t mpc555_serial_isr_to_dsr_buf1;
+
+static mpc555_serial_info mpc555_serial_info1 = {
+ MPC555_SERIAL_BASE_B,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI2_TX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI2_RX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI2_TX_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI2_RX_PRIORITY,
+ false,
+ &mpc555_serial_isr_to_dsr_buf1,
+ false};
+
+static unsigned char mpc555_serial_out_buf1[CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BUFSIZE];
+static unsigned char mpc555_serial_in_buf1[CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(
+ mpc555_serial_channel1,
+ mpc555_serial_funs,
+ mpc555_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc555_serial_out_buf1[0],
+ sizeof(mpc555_serial_out_buf1),
+ &mpc555_serial_in_buf1[0],
+ sizeof(mpc555_serial_in_buf1));
+#else
+static mpc555_serial_info mpc555_serial_info1 = {
+ MPC555_SERIAL_BASE_B,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX_PRIORITY,
+ CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX_PRIORITY,
+ false,
+ NULL,
+ false};
+static SERIAL_CHANNEL(
+ mpc555_serial_channel1,
+ mpc555_serial_funs,
+ mpc555_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC555_SERIAL_B_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT);
+#endif
+DEVTAB_ENTRY(mpc555_serial_io1,
+ CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_B_NAME,
+ 0, // does not depend on a lower level device driver
+ &cyg_io_serial_devio,
+ mpc555_serial_init,
+ mpc555_serial_lookup,
+ &mpc555_serial_channel1);
+#endif // ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B
+
+//------------------------------------------------------------------------------
+// Device driver implementation
+//------------------------------------------------------------------------------
+
+// The arbitration isr.
+// I think this is the best place to implement it.
+// The device driver is the only place in the code where the knowledge is
+// present about how the hardware is used.
+//
+// Always check receive interrupts.
+// Some rom monitor might be waiting for CTRL-C
+static cyg_uint32 hal_arbitration_isr_qsci(CYG_ADDRWORD a_vector,
+ CYG_ADDRWORD a_data)
+{
+ cyg_uint16 status;
+ cyg_uint16 control;
+
+ HAL_READ_UINT16(CYGARC_REG_IMM_SC1SR, status);
+ HAL_READ_UINT16(CYGARC_REG_IMM_SCC1R1, control);
+ if((status & CYGARC_REG_IMM_SCxSR_RDRF) &&
+ (control & CYGARC_REG_IMM_SCCxR1_RIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RX);
+// Do not waist time on unused hardware
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A
+#ifdef CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_USE_HWARE_QUEUE
+ // Only one port supports queue mode
+ if((status & CYGARC_REG_IMM_SCxSR_IDLE) &&
+ (control & CYGARC_REG_IMM_SCCxR1_ILIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_IDLE);
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1SR, status);
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1CR, control);
+ if((status & CYGARC_REG_IMM_QSCI1SR_QTHF) &&
+ (control & CYGARC_REG_IMM_QSCI1CR_QTHFI))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RXQTHF);
+ if((status & CYGARC_REG_IMM_QSCI1SR_QBHF) &&
+ (control & CYGARC_REG_IMM_QSCI1CR_QBHFI))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_RXQBHF);
+ if((status & CYGARC_REG_IMM_QSCI1SR_QTHE) &&
+ (control & CYGARC_REG_IMM_QSCI1CR_QTHEI))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TXQTHE);
+ if((status & CYGARC_REG_IMM_QSCI1SR_QBHE) &&
+ (control & CYGARC_REG_IMM_QSCI1CR_QBHEI))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TXQBHE);
+// Only for SPI, leave fo future reference
+#if 0
+ HAL_READ_UINT16(CYGARC_REG_IMM_SPSR, status);
+ HAL_READ_UINT16(CYGARC_REG_IMM_SPCR2, control);
+ if((status & CYGARC_REG_IMM_SPSR_SPIF) &&
+ (control & CYGARC_REG_IMM_SPCR2_SPIFIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SPI_FI);
+
+ HAL_READ_UINT16(CYGARC_REG_IMM_SPCR3, control);
+ if((status & CYGARC_REG_IMM_SPSR_MODF) &&
+ (control & CYGARC_REG_IMM_SPCR3_HMIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SPI_MODF);
+
+ if((status & CYGARC_REG_IMM_SPSR_HALTA) &&
+ (control & CYGARC_REG_IMM_SPCR3_HMIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SPI_HALTA);
+#endif
+#else //No HW Queue
+ if((status & CYGARC_REG_IMM_SCxSR_TDRE) &&
+ (control & CYGARC_REG_IMM_SCCxR1_TIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TX);
+// Don't waist time on unused interrupts
+// Transmit complete interrupt enabled (not used)
+// if((status & CYGARC_REG_IMM_SCxSR_TC) && (control & CYGARC_REG_IMM_SCCxR1_TCIE))
+// return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_TXC);
+// Don't waist time on unused interrupts
+// Idle-line interrupt enabled (not used)
+// if((status & CYGARC_REG_IMM_SCxSR_IDLE) && (control & CYGARC_REG_IMM_SCCxR1_ILIE))
+// return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI1_IDLE);
+#endif // HW_QUEUE
+#endif // SERIAL_A
+
+ HAL_READ_UINT16(CYGARC_REG_IMM_SC2SR, status);
+ HAL_READ_UINT16(CYGARC_REG_IMM_SCC2R1, control);
+ if((status & CYGARC_REG_IMM_SCxSR_RDRF) &&
+ (control & CYGARC_REG_IMM_SCCxR1_RIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI2_RX);
+// Do not waist time on unused hardware
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_B
+ if((status & CYGARC_REG_IMM_SCxSR_TDRE) &&
+ (control & CYGARC_REG_IMM_SCCxR1_TIE))
+ return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI2_TX);
+// Don't waist time on unused interrupts
+// Transmit complete interrupt enabled (not used)
+// if((status & CYGARC_REG_IMM_SCxSR_TC) && (control & CYGARC_REG_IMM_SCCxR1_TCIE))
+// return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI2_TXC);
+// Don't waist time on unused interrupts
+// Idle-line interrupt enabled (not used)
+// if((status & CYGARC_REG_IMM_SCxSR_IDLE) && (control & CYGARC_REG_IMM_SCCxR1_ILIE))
+// return hal_call_isr(CYGNUM_HAL_INTERRUPT_IMB3_SCI2_IDLE);
+#endif
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+// Internal function to configure the hardware to desired baud rate, etc.
+//------------------------------------------------------------------------------
+static bool mpc555_serial_config_port(serial_channel * chan,
+ cyg_serial_info_t * new_config,
+ bool init)
+{
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)(chan->dev_priv);
+
+ cyg_addrword_t port = mpc555_chan->base;
+ cyg_uint16 baud_rate = select_baud[new_config->baud];
+ unsigned char frame_length = 1; // The start bit
+
+ cyg_uint16 old_isrstate;
+ cyg_uint16 sccxr;
+
+ if(!baud_rate)
+ return false; // Invalid baud rate selected
+
+ if((new_config->word_length != CYGNUM_SERIAL_WORD_LENGTH_7) &&
+ (new_config->word_length != CYGNUM_SERIAL_WORD_LENGTH_8))
+ return false; // Invalid word length selected
+
+ if((new_config->parity != CYGNUM_SERIAL_PARITY_NONE) &&
+ (new_config->parity != CYGNUM_SERIAL_PARITY_EVEN) &&
+ (new_config->parity != CYGNUM_SERIAL_PARITY_ODD))
+ return false; // Invalid parity selected
+
+ if((new_config->stop != CYGNUM_SERIAL_STOP_1) &&
+ (new_config->stop != CYGNUM_SERIAL_STOP_2))
+ return false; // Invalid stop bits selected
+
+ frame_length += select_word_length[new_config->word_length -
+ CYGNUM_SERIAL_WORD_LENGTH_5];
+ frame_length += select_stop_bits[new_config->stop];
+ frame_length += select_parity[new_config->parity];
+
+ if((frame_length != 10) && (frame_length != 11))
+ return false; // Invalid frame format selected
+
+ // Disable port interrupts while changing hardware
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ old_isrstate = sccxr;
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_LOOPS);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_WOMS);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_ILT);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_PT);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_PE);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_M);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_WAKE);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_TE);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_RE);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_RWU);
+ old_isrstate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_SBK);
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_TIE);
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_TCIE);
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_RIE);
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_ILIE);
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+
+#ifdef CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_USE_HWARE_QUEUE
+ cyg_uint16 qsci1cr = 0;
+ if(mpc555_chan->use_queue){
+ HAL_READ_UINT16( CYGARC_REG_IMM_QSCI1SR, qsci1cr);
+ // disable queue
+ qsci1cr &= ~((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QTE);
+ qsci1cr &= ~((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QRE);
+ // disable queue interrupts
+ qsci1cr &= ~((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QTHFI);
+ qsci1cr &= ~((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QBHFI);
+ qsci1cr &= ~((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QTHEI);
+ qsci1cr &= ~((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QBHEI);
+ HAL_WRITE_UINT16( CYGARC_REG_IMM_QSCI1SR, qsci1cr);
+ }
+#endif
+ // Set databits, stopbits and parity.
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+
+ if(frame_length == 11)
+ sccxr |= (cyg_uint16)MPC555_SERIAL_SCCxR1_M;
+ else
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_M);
+
+ switch(new_config->parity){
+ case CYGNUM_SERIAL_PARITY_NONE:
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_PE);
+ break;
+ case CYGNUM_SERIAL_PARITY_EVEN:
+ sccxr |= (cyg_uint16)MPC555_SERIAL_SCCxR1_PE;
+ sccxr &= ~((cyg_uint16)MPC555_SERIAL_SCCxR1_PT);
+ break;
+ case CYGNUM_SERIAL_PARITY_ODD:
+ sccxr |= (cyg_uint16)MPC555_SERIAL_SCCxR1_PE;
+ sccxr |= (cyg_uint16)MPC555_SERIAL_SCCxR1_PT;
+ break;
+ default:
+ break;
+ }
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+
+ // Set baud rate.
+ baud_rate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR0_OTHR);
+ baud_rate &= ~((cyg_uint16)MPC555_SERIAL_SCCxR0_LINKBD);
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR0, sccxr);
+ sccxr &= ~(MPC555_SERIAL_SCCxR0_SCxBR);
+ sccxr |= baud_rate;
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR0, sccxr);
+
+ // Enable the device
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ sccxr |= MPC555_SERIAL_SCCxR1_TE;
+ sccxr |= MPC555_SERIAL_SCCxR1_RE;
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+
+ if(init){
+#ifdef CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_USE_HWARE_QUEUE
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ if(mpc555_chan->use_queue){
+ cyg_uint16 qsci1sr;
+ // enable read queue
+ qsci1cr |= ((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QRE);
+ // enable receive queue interrupts
+ qsci1cr |= ((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QTHFI);
+ qsci1cr |= ((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QBHFI);
+ HAL_WRITE_UINT16( CYGARC_REG_IMM_QSCI1CR, qsci1cr);
+ // also enable idle line detect interrupt
+ sccxr |= MPC555_SERIAL_SCxSR_IDLE;
+ HAL_READ_UINT16( CYGARC_REG_IMM_QSCI1SR, qsci1sr);
+ qsci1sr &= ~((cyg_uint16)CYGARC_REG_IMM_QSCI1SR_QBHF);
+ qsci1sr &= ~((cyg_uint16)CYGARC_REG_IMM_QSCI1SR_QTHF);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1SR, qsci1sr);
+ }
+ else {
+ // enable the receiver interrupt
+ sccxr |= MPC555_SERIAL_SCCxR1_RIE;
+ }
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+#else
+ // enable the receiver interrupt
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ sccxr |= MPC555_SERIAL_SCCxR1_RIE;
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+#endif
+ }
+ else {// Restore the old interrupt state
+
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ sccxr |= old_isrstate;
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCCxR1, sccxr);
+ }
+
+ if(new_config != &chan->config)
+ chan->config = *new_config;
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+// Function to initialize the device. Called at bootstrap time.
+//------------------------------------------------------------------------------
+static hal_mpc5xx_arbitration_data arbiter;
+static bool mpc555_serial_init(struct cyg_devtab_entry * tab){
+ serial_channel * chan = (serial_channel *)tab->priv;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ if(!mpc555_serial_config_port(chan, &chan->config, true))
+ return false;
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ if(chan->out_cbuf.len != 0){
+ arbiter.priority = CYGNUM_HAL_ISR_SOURCE_PRIORITY_QSCI;
+ arbiter.data = 0;
+ arbiter.arbiter = hal_arbitration_isr_qsci;
+
+ // Install the arbitration isr, Make sure that is is not installed twice
+ hal_mpc5xx_remove_arbitration_isr(CYGNUM_HAL_ISR_SOURCE_PRIORITY_QSCI);
+ hal_mpc5xx_install_arbitration_isr(&arbiter);
+
+ // if !(Chan_B && using queue)
+ if(!mpc555_chan->use_queue){
+ mpc555_chan->rx_circbuf->fill_pos = 0;
+ mpc555_chan->rx_circbuf->read_pos = 0;
+
+ // Create the Tx interrupt, do not enable it yet
+ cyg_drv_interrupt_create(mpc555_chan->tx_interrupt_num,
+ mpc555_chan->tx_interrupt_priority,
+ (cyg_addrword_t)chan,//Data item passed to isr
+ mpc555_serial_tx_ISR,
+ mpc555_serial_tx_DSR,
+ &mpc555_chan->tx_interrupt_handle,
+ &mpc555_chan->tx_interrupt);
+ cyg_drv_interrupt_attach(mpc555_chan->tx_interrupt_handle);
+
+ // Create the Rx interrupt, this can be safely unmasked now
+ cyg_drv_interrupt_create(mpc555_chan->rx_interrupt_num,
+ mpc555_chan->rx_interrupt_priority,
+ (cyg_addrword_t)chan,
+ mpc555_serial_rx_ISR,
+ mpc555_serial_rx_DSR,
+ &mpc555_chan->rx_interrupt_handle,
+ &mpc555_chan->rx_interrupt);
+ cyg_drv_interrupt_attach(mpc555_chan->rx_interrupt_handle);
+ cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_num);
+ }
+#ifdef CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_USE_HWARE_QUEUE
+ else {// Use HW queue
+ // Create the Tx interrupt, do not enable it yet
+ cyg_drv_interrupt_create(mpc555_chan->tx_interrupt_queue_top_empty_num,
+ mpc555_chan->tx_interrupt_queue_top_empty_priority,
+ (cyg_addrword_t)chan,//Data item passed to isr
+ mpc555_serial_tx_queue_top_ISR,
+ mpc555_serial_tx_queue_DSR,
+ &mpc555_chan->tx_queue_top_interrupt_handle,
+ &mpc555_chan->tx_queue_top_interrupt);
+ cyg_drv_interrupt_attach(mpc555_chan->tx_queue_top_interrupt_handle);
+
+
+ cyg_drv_interrupt_create(mpc555_chan->tx_interrupt_queue_bot_empty_num,
+ mpc555_chan->tx_interrupt_queue_bot_empty_priority,
+ (cyg_addrword_t)chan,//Data passed to isr
+ mpc555_serial_tx_queue_bot_ISR,
+ mpc555_serial_tx_queue_DSR,
+ &mpc555_chan->tx_queue_bot_interrupt_handle,
+ &mpc555_chan->tx_queue_bot_interrupt);
+ cyg_drv_interrupt_attach(mpc555_chan->tx_queue_bot_interrupt_handle);
+
+ // Rx queue interrupts
+ cyg_drv_interrupt_create(mpc555_chan->rx_interrupt_queue_top_full_num,
+ mpc555_chan->rx_interrupt_queue_top_full_priority,
+ (cyg_addrword_t)chan,//Data item passed to isr
+ mpc555_serial_rx_queue_top_ISR,
+ mpc555_serial_rx_queue_DSR,
+ &mpc555_chan->rx_queue_top_interrupt_handle,
+ &mpc555_chan->rx_queue_top_interrupt);
+ cyg_drv_interrupt_attach(mpc555_chan->rx_queue_top_interrupt_handle);
+
+ cyg_drv_interrupt_create(mpc555_chan->rx_interrupt_queue_bot_full_num,
+ mpc555_chan->rx_interrupt_queue_bot_full_priority,
+ (cyg_addrword_t)chan,//Data item passed to isr
+ mpc555_serial_rx_queue_bot_ISR,
+ mpc555_serial_rx_queue_DSR,
+ &mpc555_chan->rx_queue_bot_interrupt_handle,
+ &mpc555_chan->rx_queue_bot_interrupt);
+ cyg_drv_interrupt_attach(mpc555_chan->rx_queue_bot_interrupt_handle);
+
+ cyg_drv_interrupt_create(mpc555_chan->rx_interrupt_idle_line_num,
+ mpc555_chan->rx_interrupt_idle_line_priority,
+ (cyg_addrword_t)chan,//Data item passed to isr
+ mpc555_serial_rx_idle_line_ISR,
+ mpc555_serial_rx_queue_DSR,
+ &mpc555_chan->rx_idle_interrupt_handle,
+ &mpc555_chan->rx_idle_interrupt);
+ cyg_drv_interrupt_attach(mpc555_chan->rx_idle_interrupt_handle);
+ }
+#endif // use queue
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+// This routine is called when the device is "looked" up (i.e. attached)
+//----------------------------------------------------------------------------
+static Cyg_ErrNo mpc555_serial_lookup(struct cyg_devtab_entry ** tab,
+ struct cyg_devtab_entry * sub_tab,
+ const char * name)
+{
+ serial_channel * chan = (serial_channel *)(*tab)->priv;
+ //Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+
+ return ENOERR;
+}
+
+//----------------------------------------------------------------------------
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+//----------------------------------------------------------------------------
+static bool mpc555_serial_putc(serial_channel * chan, unsigned char c){
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mpc555_chan->base;
+
+ cyg_uint16 scsr;
+ cyg_uint16 scdr;
+
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+ if(scsr & MPC555_SERIAL_SCxSR_TDRE){
+ // Ok, we have space, write the character and return success
+ scdr = (cyg_uint16)c;
+ HAL_WRITE_UINT16(port + MPC555_SERIAL_SCxDR, scdr);
+ return true;
+ }
+ else
+ // We cannot write to the transmitter, return failure
+ return false;
+}
+
+//----------------------------------------------------------------------------
+// Fetch a character from the device input buffer, waiting if necessary
+//----------------------------------------------------------------------------
+static unsigned char mpc555_serial_getc(serial_channel * chan){
+ unsigned char c;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mpc555_chan->base;
+
+ cyg_uint16 scsr;
+ cyg_uint16 scdr;
+
+ do {
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+ } while(!(scsr & MPC555_SERIAL_SCxSR_RDRF));
+
+ // Ok, data is received, read it out and return
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxDR, scdr);
+ c = (unsigned char)scdr;
+
+ return c;
+}
+
+//----------------------------------------------------------------------------
+// Set up the device characteristics; baud rate, etc.
+//----------------------------------------------------------------------------
+static bool mpc555_serial_set_config(serial_channel * chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 * len)
+{
+ switch(key){
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:{
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if(*len < sizeof(cyg_serial_info_t)){
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if(true != mpc555_serial_config_port(chan, config, false))
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+//------------------------------------------------------------------------------
+// Enable the transmitter on the device
+//------------------------------------------------------------------------------
+static void mpc555_serial_start_xmit(serial_channel * chan)
+{
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+#ifdef CYGDAT_IO_SERIAL_POWERPC_MPC555_SERIAL_A_USE_HWARE_QUEUE
+ cyg_addrword_t port = mpc555_chan->base;
+ if(mpc555_chan->use_queue){
+ cyg_uint16 qscicr;
+ cyg_uint16 qscisr;
+ cyg_uint16 scsr;
+
+ int chars_avail;
+ unsigned char* chars;
+ int block_index = 0;
+ cyg_addrword_t i;
+ cyg_uint16 queue_transfer;
+
+ if(!(mpc555_chan->tx_interrupt_enable) &&
+ (chan->callbacks->data_xmt_req)(chan, 32, &chars_avail, &chars)
+ == CYG_XMT_OK){
+ queue_transfer = (chars_avail > 16) ? 16 : chars_avail;
+
+ HAL_READ_UINT16( CYGARC_REG_IMM_QSCI1CR, qscicr);
+ // Write QTSZ for first pass through the queue
+ qscicr &= ~(CYGARC_REG_IMM_QSCI1CR_QTSZ);
+ qscicr |= (CYGARC_REG_IMM_QSCI1CR_QTSZ & (queue_transfer - 1));
+ HAL_WRITE_UINT16( CYGARC_REG_IMM_QSCI1CR, qscicr);
+ // Read SC1SR to clear TC bit when followed by a write of sctq
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+
+ for(i=0; i < queue_transfer; i++){
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_SCTQ + (i * 2), chars[block_index]);
+ ++block_index;
+ }
+ chan->callbacks->data_xmt_done(chan, queue_transfer);
+
+ // clear QTHE and QBHE
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+
+ qscisr &= ~(CYGARC_REG_IMM_QSCI1SR_QTHE);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+ if(queue_transfer > 8){
+ qscisr &= ~(CYGARC_REG_IMM_QSCI1SR_QBHE);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+ }
+
+ mpc555_chan->tx_interrupt_enable = true;
+
+ cyg_drv_interrupt_unmask(mpc555_chan->tx_interrupt_queue_top_empty_num);
+ if(queue_transfer > 8){
+ cyg_drv_interrupt_unmask(mpc555_chan->tx_interrupt_queue_bot_empty_num);
+ }
+
+ HAL_READ_UINT16( CYGARC_REG_IMM_QSCI1CR, qscicr);
+ qscicr |= ((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QTE);
+ HAL_WRITE_UINT16( CYGARC_REG_IMM_QSCI1CR, qscicr);
+ }
+ }
+ else { // no queue
+ mpc555_chan->tx_interrupt_enable = true;
+ cyg_drv_interrupt_unmask(mpc555_chan->tx_interrupt_num);
+// No need to call xmt_char, this will generate an interrupt immediately.
+ }
+#else // No queue
+ mpc555_chan->tx_interrupt_enable = true;
+ cyg_drv_interrupt_unmask(mpc555_chan->tx_interrupt_num);
+// No need to call xmt_char, this will generate an interrupt immediately.
+#endif
+}
+
+//----------------------------------------------------------------------------
+// Disable the transmitter on the device
+//----------------------------------------------------------------------------
+static void mpc555_serial_stop_xmit(serial_channel * chan){
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ if(!mpc555_chan->use_queue){
+ cyg_drv_dsr_lock();
+ mpc555_chan->tx_interrupt_enable = false;
+ cyg_drv_interrupt_mask(mpc555_chan->tx_interrupt_num);
+ cyg_drv_dsr_unlock();
+ }
+}
+
+//----------------------------------------------------------------------------
+// The low level transmit interrupt handler
+//----------------------------------------------------------------------------
+static cyg_uint32 mpc555_serial_tx_ISR(cyg_vector_t vector,
+ cyg_addrword_t data){
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mpc555_chan->tx_interrupt_num);
+ cyg_drv_interrupt_acknowledge(mpc555_chan->tx_interrupt_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+//----------------------------------------------------------------------------
+// The low level receive interrupt handler
+//----------------------------------------------------------------------------
+static cyg_uint32 mpc555_serial_rx_ISR(cyg_vector_t vector,
+ cyg_addrword_t data){
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mpc555_chan->rx_interrupt_num);
+ cyg_drv_interrupt_acknowledge(mpc555_chan->rx_interrupt_num);
+
+ cyg_addrword_t port = mpc555_chan->base;
+ cyg_uint16 scdr;
+ cyg_uint16 scsr;
+
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+ // Always read out the received character, in order to clear receiver flags
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxDR, scdr);
+
+ mpc555_chan->rx_circbuf->scsr[mpc555_chan->rx_circbuf->fill_pos] = scsr;
+ mpc555_chan->rx_circbuf->buf[mpc555_chan->rx_circbuf->fill_pos] = (cyg_uint8)scdr;
+
+ if(mpc555_chan->rx_circbuf->fill_pos < MPC555_SCI_RX_BUFF_SIZE - 1){
+ mpc555_chan->rx_circbuf->fill_pos = mpc555_chan->rx_circbuf->fill_pos + 1;
+ }
+ else {
+ mpc555_chan->rx_circbuf->fill_pos = 0;
+ }
+ cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_num);
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A
+//----------------------------------------------------------------------------
+// The low level queued receive interrupt handlers
+//----------------------------------------------------------------------------
+static cyg_uint32 mpc555_serial_rx_queue_top_ISR(cyg_vector_t vector,
+ cyg_addrword_t data){
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mpc555_chan->rx_interrupt_queue_top_full_num);
+ cyg_drv_interrupt_acknowledge(mpc555_chan->rx_interrupt_queue_top_full_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+static cyg_uint32 mpc555_serial_rx_queue_bot_ISR(cyg_vector_t vector,
+ cyg_addrword_t data){
+ serial_channel* chan = (serial_channel *)data;
+ mpc555_serial_info* mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mpc555_chan->rx_interrupt_queue_bot_full_num);
+ cyg_drv_interrupt_acknowledge(mpc555_chan->rx_interrupt_queue_bot_full_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+// This is used to flush the queue when the line falls idle
+static cyg_uint32 mpc555_serial_rx_idle_line_ISR(cyg_vector_t vector,
+ cyg_addrword_t data){
+ serial_channel* chan = (serial_channel *)data;
+ mpc555_serial_info* mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mpc555_chan->rx_interrupt_idle_line_num);
+ cyg_drv_interrupt_acknowledge(mpc555_chan->rx_interrupt_idle_line_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+//----------------------------------------------------------------------------
+// The low level queued transmit interrupt handlers
+//----------------------------------------------------------------------------
+static cyg_uint32 mpc555_serial_tx_queue_top_ISR(cyg_vector_t vector,
+ cyg_addrword_t data){
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mpc555_chan->tx_interrupt_queue_top_empty_num);
+ cyg_drv_interrupt_acknowledge(mpc555_chan->tx_interrupt_queue_top_empty_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+
+static cyg_uint32 mpc555_serial_tx_queue_bot_ISR(cyg_vector_t vector,
+ cyg_addrword_t data){
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ cyg_drv_interrupt_mask(mpc555_chan->tx_interrupt_queue_bot_empty_num);
+ cyg_drv_interrupt_acknowledge(mpc555_chan->tx_interrupt_queue_bot_empty_num);
+
+ return CYG_ISR_CALL_DSR; // cause the DSR to run
+}
+#endif // SERIAL_A
+
+//----------------------------------------------------------------------------
+// The high level transmit interrupt handler
+//----------------------------------------------------------------------------
+static void mpc555_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data){
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+
+ (chan->callbacks->xmt_char)(chan);
+ if(mpc555_chan->tx_interrupt_enable)
+ cyg_drv_interrupt_unmask(mpc555_chan->tx_interrupt_num);
+}
+
+//----------------------------------------------------------------------------
+// The high level receive interrupt handler
+//----------------------------------------------------------------------------
+#define MPC555_SERIAL_SCxSR_ERRORS (MPC555_SERIAL_SCxSR_OR | \
+ MPC555_SERIAL_SCxSR_NF | \
+ MPC555_SERIAL_SCxSR_FE | \
+ MPC555_SERIAL_SCxSR_PF)
+
+static void mpc555_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data){
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+// cyg_addrword_t port = mpc555_chan->base;
+// cyg_uint16 scdr;
+ cyg_uint16 scsr;
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ cyg_serial_line_status_t stat;
+#endif
+
+
+ int i = mpc555_chan->rx_circbuf->read_pos;
+ while (i < mpc555_chan->rx_circbuf->fill_pos){
+ scsr = mpc555_chan->rx_circbuf->scsr[i];
+ if(scsr & (cyg_uint16)MPC555_SERIAL_SCxSR_ERRORS){
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ if(scsr & MPC555_SERIAL_SCxSR_OR){
+ stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ // The current byte is still valid when OR is set
+ (chan->callbacks->rcv_char)(chan, mpc555_chan->rx_circbuf->buf[i]);
+ }
+ else { // OR is never set with any other error bits
+ if(scsr & MPC555_SERIAL_SCxSR_NF){
+ stat.which = CYGNUM_SERIAL_STATUS_NOISEERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+ if(scsr & MPC555_SERIAL_SCxSR_FE){
+ stat.which = CYGNUM_SERIAL_STATUS_FRAMEERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+ if(scsr & MPC555_SERIAL_SCxSR_PF){
+ stat.which = CYGNUM_SERIAL_STATUS_PARITYERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+ }
+#endif
+ }
+ else {
+ (chan->callbacks->rcv_char)(chan, mpc555_chan->rx_circbuf->buf[i]);
+ }
+ ++i;
+ }
+
+ cyg_drv_isr_lock();
+ mpc555_chan->rx_circbuf->fill_pos = 0;
+ mpc555_chan->rx_circbuf->read_pos = 0;
+ cyg_drv_isr_unlock();
+}
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC555_SERIAL_A
+//----------------------------------------------------------------------------
+// The high level queued transmit interrupt handler
+//----------------------------------------------------------------------------
+static void mpc555_serial_tx_queue_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data){
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+ bool QTHE = false;
+ bool QBHE = false;
+ cyg_uint16 qscisr;
+ cyg_uint16 qscicr;
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+ QTHE = (qscisr & CYGARC_REG_IMM_QSCI1SR_QTHE) ? true : false;
+ QBHE = (qscisr & CYGARC_REG_IMM_QSCI1SR_QBHE) ? true : false;
+
+ CYG_ASSERT(QTHE || QBHE,"In tx queue DSR for no reason");
+
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1CR, qscicr);
+ int chars_avail;
+ unsigned char* chars;
+ int block_index = 0;
+ cyg_addrword_t i;
+ cyg_uint16 queue_transfer;
+ xmt_req_reply_t result = (chan->callbacks->data_xmt_req)(chan, 24, &chars_avail, &chars);
+ if(CYG_XMT_OK == result){
+ queue_transfer = (chars_avail > 8) ? 8 : chars_avail;
+ if(QTHE){
+ for(i=0; i < queue_transfer; i++){
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_SCTQ + (i * 2), chars[block_index]);
+ ++block_index;
+ }
+ chan->callbacks->data_xmt_done(chan, queue_transfer);
+ // Clear QTHE
+ qscisr &= ~(CYGARC_REG_IMM_QSCI1SR_QTHE);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+
+ // Re-enable wrap QTWE
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1CR, qscicr);
+ qscicr |= ((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QTWE);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1CR, qscicr);
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1CR, qscicr);
+ // load QTSZ with how many chars *after* the next wrap
+ cyg_uint16 next_time = (chars_avail) > 16 ? 15 : chars_avail -1;
+ qscicr &= ~(CYGARC_REG_IMM_QSCI1CR_QTSZ);
+ qscicr |= (CYGARC_REG_IMM_QSCI1CR_QTSZ & next_time);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1CR, qscicr);
+ cyg_drv_interrupt_unmask(mpc555_chan->tx_interrupt_queue_top_empty_num);
+ }
+ else if(QBHE){
+ for(i=8; i < queue_transfer + 8; i++){
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_SCTQ + (i * 2), chars[block_index]);
+ ++block_index;
+ }
+ chan->callbacks->data_xmt_done(chan, queue_transfer);
+ // Clear QBHE
+ qscisr &= ~(CYGARC_REG_IMM_QSCI1SR_QBHE);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+ cyg_drv_interrupt_unmask(mpc555_chan->tx_interrupt_queue_bot_empty_num);
+ }
+
+ }
+ else if(CYG_XMT_EMPTY== result){
+ // No more data
+ cyg_drv_interrupt_mask(mpc555_chan->tx_interrupt_queue_top_empty_num);
+ cyg_drv_interrupt_mask(mpc555_chan->tx_interrupt_queue_bot_empty_num);
+ mpc555_chan->tx_interrupt_enable = false;
+
+ // Clear QTHE
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+ qscisr &= ~(CYGARC_REG_IMM_QSCI1SR_QTHE);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+ }
+}
+
+//----------------------------------------------------------------------------
+// The high level queued receive interrupt handler
+//----------------------------------------------------------------------------
+static void mpc555_serial_rx_queue_DSR(cyg_vector_t vector,
+ cyg_ucount32 count, cyg_addrword_t data){
+ serial_channel * chan = (serial_channel *)data;
+ mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;
+ cyg_addrword_t port = mpc555_chan->base;
+ cyg_uint16 scrq;
+ cyg_uint16 qscisr;
+ cyg_uint16 scsr;
+ cyg_uint16 scdr;
+ bool QTHF = false;
+ bool QBHF = false;
+ bool idle = false;
+ // Read status reg before reading any data otherwise NE flag will be lost
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxSR, scsr);
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+ QTHF = (qscisr & CYGARC_REG_IMM_QSCI1SR_QTHF) ? true : false;
+ QBHF = (qscisr & CYGARC_REG_IMM_QSCI1SR_QBHF) ? true : false;
+ idle = (scsr & CYGARC_REG_IMM_SCxSR_IDLE)? true : false;
+ // The queue pointer is the next place to be filled by incomming data
+ cyg_uint16 queue_pointer = (qscisr & CYGARC_REG_IMM_QSCI1SR_QRPNT) >> 4;
+
+ int start;
+ int space_req = 0;
+ // Idle needs to be handled first as the IDLE bit will be cleared by a read of
+ // scsr followed by a read of scrq[0:16]
+
+ if(queue_pointer > mpc555_chan->rx_last_queue_pointer){
+ start = mpc555_chan->rx_last_queue_pointer;
+ space_req = mpc555_serial_read_queue(chan, start, queue_pointer - 1);
+ }
+ else {// Its wrapped around
+ if(mpc555_chan->rx_last_queue_pointer > queue_pointer){
+ space_req = mpc555_serial_read_queue(chan, mpc555_chan->rx_last_queue_pointer,15);
+ if(queue_pointer != 0){
+ mpc555_serial_read_queue(chan, 0,queue_pointer -1);
+ }
+ }
+ else // No new data to read, do nothing here
+ {
+ }
+ }
+
+ mpc555_chan->rx_last_queue_pointer = queue_pointer;
+
+ if(CYGARC_REG_IMM_QSCI1SR_QOR & qscisr){
+ // Need to re-enable the queue
+ cyg_uint16 qscicr;
+ HAL_READ_UINT16( CYGARC_REG_IMM_QSCI1CR, qscicr);
+ qscicr |= ((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QRE);
+ HAL_WRITE_UINT16( CYGARC_REG_IMM_QSCI1CR, qscicr);
+ // Queue has overrun but data might not have been lost yet
+ if(scsr & MPC555_SERIAL_SCxSR_OR){
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ cyg_serial_line_status_t stat;
+ stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+#endif
+ }
+ }
+
+ if(scsr & (cyg_uint16)MPC555_SERIAL_SCxSR_ERRORS){
+ // Special case for queue overrun handled above.
+ // Only data without FE or PF is allowed into the queue.
+ // Data with NE is allowed into the queue.
+ // If FE or PF have occured then the queue is disabled
+ // until they are cleared (by reading scsr then scdr).
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ cyg_serial_line_status_t stat;
+ if(scsr & MPC555_SERIAL_SCxSR_NF){
+ // Note if there is more than one frame in the queue
+ // it is not possible to tell which frame
+ // in the queue caused the noise error.
+ // The error has already been cleared by reading
+ // srsr then scrq[n], so no action is required here.
+ stat.which = CYGNUM_SERIAL_STATUS_NOISEERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+ if(scsr & (MPC555_SERIAL_SCxSR_FE | MPC555_SERIAL_SCxSR_PF)){
+ // This action needs to be taken clear the status bits so that
+ // the queue can be re-enabled.
+ HAL_READ_UINT16(port + MPC555_SERIAL_SCxDR, scdr);
+ // Need to re-enable the queue
+ cyg_uint16 qscicr;
+ HAL_READ_UINT16(CYGARC_REG_IMM_QSCI1CR, qscicr);
+ qscicr |= ((cyg_uint16)CYGARC_REG_IMM_QSCI1CR_QRE);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1CR, qscicr);
+
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ if(scsr & MPC555_SERIAL_SCxSR_FE){
+ stat.which = CYGNUM_SERIAL_STATUS_FRAMEERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+ if(scsr & MPC555_SERIAL_SCxSR_PF){
+ stat.which = CYGNUM_SERIAL_STATUS_PARITYERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+ }
+ }
+ if(QTHF){
+ qscisr &= ~((cyg_uint16)CYGARC_REG_IMM_QSCI1SR_QTHF);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+ //cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_queue_top_full_num);
+ }
+ if(QBHF){
+ qscisr &= ~((cyg_uint16)CYGARC_REG_IMM_QSCI1SR_QBHF);
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_QSCI1SR, qscisr);
+ //cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_queue_bot_full_num);
+ }
+ if(idle){
+ if(idle && !space_req){
+ // The IDLE flag can be set sometimes when RE is set
+ // so a read of scrq is needed to clear it.
+ // If this occurs there should be no new data yet otherwise the
+ // condition is impossible to detect
+ HAL_READ_UINT16(CYGARC_REG_IMM_SCRQ, scrq);
+ }
+ HAL_READ_UINT16(CYGARC_REG_IMM_SCRQ, scrq);
+ //cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_idle_line_num);
+ }
+ // A bit lasy, but we don't know or care what the original ISR source
+ // was so to cover all bases re-enble them all
+ cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_queue_top_full_num);
+ cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_queue_bot_full_num);
+ cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_idle_line_num);
+}
+
+static int mpc555_serial_read_queue(serial_channel* chan, int start, int end)
+{
+ int block_index = 0;
+ cyg_uint16 scrq;
+ cyg_addrword_t i;
+ unsigned char* space;
+ int space_avail = 0;
+ int space_req = end - start + 1;
+ if((space_req > 0) &&
+ ((chan->callbacks->data_rcv_req)
+ (chan, space_req, &space_avail, &space) == CYG_RCV_OK)) {
+ CYG_ASSERT((start >= 0) && (start < 16),"rx queue read start point out of range");
+ CYG_ASSERT(start <= end,"rx queue read start and end points reversed");
+ for(i=start ;i < (start + space_avail); i++){
+ CYG_ASSERT((i >= 0) && (i < 16),"rx queue read out of range");
+ HAL_READ_UINT16(CYGARC_REG_IMM_SCRQ + (i * 2), scrq);
+ space[block_index] = scrq;
+ ++block_index;
+ }
+ (chan->callbacks->data_rcv_done)(chan,space_avail);
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+// If there's not enough room data will be lost.
+// There's no point calling rcv_char because the reader is blocked by this DSR.
+ if(space_avail < space_req){
+ cyg_serial_line_status_t stat;
+ stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;
+ (chan->callbacks->indicate_status)(chan, &stat);
+ }
+#endif
+ }
+ return space_req;
+}
+#endif // SERIAL_A
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC555
+
+// EOF mpc555_serial_with_ints.c
+
diff --git a/ecos/packages/devs/serial/powerpc/mpc8xxx/current/ChangeLog b/ecos/packages/devs/serial/powerpc/mpc8xxx/current/ChangeLog
new file mode 100644
index 0000000..c4c0aec
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/mpc8xxx/current/ChangeLog
@@ -0,0 +1,29 @@
+2003-11-09 Gary Thomas <gary@mlbassoc.com>
+
+ * src/mpc8xxx_serial.h:
+ * src/mpc8xxx_serial.c:
+ * cdl/ser_mpc8xxx.cdl: New package - serial I/O for MPC8xxx
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/powerpc/mpc8xxx/current/cdl/ser_mpc8xxx.cdl b/ecos/packages/devs/serial/powerpc/mpc8xxx/current/cdl/ser_mpc8xxx.cdl
new file mode 100644
index 0000000..93d0520
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/mpc8xxx/current/cdl/ser_mpc8xxx.cdl
@@ -0,0 +1,511 @@
+# ====================================================================
+#
+# ser_mpc8xxx.cdl
+#
+# eCos serial PowerPC MPC8XXX (QUICC-II) configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-14
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_POWERPC_MPC8XXX {
+ display "PowerPC MPC8XXX (QUICC-II) serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_POWERPC_MPC8XXX
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ PowerPC MPC8XXX (QUICC-II) SMC/SCC."
+
+ compile -library=libextras.a mpc8xxx_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_powerpc_mpc8xxx.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC1 {
+ display "PowerPC MPC8XXX/SMC serial port 1 driver"
+ flavor bool
+ active_if CYGNUM_HAL_MPC8XXX_SMC1
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ MPC8XXX/SMC port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SMC1_NAME {
+ display "Device name for PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the PowerPC
+ MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BAUD {
+ display "Baud rate for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BUFSIZE {
+ display "Buffer size for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxSIZE {
+ display "Output buffer size for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxSIZE {
+ display "Input buffer size for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC MPC8XXX/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM {
+ display "Number of input buffers for the PowerPC MPC8XXX/SMC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC MPC8XXX/SMC port 1."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC2 {
+ display "PowerPC MPC8XXX/SMC serial port 2 driver"
+ flavor bool
+ active_if CYGNUM_HAL_MPC8XXX_SMC2
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ MPC8XXX/SMC port 2."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SMC2_NAME {
+ display "Device name for PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the PowerPC
+ MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BAUD {
+ display "Baud rate for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BUFSIZE {
+ display "Buffer size for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxSIZE {
+ display "Output buffer size for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxSIZE {
+ display "Input buffer size for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC MPC8XXX/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SMC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC MPC8XXX/SMC port 2."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC1 {
+ display "PowerPC MPC8XXX/SCC serial port 1 driver"
+ flavor bool
+ active_if CYGNUM_HAL_MPC8XXX_SCC1
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ MPC8XXX/SCC port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC1_NAME {
+ display "Device name for PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ default_value {"\"/dev/scc1\""}
+ description "
+ This option specifies the device name for the PowerPC
+ MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BAUD {
+ display "Baud rate for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BUFSIZE {
+ display "Buffer size for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxSIZE {
+ display "Output buffer size for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxSIZE {
+ display "Input buffer size for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC MPC8XXX/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM {
+ display "Number of input buffers for the PowerPC MPC8XXX/SCC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 1."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC2 {
+ display "PowerPC MPC8XXX/SCC serial port 2 driver"
+ flavor bool
+ active_if CYGNUM_HAL_MPC8XXX_SCC2
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ MPC8XXX/SCC port 2."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC2_NAME {
+ display "Device name for PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ default_value {"\"/dev/scc2\""}
+ description "
+ This option specifies the device name for the PowerPC
+ MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BAUD {
+ display "Baud rate for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BUFSIZE {
+ display "Buffer size for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxSIZE {
+ display "Output buffer size for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxSIZE {
+ display "Input buffer size for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC MPC8XXX/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM {
+ display "Number of input buffers for the PowerPC MPC8XXX/SCC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 2."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC3 {
+ display "PowerPC MPC8XXX/SCC serial port 3 driver"
+ flavor bool
+ active_if CYGNUM_HAL_MPC8XXX_SCC3
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ MPC8XXX/SCC port 3."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC3_NAME {
+ display "Device name for PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ default_value {"\"/dev/scc3\""}
+ description "
+ This option specifies the device name for the PowerPC
+ MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BAUD {
+ display "Baud rate for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BUFSIZE {
+ display "Buffer size for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxSIZE {
+ display "Output buffer size for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM {
+ display "Number of output buffers for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxSIZE {
+ display "Input buffer size for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC MPC8XXX/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM {
+ display "Number of input buffers for the PowerPC MPC8XXX/SCC serial port 3"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC MPC8XXX/SCC port 3."
+ }
+}
+
+# EOF ser_mpc8xxx_smc.cdl
diff --git a/ecos/packages/devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.c b/ecos/packages/devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.c
new file mode 100644
index 0000000..2c5eb7d
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.c
@@ -0,0 +1,1014 @@
+//==========================================================================
+//
+// io/serial/powerpc/mpc8xxx_serial.c
+//
+// PowerPC MPC8XXX (QUICC-II) (SMC/SCC) Serial I/O Interface Module
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-06-20
+// Purpose: MPC8XXX Serial I/O module
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/mpc8xxx.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include "mpc8xxx_serial.h"
+
+typedef struct mpc8xxx_sxx_serial_info {
+ CYG_ADDRWORD channel; // Which channel SMCx/SCCx
+ short int_num; // Interrupt number
+ short type; // Channel type - SCC or SMC
+ unsigned long *brg; // Which baud rate generator
+ void *pram; // Parameter RAM pointer
+ void *ctl; // SMC/SCC control registers
+ volatile struct cp_bufdesc *txbd, *rxbd; // Next Tx,Rx descriptor to use
+ struct cp_bufdesc *tbase, *rbase; // First Tx,Rx descriptor
+ int txsize, rxsize; // Length of individual buffers
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} mpc8xxx_sxx_serial_info;
+
+static bool mpc8xxx_sxx_serial_init(struct cyg_devtab_entry *tab);
+static bool mpc8xxx_sxx_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo mpc8xxx_sxx_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char mpc8xxx_sxx_serial_getc(serial_channel *chan);
+static Cyg_ErrNo mpc8xxx_sxx_serial_set_config(serial_channel *chan,
+ cyg_uint32 key, const void *xbuf,
+ cyg_uint32 *len);
+static void mpc8xxx_sxx_serial_start_xmit(serial_channel *chan);
+static void mpc8xxx_sxx_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 mpc8xxx_sxx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void mpc8xxx_sxx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_putc,
+ mpc8xxx_sxx_serial_getc,
+ mpc8xxx_sxx_serial_set_config,
+ mpc8xxx_sxx_serial_start_xmit,
+ mpc8xxx_sxx_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC1
+static mpc8xxx_sxx_serial_info mpc8xxx_sxx_serial_info_smc1 = {
+ SMC1_PAGE_SUBBLOCK, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_SMC1, // interrupt
+ _SMC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BUFSIZE > 0
+static unsigned char mpc8xxx_smc_serial_out_buf_smc1[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BUFSIZE];
+static unsigned char mpc8xxx_smc_serial_in_buf_smc1[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc8xxx_sxx_serial_channel_smc1,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_smc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc8xxx_smc_serial_out_buf_smc1[0], sizeof(mpc8xxx_smc_serial_out_buf_smc1),
+ &mpc8xxx_smc_serial_in_buf_smc1[0], sizeof(mpc8xxx_smc_serial_in_buf_smc1)
+ );
+#else
+static SERIAL_CHANNEL(mpc8xxx_sxx_serial_channel_smc1,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_smc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+static unsigned char mpc8xxx_smc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char mpc8xxx_smc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(mpc8xxx_smc_serial_io_smc1,
+ CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SMC1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mpc8xxx_sxx_serial_init,
+ mpc8xxx_sxx_serial_lookup, // Serial driver may need initializing
+ &mpc8xxx_sxx_serial_channel_smc1
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC1
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC2
+static mpc8xxx_sxx_serial_info mpc8xxx_sxx_serial_info_smc2 = {
+ SMC2_PAGE_SUBBLOCK, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_SMC2, // interrupt
+ _SMC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BUFSIZE > 0
+static unsigned char mpc8xxx_smc_serial_out_buf_smc2[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BUFSIZE];
+static unsigned char mpc8xxx_smc_serial_in_buf_smc2[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc8xxx_sxx_serial_channel_smc2,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_smc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc8xxx_smc_serial_out_buf_smc2[0], sizeof(mpc8xxx_smc_serial_out_buf_smc2),
+ &mpc8xxx_smc_serial_in_buf_smc2[0], sizeof(mpc8xxx_smc_serial_in_buf_smc2)
+ );
+#else
+static SERIAL_CHANNEL(mpc8xxx_sxx_serial_channel_smc2,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_smc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char mpc8xxx_smc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char mpc8xxx_smc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(mpc8xxx_smc_serial_io_smc2,
+ CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SMC2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mpc8xxx_sxx_serial_init,
+ mpc8xxx_sxx_serial_lookup, // Serial driver may need initializing
+ &mpc8xxx_sxx_serial_channel_smc2
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC2
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC1
+static mpc8xxx_sxx_serial_info mpc8xxx_sxx_serial_info_scc1 = {
+ SCC1_PAGE_SUBBLOCK, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_SCC1, // interrupt
+ _SCC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BUFSIZE > 0
+static unsigned char mpc8xxx_smc_serial_out_buf_scc1[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BUFSIZE];
+static unsigned char mpc8xxx_smc_serial_in_buf_scc1[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc8xxx_sxx_serial_channel_scc1,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc8xxx_smc_serial_out_buf_scc1[0], sizeof(mpc8xxx_smc_serial_out_buf_scc1),
+ &mpc8xxx_smc_serial_in_buf_scc1[0], sizeof(mpc8xxx_smc_serial_in_buf_scc1)
+ );
+#else
+static SERIAL_CHANNEL(mpc8xxx_sxx_serial_channel_scc1,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char mpc8xxx_scc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char mpc8xxx_scc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(mpc8xxx_smc_serial_io_scc1,
+ CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mpc8xxx_sxx_serial_init,
+ mpc8xxx_sxx_serial_lookup, // Serial driver may need initializing
+ &mpc8xxx_sxx_serial_channel_scc1
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC1
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC2
+static mpc8xxx_sxx_serial_info mpc8xxx_sxx_serial_info_scc2 = {
+ SCC2_PAGE_SUBBLOCK, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_SCC2, // interrupt
+ _SCC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BUFSIZE > 0
+static unsigned char mpc8xxx_smc_serial_out_buf_scc2[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BUFSIZE];
+static unsigned char mpc8xxx_smc_serial_in_buf_scc2[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc8xxx_sxx_serial_channel_scc2,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc8xxx_smc_serial_out_buf_scc2[0], sizeof(mpc8xxx_smc_serial_out_buf_scc2),
+ &mpc8xxx_smc_serial_in_buf_scc2[0], sizeof(mpc8xxx_smc_serial_in_buf_scc2)
+ );
+#else
+static SERIAL_CHANNEL(mpc8xxx_sxx_serial_channel_scc2,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char mpc8xxx_scc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char mpc8xxx_scc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(mpc8xxx_smc_serial_io_scc2,
+ CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mpc8xxx_sxx_serial_init,
+ mpc8xxx_sxx_serial_lookup, // Serial driver may need initializing
+ &mpc8xxx_sxx_serial_channel_scc2
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC2
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC3
+static mpc8xxx_sxx_serial_info mpc8xxx_sxx_serial_info_scc3 = {
+ SCC3_PAGE_SUBBLOCK, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_SCC3, // interrupt
+ _SCC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BUFSIZE > 0
+static unsigned char mpc8xxx_smc_serial_out_buf_scc3[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BUFSIZE];
+static unsigned char mpc8xxx_smc_serial_in_buf_scc3[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(mpc8xxx_sxx_serial_channel_scc3,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &mpc8xxx_smc_serial_out_buf_scc3[0], sizeof(mpc8xxx_smc_serial_out_buf_scc3),
+ &mpc8xxx_smc_serial_in_buf_scc3[0], sizeof(mpc8xxx_smc_serial_in_buf_scc3)
+ );
+#else
+static SERIAL_CHANNEL(mpc8xxx_sxx_serial_channel_scc3,
+ mpc8xxx_sxx_serial_funs,
+ mpc8xxx_sxx_serial_info_scc3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char mpc8xxx_scc3_txbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char mpc8xxx_scc3_rxbuf[CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(mpc8xxx_smc_serial_io_scc3,
+ CYGDAT_IO_SERIAL_POWERPC_MPC8XXX_SCC3_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ mpc8xxx_sxx_serial_init,
+ mpc8xxx_sxx_serial_lookup, // Serial driver may need initializing
+ &mpc8xxx_sxx_serial_channel_scc3
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC3
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+mpc8xxx_smc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ unsigned int baud_divisor = select_baud[new_config->baud];
+ cyg_uint32 _lcr;
+ volatile struct smc_regs_8260 *ctl = (volatile struct smc_regs_8260*)smc_chan->ctl;
+
+ if (baud_divisor == 0) return false;
+ // Disable channel during setup
+ ctl->smc_smcmr = MPC8XXX_SMCMR_UART; // Disabled, UART mode
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ // Disable port interrupts while changing hardware
+ _lcr = smc_select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ smc_select_stop_bits[new_config->stop] |
+ smc_select_parity[new_config->parity];
+ // Stop transmitter while changing baud rate
+ IMM->cpm_cpcr = smc_chan->channel | CPCR_STOP_TX | CPCR_FLG;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ // Set baud rate generator
+ *smc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1);
+
+ // Enable channel with new configuration
+ ctl->smc_smcmr = MPC8XXX_SMCMR_UART|MPC8XXX_SMCMR_TEN|MPC8XXX_SMCMR_REN|_lcr;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ IMM->cpm_cpcr = smc_chan->channel | CPCR_INIT_TX_RX_PARAMS | CPCR_FLG;
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to set up internal tables for device.
+static void
+mpc8xxx_smc_serial_init_info(mpc8xxx_sxx_serial_info *smc_chan,
+ t_Smc_Pram *uart_pram,
+ volatile struct smc_regs_8260 *ctl,
+ unsigned long *brg,
+ int TxBD, int TxNUM, int TxSIZE,
+ cyg_uint8 *TxBUF,
+ int RxBD, int RxNUM, int RxSIZE,
+ cyg_uint8 *RxBUF)
+{
+ struct cp_bufdesc *txbd, *rxbd;
+ int i;
+
+ smc_chan->pram = (void *)uart_pram;
+ smc_chan->ctl = (void *)ctl;
+
+ // Set up baud rate generator
+ smc_chan->brg = (void *)brg;
+
+ // Disable channel during setup
+ ctl->smc_smcmr = MPC8XXX_SMCMR_UART; // Disabled, UART mode
+
+ // Rx, Tx function codes (used for access)
+ uart_pram->rfcr = 0x18;
+ uart_pram->tfcr = 0x18;
+
+ // Pointers to Rx & Tx buffer descriptor rings
+ uart_pram->rbase = RxBD;
+ uart_pram->tbase = TxBD;
+
+ /* tx and rx buffer descriptors */
+ txbd = (struct cp_bufdesc *)((char *)IMM + TxBD);
+ rxbd = (struct cp_bufdesc *)((char *)IMM + RxBD);
+ smc_chan->txbd = txbd;
+ smc_chan->tbase = txbd;
+ smc_chan->txsize = TxSIZE;
+ smc_chan->rxbd = rxbd;
+ smc_chan->rbase = rxbd;
+ smc_chan->rxsize = RxSIZE;
+
+ /* set max_idle feature - generate interrupt after 4 chars idle period */
+ uart_pram->max_idl = 4;
+
+ /* no last brk char received */
+ uart_pram->brkln = 0;
+
+ /* no break condition occurred */
+ uart_pram->brkec = 0;
+
+ /* 1 break char sent on top XMIT */
+ uart_pram->brkcr = 1;
+
+ /* setup RX buffer descriptors */
+ for (i = 0; i < RxNUM; i++) {
+ rxbd->length = 0;
+ rxbd->buffer = RxBUF;
+ rxbd->ctrl = _BD_CTL_Ready | _BD_CTL_Int;
+ if (i == (RxNUM-1)) rxbd->ctrl |= _BD_CTL_Wrap; // Last buffer
+ RxBUF += RxSIZE;
+ rxbd++;
+ }
+ /* setup TX buffer descriptors */
+ for (i = 0; i < TxNUM; i++) {
+ txbd->length = 0;
+ txbd->buffer = TxBUF;
+ txbd->ctrl = 0;
+ if (i == (TxNUM-1)) txbd->ctrl |= _BD_CTL_Wrap; // Last buffer
+ TxBUF += TxSIZE;
+ txbd++;
+ }
+ /*
+ * Reset Rx & Tx params
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ IMM->cpm_cpcr = smc_chan->channel | CPCR_INIT_TX_RX_PARAMS | CPCR_FLG;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ /*
+ * Clear any previous events. Enable interrupts.
+ * (Section 16.15.7.14 and 16.15.7.15)
+ */
+ ctl->smc_smce = 0xFF;
+ ctl->smc_smcm = SMCE_Bsy|SMCE_Tx|SMCE_Rx;
+}
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+mpc8xxx_scc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ mpc8xxx_sxx_serial_info *scc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ unsigned int baud_divisor = select_baud[new_config->baud];
+ volatile struct scc_regs_8260 *regs = (volatile struct scc_regs_8260*)scc_chan->ctl;
+
+ if (baud_divisor == 0) return false;
+ // Set baud rate generator
+ *scc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1);
+ // Disable channel during setup
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ regs->gsmr_l = 0;
+ regs->psmr = MPC8XXX_SCC_PSMR_ASYNC |
+ scc_select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ scc_select_stop_bits[new_config->stop] |
+ scc_select_parity[new_config->parity];
+
+ // Enable channel with new configuration
+ regs->gsmr_h = 0x20; // 8bit FIFO
+ regs->gsmr_l = 0x00028004; // 16x TxCLK, 16x RxCLK, UART
+
+ /*
+ * Init Rx & Tx params for SCCX
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ IMM->cpm_cpcr = CPCR_INIT_TX_RX_PARAMS | scc_chan->channel | CPCR_FLG;
+
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ regs->gsmr_l |= GSMR_L1_ENT | GSMR_L1_ENR; // Enable Rx, Tx
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to set up internal tables for device.
+static void
+mpc8xxx_scc_serial_init_info(mpc8xxx_sxx_serial_info *scc_chan,
+ volatile t_Scc_Pram *uart_pram,
+ volatile struct scc_regs_8260 *ctl,
+ unsigned long *brg,
+ int TxBD, int TxNUM, int TxSIZE,
+ cyg_uint8 *TxBUF,
+ int RxBD, int RxNUM, int RxSIZE,
+ cyg_uint8 *RxBUF)
+{
+ struct cp_bufdesc *txbd, *rxbd;
+ int i;
+
+ // Disable channel during setup
+ ctl->gsmr_l = 0;
+ scc_chan->pram = (void *)uart_pram;
+ scc_chan->ctl = (void *)ctl;
+
+ // Set up baud rate generator
+ scc_chan->brg = brg;
+
+ /*
+ * Set Rx and Tx function code
+ * (Section 16.15.4.2)
+ */
+ uart_pram->rfcr = 0x18;
+ uart_pram->tfcr = 0x18;
+ /*
+ * Set pointers to buffer descriptors.
+ * (Sections 16.15.4.1, 16.15.7.12, and 16.15.7.13)
+ */
+ uart_pram->rbase = RxBD;
+ uart_pram->tbase = TxBD;
+ /* tx and rx buffer descriptors */
+ txbd = (struct cp_bufdesc *)((char *)IMM + TxBD);
+ rxbd = (struct cp_bufdesc *)((char *)IMM + RxBD);
+ scc_chan->txbd = txbd;
+ scc_chan->tbase = txbd;
+ scc_chan->txsize = TxSIZE;
+ scc_chan->rxbd = rxbd;
+ scc_chan->rbase = rxbd;
+ scc_chan->rxsize = RxSIZE;
+ /* max receive buffer length */
+ uart_pram->mrblr = RxSIZE;
+ /* set max_idle feature - generate interrupt after 4 chars idle period */
+ uart_pram->SpecificProtocol.u.max_idl = 4;
+ /* no last brk char received */
+ uart_pram->SpecificProtocol.u.brkln = 0;
+ /* no break condition occurred */
+ uart_pram->SpecificProtocol.u.brkec = 0;
+ /* 1 break char sent on top XMIT */
+ uart_pram->SpecificProtocol.u.brkcr = 1;
+ /* character mask */
+ uart_pram->SpecificProtocol.u.rccm = 0xC0FF;
+ /* control characters */
+ for (i = 0; i < 8; i++) {
+ uart_pram->SpecificProtocol.u.cc[i] = 0x8000; // Mark unused
+ }
+ /* setup RX buffer descriptors */
+ for (i = 0; i < RxNUM; i++) {
+ rxbd->length = 0;
+ rxbd->buffer = RxBUF;
+ rxbd->ctrl = _BD_CTL_Ready | _BD_CTL_Int;
+ if (i == (RxNUM-1)) rxbd->ctrl |= _BD_CTL_Wrap; // Last buffer
+ RxBUF += RxSIZE;
+ rxbd++;
+ }
+ /* setup TX buffer descriptors */
+ for (i = 0; i < TxNUM; i++) {
+ txbd->length = 0;
+ txbd->buffer = TxBUF;
+ txbd->ctrl = 0;
+ if (i == (TxNUM-1)) txbd->ctrl |= _BD_CTL_Wrap; // Last buffer
+ TxBUF += TxSIZE;
+ txbd++;
+ }
+ /*
+ * Reset Rx & Tx params
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ IMM->cpm_cpcr = scc_chan->channel | CPCR_INIT_TX_RX_PARAMS | CPCR_FLG;
+ /*
+ * Clear any previous events. Enable interrupts.
+ * (Section 16.15.7.14 and 16.15.7.15)
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ ctl->scce = 0xFFFF;
+ ctl->sccm = (SCCE_Bsy | SCCE_Tx | SCCE_Rx);
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+mpc8xxx_sxx_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ int TxBD, RxBD;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+#ifdef CYGDBG_IO_INIT
+ diag_printf("MPC8XXX_SMC SERIAL init - dev: %x.%d = %s\n", smc_chan->channel, smc_chan->int_num, tab->name);
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC1
+ if (chan == &mpc8xxx_sxx_serial_channel_smc1) {
+ TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM);
+ RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM);
+ mpc8xxx_smc_serial_init_info(&mpc8xxx_sxx_serial_info_smc1,
+ (t_Smc_Pram *)((char *)IMM + DPRAM_SMC1_OFFSET),
+ &IMM->smc_regs[SMC1],
+ (unsigned long *)&IMM->brgs_brgc7,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxSIZE,
+ &mpc8xxx_smc1_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxSIZE,
+ &mpc8xxx_smc1_rxbuf[0]
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC2
+#warning "Serial driver on SMC2 is unverified"
+ if (chan == &mpc8xxx_sxx_serial_channel_smc2) {
+ TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM);
+ RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM);
+ mpc8xxx_smc_serial_init_info(&mpc8xxx_sxx_serial_info_smc2,
+ &IMM->pram[3].scc.pothers.smc_modem.psmc.u, // PRAM
+ &IMM->smc_regs[1], // Control registers
+ &IMM->brgs_brgc7,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxSIZE,
+ &mpc8xxx_smc2_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxSIZE,
+ &mpc8xxx_smc2_rxbuf[0]
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC1
+ if (chan == &mpc8xxx_sxx_serial_channel_scc1) {
+ TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM);
+ RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM);
+ mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc1,
+ &IMM->pram.serials.scc_pram[SCC1],
+ &IMM->scc_regs[SCC1],
+ (unsigned long *)&IMM->brgs_brgc1,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxSIZE,
+ &mpc8xxx_scc1_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxSIZE,
+ &mpc8xxx_scc1_rxbuf[0]
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC2
+#warning "Serial driver on SCC2 is unverified"
+ if (chan == &mpc8xxx_sxx_serial_channel_scc2) {
+ TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM);
+ RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM);
+ mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc2,
+ &IMM->pram[1].scc.pscc.u, // PRAM
+ &IMM->scc_regs[1], // Control registers
+ &IMM->brgs_brgc2,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxSIZE,
+ &mpc8xxx_scc2_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxSIZE,
+ &mpc8xxx_scc2_rxbuf[0]
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC3
+#warning "Serial driver on SCC3 is unverified"
+ if (chan == &mpc8xxx_sxx_serial_channel_scc3) {
+ TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM);
+ RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM);
+ mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc3,
+ &IMM->pram[2].scc.pscc.u, // PRAM
+ &IMM->scc_regs[2], // Control registersn
+ &IMM->brgs_brgc3,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxSIZE,
+ &mpc8xxx_scc3_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxSIZE,
+ &mpc8xxx_scc3_rxbuf[0]
+ );
+ }
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(smc_chan->int_num,
+ 0, // Priority - unused (but asserted)
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ mpc8xxx_sxx_serial_ISR,
+ mpc8xxx_sxx_serial_DSR,
+ &smc_chan->serial_interrupt_handle,
+ &smc_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(smc_chan->int_num);
+ }
+ if (smc_chan->type == _SMC_CHAN) {
+ mpc8xxx_smc_serial_config_port(chan, &chan->config, true);
+ } else {
+ mpc8xxx_scc_serial_config_port(chan, &chan->config, true);
+ }
+ if (cache_state)
+ HAL_DCACHE_ENABLE();
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+mpc8xxx_sxx_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Force the current transmit buffer to be sent
+static void
+mpc8xxx_sxx_serial_flush(mpc8xxx_sxx_serial_info *smc_chan)
+{
+ volatile struct cp_bufdesc *txbd = smc_chan->txbd;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(txbd->buffer, smc_chan->txsize);
+ }
+ if ((txbd->length > 0) &&
+ ((txbd->ctrl & (_BD_CTL_Ready|_BD_CTL_Int)) == 0)) {
+ txbd->ctrl |= _BD_CTL_Ready|_BD_CTL_Int; // Signal buffer ready
+ if (txbd->ctrl & _BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ } else {
+ txbd++;
+ }
+ smc_chan->txbd = txbd;
+ }
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+mpc8xxx_sxx_serial_putc(serial_channel *chan, unsigned char c)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ volatile struct cp_bufdesc *txbd, *txfirst;
+ volatile t_Smc_Pram *pram = (volatile t_Smc_Pram *)smc_chan->pram;
+ bool res;
+
+ cyg_drv_dsr_lock(); // Avoid race condition testing pointers
+ txbd = (struct cp_bufdesc *)((char *)IMM + pram->tbptr);
+ txfirst = txbd;
+ // Scan for a non-busy buffer
+ while (txbd->ctrl & _BD_CTL_Ready) {
+ // This buffer is busy, move to next one
+ if (txbd->ctrl & _BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ } else {
+ txbd++;
+ }
+ if (txbd == txfirst) break; // Went all the way around
+ }
+ smc_chan->txbd = txbd;
+ if ((txbd->ctrl & (_BD_CTL_Ready|_BD_CTL_Int)) == 0) {
+ // Transmit buffer is not full/busy
+ txbd->buffer[txbd->length++] = c;
+ if (txbd->length == smc_chan->txsize) {
+ // This buffer is now full, tell SMC to start processing it
+ mpc8xxx_sxx_serial_flush(smc_chan);
+ }
+ res = true;
+ } else {
+ // No space
+ res = false;
+ }
+ cyg_drv_dsr_unlock();
+ return res;
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+mpc8xxx_sxx_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;
+
+ while ((rxbd->ctrl & _BD_CTL_Ready) != 0) ;
+ c = rxbd->buffer[0];
+ rxbd->length = smc_chan->rxsize;
+ rxbd->ctrl |= _BD_CTL_Ready;
+ if (rxbd->ctrl & _BD_CTL_Wrap) {
+ rxbd = smc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ smc_chan->rxbd = (struct cp_bufdesc *)rxbd;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+mpc8xxx_sxx_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ int res;
+
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ // FIXME - The documentation says that you can't change the baud rate
+ // again until at least two BRG input clocks have occurred.
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if (smc_chan->type == _SMC_CHAN) {
+ res = mpc8xxx_smc_serial_config_port(chan, config, true);
+ } else {
+ res = mpc8xxx_scc_serial_config_port(chan, config, true);
+ }
+ if ( true != res )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter (interrupt) on the device
+static void
+mpc8xxx_sxx_serial_start_xmit(serial_channel *chan)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ cyg_drv_dsr_lock();
+ if (smc_chan->txbd->length == 0) {
+ // See if there is anything to put in this buffer, just to get it going
+ (chan->callbacks->xmt_char)(chan);
+ }
+ if (smc_chan->txbd->length != 0) {
+ // Make sure it gets started
+ mpc8xxx_sxx_serial_flush(smc_chan);
+ }
+ cyg_drv_dsr_unlock();
+}
+
+// Disable the transmitter on the device
+static void
+mpc8xxx_sxx_serial_stop_xmit(serial_channel *chan)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ // If anything is in the last buffer, need to get it started
+ if (smc_chan->txbd->length != 0) {
+ mpc8xxx_sxx_serial_flush(smc_chan);
+ }
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+mpc8xxx_sxx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(smc_chan->int_num);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+mpc8xxx_smc_serial_DSR(serial_channel *chan)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ volatile struct smc_regs_8260 *ctl = (volatile struct smc_regs_8260 *)smc_chan->ctl;
+ volatile struct cp_bufdesc *txbd;
+ volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;
+ volatile t_Smc_Pram *pram = (volatile t_Smc_Pram *)smc_chan->pram;
+ struct cp_bufdesc *rxlast;
+ int i, cache_state;
+
+ if (ctl->smc_smce & SMCE_Tx) {
+ // Transmit interrupt
+ ctl->smc_smce = SMCE_Tx; // Reset interrupt state;
+ txbd = smc_chan->tbase; // First buffer
+ while (true) {
+ if ((txbd->ctrl & (_BD_CTL_Ready|_BD_CTL_Int)) == _BD_CTL_Int) {
+ txbd->length = 0;
+ txbd->ctrl &= ~_BD_CTL_Int; // Reset interrupt bit
+ }
+ if (txbd->ctrl & _BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ break;
+ } else {
+ txbd++;
+ }
+ }
+ (chan->callbacks->xmt_char)(chan);
+ }
+ while (ctl->smc_smce & SMCE_Rx) {
+ // Receive interrupt
+ ctl->smc_smce = SMCE_Rx; // Reset interrupt state;
+ rxlast = (struct cp_bufdesc *) (
+ (char *)IMM + pram->rbptr );
+ while (rxbd != rxlast) {
+ if ((rxbd->ctrl & _BD_CTL_Ready) == 0) {
+ for (i = 0; i < rxbd->length; i++) {
+ (chan->callbacks->rcv_char)(chan, rxbd->buffer[i]);
+ }
+ // Note: the MBX860 does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(rxbd->buffer, smc_chan->rxsize); // Make sure no stale data
+ }
+ rxbd->length = 0;
+ rxbd->ctrl |= _BD_CTL_Ready;
+ }
+ if (rxbd->ctrl & _BD_CTL_Wrap) {
+ rxbd = smc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ }
+ smc_chan->rxbd = (struct cp_bufdesc *)rxbd;
+ }
+ if (ctl->smc_smce & SMCE_Bsy) {
+ ctl->smc_smce = SMCE_Bsy; // Reset interrupt state;
+ }
+ cyg_drv_interrupt_acknowledge(smc_chan->int_num);
+ cyg_drv_interrupt_unmask(smc_chan->int_num);
+}
+
+static void
+mpc8xxx_scc_serial_DSR(serial_channel *chan)
+{
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+ volatile struct scc_regs_8260 *ctl = (volatile struct scc_regs_8260 *)smc_chan->ctl;
+ volatile struct cp_bufdesc *txbd;
+ volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;
+ volatile t_Smc_Pram *pram = (volatile t_Smc_Pram *)smc_chan->pram;
+ struct cp_bufdesc *rxlast;
+ int i, cache_state;
+
+ if (ctl->scce & SCCE_Tx) {
+ // Transmit interrupt
+ ctl->scce = SCCE_Tx; // Reset interrupt state;
+ txbd = smc_chan->tbase; // First buffer
+ while (true) {
+ if ((txbd->ctrl & (_BD_CTL_Ready|_BD_CTL_Int)) == _BD_CTL_Int) {
+ txbd->length = 0;
+ txbd->ctrl &= ~_BD_CTL_Int; // Reset interrupt bit
+ }
+ if (txbd->ctrl & _BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ break;
+ } else {
+ txbd++;
+ }
+ }
+ (chan->callbacks->xmt_char)(chan);
+ }
+ while (ctl->scce & SCCE_Rx) {
+ // Receive interrupt
+ ctl->scce = SCCE_Rx; // Reset interrupt state;
+ rxlast = (struct cp_bufdesc *) ((char *)IMM + pram->rbptr);
+ while (rxbd != rxlast) {
+ if ((rxbd->ctrl & _BD_CTL_Ready) == 0) {
+ for (i = 0; i < rxbd->length; i++) {
+ (chan->callbacks->rcv_char)(chan, rxbd->buffer[i]);
+ }
+ // Note: the MBX860 does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(rxbd->buffer, smc_chan->rxsize); // Make sure no stale data
+ }
+ rxbd->length = 0;
+ rxbd->ctrl |= _BD_CTL_Ready;
+ }
+ if (rxbd->ctrl & _BD_CTL_Wrap) {
+ rxbd = smc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ }
+ smc_chan->rxbd = (struct cp_bufdesc *)rxbd;
+ }
+ if (ctl->scce & SCCE_Bsy) {
+ ctl->scce = SCCE_Bsy; // Reset interrupt state;
+ }
+ cyg_drv_interrupt_acknowledge(smc_chan->int_num);
+ cyg_drv_interrupt_unmask(smc_chan->int_num);
+}
+
+static void
+mpc8xxx_sxx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv;
+
+ if (smc_chan->type == _SMC_CHAN) {
+ mpc8xxx_smc_serial_DSR(chan);
+ } else {
+ mpc8xxx_scc_serial_DSR(chan);
+ }
+}
+
+// ------------------------------------------------------------------------
+// EOF powerpc/mpc8xxx_smc_serial.c
diff --git a/ecos/packages/devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.h b/ecos/packages/devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.h
new file mode 100644
index 0000000..b0ebd71
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/mpc8xxx/current/src/mpc8xxx_serial.h
@@ -0,0 +1,153 @@
+#ifndef CYGONCE_POWERPC_MPC8XXX_SERIAL_H
+#define CYGONCE_POWERPC_MPC8XXX_SERIAL_H
+
+// ====================================================================
+//
+// mpc8xxx_serial.h
+//
+// Device I/O - Description of PowerPC MPC8XXX (QUICC-II) serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-06-21
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports using MPC8XXX (QUICC-II)
+
+// SMC Mode Register
+#define MPC8XXX_SMCMR_CLEN(n) ((n+1)<<11) // Character length
+#define MPC8XXX_SMCMR_SB(n) ((n-1)<<10) // Stop bits (1 or 2)
+#define MPC8XXX_SMCMR_PE(n) (n<<9) // Parity enable (0=disable, 1=enable)
+#define MPC8XXX_SMCMR_PM(n) (n<<8) // Parity mode (0=odd, 1=even)
+#define MPC8XXX_SMCMR_UART (2<<4) // UART mode
+#define MPC8XXX_SMCMR_TEN (1<<1) // Enable transmitter
+#define MPC8XXX_SMCMR_REN (1<<0) // Enable receiver
+
+static unsigned int smc_select_word_length[] = {
+ MPC8XXX_SMCMR_CLEN(5), // 5 bits / word (char)
+ MPC8XXX_SMCMR_CLEN(6),
+ MPC8XXX_SMCMR_CLEN(7),
+ MPC8XXX_SMCMR_CLEN(8)
+};
+
+static unsigned int smc_select_stop_bits[] = {
+ 0,
+ MPC8XXX_SMCMR_SB(1), // 1 stop bit
+ MPC8XXX_SMCMR_SB(1), // 1.5 stop bit
+ MPC8XXX_SMCMR_SB(2) // 2 stop bits
+};
+
+static unsigned int smc_select_parity[] = {
+ MPC8XXX_SMCMR_PE(0), // No parity
+ MPC8XXX_SMCMR_PE(1)|MPC8XXX_SMCMR_PM(1), // Even parity
+ MPC8XXX_SMCMR_PE(1)|MPC8XXX_SMCMR_PM(0), // Odd parity
+ 0, // Mark parity
+ 0, // Space parity
+};
+
+// SCC PSMR masks ....
+#define MPC8XXX_SCC_PSMR_ASYNC 0x8000
+#define MPC8XXX_SCC_PSMR_SB(n) ((n-1)<<14) // Stop bits (1=1sb, 2=2sb)
+#define MPC8XXX_SCC_PSMR_CLEN(n) ((n-5)<<12) // Character Length (5-8)
+#define MPC8XXX_SCC_PSMR_PE(n) (n<<4) // Parity enable(0=disabled, 1=enabled)
+#define MPC8XXX_SCC_PSMR_RPM(n) (n<<2) // Rx Parity mode (0=odd, 1=low, 2=even, 3=high)
+#define MPC8XXX_SCC_PSMR_TPM(n) (n) // Tx Parity mode (0=odd, 1=low, 2=even, 3=high)
+
+static unsigned int scc_select_word_length[] = {
+ MPC8XXX_SCC_PSMR_CLEN(5), // 5 bits / word (char)
+ MPC8XXX_SCC_PSMR_CLEN(6),
+ MPC8XXX_SCC_PSMR_CLEN(7),
+ MPC8XXX_SCC_PSMR_CLEN(8)
+};
+
+static unsigned int scc_select_stop_bits[] = {
+ MPC8XXX_SCC_PSMR_SB(1), // 0.5 stop bit ??
+ MPC8XXX_SCC_PSMR_SB(1), // 1 stop bit
+ MPC8XXX_SCC_PSMR_SB(2), // 1.5 stop bit
+ MPC8XXX_SCC_PSMR_SB(2) // 2 stop bits
+};
+
+
+static unsigned int scc_select_parity[] = {
+ MPC8XXX_SCC_PSMR_PE(0), // No parity
+ MPC8XXX_SCC_PSMR_PE(1)|MPC8XXX_SCC_PSMR_TPM(2)|MPC8XXX_SCC_PSMR_RPM(2), // Even parity
+ MPC8XXX_SCC_PSMR_PE(1)|MPC8XXX_SCC_PSMR_TPM(0)|MPC8XXX_SCC_PSMR_RPM(0), // Odd parity
+ MPC8XXX_SCC_PSMR_PE(1)|MPC8XXX_SCC_PSMR_TPM(3)|MPC8XXX_SCC_PSMR_RPM(3), // High (mark) parity
+ MPC8XXX_SCC_PSMR_PE(1)|MPC8XXX_SCC_PSMR_TPM(1)|MPC8XXX_SCC_PSMR_RPM(1), // Low (space) parity
+};
+
+// Baud rate values, based on board clock
+
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 0, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 0, // 230400
+};
+
+#define UART_BITRATE(n) \
+ ((((int)(((CYGHWR_HAL_POWERPC_CPM_SPEED*2)*1000000)/16))/(n * 16))-1)
+
+// Channel type select
+#define _SCC_CHAN 0
+#define _SMC_CHAN 1
+
+#endif // CYGONCE_POWERPC_MPC8XXX_SERIAL_H
diff --git a/ecos/packages/devs/serial/powerpc/ppc405/current/ChangeLog b/ecos/packages/devs/serial/powerpc/ppc405/current/ChangeLog
new file mode 100644
index 0000000..268d814
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/ppc405/current/ChangeLog
@@ -0,0 +1,33 @@
+2005-08-25 Markus Schade <marks@peppercon.de>
+
+ * enabled build for PowerPC 405EP
+
+2003-09-19 Gary Thomas <gary@mlbassoc.com>
+
+ * include/powerpc_ppc405_ser.inl:
+ * cdl/ser_powerpc_ppc405.cdl: New package - support for PowerPC 405GP,
+ based on generic 165x5 uart.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/powerpc/ppc405/current/cdl/ser_powerpc_ppc405.cdl b/ecos/packages/devs/serial/powerpc/ppc405/current/cdl/ser_powerpc_ppc405.cdl
new file mode 100644
index 0000000..9fbf9fd
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/ppc405/current/cdl/ser_powerpc_ppc405.cdl
@@ -0,0 +1,195 @@
+# ====================================================================
+#
+# ser_powerpc_ppc405.cdl
+#
+# eCos serial configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data:
+# Contributors:
+# Date: 2003-09-16
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_POWERPC_PPC405 {
+ display "PowerPC PPC405 (16x5x) serial device driver"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_POWERPC_PPC40x
+# Only the 405GP has these ports
+ active_if { CYGHWR_HAL_POWERPC_PPC4XX == "405GP" || CYGHWR_HAL_POWERPC_PPC4XX == "405EP" }
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial 16x5x device drivers for the
+ PowerPC PPC405GP/EP based platforms."
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_IO_SERIAL_GENERIC_16X5X_STEP 1"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/powerpc_ppc405_ser.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_powerpc_ppc405.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_PPC405_SERIAL0 {
+ display "PowerPC PPC405GP/EP serial port 0 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the
+ PowerPC PPC405GP port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_PPC405_SERIAL0_NAME {
+ display "Device name for PowerPC PPC405GP/EP serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device
+ for the PowerPC PPC405GP port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL0_BAUD {
+ display "Baud rate for the PowerPC PPC405GP serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 115200
+ description "
+ This option specifies the default baud rate (speed)
+ for the PowerPC PPC405GP port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL0_BUFSIZE {
+ display "Buffer size for the PowerPC PPC405GP serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal
+ buffers used for the PowerPC PPC405GP port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_PPC405_SERIAL1 {
+ display "PowerPC PPC405GP serial port 1 driver"
+ flavor bool
+ default_value 1
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ description "
+ This option includes the serial device driver for the
+ PowerPC PPC405GP port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_PPC405_SERIAL1_NAME {
+ display "Device name for PowerPC PPC405GP serial port 1 driver"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the name of the serial device
+ for the PowerPC PPC405GP port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL1_BAUD {
+ display "Baud rate for the PowerPC PPC405GP serial port 1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400
+ 3600 4800 7200 9600 14400 19200 38400
+ 57600 115200 230400 }
+ default_value 115200
+ description "
+ This option specifies the default baud rate (speed)
+ for the PowerPC PPC405GP port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL1_BUFSIZE {
+ display "Buffer size for the PowerPC PPC405GP serial port 1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal
+ buffers used for the PowerPC PPC405GP/EP port 1."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_PPC405_TESTING {
+ display "Testing parameters"
+ flavor bool
+ default_value 1
+ no_define
+ active_if { CYGPKG_IO_SERIAL_POWERPC_PPC405_SERIAL1 }
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_POWERPC_PPC405_SERIAL1_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"PPC405GP\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+
+}
+
+# EOF ser_powerpc_ppc405.cdl
diff --git a/ecos/packages/devs/serial/powerpc/ppc405/current/include/powerpc_ppc405_ser.inl b/ecos/packages/devs/serial/powerpc/ppc405/current/include/powerpc_ppc405_ser.inl
new file mode 100644
index 0000000..b89898b
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/ppc405/current/include/powerpc_ppc405_ser.inl
@@ -0,0 +1,175 @@
+//==========================================================================
+//
+// io/serial/powerpc/powerpc_ppc405_ser.inl
+//
+// PPC405GP/EP Serial I/O definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors:
+// Date: 2003-09-16
+// Purpose: PowerPC PPC405GP/EP serial drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_intr.h>
+#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
+#include <cyg/hal/ppc_regs.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification
+
+static unsigned int select_baud[] = {
+ 9999, // Unused -- marker
+ 50,
+ 75,
+ 110,
+ 134,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 3600,
+ 4800,
+ 7200,
+ 9600,
+ 14400,
+ 19200,
+ 38400,
+ 57600,
+ 115200,
+ 230400
+};
+
+externC int cyg_var_baud_generator(int baud);
+#define CYG_IO_SERIAL_GENERIC_16X5X_BAUD_GENERATOR cyg_var_baud_generator
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_PPC405_SERIAL0
+#if defined(CYGHWR_HAL_POWERPC_PPC4XX_405GP)
+static pc_serial_info ppc405_serial_info0 = {_PPC405GP_UART0, CYGNUM_HAL_INTERRUPT_UART0};
+#endif
+#if defined(CYGHWR_HAL_POWERPC_PPC4XX_405EP)
+static pc_serial_info ppc405_serial_info0 = {_PPC405EP_UART0, CYGNUM_HAL_INTERRUPT_UART0};
+#endif
+#if CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL0_BUFSIZE > 0
+static unsigned char ppc405_serial_out_buf0[CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL0_BUFSIZE];
+static unsigned char ppc405_serial_in_buf0[CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(ppc405_serial_channel0,
+ pc_serial_funs,
+ ppc405_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &ppc405_serial_out_buf0[0], sizeof(ppc405_serial_out_buf0),
+ &ppc405_serial_in_buf0[0], sizeof(ppc405_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(ppc405_serial_channel0,
+ pc_serial_funs,
+ ppc405_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(ppc405_serial_io0,
+ CYGDAT_IO_SERIAL_POWERPC_PPC405_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &ppc405_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_PPC405_SERIAL0
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_PPC405_SERIAL1
+#if defined(CYGHWR_HAL_POWERPC_PPC4XX_405GP)
+static pc_serial_info ppc405_serial_info1 = {_PPC405GP_UART1, CYGNUM_HAL_INTERRUPT_UART1};
+#endif
+#if defined(CYGHWR_HAL_POWERPC_PPC4XX_405EP)
+static pc_serial_info ppc405_serial_info1 = {_PPC405EP_UART1, CYGNUM_HAL_INTERRUPT_UART1};
+#endif
+#if CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL1_BUFSIZE > 0
+static unsigned char ppc405_serial_out_buf1[CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL1_BUFSIZE];
+static unsigned char ppc405_serial_in_buf1[CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(ppc405_serial_channel1,
+ pc_serial_funs,
+ ppc405_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &ppc405_serial_out_buf1[0], sizeof(ppc405_serial_out_buf1),
+ &ppc405_serial_in_buf1[0], sizeof(ppc405_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(ppc405_serial_channel1,
+ pc_serial_funs,
+ ppc405_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_PPC405_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(ppc405_serial_io1,
+ CYGDAT_IO_SERIAL_POWERPC_PPC405_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &ppc405_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_PPC405_SERIAL1
+
+// EOF powerpc_ppc405_ser.inl
diff --git a/ecos/packages/devs/serial/powerpc/quicc/current/ChangeLog b/ecos/packages/devs/serial/powerpc/quicc/current/ChangeLog
new file mode 100644
index 0000000..fea1a1a
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/quicc/current/ChangeLog
@@ -0,0 +1,1285 @@
+2010-12-06 Mark Retallack <mark.retallack@siemens.com>
+
+ * src/quicc_smc_serial.c: Wait for CPM Busy Flag to clear on write to
+ CP Command Register
+
+2006-01-27 Will Wagner <willw@carallon.com>
+
+ * src/quicc_smc_serial.h: Removed unused structure
+ * src/quicc_smc_serial.c(quicc_smc_serial_config_port): Corrected CLEN in SMCMR
+ * src/quicc_smc_serial.c(quicc_smc_serial_DSR & quicc_scc_serial_DSR): Better handling of frame and parity errors
+
+2004-05-10 Robert Chenault <robertchenault@yahoo.com>
+
+ * src/quicc_smc_serial.h: Added two casts of (int) on
+ calculations involving CYGHWR_HAL_POWERPC_BOARD_SPEED.
+
+2004-01-24 Philip Soeberg <ecos@soeberg.net>
+
+ * src/quicc_smc_serial.c(quicc_sxx_serial_init): SCC3 support
+ for MPC8XX_823.
+
+2003-10-13 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc_smc_serial.c: Add some I/O barriers to make sure that
+ operations happen in the correct order. Fixes BUG #90391
+
+2003-10-08 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc_smc_serial.c: Fix compile error for Adder-II (852T)
+
+2003-09-08 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc_smc_serial.h: Fix baud rate clock setup - was off by 1.
+ Reported by Tord Andersson <Tord.Andersson@combitechsystems.com>
+
+2003-03-31 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc_smc_serial.c (quicc_sxx_serial_init): Handle SCC3 on
+ various processors (signal routing differs).
+
+2003-03-28 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc_smc_serial.c: Change how buffers are allocated & aligned
+ to a cache line - previous attempt wasted a huge amount of space.
+
+2003-03-23 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc_smc_serial.h: Move common definitions to common
+ include file (in HAL).
+
+ * src/quicc_smc_serial.c:
+ * cdl/ser_quicc_smc.cdl: Remove options for baud rate generator
+ assignment - use more generic [automatic] support.
+
+2003-03-17 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc_smc_serial.h:
+ * src/quicc_smc_serial.c:
+ * cdl/ser_quicc_smc.cdl: Add support for SCC1/SCC2/SCC3. Inspired
+ by Paul Randall <prandall@delta-info.com>
+
+2003-03-05 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc_smc_serial.c: Use common routines to manage CPM/DPRAM
+ pointers - much nicer in a multi-driver environment.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_quicc_smc.cdl: Remove irrelevant doc link.
+
+2002-12-10 Gary Thomas <gthomas@ecoscentric.com>
+
+ * cdl/ser_quicc_smc.cdl: Only enable devices which exist - as described
+ by the HAL/CDL interfaces.
+
+2001-11-30 Jonathan Larmour <jlarmour@redhat.com>
+2001-11-29 Christoph Csebits <christoph.csebits@frequentis.com>
+
+ * src/quicc_smc_serial.c:
+ aligning buffer to cache lines,
+ flushing buffer in cache before flushing the device.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_quicc_smc.cdl:
+ Fix 234000->230400 typo.
+
+2000-12-22 Björn Stenberg <bjorn@haxx.se>
+
+ * src/quicc_smc_serial.c (quicc_smc_serial_init_info):
+ Set quicc going only after most of the other initialization is
+ complete - otherwise initializing too early causes some of the
+ parameters not to be initialized properly.
+
+2000-12-13 Daniel Lind <daniel.lind@sth.frontec.se>
+
+ * src/quicc_smc_serial.c (quicc_smc_serial_flush):
+ Don't mark a buffer ready unless it has been fully serviced - in
+ particular, the interrupt bit must be clear.
+ [2000-12-13] committed by Gary Thomas <gthomas@redhat.com>
+
+2000-12-06 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/quicc_smc_serial.c: Remove unread tx_enabled variable from
+ quicc_smc_serial_info
+ Ensure quicc serial interrupt is unmasked in general so that rx works!
+ (quicc_smc_serial_start_xmit): Protect better from DSR interruption
+
+2000-10-24 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/quicc_smc_serial.c (quicc_smc_serial_ISR): Return with
+ CYG_ISR_HANDLED (reported by Daniel Lind)
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/quicc_smc_serial.c (quicc_smc_serial_set_config): Now use keys
+ to make more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_quicc_smc.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/powerpc/quicc/current/cdl/ser_quicc_smc.cdl b/ecos/packages/devs/serial/powerpc/quicc/current/cdl/ser_quicc_smc.cdl
new file mode 100644
index 0000000..61867cc
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/quicc/current/cdl/ser_quicc_smc.cdl
@@ -0,0 +1,512 @@
+# ====================================================================
+#
+# ser_quicc_smc.cdl
+#
+# eCos serial PowerPC/QUICC SMC/SCC configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-14
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC {
+ display "PowerPC QUICC/SMC serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_QUICC
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ PowerPC QUICC/SMC/SCC."
+
+ compile -library=libextras.a quicc_smc_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_powerpc_quicc_smc.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1 {
+ display "PowerPC QUICC/SMC serial port 1 driver"
+ flavor bool
+ active_if CYGNUM_HAL_QUICC_SMC1
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ QUICC/SMC port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_NAME {
+ display "Device name for PowerPC QUICC/SMC serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the PowerPC
+ QUICC/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BAUD {
+ display "Baud rate for the PowerPC QUICC/SMC serial port 1"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC QUICC/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE {
+ display "Buffer size for the PowerPC QUICC/SMC serial port 1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC QUICC/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE {
+ display "Output buffer size for the PowerPC QUICC/SMC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC QUICC/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM {
+ display "Number of output buffers for the PowerPC QUICC/SMC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC QUICC/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE {
+ display "Input buffer size for the PowerPC QUICC/SMC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC QUICC/SMC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM {
+ display "Number of input buffers for the PowerPC QUICC/SMC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC QUICC/SMC port 1."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2 {
+ display "PowerPC QUICC/SMC serial port 2 driver"
+ flavor bool
+ active_if CYGNUM_HAL_QUICC_SMC2
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ QUICC/SMC port 2."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_NAME {
+ display "Device name for PowerPC QUICC/SMC serial port 2"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the PowerPC
+ QUICC/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BAUD {
+ display "Baud rate for the PowerPC QUICC/SMC serial port 2"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC QUICC/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE {
+ display "Buffer size for the PowerPC QUICC/SMC serial port 2"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC QUICC/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE {
+ display "Output buffer size for the PowerPC QUICC/SMC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC QUICC/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM {
+ display "Number of output buffers for the PowerPC QUICC/SMC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC QUICC/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE {
+ display "Input buffer size for the PowerPC QUICC/SMC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC QUICC/SMC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM {
+ display "Number of output buffers for the PowerPC QUICC/SMC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC QUICC/SMC port 2."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC1 {
+ display "PowerPC QUICC/SCC serial port 1 driver"
+ flavor bool
+ active_if CYGNUM_HAL_QUICC_SCC1
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ QUICC/SCC port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_NAME {
+ display "Device name for PowerPC QUICC/SCC serial port 1"
+ flavor data
+ default_value {"\"/dev/scc1\""}
+ description "
+ This option specifies the device name for the PowerPC
+ QUICC/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_BAUD {
+ display "Baud rate for the PowerPC QUICC/SCC serial port 1"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC QUICC/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_BUFSIZE {
+ display "Buffer size for the PowerPC QUICC/SCC serial port 1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC QUICC/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_TxSIZE {
+ display "Output buffer size for the PowerPC QUICC/SCC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC QUICC/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_TxNUM {
+ display "Number of output buffers for the PowerPC QUICC/SCC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC QUICC/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_RxSIZE {
+ display "Input buffer size for the PowerPC QUICC/SCC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC QUICC/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_RxNUM {
+ display "Number of input buffers for the PowerPC QUICC/SCC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC QUICC/SCC port 1."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC2 {
+ display "PowerPC QUICC/SCC serial port 2 driver"
+ flavor bool
+ active_if CYGNUM_HAL_QUICC_SCC2
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ QUICC/SCC port 2."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_NAME {
+ display "Device name for PowerPC QUICC/SCC serial port 2"
+ flavor data
+ default_value {"\"/dev/scc2\""}
+ description "
+ This option specifies the device name for the PowerPC
+ QUICC/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_BAUD {
+ display "Baud rate for the PowerPC QUICC/SCC serial port 2"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC QUICC/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_BUFSIZE {
+ display "Buffer size for the PowerPC QUICC/SCC serial port 2"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC QUICC/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_TxSIZE {
+ display "Output buffer size for the PowerPC QUICC/SCC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC QUICC/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_TxNUM {
+ display "Number of output buffers for the PowerPC QUICC/SCC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC QUICC/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_RxSIZE {
+ display "Input buffer size for the PowerPC QUICC/SCC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC QUICC/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_RxNUM {
+ display "Number of input buffers for the PowerPC QUICC/SCC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC QUICC/SCC port 2."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC3 {
+ display "PowerPC QUICC/SCC serial port 3 driver"
+ flavor bool
+ active_if CYGNUM_HAL_QUICC_SCC3
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ QUICC/SCC port 3."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_NAME {
+ display "Device name for PowerPC QUICC/SCC serial port 3"
+ flavor data
+ default_value {"\"/dev/scc3\""}
+ description "
+ This option specifies the device name for the PowerPC
+ QUICC/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BAUD {
+ display "Baud rate for the PowerPC QUICC/SCC serial port 3"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC QUICC/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BUFSIZE {
+ display "Buffer size for the PowerPC QUICC/SCC serial port 3"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC QUICC/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxSIZE {
+ display "Output buffer size for the PowerPC QUICC/SCC serial port 3"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC QUICC/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxNUM {
+ display "Number of output buffers for the PowerPC QUICC/SCC serial port 3"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC QUICC/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxSIZE {
+ display "Input buffer size for the PowerPC QUICC/SCC serial port 3"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC QUICC/SCC port 3."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxNUM {
+ display "Number of input buffers for the PowerPC QUICC/SCC serial port 3"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC QUICC/SCC port 3."
+ }
+}
+
+# EOF ser_quicc_smc.cdl
diff --git a/ecos/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c b/ecos/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c
new file mode 100644
index 0000000..c327849
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c
@@ -0,0 +1,1122 @@
+//==========================================================================
+//
+// io/serial/powerpc/quicc_smc_serial.c
+//
+// PowerPC QUICC (SMC/SCC) Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-06-20
+// Purpose: QUICC SMC Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/quicc/ppc8xx.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC
+
+#include "quicc_smc_serial.h"
+
+typedef struct quicc_sxx_serial_info {
+ CYG_ADDRWORD channel; // Which channel SMCx/SCCx
+ short int_num; // Interrupt number
+ short type; // Channel type - SCC or SMC
+ unsigned long *brg; // Which baud rate generator
+ void *pram; // Parameter RAM pointer
+ void *ctl; // SMC/SCC control registers
+ volatile struct cp_bufdesc *txbd, *rxbd; // Next Tx,Rx descriptor to use
+ struct cp_bufdesc *tbase, *rbase; // First Tx,Rx descriptor
+ int txsize, rxsize; // Length of individual buffers
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} quicc_sxx_serial_info;
+
+static bool quicc_sxx_serial_init(struct cyg_devtab_entry *tab);
+static bool quicc_sxx_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo quicc_sxx_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char quicc_sxx_serial_getc(serial_channel *chan);
+static Cyg_ErrNo quicc_sxx_serial_set_config(serial_channel *chan,
+ cyg_uint32 key, const void *xbuf,
+ cyg_uint32 *len);
+static void quicc_sxx_serial_start_xmit(serial_channel *chan);
+static void quicc_sxx_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 quicc_sxx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void quicc_sxx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(quicc_sxx_serial_funs,
+ quicc_sxx_serial_putc,
+ quicc_sxx_serial_getc,
+ quicc_sxx_serial_set_config,
+ quicc_sxx_serial_start_xmit,
+ quicc_sxx_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1
+static quicc_sxx_serial_info quicc_sxx_serial_info_smc1 = {
+ QUICC_CPM_SMC1, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_CPM_SMC1, // interrupt
+ _SMC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE > 0
+static unsigned char quicc_smc_serial_out_buf_smc1[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE];
+static unsigned char quicc_smc_serial_in_buf_smc1[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(quicc_sxx_serial_channel_smc1,
+ quicc_sxx_serial_funs,
+ quicc_sxx_serial_info_smc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &quicc_smc_serial_out_buf_smc1[0], sizeof(quicc_smc_serial_out_buf_smc1),
+ &quicc_smc_serial_in_buf_smc1[0], sizeof(quicc_smc_serial_in_buf_smc1)
+ );
+#else
+static SERIAL_CHANNEL(quicc_sxx_serial_channel_smc1,
+ quicc_sxx_serial_funs,
+ quicc_sxx_serial_info_smc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+static unsigned char quicc_smc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char quicc_smc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(quicc_smc_serial_io_smc1,
+ CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ quicc_sxx_serial_init,
+ quicc_sxx_serial_lookup, // Serial driver may need initializing
+ &quicc_sxx_serial_channel_smc1
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2
+static quicc_sxx_serial_info quicc_sxx_serial_info_smc2 = {
+ QUICC_CPM_SMC2, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_CPM_SMC2_PIP, // interrupt
+ _SMC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE > 0
+static unsigned char quicc_smc_serial_out_buf_smc2[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE];
+static unsigned char quicc_smc_serial_in_buf_smc2[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(quicc_sxx_serial_channel_smc2,
+ quicc_sxx_serial_funs,
+ quicc_sxx_serial_info_smc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &quicc_smc_serial_out_buf_smc2[0], sizeof(quicc_smc_serial_out_buf_smc2),
+ &quicc_smc_serial_in_buf_smc2[0], sizeof(quicc_smc_serial_in_buf_smc2)
+ );
+#else
+static SERIAL_CHANNEL(quicc_sxx_serial_channel_smc2,
+ quicc_sxx_serial_funs,
+ quicc_sxx_serial_info_smc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char quicc_smc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char quicc_smc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(quicc_smc_serial_io_smc2,
+ CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ quicc_sxx_serial_init,
+ quicc_sxx_serial_lookup, // Serial driver may need initializing
+ &quicc_sxx_serial_channel_smc2
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC1
+static quicc_sxx_serial_info quicc_sxx_serial_info_scc1 = {
+ QUICC_CPM_SCC1, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_CPM_SCC1, // interrupt
+ _SCC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_BUFSIZE > 0
+static unsigned char quicc_smc_serial_out_buf_scc1[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_BUFSIZE];
+static unsigned char quicc_smc_serial_in_buf_scc1[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(quicc_sxx_serial_channel_scc1,
+ quicc_sxx_serial_funs,
+ quicc_sxx_serial_info_scc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &quicc_smc_serial_out_buf_scc1[0], sizeof(quicc_smc_serial_out_buf_scc1),
+ &quicc_smc_serial_in_buf_scc1[0], sizeof(quicc_smc_serial_in_buf_scc1)
+ );
+#else
+static SERIAL_CHANNEL(quicc_sxx_serial_channel_scc1,
+ quicc_sxx_serial_funs,
+ quicc_sxx_serial_info_scc1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char quicc_scc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_TxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char quicc_scc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_RxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(quicc_smc_serial_io_scc1,
+ CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ quicc_sxx_serial_init,
+ quicc_sxx_serial_lookup, // Serial driver may need initializing
+ &quicc_sxx_serial_channel_scc1
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC1
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC2
+static quicc_sxx_serial_info quicc_sxx_serial_info_scc2 = {
+ QUICC_CPM_SCC2, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_CPM_SCC2, // interrupt
+ _SCC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_BUFSIZE > 0
+static unsigned char quicc_smc_serial_out_buf_scc2[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_BUFSIZE];
+static unsigned char quicc_smc_serial_in_buf_scc2[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(quicc_sxx_serial_channel_scc2,
+ quicc_sxx_serial_funs,
+ quicc_sxx_serial_info_scc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &quicc_smc_serial_out_buf_scc2[0], sizeof(quicc_smc_serial_out_buf_scc2),
+ &quicc_smc_serial_in_buf_scc2[0], sizeof(quicc_smc_serial_in_buf_scc2)
+ );
+#else
+static SERIAL_CHANNEL(quicc_sxx_serial_channel_scc2,
+ quicc_sxx_serial_funs,
+ quicc_sxx_serial_info_scc2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char quicc_scc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_TxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char quicc_scc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_RxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(quicc_smc_serial_io_scc2,
+ CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ quicc_sxx_serial_init,
+ quicc_sxx_serial_lookup, // Serial driver may need initializing
+ &quicc_sxx_serial_channel_scc2
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC2
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC3
+static quicc_sxx_serial_info quicc_sxx_serial_info_scc3 = {
+ QUICC_CPM_SCC3, // Channel indicator
+ CYGNUM_HAL_INTERRUPT_CPM_SCC3, // interrupt
+ _SCC_CHAN
+};
+#if CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BUFSIZE > 0
+static unsigned char quicc_smc_serial_out_buf_scc3[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BUFSIZE];
+static unsigned char quicc_smc_serial_in_buf_scc3[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(quicc_sxx_serial_channel_scc3,
+ quicc_sxx_serial_funs,
+ quicc_sxx_serial_info_scc3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &quicc_smc_serial_out_buf_scc3[0], sizeof(quicc_smc_serial_out_buf_scc3),
+ &quicc_smc_serial_in_buf_scc3[0], sizeof(quicc_smc_serial_in_buf_scc3)
+ );
+#else
+static SERIAL_CHANNEL(quicc_sxx_serial_channel_scc3,
+ quicc_sxx_serial_funs,
+ quicc_sxx_serial_info_scc3,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char quicc_scc3_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+static unsigned char quicc_scc3_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
+
+DEVTAB_ENTRY(quicc_smc_serial_io_scc3,
+ CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ quicc_sxx_serial_init,
+ quicc_sxx_serial_lookup, // Serial driver may need initializing
+ &quicc_sxx_serial_channel_scc3
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC3
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+quicc_smc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ unsigned int baud_divisor = select_baud[new_config->baud];
+ cyg_uint32 _lcr;
+ EPPC *eppc = eppc_base();
+ volatile struct smc_regs *ctl = (volatile struct smc_regs *)smc_chan->ctl;
+
+ if (baud_divisor == 0) return false;
+ // Stop transmitter while changing baud rate
+ eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_StopTx;
+ while (eppc->cp_cr & QUICC_SMC_CMD_Go )
+ continue;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ // Disable channel during setup
+ ctl->smc_smcmr = QUICC_SMCMR_UART; // Disabled, UART mode
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ // Disable port interrupts while changing hardware
+ _lcr = QUICC_SMCMR_CLEN(new_config->word_length + ((new_config->parity == CYGNUM_SERIAL_PARITY_NONE)? 0: 1) + ((new_config->stop == CYGNUM_SERIAL_STOP_2)? 2: 1)) |
+ smc_select_stop_bits[new_config->stop] |
+ smc_select_parity[new_config->parity];
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ // Set baud rate generator
+ *smc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1);
+
+ // Enable channel with new configuration
+ ctl->smc_smcmr = QUICC_SMCMR_UART|QUICC_SMCMR_TEN|QUICC_SMCMR_REN|_lcr;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_RestartTx;
+ while (eppc->cp_cr & QUICC_SMC_CMD_Go )
+ continue;
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to set up internal tables for device.
+static void
+quicc_smc_serial_init_info(quicc_sxx_serial_info *smc_chan,
+ volatile struct smc_uart_pram *uart_pram,
+ volatile struct smc_regs *ctl,
+ int TxBD, int TxNUM, int TxSIZE,
+ cyg_uint8 *TxBUF,
+ int RxBD, int RxNUM, int RxSIZE,
+ cyg_uint8 *RxBUF,
+ int portBmask,
+ int port)
+{
+ EPPC *eppc = eppc_base();
+ struct cp_bufdesc *txbd, *rxbd;
+ int i;
+
+ smc_chan->pram = (void *)uart_pram;
+ smc_chan->ctl = (void *)ctl;
+
+ // Set up baud rate generator
+ smc_chan->brg = _mpc8xx_allocate_brg(port);
+
+ // Disable channel during setup
+ ctl->smc_smcmr = QUICC_SMCMR_UART; // Disabled, UART mode
+
+ /*
+ * Set up the PortB pins for UART operation.
+ * Set PAR and DIR to allow SMCTXDx and SMRXDx
+ * (Table 16-39)
+ */
+ eppc->pip_pbpar |= portBmask;
+ eppc->pip_pbdir &= ~portBmask;
+ /*
+ * SDMA & LCD bus request level 5
+ * (Section 16.10.2.1)
+ */
+ eppc->dma_sdcr = 1;
+ /*
+ * Set Rx and Tx function code
+ * (Section 16.15.4.2)
+ */
+ uart_pram->rfcr = 0x18;
+ uart_pram->tfcr = 0x18;
+ /*
+ * Set pointers to buffer descriptors.
+ * (Sections 16.15.4.1, 16.15.7.12, and 16.15.7.13)
+ */
+ uart_pram->rbase = RxBD;
+ uart_pram->tbase = TxBD;
+ /* tx and rx buffer descriptors */
+ txbd = (struct cp_bufdesc *)((char *)eppc + TxBD);
+ rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD);
+ smc_chan->txbd = txbd;
+ smc_chan->tbase = txbd;
+ smc_chan->txsize = TxSIZE;
+ smc_chan->rxbd = rxbd;
+ smc_chan->rbase = rxbd;
+ smc_chan->rxsize = RxSIZE;
+ /* max receive buffer length */
+ uart_pram->mrblr = RxSIZE;
+ /* set max_idle feature - generate interrupt after 4 chars idle period */
+ uart_pram->max_idl = 4;
+ /* no last brk char received */
+ uart_pram->brkln = 0;
+ /* no break condition occurred */
+ uart_pram->brkec = 0;
+ /* 1 break char sent on top XMIT */
+ uart_pram->brkcr = 1;
+ /* setup RX buffer descriptors */
+ for (i = 0; i < RxNUM; i++) {
+ rxbd->length = 0;
+ rxbd->buffer = RxBUF;
+ rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;
+ if (i == (RxNUM-1)) rxbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer
+ RxBUF += RxSIZE;
+ rxbd++;
+ }
+ /* setup TX buffer descriptors */
+ for (i = 0; i < TxNUM; i++) {
+ txbd->length = 0;
+ txbd->buffer = TxBUF;
+ txbd->ctrl = 0;
+ if (i == (TxNUM-1)) txbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer
+ TxBUF += TxSIZE;
+ txbd++;
+ }
+ /*
+ * Reset Rx & Tx params
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_InitTxRx;
+ while (eppc->cp_cr & QUICC_SMC_CMD_Go )
+ continue;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ /*
+ * Clear any previous events. Enable interrupts.
+ * (Section 16.15.7.14 and 16.15.7.15)
+ */
+ ctl->smc_smce = 0xFF;
+ ctl->smc_smcm = QUICC_SMCE_BSY|QUICC_SMCE_TX|QUICC_SMCE_RX;
+}
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+quicc_scc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ quicc_sxx_serial_info *scc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ unsigned int baud_divisor = select_baud[new_config->baud];
+ EPPC *eppc = eppc_base();
+ volatile struct scc_regs *regs = (volatile struct scc_regs *)scc_chan->ctl;
+
+ if (baud_divisor == 0) return false;
+ // Set baud rate generator
+ *scc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1);
+ // Disable channel during setup
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ regs->scc_gsmr_l = 0;
+ regs->scc_psmr = QUICC_SCC_PSMR_ASYNC |
+ scc_select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ scc_select_stop_bits[new_config->stop] |
+ scc_select_parity[new_config->parity];
+
+ // Enable channel with new configuration
+ regs->scc_gsmr_h = 0x20; // 8bit FIFO
+ regs->scc_gsmr_l = 0x00028004; // 16x TxCLK, 16x RxCLK, UART
+
+ /*
+ * Init Rx & Tx params for SCCX
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ eppc->cp_cr = QUICC_CPM_CR_INIT_TXRX | scc_chan->channel | QUICC_CPM_CR_BUSY;
+ while (eppc->cp_cr & QUICC_CPM_CR_BUSY )
+ continue;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ regs->scc_gsmr_l |= (QUICC_SCC_GSMR_L_Tx | QUICC_SCC_GSMR_L_Rx); // Enable Rx, Tx
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to set up internal tables for device.
+static void
+quicc_scc_serial_init_info(quicc_sxx_serial_info *scc_chan,
+ volatile struct uart_pram *uart_pram,
+ volatile struct scc_regs *ctl,
+ int TxBD, int TxNUM, int TxSIZE,
+ cyg_uint8 *TxBUF,
+ int RxBD, int RxNUM, int RxSIZE,
+ cyg_uint8 *RxBUF,
+ int portAmask, int portBmask, int portCmask,
+ int port)
+{
+ EPPC *eppc = eppc_base();
+ struct cp_bufdesc *txbd, *rxbd;
+ int i;
+
+ // Disable channel during setup
+ ctl->scc_gsmr_l = 0;
+ scc_chan->pram = (void *)uart_pram;
+ scc_chan->ctl = (void *)ctl;
+
+ // Set up baud rate generator
+ scc_chan->brg = _mpc8xx_allocate_brg(port);
+
+ /*
+ * Set up the PortA/B/C pins for UART operation.
+ */
+ eppc->pio_papar |= portAmask;
+ eppc->pio_padir &= ~portAmask;
+ eppc->pio_paodr &= ~portAmask;
+
+ eppc->pio_pcdir &= portCmask;
+ eppc->pio_pcpar &= portCmask;
+ eppc->pio_pcso |= portCmask;
+
+ eppc->pip_pbpar |= portBmask;
+ eppc->pip_pbdir |= portBmask;
+
+ /*
+ * SDMA & LCD bus request level 5
+ * (Section 16.10.2.1)
+ */
+ eppc->dma_sdcr = 1;
+ /*
+ * Set Rx and Tx function code
+ * (Section 16.15.4.2)
+ */
+ uart_pram->rfcr = 0x18;
+ uart_pram->tfcr = 0x18;
+ /*
+ * Set pointers to buffer descriptors.
+ * (Sections 16.15.4.1, 16.15.7.12, and 16.15.7.13)
+ */
+ uart_pram->rbase = RxBD;
+ uart_pram->tbase = TxBD;
+ /* tx and rx buffer descriptors */
+ txbd = (struct cp_bufdesc *)((char *)eppc + TxBD);
+ rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD);
+ scc_chan->txbd = txbd;
+ scc_chan->tbase = txbd;
+ scc_chan->txsize = TxSIZE;
+ scc_chan->rxbd = rxbd;
+ scc_chan->rbase = rxbd;
+ scc_chan->rxsize = RxSIZE;
+ /* max receive buffer length */
+ uart_pram->mrblr = RxSIZE;
+ /* set max_idle feature - generate interrupt after 4 chars idle period */
+ uart_pram->max_idl = 4;
+ /* no last brk char received */
+ uart_pram->brkln = 0;
+ /* no break condition occurred */
+ uart_pram->brkec = 0;
+ /* 1 break char sent on top XMIT */
+ uart_pram->brkcr = 1;
+ /* character mask */
+ uart_pram->rccm = 0xC0FF;
+ /* control characters */
+ for (i = 0; i < 8; i++) {
+ uart_pram->cc[i] = 0x8000; // Mark unused
+ }
+ /* setup RX buffer descriptors */
+ for (i = 0; i < RxNUM; i++) {
+ rxbd->length = 0;
+ rxbd->buffer = RxBUF;
+ rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;
+ if (i == (RxNUM-1)) rxbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer
+ RxBUF += RxSIZE;
+ rxbd++;
+ }
+ /* setup TX buffer descriptors */
+ for (i = 0; i < TxNUM; i++) {
+ txbd->length = 0;
+ txbd->buffer = TxBUF;
+ txbd->ctrl = 0;
+ if (i == (TxNUM-1)) txbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer
+ TxBUF += TxSIZE;
+ txbd++;
+ }
+ /*
+ * Reset Rx & Tx params
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ eppc->cp_cr = scc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_InitTxRx;
+ while (eppc->cp_cr & QUICC_SMC_CMD_Go )
+ continue;
+ /*
+ * Clear any previous events. Enable interrupts.
+ * (Section 16.15.7.14 and 16.15.7.15)
+ */
+ HAL_IO_BARRIER(); // Inforce I/O ordering
+ ctl->scc_scce = 0xFFFF;
+ ctl->scc_sccm = (QUICC_SCCE_BSY | QUICC_SCCE_TX | QUICC_SCCE_RX);
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+quicc_sxx_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ volatile EPPC *eppc = (volatile EPPC *)eppc_base();
+ int TxBD, RxBD;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+#ifdef CYGDBG_IO_INIT
+ diag_printf("QUICC_SMC SERIAL init - dev: %x.%d = %s\n", smc_chan->channel, smc_chan->int_num, tab->name);
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1
+ if (chan == &quicc_sxx_serial_channel_smc1) {
+ TxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM);
+ RxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM);
+ quicc_smc_serial_init_info(&quicc_sxx_serial_info_smc1,
+ &eppc->pram[2].scc.pothers.smc_modem.psmc.u, // PRAM
+ &eppc->smc_regs[0], // Control registers
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE,
+ &quicc_smc1_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE,
+ &quicc_smc1_rxbuf[0],
+ 0xC0, // PortB mask
+ QUICC_CPM_SMC1
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2
+ if (chan == &quicc_sxx_serial_channel_smc2) {
+ TxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM);
+ RxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM);
+ quicc_smc_serial_init_info(&quicc_sxx_serial_info_smc2,
+ &eppc->pram[3].scc.pothers.smc_modem.psmc.u, // PRAM
+ &eppc->smc_regs[1], // Control registers
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE,
+ &quicc_smc2_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE,
+ &quicc_smc2_rxbuf[0],
+ 0xC00, // PortB mask
+ QUICC_CPM_SMC2
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC1
+ if (chan == &quicc_sxx_serial_channel_scc1) {
+ TxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_TxNUM);
+ RxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_RxNUM);
+ quicc_scc_serial_init_info(&quicc_sxx_serial_info_scc1,
+ &eppc->pram[0].scc.pscc.u, // PRAM
+ &eppc->scc_regs[0], // Control registersn
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_TxSIZE,
+ &quicc_scc1_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_RxSIZE,
+ &quicc_scc1_rxbuf[0],
+ 0x0003, // PortA mask
+ 0x1000, // PortB mask
+ 0x0800, // PortC mask
+ QUICC_CPM_SCC1
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC2
+ if (chan == &quicc_sxx_serial_channel_scc2) {
+ TxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_TxNUM);
+ RxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_RxNUM);
+ quicc_scc_serial_init_info(&quicc_sxx_serial_info_scc2,
+ &eppc->pram[1].scc.pscc.u, // PRAM
+ &eppc->scc_regs[1], // Control registersn
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_TxSIZE,
+ &quicc_scc2_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_RxSIZE,
+ &quicc_scc2_rxbuf[0],
+ 0x000C, // PortA mask
+ 0x2000, // PortB mask
+ 0x0C00, // PortC mask
+ QUICC_CPM_SCC2
+ );
+ }
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC3
+ if (chan == &quicc_sxx_serial_channel_scc3) {
+ TxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxNUM);
+ RxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxNUM);
+ quicc_scc_serial_init_info(&quicc_sxx_serial_info_scc3,
+ &eppc->pram[2].scc.pscc.u, // PRAM
+ &eppc->scc_regs[2], // Control registersn
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxSIZE,
+ &quicc_scc3_txbuf[0],
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxSIZE,
+ &quicc_scc3_rxbuf[0],
+#if defined(CYGHWR_HAL_POWERPC_MPC8XX_850)
+ 0x0000, // PortA mask
+ 0x00C0, // PortB mask
+ 0x0000, // PortC mask
+#elif defined(CYGHWR_HAL_POWERPC_MPC8XX_852T)
+ 0x0030, // PortA mask
+ 0x0000, // PortB mask
+ 0x0000, // PortC mask
+#elif defined(CYGHWR_HAL_POWERPC_MPC8XX_823)
+ 0x0000, // PortA mask
+ 0x00C0, // PortB mask
+ 0x0000, // PortC mask
+#else
+#error "Cannot route SCC3"
+#endif
+ QUICC_CPM_SCC3
+ );
+ }
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(smc_chan->int_num,
+ CYGARC_SIU_PRIORITY_HIGH, // Priority - unused (but asserted)
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ quicc_sxx_serial_ISR,
+ quicc_sxx_serial_DSR,
+ &smc_chan->serial_interrupt_handle,
+ &smc_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(smc_chan->int_num);
+ }
+ if (smc_chan->type == _SMC_CHAN) {
+ quicc_smc_serial_config_port(chan, &chan->config, true);
+ } else {
+ quicc_scc_serial_config_port(chan, &chan->config, true);
+ }
+ if (cache_state)
+ HAL_DCACHE_ENABLE();
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+quicc_sxx_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Force the current transmit buffer to be sent
+static void
+quicc_sxx_serial_flush(quicc_sxx_serial_info *smc_chan)
+{
+ volatile struct cp_bufdesc *txbd = smc_chan->txbd;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(txbd->buffer, smc_chan->txsize);
+ }
+ if ((txbd->length > 0) &&
+ ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == 0)) {
+ txbd->ctrl |= QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int; // Signal buffer ready
+ if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ } else {
+ txbd++;
+ }
+ smc_chan->txbd = txbd;
+ }
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+quicc_sxx_serial_putc(serial_channel *chan, unsigned char c)
+{
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ volatile struct cp_bufdesc *txbd, *txfirst;
+ volatile struct smc_uart_pram *pram = (volatile struct smc_uart_pram *)smc_chan->pram;
+ EPPC *eppc = eppc_base();
+ bool res;
+
+ cyg_drv_dsr_lock(); // Avoid race condition testing pointers
+ txbd = (struct cp_bufdesc *)((char *)eppc + pram->tbptr);
+ txfirst = txbd;
+ // Scan for a non-busy buffer
+ while (txbd->ctrl & QUICC_BD_CTL_Ready) {
+ // This buffer is busy, move to next one
+ if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ } else {
+ txbd++;
+ }
+ if (txbd == txfirst) break; // Went all the way around
+ }
+ smc_chan->txbd = txbd;
+ if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == 0) {
+ // Transmit buffer is not full/busy
+ txbd->buffer[txbd->length++] = c;
+ if (txbd->length == smc_chan->txsize) {
+ // This buffer is now full, tell SMC to start processing it
+ quicc_sxx_serial_flush(smc_chan);
+ }
+ res = true;
+ } else {
+ // No space
+ res = false;
+ }
+ cyg_drv_dsr_unlock();
+ return res;
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+quicc_sxx_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;
+
+ while ((rxbd->ctrl & QUICC_BD_CTL_Ready) != 0) ;
+ c = rxbd->buffer[0];
+ rxbd->length = smc_chan->rxsize;
+ rxbd->ctrl |= QUICC_BD_CTL_Ready;
+ if (rxbd->ctrl & QUICC_BD_CTL_Wrap) {
+ rxbd = smc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ smc_chan->rxbd = (struct cp_bufdesc *)rxbd;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+quicc_sxx_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ int res;
+
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ // FIXME - The documentation says that you can't change the baud rate
+ // again until at least two BRG input clocks have occurred.
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if (smc_chan->type == _SMC_CHAN) {
+ res = quicc_smc_serial_config_port(chan, config, true);
+ } else {
+ res = quicc_scc_serial_config_port(chan, config, true);
+ }
+ if ( true != res )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter (interrupt) on the device
+static void
+quicc_sxx_serial_start_xmit(serial_channel *chan)
+{
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ cyg_drv_dsr_lock();
+ if (smc_chan->txbd->length == 0) {
+ // See if there is anything to put in this buffer, just to get it going
+ (chan->callbacks->xmt_char)(chan);
+ }
+ if (smc_chan->txbd->length != 0) {
+ // Make sure it gets started
+ quicc_sxx_serial_flush(smc_chan);
+ }
+ cyg_drv_dsr_unlock();
+}
+
+// Disable the transmitter on the device
+static void
+quicc_sxx_serial_stop_xmit(serial_channel *chan)
+{
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ // If anything is in the last buffer, need to get it started
+ if (smc_chan->txbd->length != 0) {
+ quicc_sxx_serial_flush(smc_chan);
+ }
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+quicc_sxx_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(smc_chan->int_num);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+quicc_smc_serial_DSR(serial_channel *chan)
+{
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ volatile struct smc_regs *ctl = (volatile struct smc_regs *)smc_chan->ctl;
+ volatile struct cp_bufdesc *txbd;
+ volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;
+ volatile struct smc_uart_pram *pram = (volatile struct smc_uart_pram *)smc_chan->pram;
+ struct cp_bufdesc *rxlast;
+ int i, cache_state;
+
+ if (ctl->smc_smce & QUICC_SMCE_TX) {
+ // Transmit interrupt
+ ctl->smc_smce = QUICC_SMCE_TX; // Reset interrupt state;
+ txbd = smc_chan->tbase; // First buffer
+ while (true) {
+ if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) {
+ txbd->length = 0;
+ txbd->ctrl &= ~QUICC_BD_CTL_Int; // Reset interrupt bit
+ }
+ if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ break;
+ } else {
+ txbd++;
+ }
+ }
+ (chan->callbacks->xmt_char)(chan);
+ }
+ while (ctl->smc_smce & QUICC_SMCE_RX) {
+ // Receive interrupt
+ ctl->smc_smce = QUICC_SMCE_RX; // Reset interrupt state;
+ rxlast = (struct cp_bufdesc *) ((char *)eppc_base() + pram->rbptr);
+ while (rxbd != rxlast) {
+ if ((rxbd->ctrl & QUICC_BD_CTL_Ready) == 0) {
+ if((rxbd->ctrl & (QUICC_BD_CTL_Frame | QUICC_BD_CTL_Parity)) == 0) {
+ for (i = 0; i < rxbd->length; i++) {
+ (chan->callbacks->rcv_char)(chan, rxbd->buffer[i]);
+ }
+ } else {
+ // is this necessary?
+ rxbd->ctrl &= QUICC_BD_CTL_MASK;
+ // should we report the error?
+ }
+ // Note: the MBX860 does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(rxbd->buffer, smc_chan->rxsize); // Make sure no stale data
+ }
+ rxbd->length = 0;
+ rxbd->ctrl |= QUICC_BD_CTL_Ready;
+ }
+ if (rxbd->ctrl & QUICC_BD_CTL_Wrap) {
+ rxbd = smc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ }
+ smc_chan->rxbd = (struct cp_bufdesc *)rxbd;
+ }
+ if (ctl->smc_smce & QUICC_SMCE_BSY) {
+ ctl->smc_smce = QUICC_SMCE_BSY; // Reset interrupt state;
+ }
+ cyg_drv_interrupt_acknowledge(smc_chan->int_num);
+ cyg_drv_interrupt_unmask(smc_chan->int_num);
+}
+
+static void
+quicc_scc_serial_DSR(serial_channel *chan)
+{
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+ volatile struct scc_regs *ctl = (volatile struct scc_regs *)smc_chan->ctl;
+ volatile struct cp_bufdesc *txbd;
+ volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;
+ volatile struct uart_pram *pram = (volatile struct uart_pram *)smc_chan->pram;
+ struct cp_bufdesc *rxlast;
+ int i, cache_state;
+
+ if (ctl->scc_scce & QUICC_SCCE_TX) {
+ // Transmit interrupt
+ ctl->scc_scce = QUICC_SCCE_TX; // Reset interrupt state;
+ txbd = smc_chan->tbase; // First buffer
+ while (true) {
+ if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) {
+ txbd->length = 0;
+ txbd->ctrl &= ~QUICC_BD_CTL_Int; // Reset interrupt bit
+ }
+ if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ break;
+ } else {
+ txbd++;
+ }
+ }
+ (chan->callbacks->xmt_char)(chan);
+ }
+ while (ctl->scc_scce & QUICC_SCCE_RX) {
+ // Receive interrupt
+ ctl->scc_scce = QUICC_SCCE_RX; // Reset interrupt state;
+ rxlast = (struct cp_bufdesc *) ((char *)eppc_base() + pram->rbptr);
+ while (rxbd != rxlast) {
+ if ((rxbd->ctrl & QUICC_BD_CTL_Ready) == 0) {
+ if((rxbd->ctrl & (QUICC_BD_CTL_Frame | QUICC_BD_CTL_Parity)) == 0) {
+ for (i = 0; i < rxbd->length; i++) {
+ (chan->callbacks->rcv_char)(chan, rxbd->buffer[i]);
+ }
+ } else {
+ // is this necessary?
+ rxbd->ctrl &= QUICC_BD_CTL_MASK;
+ // should we report the error?
+ }
+ // Note: the MBX860 does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(rxbd->buffer, smc_chan->rxsize); // Make sure no stale data
+ }
+ rxbd->length = 0;
+ rxbd->ctrl |= QUICC_BD_CTL_Ready;
+ }
+ if (rxbd->ctrl & QUICC_BD_CTL_Wrap) {
+ rxbd = smc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ }
+ smc_chan->rxbd = (struct cp_bufdesc *)rxbd;
+ }
+ if (ctl->scc_scce & QUICC_SCCE_BSY) {
+ ctl->scc_scce = QUICC_SCCE_BSY; // Reset interrupt state;
+ }
+ cyg_drv_interrupt_acknowledge(smc_chan->int_num);
+ cyg_drv_interrupt_unmask(smc_chan->int_num);
+}
+
+static void
+quicc_sxx_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
+
+ if (smc_chan->type == _SMC_CHAN) {
+ quicc_smc_serial_DSR(chan);
+ } else {
+ quicc_scc_serial_DSR(chan);
+ }
+}
+
+void
+show_rxbd(int dump_all)
+{
+#ifdef CYGDBG_DIAG_BUF
+ EPPC *eppc = eppc_base();
+ struct smc_uart_pram *pram = &eppc->pram[2].scc.pothers.smc_modem.psmc.u;
+ struct cp_bufdesc *rxbd = (struct cp_bufdesc *)((char *)eppc+pram->rbase);
+ int _enable = enable_diag_uart;
+ enable_diag_uart = 0;
+#if 1
+ diag_printf("SMC Mask: %x, Events: %x, Rbase: %x, Rbptr: %x\n",
+ eppc->smc_regs[0].smc_smcm, eppc->smc_regs[0].smc_smce,
+ pram->rbase, pram->rbptr);
+ while (true) {
+ diag_printf("Rx BD: %x, ctl: %x, length: %d\n", rxbd, rxbd->ctrl, rxbd->length);
+ if (rxbd->ctrl & QUICC_BD_CTL_Wrap) break;
+ rxbd++;
+ }
+#endif
+ enable_diag_uart = _enable;
+ if (dump_all) dump_diag_buf();
+#endif // CYGDBG_DIAG_BUF
+}
+#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC
+
+// ------------------------------------------------------------------------
+// EOF powerpc/quicc_smc_serial.c
diff --git a/ecos/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.h b/ecos/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.h
new file mode 100644
index 0000000..63b0d52
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.h
@@ -0,0 +1,131 @@
+#ifndef CYGONCE_POWERPC_QUICC_SMC_SERIAL_H
+#define CYGONCE_POWERPC_QUICC_SMC_SERIAL_H
+
+// ====================================================================
+//
+// quicc_smc_serial.h
+//
+// Device I/O - Description of PowerPC QUICC/SMC serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-06-21
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports using QUICC/SMC
+
+#include <cyg/hal/quicc/ppc8xx.h> // QUICC structure definitions
+
+static unsigned int smc_select_stop_bits[] = {
+ 0,
+ QUICC_SMCMR_SB(1), // 1 stop bit
+ QUICC_SMCMR_SB(1), // 1.5 stop bit
+ QUICC_SMCMR_SB(2) // 2 stop bits
+};
+
+static unsigned int smc_select_parity[] = {
+ QUICC_SMCMR_PE(0), // No parity
+ QUICC_SMCMR_PE(1)|QUICC_SMCMR_PM(1), // Even parity
+ QUICC_SMCMR_PE(1)|QUICC_SMCMR_PM(0), // Odd parity
+ 0, // Mark parity
+ 0, // Space parity
+};
+
+static unsigned int scc_select_word_length[] = {
+ QUICC_SCC_PSMR_CLEN(5), // 5 bits / word (char)
+ QUICC_SCC_PSMR_CLEN(6),
+ QUICC_SCC_PSMR_CLEN(7),
+ QUICC_SCC_PSMR_CLEN(8)
+};
+
+static unsigned int scc_select_stop_bits[] = {
+ QUICC_SCC_PSMR_SB(1), // 0.5 stop bit ??
+ QUICC_SCC_PSMR_SB(1), // 1 stop bit
+ QUICC_SCC_PSMR_SB(2), // 1.5 stop bit
+ QUICC_SCC_PSMR_SB(2) // 2 stop bits
+};
+
+
+static unsigned int scc_select_parity[] = {
+ QUICC_SCC_PSMR_PE(0), // No parity
+ QUICC_SCC_PSMR_PE(1)|QUICC_SCC_PSMR_TPM(2)|QUICC_SCC_PSMR_RPM(2), // Even parity
+ QUICC_SCC_PSMR_PE(1)|QUICC_SCC_PSMR_TPM(0)|QUICC_SCC_PSMR_RPM(0), // Odd parity
+ QUICC_SCC_PSMR_PE(1)|QUICC_SCC_PSMR_TPM(3)|QUICC_SCC_PSMR_RPM(3), // High (mark) parity
+ QUICC_SCC_PSMR_PE(1)|QUICC_SCC_PSMR_TPM(1)|QUICC_SCC_PSMR_RPM(1), // Low (space) parity
+};
+
+// Baud rate values, based on board clock
+
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 0, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 0, // 230400
+};
+
+#define UART_BITRATE(n) ((((int)(CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000)/16)/n)-1)
+#define UART_SLOW_BITRATE(n) ((int)(CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000)/n))
+
+// Channel type select
+#define _SCC_CHAN 0
+#define _SMC_CHAN 1
+
+#endif // CYGONCE_POWERPC_QUICC_SMC_SERIAL_H
diff --git a/ecos/packages/devs/serial/powerpc/quicc2/current/ChangeLog b/ecos/packages/devs/serial/powerpc/quicc2/current/ChangeLog
new file mode 100644
index 0000000..6aeb529
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/quicc2/current/ChangeLog
@@ -0,0 +1,45 @@
+2003-09-08 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc2_scc_serial.h: Fix baud rate clock setup - was off by 1.
+ Reported by Tord Andersson <Tord.Andersson@combitechsystems.com>
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_quicc2_scc.cdl: Remove irrelevant doc link.
+
+2003-01-24 Gary Thomas <gary@mlbassoc.com> (inspired by)
+2003-01-24 Christoph Csebits <christoph.csebits@frequentis.com>
+
+ * src/quicc2_scc_serial.h: Remove invalid ";" from #defines
+
+2002-12-12 Gary Thomas <gthomas@ecoscentric.com>
+2002-12-12 Patrick Doyle <wpd@delcomsys.com>
+
+ * src/quicc2_scc_serial.h:
+ * src/quicc2_scc_serial.c:
+ * cdl/ser_quicc2_scc.cdl: New package - serial I/O suport on
+ PowerPC/QUICC2 based systems (like MPC8260).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/powerpc/quicc2/current/cdl/ser_quicc2_scc.cdl b/ecos/packages/devs/serial/powerpc/quicc2/current/cdl/ser_quicc2_scc.cdl
new file mode 100644
index 0000000..a7d7ac1
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/quicc2/current/cdl/ser_quicc2_scc.cdl
@@ -0,0 +1,287 @@
+# ====================================================================
+#
+# ser_quicc2_scc.cdl
+#
+# eCos serial PowerPC/QUICC2 SCC configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): mtek
+# Original data: gthomas
+# Contributors:
+# Date: 2002-02-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC {
+ display "PowerPC QUICC2/SCC serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_POWERPC_MPC8260
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ PowerPC QUICC2/SCC."
+
+ compile -library=libextras.a quicc2_scc_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_powerpc_quicc2_scc.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1 {
+ display "PowerPC QUICC2/SCC serial port 1 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ QUICC2/SCC port 1."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_NAME {
+ display "Device name for PowerPC QUICC2/SCC serial port 1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the PowerPC
+ QUICC2/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_BAUD {
+ display "Baud rate for the PowerPC QUICC2/SCC serial port 1"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 9600
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC QUICC2/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_BUFSIZE {
+ display "Buffer size for the PowerPC QUICC2/SCC serial port 1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC QUICC2/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_BRG {
+ display "Which baud rate generator to use for the PowerPC QUICC2/SCC serial port 1"
+ flavor data
+ legal_values 1 to 4
+ default_value 1
+ description "
+ This option specifies which of the four baud rate generators
+ to use for the PowerPC QUICC2/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_TxSIZE {
+ display "Output buffer size for the PowerPC QUICC2/SCC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC QUICC2/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_TxNUM {
+ display "Number of output buffers for the PowerPC QUICC2/SCC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC QUICC2/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_RxSIZE {
+ display "Input buffer size for the PowerPC QUICC2/SCC serial port 1"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC QUICC2/SCC port 1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_RxNUM {
+ display "Number of input buffers for the PowerPC QUICC2/SCC serial port 1"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC QUICC2/SCC port 1."
+ }
+}
+
+cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2 {
+ display "PowerPC QUICC2/SCC serial port 2 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the PowerPC
+ QUICC2/SCC port 2."
+
+ cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_NAME {
+ display "Device name for PowerPC QUICC2/SCC serial port 2"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the PowerPC
+ QUICC2/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_BAUD {
+ display "Baud rate for the PowerPC QUICC2/SCC serial port 2"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 9600
+ description "
+ This option specifies the default baud rate (speed) for the
+ PowerPC QUICC2/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_BUFSIZE {
+ display "Buffer size for the PowerPC QUICC2/SCC serial port 2"
+ flavor data
+ legal_values 0 to 8192
+ default_value 256
+ description "
+ This option specifies the size of the internal buffers used
+ for the PowerPC QUICC2/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_BRG {
+ display "Which baud rate generator to use for the PowerPC QUICC2/SCC serial port 2"
+ flavor data
+ legal_values 1 to 4
+ default_value 2
+ description "
+ This option specifies which of the four baud rate generators
+ to use for the PowerPC QUICC2/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_TxSIZE {
+ display "Output buffer size for the PowerPC QUICC2/SCC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per
+ transmit request to be used for the PowerPC QUICC2/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_TxNUM {
+ display "Number of output buffers for the PowerPC QUICC2/SCC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of output buffer packets
+ to be used for the PowerPC QUICC2/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_RxSIZE {
+ display "Input buffer size for the PowerPC QUICC2/SCC serial port 2"
+ flavor data
+ legal_values 16 to 128
+ default_value 16
+ description "
+ This option specifies the maximum number of characters per receive
+ request to be used for the PowerPC QUICC2/SCC port 2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_RxNUM {
+ display "Number of output buffers for the PowerPC QUICC2/SCC serial port 2"
+ flavor data
+ legal_values 2 to 16
+ default_value 4
+ description "
+ This option specifies the number of input buffer packets
+ to be used for the PowerPC QUICC2/SCC port 2."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_quicc_smc.cdl
diff --git a/ecos/packages/devs/serial/powerpc/quicc2/current/src/quicc2_scc_serial.c b/ecos/packages/devs/serial/powerpc/quicc2/current/src/quicc2_scc_serial.c
new file mode 100644
index 0000000..8343d2c
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/quicc2/current/src/quicc2_scc_serial.c
@@ -0,0 +1,849 @@
+//==========================================================================
+//
+// io/serial/powerpc/quicc2_scc_serial.c
+//
+// PowerPC QUICC2 (SCC) Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): mtek
+// Contributors: gthomas
+// Date: 1999-06-20
+// Purpose: QUICC2 SCC Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/var_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/mpc8260.h>
+#include CYGBLD_HAL_PLATFORM_H
+
+#include "quicc2_scc_serial.h"
+#define QUICC2_VADS_IMM_BASE 0x04700000
+#define QUICC2_VADS_BCSR_BASE 0x04500000
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC
+
+static bool
+quicc2_scc_serial_init(struct cyg_devtab_entry *tab);
+static bool
+quicc2_scc_serial_putc(serial_channel *chan,
+ unsigned char c);
+static Cyg_ErrNo
+quicc2_scc_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char
+quicc2_scc_serial_getc(serial_channel *chan);
+static Cyg_ErrNo
+quicc2_scc_serial_set_config(serial_channel *chan,
+ cyg_uint32 key, const void *xbuf,
+ cyg_uint32 *len);
+static void
+quicc2_scc_serial_start_xmit(serial_channel *chan);
+static void
+quicc2_scc_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32
+quicc2_scc_serial_ISR(cyg_vector_t vector,
+ cyg_addrword_t data);
+static void
+quicc2_scc_serial_DSR(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+
+static SERIAL_FUNS(quicc2_scc_serial_funs,
+ quicc2_scc_serial_putc,
+ quicc2_scc_serial_getc,
+ quicc2_scc_serial_set_config,
+ quicc2_scc_serial_start_xmit,
+ quicc2_scc_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1
+static quicc2_scc_serial_info quicc2_scc_serial_info1;
+
+#if CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_BUFSIZE > 0
+static unsigned char quicc2_scc_serial_out_buf1[CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_BUFSIZE];
+static unsigned char quicc2_scc_serial_in_buf1[CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(quicc2_scc_serial_channel1,
+ quicc2_scc_serial_funs,
+ quicc2_scc_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &quicc2_scc_serial_out_buf1[0], sizeof(quicc2_scc_serial_out_buf1),
+ &quicc2_scc_serial_in_buf1[0], sizeof(quicc2_scc_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(quicc2_scc_serial_channel1,
+ quicc2_scc_serial_funs,
+ quicc2_scc_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+static unsigned char quicc2_scc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_TxNUM]
+ [CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_TxSIZE + HAL_DCACHE_LINE_SIZE-1];
+static unsigned char quicc2_scc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_RxNUM]
+ [CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_RxSIZE + HAL_DCACHE_LINE_SIZE-1];
+
+DEVTAB_ENTRY(quicc2_scc_serial_io1,
+ CYGDAT_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ quicc2_scc_serial_init,
+ quicc2_scc_serial_lookup, // Serial driver may need initializing
+ &quicc2_scc_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1
+
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2
+static quicc2_scc_serial_info quicc2_scc_serial_info2;
+
+#if CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_BUFSIZE > 0
+static unsigned char quicc2_scc_serial_out_buf2[CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_BUFSIZE];
+static unsigned char quicc2_scc_serial_in_buf2[CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(quicc2_scc_serial_channel2,
+ quicc2_scc_serial_funs,
+ quicc2_scc_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &quicc2_scc_serial_out_buf2[0], sizeof(quicc2_scc_serial_out_buf2),
+ &quicc2_scc_serial_in_buf2[0], sizeof(quicc2_scc_serial_in_buf2)
+ );
+#else
+static SERIAL_CHANNEL(quicc2_scc_serial_channel2,
+ quicc2_scc_serial_funs,
+ quicc2_scc_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+static unsigned char quicc2_scc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_TxNUM]
+ [CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_TxSIZE + HAL_DCACHE_LINE_SIZE-1];
+static unsigned char quicc2_scc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_RxNUM]
+ [CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_RxSIZE + HAL_DCACHE_LINE_SIZE-1];
+
+DEVTAB_ENTRY(quicc2_scc_serial_io2,
+ CYGDAT_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ quicc2_scc_serial_init,
+ quicc2_scc_serial_lookup, // Serial driver may need initializing
+ &quicc2_scc_serial_channel2
+ );
+#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC
+
+#ifdef CYGDBG_DIAG_BUF
+extern int enable_diag_uart;
+#endif // CYGDBG_DIAG_BUF
+
+// Internal function to actually configure the hardware to
+// desired baud rate, stop bits and parity ...
+static bool
+quicc2_scc_serial_config_port(serial_channel *chan,
+ cyg_serial_info_t *new_config,
+ bool init)
+{
+ quicc2_scc_serial_info *scc_chan = (quicc2_scc_serial_info *)chan->dev_priv;
+ volatile t_PQ2IMM *IMM = (volatile t_PQ2IMM *) QUICC2_VADS_IMM_BASE;
+
+ unsigned long b_rate = select_baud[new_config->baud];
+
+ if (b_rate == 0) return false;
+
+ // Stop the transmitter while changing baud rate
+ while (IMM->cpm_cpcr & QUICC2_CPCR_READY);
+ IMM->cpm_cpcr = scc_chan->scc_cpcr | QUICC2_CPCR_STOP_TX | QUICC2_CPCR_READY;
+ while (IMM->cpm_cpcr & QUICC2_CPCR_READY);
+
+ // Disable Tx, RX and put them in a reset state
+ scc_chan->scc_regs->gsmr_l &= ~(QUICC2_SCC_GSMR_L_ENT | QUICC2_SCC_GSMR_L_ENR);
+
+ // Set the baud rate
+ *(scc_chan->brg) = (UART_BIT_RATE(b_rate) << 1) | QUICC2_BRG_EN;
+
+ // Set stop bits, word length and parity
+ scc_chan->scc_regs->psmr = QUICC2_SCC_PSMR_ASYNC |
+ select_stop_bits[new_config->stop] |
+ select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ select_parity[new_config->parity];
+
+ // Support fractional stop bits
+ scc_chan->scc_regs->dsr = (new_config->stop & 1) ? QUICC2_SCC_DSR_FULL : QUICC2_SCC_DSR_HALF;
+
+ // Initialize the parameters
+ while (IMM->cpm_cpcr & QUICC2_CPCR_READY);
+ IMM->cpm_cpcr = scc_chan->scc_cpcr | QUICC2_CPCR_INIT_TX_RX | QUICC2_CPCR_READY;
+ while (IMM->cpm_cpcr & QUICC2_CPCR_READY);
+
+ // Enable Tx and Rx
+ scc_chan->scc_regs->gsmr_l |= (QUICC2_SCC_GSMR_L_ENT | QUICC2_SCC_GSMR_L_ENR);
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to set up internal tables for device.
+static void
+quicc2_scc_serial_init_info(quicc2_scc_serial_info *scc_chan,
+ int SCC_index,
+ int BRG_index,
+ int TxBD, int TxNUM, int TxSIZE,
+ cyg_uint8 *TxBUF,
+ int RxBD, int RxNUM, int RxSIZE,
+ cyg_uint8 *RxBUF)
+{
+ volatile t_PQ2IMM *IMM = (volatile t_PQ2IMM *) QUICC2_VADS_IMM_BASE;
+#ifdef CYGPKG_HAL_POWERPC_VADS
+ volatile t_BCSR *bcsr = (volatile t_BCSR *) QUICC2_VADS_BCSR_BASE;
+#endif
+ t_UartScc_Pram *uart_pram;
+ scc_bd *txbd, *rxbd;
+ int i;
+
+ // Disable the channel, just in case
+ IMM->scc_regs[SCC_index-1].gsmr_l &= ~(QUICC2_SCC_GSMR_L_ENT | QUICC2_SCC_GSMR_L_ENR);
+
+ switch (SCC_index) {
+
+ case 1:
+ // Put the data into the info structure
+ scc_chan->scc_cpcr = QUICC2_CPCR_SCC1;
+ scc_chan->scc_regs = &(IMM->scc_regs[0]);
+ scc_chan->scc_pram = &(IMM->pram.serials.scc_pram[0]);
+ scc_chan->int_vector = CYGNUM_HAL_INTERRUPT_SCC1;
+
+ // Set-up the PORT D pins
+ IMM->io_regs[PORT_D].psor &= ~QUICC2_SCC1_PORTD_PPAR;
+ IMM->io_regs[PORT_D].psor |= QUICC2_SCC1_PORTD_PDIR;
+ IMM->io_regs[PORT_D].ppar |= QUICC2_SCC1_PORTD_PPAR;
+ IMM->io_regs[PORT_D].pdir &= ~QUICC2_SCC1_PORTD_PPAR;
+ IMM->io_regs[PORT_D].pdir |= QUICC2_SCC1_PORTD_PDIR;
+ IMM->io_regs[PORT_D].podr &= ~QUICC2_SCC1_PORTD_PPAR;
+
+ // Set-up the PORT C pins
+ IMM->io_regs[PORT_C].psor &= ~QUICC2_SCC1_PORTC_PPAR;
+ IMM->io_regs[PORT_C].ppar |= QUICC2_SCC1_PORTC_PPAR;
+ IMM->io_regs[PORT_C].pdir &= ~QUICC2_SCC1_PORTC_PPAR;
+ IMM->io_regs[PORT_C].podr &= ~QUICC2_SCC1_PORTC_PPAR;
+
+ // Select the baud rate generator and connect it
+ IMM->cpm_mux_cmxscr &= QUICC2_CMX_SCC1_CLR;
+
+ switch (BRG_index) {
+ case 1:
+ scc_chan->brg = &(IMM->brgs_brgc1);
+ IMM->cpm_mux_cmxscr |= QUICC2_CMX_SCC1_BRG1;
+ break;
+ case 2:
+ scc_chan->brg = &(IMM->brgs_brgc2);
+ IMM->cpm_mux_cmxscr |= QUICC2_CMX_SCC1_BRG2;
+ break;
+ case 3:
+ scc_chan->brg = &(IMM->brgs_brgc3);
+ IMM->cpm_mux_cmxscr |= QUICC2_CMX_SCC1_BRG3;
+ break;
+ case 4:
+ scc_chan->brg = &(IMM->brgs_brgc4);
+ IMM->cpm_mux_cmxscr |= QUICC2_CMX_SCC1_BRG4;
+ break;
+ }
+#ifdef CYGPKG_HAL_POWERPC_VADS
+ // Enable the transciever
+ bcsr->bcsr1 &= ~(QUICC2_BCSR_EN_SCC1);
+#endif
+ break;
+
+ case 2:
+ // Put the data into the info structure
+ scc_chan->scc_cpcr = QUICC2_CPCR_SCC2;
+ scc_chan->scc_regs = &(IMM->scc_regs[1]);
+ scc_chan->scc_pram = &(IMM->pram.serials.scc_pram[1]);
+ scc_chan->int_vector = CYGNUM_HAL_INTERRUPT_SCC2;
+
+ // Set-up the PORT D pins
+ IMM->io_regs[PORT_D].psor &= ~QUICC2_SCC2_PORTD_PPAR;
+ IMM->io_regs[PORT_D].ppar |= QUICC2_SCC2_PORTD_PPAR;
+ IMM->io_regs[PORT_D].pdir &= ~QUICC2_SCC2_PORTD_PPAR;
+ IMM->io_regs[PORT_D].pdir |= QUICC2_SCC2_PORTD_PDIR;
+ IMM->io_regs[PORT_D].podr &= ~QUICC2_SCC2_PORTD_PPAR;
+
+ // Set-up the PORT C pins
+ IMM->io_regs[PORT_C].psor &= ~QUICC2_SCC2_PORTC_PPAR;
+ IMM->io_regs[PORT_C].ppar |= QUICC2_SCC2_PORTC_PPAR;
+ IMM->io_regs[PORT_C].pdir &= ~QUICC2_SCC2_PORTC_PPAR;
+ IMM->io_regs[PORT_C].podr &= ~QUICC2_SCC2_PORTC_PPAR;
+
+ // Select the baud rate generator and connect it
+ IMM->cpm_mux_cmxscr &= QUICC2_CMX_SCC2_CLR;
+
+ switch (BRG_index) {
+ case 1:
+ scc_chan->brg = &(IMM->brgs_brgc1);
+ IMM->cpm_mux_cmxscr |= QUICC2_CMX_SCC2_BRG1;
+ break;
+ case 2:
+ scc_chan->brg = &(IMM->brgs_brgc2);
+ IMM->cpm_mux_cmxscr |= QUICC2_CMX_SCC2_BRG2;
+ break;
+ case 3:
+ scc_chan->brg = &(IMM->brgs_brgc3);
+ IMM->cpm_mux_cmxscr |= QUICC2_CMX_SCC2_BRG3;
+ break;
+ case 4:
+ scc_chan->brg = &(IMM->brgs_brgc4);
+ IMM->cpm_mux_cmxscr |= QUICC2_CMX_SCC2_BRG4;
+ break;
+ }
+#ifdef CYGPKG_HAL_POWERPC_VADS
+ // Enable the transciever
+ bcsr->bcsr1 &= ~(QUICC2_BCSR_EN_SCC2);
+#endif
+ break;
+
+ default:
+ diag_printf("Incorrect SCC index in quicc2_scc_serial_init_info \n");
+ break;
+ }
+
+ // Initialize common SCC PRAM
+ scc_chan->tbase = (scc_bd *) (QUICC2_VADS_IMM_BASE + TxBD);
+ scc_chan->rbase = (scc_bd *) (QUICC2_VADS_IMM_BASE + RxBD);
+ scc_chan->txbd = (scc_bd *) (QUICC2_VADS_IMM_BASE + TxBD);
+ scc_chan->rxbd = (scc_bd *) (QUICC2_VADS_IMM_BASE + RxBD);
+ scc_chan->txsize = TxSIZE;
+ scc_chan->rxsize = RxSIZE;
+
+ scc_chan->scc_pram->rbase = RxBD;
+ scc_chan->scc_pram->tbase = TxBD;
+ scc_chan->scc_pram->rfcr = 0x10;
+ scc_chan->scc_pram->tfcr = 0x10;
+ scc_chan->scc_pram->mrblr = RxSIZE;
+
+ // Initialize UART PRAM
+ uart_pram = &(scc_chan->scc_pram->SpecificProtocol.u);
+
+ uart_pram->max_idl = 4;
+ uart_pram->brkcr = 1;
+ uart_pram->brkln = 0;
+ uart_pram->parec = 0;
+ uart_pram->frmec = 0;
+ uart_pram->nosec = 0;
+ uart_pram->brkec = 0;
+ uart_pram->uaddr1 = 0;
+ uart_pram->uaddr2 = 0;
+ uart_pram->toseq = 0;
+ uart_pram->cc[0] = 0x8000;
+ uart_pram->cc[1] = 0x8000;
+ uart_pram->cc[2] = 0x8000;
+ uart_pram->cc[3] = 0x8000;
+ uart_pram->cc[4] = 0x8000;
+ uart_pram->cc[5] = 0x8000;
+ uart_pram->cc[6] = 0x8000;
+ uart_pram->cc[7] = 0x8000;
+ uart_pram->rccm = 0xC0FF;
+
+ // Initialize registers
+ scc_chan->scc_regs->gsmr_l = QUICC2_SCC_GSMR_L_INIT;
+ scc_chan->scc_regs->gsmr_h = QUICC2_SCC_GSMR_H_INIT;
+ // scc_chan->scc_regs->psmr = 0x8000; // Set by config
+ scc_chan->scc_regs->todr = 0;
+ // scc_chan->scc_regs->dsr = 0x7e7e; // Set by config
+ scc_chan->scc_regs->scce = 0xffff;
+ scc_chan->scc_regs->sccm = (QUICC2_SCCE_BSY | QUICC2_SCCE_TX | QUICC2_SCCE_RX);
+
+ /* setup RX buffer descriptors */
+ rxbd = (struct scc_bd *)((char *) QUICC2_VADS_IMM_BASE + RxBD);
+
+ for (i = 0; i < RxNUM; i++) {
+ rxbd->ctrl = QUICC2_BD_CTL_Ready | QUICC2_BD_CTL_Int;
+ rxbd->length = 0;
+ rxbd->buffer = RxBUF;
+
+ RxBUF += RxSIZE;
+ rxbd++;
+ }
+
+ rxbd--;
+ rxbd->ctrl |= QUICC2_BD_CTL_Wrap; // Last buffer
+
+ /* setup TX buffer descriptors */
+ txbd = (struct scc_bd *)((char *) QUICC2_VADS_IMM_BASE + TxBD);
+
+ for (i = 0; i < TxNUM; i++) {
+ txbd->ctrl = 0;
+ txbd->length = 0;
+ txbd->buffer = TxBUF;
+ TxBUF += TxSIZE;
+ txbd++;
+ }
+
+ txbd--;
+ txbd->ctrl |= QUICC2_BD_CTL_Wrap; // Last buffer
+
+ // Issue Init RX & TX Parameters Command
+ while (IMM->cpm_cpcr & QUICC2_CPCR_READY);
+ IMM->cpm_cpcr = scc_chan->scc_cpcr | QUICC2_CPCR_INIT_TX_RX | QUICC2_CPCR_READY;
+ while (IMM->cpm_cpcr & QUICC2_CPCR_READY);
+
+ return;
+
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+quicc2_scc_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ quicc2_scc_serial_info *scc_chan = (quicc2_scc_serial_info *)chan->dev_priv;
+ volatile t_PQ2IMM *IMM = (volatile t_PQ2IMM *) QUICC2_VADS_IMM_BASE;
+ int TxBD, RxBD;
+ static int first_init = 1;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ HAL_DCACHE_SYNC();
+ HAL_DCACHE_DISABLE();
+
+#ifdef CYGDBG_IO_INIT
+ diag_printf("QUICC2_SCC SERIAL init - dev: %x\n",
+ scc_chan->channel);
+#endif
+ if (first_init) {
+ // Set up tables since many fields are dynamic [computed at runtime]
+ first_init = 0;
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1
+
+ // Totally reset the CP
+ while (IMM->cpm_cpcr & QUICC2_CPCR_READY);
+ IMM->cpm_cpcr = QUICC2_CPCR_RESET | QUICC2_CPCR_READY;
+ while (IMM->cpm_cpcr & QUICC2_CPCR_READY);
+
+ TxBD = 0x2800; // Note: this should be configurable
+ RxBD = TxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_TxNUM*8;
+ quicc2_scc_serial_init_info(&quicc2_scc_serial_info1,
+ 1, // indicates SCC1
+ CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_BRG,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_TxSIZE,
+ ALIGN_TO_CACHELINES(&quicc2_scc1_txbuf[0][0]),
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_RxSIZE,
+ ALIGN_TO_CACHELINES(&quicc2_scc1_rxbuf[0][0])
+ );
+#else
+#ifdef CYGPKG_HAL_POWERPC_MPC8260
+ // Ensure that SCC1 side is initialized first
+ diag_init(); // (pull in constructor that inits diag channel)
+ TxBD = 0x2900; // Note : this should be inferred from the
+ // chip state
+#else
+ // there is no diag device wanting to use the QUICC, so prepare it
+ // for SCC2 use only.
+ while (IMM->cpm_cpcr & QUICC2_CPCR_READY); // Totally reset the CP
+ IMM->cpm_cpcr = QUICC2_CPCR_RESET | QUICC2_CPCR_READY;
+ while (IMM->cpm_cpcr & QUICC2_CPCR_READY);
+ TxBD = 0x2800; // Note: this should be configurable
+#endif
+#endif
+#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2
+
+ RxBD = TxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_TxNUM*8;
+ quicc2_scc_serial_init_info(&quicc2_scc_serial_info2,
+ 2, // indicates SCC2
+ CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_BRG,
+ TxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_TxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_TxSIZE,
+ ALIGN_TO_CACHELINES(&quicc2_scc2_txbuf[0][0]),
+ RxBD,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_RxNUM,
+ CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC2_RxSIZE,
+ ALIGN_TO_CACHELINES(&quicc2_scc2_rxbuf[0][0])
+ );
+#endif
+ }
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(scc_chan->int_vector,
+ 0, // CYGARC_SIU_PRIORITY_HIGH, - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ quicc2_scc_serial_ISR,
+ quicc2_scc_serial_DSR,
+ &scc_chan->serial_interrupt_handle,
+ &scc_chan->serial_interrupt);
+ cyg_drv_interrupt_attach(scc_chan->serial_interrupt_handle);
+ cyg_drv_interrupt_acknowledge(scc_chan->int_vector);
+ cyg_drv_interrupt_unmask(scc_chan->int_vector);
+ }
+ quicc2_scc_serial_config_port(chan, &chan->config, true);
+ if (cache_state)
+ HAL_DCACHE_ENABLE();
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+quicc2_scc_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Force the current transmit buffer to be sent
+static void
+quicc2_scc_serial_flush(quicc2_scc_serial_info *scc_chan)
+{
+ volatile struct scc_bd *txbd = scc_chan->txbd;
+ int cache_state;
+
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_FLUSH(txbd->buffer, scc_chan->txsize);
+ }
+
+ if ((txbd->length > 0) &&
+ ((txbd->ctrl & (QUICC2_BD_CTL_Ready|QUICC2_BD_CTL_Int)) == 0)) {
+ txbd->ctrl |= QUICC2_BD_CTL_Ready|QUICC2_BD_CTL_Int; // Signal buffer ready
+ if (txbd->ctrl & QUICC2_BD_CTL_Wrap) {
+ txbd = scc_chan->tbase;
+ } else {
+ txbd++;
+ }
+ scc_chan->txbd = (scc_bd *) txbd;
+ }
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+quicc2_scc_serial_putc(serial_channel *chan, unsigned char c)
+{
+ quicc2_scc_serial_info *scc_chan = (quicc2_scc_serial_info *)chan->dev_priv;
+ volatile struct scc_bd *txbd, *txfirst;
+ bool res;
+
+ cyg_drv_dsr_lock(); // Avoid race condition testing pointers
+
+ txbd = (scc_bd *)(QUICC2_VADS_IMM_BASE + ((int) scc_chan->scc_pram->tbptr));
+ txfirst = txbd;
+
+ // Scan for a non-busy buffer
+ while (txbd->ctrl & QUICC2_BD_CTL_Ready) {
+ // This buffer is busy, move to next one
+ if (txbd->ctrl & QUICC2_BD_CTL_Wrap) {
+ txbd = scc_chan->tbase;
+ } else {
+ txbd++;
+ }
+ if (txbd == txfirst) break; // Went all the way around
+ }
+
+ scc_chan->txbd = (scc_bd *) txbd;
+ if ((txbd->ctrl & (QUICC2_BD_CTL_Ready|QUICC2_BD_CTL_Int)) == 0) {
+ // Transmit buffer is not full/busy
+ txbd->buffer[txbd->length++] = c;
+ if (txbd->length == scc_chan->txsize) {
+ // This buffer is now full, tell SCC to start processing it
+ quicc2_scc_serial_flush(scc_chan);
+ }
+ res = true;
+ } else {
+ // No space
+ res = false;
+ }
+
+ cyg_drv_dsr_unlock();
+ return res;
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+quicc2_scc_serial_getc(serial_channel *chan)
+{
+ unsigned char c;
+ quicc2_scc_serial_info *scc_chan = (quicc2_scc_serial_info *)chan->dev_priv;
+ volatile scc_bd *rxbd = scc_chan->rxbd;
+
+ while ((rxbd->ctrl & QUICC2_BD_CTL_Ready) != 0) ; // WAIT ...
+
+ c = rxbd->buffer[0];
+ rxbd->length = scc_chan->rxsize;
+ rxbd->ctrl |= QUICC2_BD_CTL_Ready;
+ if (rxbd->ctrl & QUICC2_BD_CTL_Wrap) {
+ rxbd = scc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ scc_chan->rxbd = (scc_bd *) rxbd;
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+quicc2_scc_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ // FIXME - The documentation says that you can't change the baud rate
+ // again until at least two BRG input clocks have occurred.
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != quicc2_scc_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter (interrupt) on the device
+static void
+quicc2_scc_serial_start_xmit(serial_channel *chan)
+{
+ quicc2_scc_serial_info *scc_chan = (quicc2_scc_serial_info *)chan->dev_priv;
+
+ cyg_drv_dsr_lock();
+
+ if (scc_chan->txbd->length == 0) {
+ // See if there is anything to put in this buffer, just to get it going
+ (chan->callbacks->xmt_char)(chan);
+ }
+ if (scc_chan->txbd->length != 0) {
+ // Make sure it gets started
+ quicc2_scc_serial_flush(scc_chan);
+ }
+
+ cyg_drv_dsr_unlock();
+}
+
+// Disable the transmitter on the device
+static void
+quicc2_scc_serial_stop_xmit(serial_channel *chan)
+{
+ quicc2_scc_serial_info *scc_chan = (quicc2_scc_serial_info *)chan->dev_priv;
+ // If anything is in the last buffer, need to get it started
+ if (scc_chan->txbd->length != 0) {
+ quicc2_scc_serial_flush(scc_chan);
+ }
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+quicc2_scc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ quicc2_scc_serial_info *scc_chan = (quicc2_scc_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(scc_chan->int_vector);
+ return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+quicc2_scc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ quicc2_scc_serial_info *scc_chan = (quicc2_scc_serial_info *)chan->dev_priv;
+ volatile struct scc_regs_8260 *regs = scc_chan->scc_regs;
+ volatile scc_bd *txbd;
+ volatile scc_bd *rxbd = scc_chan->rxbd;
+ scc_bd *rxlast;
+ int i, cache_state;
+
+#ifdef CYGDBG_DIAG_BUF
+ int _time, _stime;
+ externC cyg_tick_count_t cyg_current_time(void);
+ cyg_drv_isr_lock();
+ enable_diag_uart = 0;
+ HAL_CLOCK_READ(&_time);
+ _stime = (int)cyg_current_time();
+ diag_printf("DSR start - CE: %x, time: %x.%x\n",
+ regs->scce, _stime, _time);
+ enable_diag_uart = 1;
+#endif // CYGDBG_DIAG_BUF
+
+ if (regs->scce & QUICC2_SCCE_TX) { // Tx Event
+
+#ifdef XX_CYGDBG_DIAG_BUF
+ enable_diag_uart = 0;
+ txbd = scc_chan->tbase;
+ for (i = 0; i < CYGNUM_IO_SERIAL_POWERPC_QUICC2_SCC_SCC1_TxNUM; i++, txbd++) {
+ diag_printf("Tx BD: %x, length: %d, ctl: %x\n", txbd, txbd->length, txbd->ctrl);
+ }
+ enable_diag_uart = 1;
+#endif // CYGDBG_DIAG_BUF
+
+ regs->scce = QUICC2_SCCE_TX; // Reset Tx Event
+ txbd = scc_chan->tbase; // First buffer
+ while (true) {
+ if ((txbd->ctrl & (QUICC2_BD_CTL_Ready|QUICC2_BD_CTL_Int)) == QUICC2_BD_CTL_Int) {
+#ifdef XX_CYGDBG_DIAG_BUF
+ enable_diag_uart = 0;
+ HAL_CLOCK_READ(&_time);
+ _stime = (int)cyg_current_time();
+ diag_printf("TX Done - Tx: %x, length: %d, time: %x.%x\n",
+ txbd, txbd->length, _stime, _time);
+ enable_diag_uart = 1;
+#endif // CYGDBG_DIAG_BUF
+ txbd->length = 0;
+ txbd->ctrl &= ~QUICC2_BD_CTL_Int; // Reset interrupt bit
+ }
+
+ if (txbd->ctrl & QUICC2_BD_CTL_Wrap) {
+ txbd = scc_chan->tbase;
+ break;
+ } else {
+ txbd++;
+ }
+ }
+ (chan->callbacks->xmt_char)(chan);
+ }
+
+ while (regs->scce & QUICC2_SCCE_RX) { // Rx Event
+
+ regs->scce = QUICC2_SCCE_RX; // Reset interrupt state;
+ rxlast = (scc_bd *) ((char *)QUICC2_VADS_IMM_BASE + scc_chan->scc_pram->rbptr );
+
+#ifdef CYGDBG_DIAG_BUF
+ enable_diag_uart = 0;
+ HAL_CLOCK_READ(&_time);
+ _stime = (int)cyg_current_time();
+ diag_printf("Scan RX - rxbd: %x, rbptr: %x, time: %x.%x\n",
+ rxbd, rxlast, _stime, _time);
+#endif // CYGDBG_DIAG_BUF
+ while (rxbd != rxlast) {
+ if ((rxbd->ctrl & QUICC2_BD_CTL_Ready) == 0) {
+#ifdef CYGDBG_DIAG_BUF
+ diag_printf("rxbuf: %x, flags: %x, length: %d\n",
+ rxbd, rxbd->ctrl, rxbd->length);
+ diag_dump_buf(rxbd->buffer, rxbd->length);
+#endif // CYGDBG_DIAG_BUF
+
+ for (i = 0; i < rxbd->length; i++) {
+ (chan->callbacks->rcv_char)(chan, rxbd->buffer[i]);
+ }
+ // Note: the MBX860 does not seem to snoop/invalidate the data cache properly!
+ HAL_DCACHE_IS_ENABLED(cache_state);
+ if (cache_state) {
+ HAL_DCACHE_INVALIDATE(rxbd->buffer, scc_chan->rxsize); // Make sure no stale data
+ }
+
+ rxbd->length = 0;
+ rxbd->ctrl |= QUICC2_BD_CTL_Ready;
+ }
+
+ if (rxbd->ctrl & QUICC2_BD_CTL_Wrap) {
+ rxbd = scc_chan->rbase;
+ } else {
+ rxbd++;
+ }
+ }
+#ifdef CYGDBG_DIAG_BUF
+ enable_diag_uart = 1;
+#endif // CYGDBG_DIAG_BUF
+ scc_chan->rxbd = (scc_bd *) rxbd;
+ }
+
+ if (regs->scce & QUICC2_SCCE_BSY) {
+#ifdef CYGDBG_DIAG_BUF
+ enable_diag_uart = 0;
+ diag_printf("RX BUSY interrupt\n");
+ enable_diag_uart = 1;
+#endif // CYGDBG_DIAG_BUF
+ regs->scce = QUICC2_SCCE_BSY; // Reset interrupt state;
+ }
+#ifdef CYGDBG_DIAG_BUF
+ enable_diag_uart = 0;
+ HAL_CLOCK_READ(&_time);
+ _stime = (int)cyg_current_time();
+ diag_printf("DSR done - CE: %x, time: %x.%x\n",
+ regs->scce, _stime, _time);
+ enable_diag_uart = 1;
+#endif // CYGDBG_DIAG_BUF
+ cyg_drv_interrupt_acknowledge(scc_chan->int_vector);
+ cyg_drv_interrupt_unmask(scc_chan->int_vector);
+#ifdef CYGDBG_DIAG_BUF
+ cyg_drv_isr_unlock();
+#endif // CYGDBG_DIAG_BUF
+}
+
+#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC2_SCC
+
+// ------------------------------------------------------------------------
+// EOF powerpc/quicc2_scc_serial.c
diff --git a/ecos/packages/devs/serial/powerpc/quicc2/current/src/quicc2_scc_serial.h b/ecos/packages/devs/serial/powerpc/quicc2/current/src/quicc2_scc_serial.h
new file mode 100644
index 0000000..d90162c
--- /dev/null
+++ b/ecos/packages/devs/serial/powerpc/quicc2/current/src/quicc2_scc_serial.h
@@ -0,0 +1,207 @@
+#ifndef CYGONCE_POWERPC_QUICC2_SCC_SERIAL_H
+#define CYGONCE_POWERPC_QUICC2_SCC_SERIAL_H
+
+// ====================================================================
+//
+// quicc2_scc_serial.h
+//
+// Device I/O - Description of PowerPC QUICC2/SCC serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): mtek
+// Contributors: gthomas
+// Date: 2002-2-27
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports using QUICC2/SCC
+
+// macro for aligning buffers to cache lines
+#define ALIGN_TO_CACHELINES(b) ((cyg_uint8 *)(((CYG_ADDRESS)(b) + (HAL_DCACHE_LINE_SIZE-1)) & ~(HAL_DCACHE_LINE_SIZE-1)))
+
+#define UART_BIT_RATE(n) \
+ ((((int)(CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000))/(n * 64))-1)
+
+// SCC PSMR masks ....
+#define QUICC2_SCC_PSMR_ASYNC 0x8000
+#define QUICC2_SCC_PSMR_SB(n) ((n-1)<<14) // Stop bits (1=1sb, 2=2sb)
+#define QUICC2_SCC_PSMR_CLEN(n) ((n-5)<<12) // Character Length (5-8)
+#define QUICC2_SCC_PSMR_PE(n) (n<<4) // Parity enable(0=disabled, 1=enabled)
+#define QUICC2_SCC_PSMR_RPM(n) (n<<2) // Rx Parity mode (0=odd, 1=low, 2=even, 3=high)
+#define QUICC2_SCC_PSMR_TPM(n) (n) // Tx Parity mode (0=odd, 1=low, 2=even, 3=high)
+
+// SCC DSR masks
+#define QUICC2_SCC_DSR_FULL 0x7e7e
+#define QUICC2_SCC_DSR_HALF 0x467e
+
+// SCC GSMR masks ...
+#define QUICC2_SCC_GSMR_H_INIT 0x00000060
+#define QUICC2_SCC_GSMR_L_INIT 0x00028004
+#define QUICC2_SCC_GSMR_L_ENT 0x00000010
+#define QUICC2_SCC_GSMR_L_ENR 0x00000020
+
+// SCC Events (interrupts)
+#define QUICC2_SCCE_BRK 0x0040
+#define QUICC2_SCCE_BSY 0x0004
+#define QUICC2_SCCE_TX 0x0002
+#define QUICC2_SCCE_RX 0x0001
+
+// CP commands for SCC1 and SCC2
+#define QUICC2_CPCR_SCC1 0x00800000
+#define QUICC2_CPCR_SCC2 0x04A00000
+#define QUICC2_CPCR_READY 0x00010000
+#define QUICC2_CPCR_INIT_TX_RX 0x0
+#define QUICC2_CPCR_INIT_RX 0x1
+#define QUICC2_CPCR_INIT_TX 0x2
+#define QUICC2_CPCR_STOP_TX 0x4
+#define QUICC2_CPCR_RESTART_TX 0x6
+#define QUICC2_CPCR_RESET 0x80000000
+
+// SCC Buffer descriptor control bits
+#define QUICC2_BD_CTL_Ready 0x8000 // Buffer contains data (tx) or is empty (rx)
+#define QUICC2_BD_CTL_Wrap 0x2000 // Last buffer in list
+#define QUICC2_BD_CTL_Int 0x1000 // Generate interrupt when empty (tx) or full (rx)
+
+// PORT configuration masks for SCC1 and SCC2
+#define QUICC2_SCC1_PORTC_PPAR (0x00020000)
+#define QUICC2_SCC1_PORTD_PPAR (0x00000003)
+#define QUICC2_SCC1_PORTD_PDIR (0x00000002)
+
+#define QUICC2_SCC2_PORTC_PPAR (0x00080000)
+#define QUICC2_SCC2_PORTD_PPAR (0x00000018)
+#define QUICC2_SCC2_PORTD_PDIR (0x00000010)
+
+// SCC clock Route register constants
+#define QUICC2_CMX_SCC1_CLR 0x00ffffff
+#define QUICC2_CMX_SCC1_BRG1 0x00000000
+#define QUICC2_CMX_SCC1_BRG2 0x09000000
+#define QUICC2_CMX_SCC1_BRG3 0x12000000
+#define QUICC2_CMX_SCC1_BRG4 0x1b000000
+
+#define QUICC2_CMX_SCC2_CLR 0xff00ffff
+#define QUICC2_CMX_SCC2_BRG1 0x00000000
+#define QUICC2_CMX_SCC2_BRG2 0x00090000
+#define QUICC2_CMX_SCC2_BRG3 0x00120000
+#define QUICC2_CMX_SCC2_BRG4 0x001b0000
+
+static unsigned int select_word_length[] = {
+ QUICC2_SCC_PSMR_CLEN(5), // 5 bits / word (char)
+ QUICC2_SCC_PSMR_CLEN(6),
+ QUICC2_SCC_PSMR_CLEN(7),
+ QUICC2_SCC_PSMR_CLEN(8)
+};
+
+static unsigned int select_stop_bits[] = {
+ QUICC2_SCC_PSMR_SB(1), // 0.5 stop bit ??
+ QUICC2_SCC_PSMR_SB(1), // 1 stop bit
+ QUICC2_SCC_PSMR_SB(2), // 1.5 stop bit
+ QUICC2_SCC_PSMR_SB(2) // 2 stop bits
+};
+
+
+static unsigned int select_parity[] = {
+ QUICC2_SCC_PSMR_PE(0), // No parity
+ QUICC2_SCC_PSMR_PE(1)|QUICC2_SCC_PSMR_TPM(2)|QUICC2_SCC_PSMR_RPM(2), // Even parity
+ QUICC2_SCC_PSMR_PE(1)|QUICC2_SCC_PSMR_TPM(0)|QUICC2_SCC_PSMR_RPM(0), // Odd parity
+ QUICC2_SCC_PSMR_PE(1)|QUICC2_SCC_PSMR_TPM(3)|QUICC2_SCC_PSMR_RPM(3), // High (mark) parity
+ QUICC2_SCC_PSMR_PE(1)|QUICC2_SCC_PSMR_TPM(1)|QUICC2_SCC_PSMR_RPM(1), // Low (space) parity
+};
+
+
+// Baud rate values, will be used by the macro ...
+#define QUICC2_BRG_EN 0x00010000
+static unsigned long select_baud[] = {
+ 0, // unused
+ 50,
+ 75,
+ 110,
+ 134,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 3600,
+ 4800,
+ 7200,
+ 9600,
+ 14400,
+ 19200,
+ 38400,
+ 57600,
+ 115200,
+ 230400
+};
+
+// Board control and status registers
+#define QUICC2_BCSR_EN_SCC1 0x02000000
+#define QUICC2_BCSR_EN_SCC2 0x01000000
+
+typedef struct bcsr {
+ volatile unsigned long bcsr0;
+ volatile unsigned long bcsr1;
+ volatile unsigned long bcsr2;
+ volatile unsigned long bcsr3;
+} t_BCSR;
+
+
+typedef struct scc_bd{
+ cyg_int16 ctrl;
+ cyg_int16 length;
+ cyg_int8 *buffer;
+} scc_bd;
+
+typedef struct quicc2_scc_serial_info {
+ unsigned long scc_cpcr; // Selects scc for cpcr
+ volatile struct scc_regs_8260 *scc_regs; // Ptr to scc registers
+ volatile t_Scc_Pram *scc_pram; // Ptr to scc pram
+ volatile int *brg; // Ptr to baud rate generator
+ struct scc_bd *txbd, *rxbd; // Next Tx, Rx descriptor to use
+ struct scc_bd *tbase, *rbase; // First Tx, Rx descriptor
+ int txsize, rxsize; // Length of individual buffers
+ unsigned int int_vector;
+ cyg_interrupt serial_interrupt;
+ cyg_handle_t serial_interrupt_handle;
+} quicc2_scc_serial_info;
+
+#endif // CYGONCE_POWERPC_QUICC_SMC_SERIAL_H
diff --git a/ecos/packages/devs/serial/sh/cq7708/current/ChangeLog b/ecos/packages/devs/serial/sh/cq7708/current/ChangeLog
new file mode 100644
index 0000000..e32de66
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/cq7708/current/ChangeLog
@@ -0,0 +1,62 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_sh_cq7708.cdl: Remove irrelevant doc link.
+
+2002-05-08 Jesper Skov <jskov@redhat.com>
+
+ * include/sh_sh3_cq7708_sci.inl: Serial register renaming.
+
+2002-04-23 Jesper Skov <jskov@redhat.com>
+
+ * include/sh_sh3_cq7708_sci.inl (sh_serial_info): Use variant
+ register definition for base.
+
+2000-10-03 Jesper Skov <jskov@redhat.co.uk>
+
+ * cdl/ser_sh_cq7708.cdl: Added testing parameters.
+
+ * include/sh_sh3_cq7708_sci.inl: Use named elements in structure
+ initializer.
+
+2000-09-05 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_sci_serial.c: Moved to SCI package.
+ * scr/sh_sci_cq7708.inl: moved...
+ * include/sh_sh3_cq7708_sci.inl: ... to here.
+ * cdl/ser_sh_cq7708.cdl: Matching changes.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/sh_sci_serial.c (sh_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-23 Jesper Skov <jskov@redhat.com>
+
+
+ * Imported sources contributed by Haruki Kashiwaya
+ (kashiwaya at redhat dot com). Still need to fix this to properly
+ share the driver with the EDK (and any other platform using SCI).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl b/ecos/packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl
new file mode 100644
index 0000000..01aa6fd
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl
@@ -0,0 +1,130 @@
+# ====================================================================
+#
+# ser_sh_cq7708.cdl
+#
+# eCos serial SH/CQ7708 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors:
+# Date: 1999-07-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_SH_CQ7708 {
+ display "SH3 cq7708 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_SH_SH7708_CQ7708
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ CQ SH3 cq7708 board, based on the generic SH SCI driver."
+
+ # FIXME: This really belongs in the SH_SCI package
+ cdl_interface CYGINT_IO_SERIAL_SH_SCI_REQUIRED {
+ display "SH SCI driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_SH_SCI_INL <cyg/io/sh_sh3_cq7708_sci.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_SH_SCI_CFG <pkgconf/io_serial_sh_cq7708.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_SH_CQ7708_SERIAL1 {
+ display "SH3 CQ7708 serial 1 device driver (SCI)"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the SCI
+ port."
+
+ implements CYGINT_IO_SERIAL_SH_SCI_REQUIRED
+
+ cdl_option CYGDAT_IO_SERIAL_SH_CQ7708_SERIAL1_NAME {
+ display "Device name for SH3 CQ7708 SCI"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the SCI port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SH_CQ7708_SERIAL1_BAUD {
+ display "Baud rate for the SH SCI driver"
+ flavor data
+ legal_values { 4800 9600 14400 19200 38400 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the SCI port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SH_CQ7708_SERIAL1_BUFSIZE {
+ display "Buffer size for the SH SCI driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the SCI port."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_SH_CQ7708_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ no_define
+ active_if CYGPKG_IO_SERIAL_SH_CQ7708_SERIAL1
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"sh-cq7708\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_SER_DEV CYGDAT_IO_SERIAL_SH_CQ7708_SERIAL1_NAME"
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+# EOF ser_sh_cq7708.cdl
diff --git a/ecos/packages/devs/serial/sh/cq7708/current/include/sh_sh3_cq7708_sci.inl b/ecos/packages/devs/serial/sh/cq7708/current/include/sh_sh3_cq7708_sci.inl
new file mode 100644
index 0000000..fcf6210
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/cq7708/current/include/sh_sh3_cq7708_sci.inl
@@ -0,0 +1,104 @@
+#ifndef CYGONCE_DEVS_SH_CQ7708_SCI_H
+#define CYGONCE_DEVS_SH_CQ7708_SCI_H
+
+//==========================================================================
+//
+// io/serial/sh/sh_sh3_cq7708_sci.inl
+//
+// Serial I/O Interface Module definitions for SH3/CQ7708
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 1999-06-16
+// Purpose: Defines SCI serial resources for SH3/CQ7708.
+// Description:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+#include <pkgconf/io_serial_sh_cq7708.h>
+
+static sh_sci_info sh_serial_info =
+{
+ data : CYGARC_REG_SCI_SCSPTR,
+ er_int_num : CYGNUM_HAL_INTERRUPT_SCI_ERI,
+ rx_int_num : CYGNUM_HAL_INTERRUPT_SCI_RXI,
+ tx_int_num : CYGNUM_HAL_INTERRUPT_SCI_TXI,
+ ctrl_base : CYGARC_REG_SCI_SCSMR
+};
+
+#if CYGNUM_IO_SERIAL_SH_CQ7708_SERIAL1_BUFSIZE > 0
+static unsigned char sh_serial_out_buf[CYGNUM_IO_SERIAL_SH_CQ7708_SERIAL1_BUFSIZE];
+static unsigned char sh_serial_in_buf[CYGNUM_IO_SERIAL_SH_CQ7708_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(sh_serial_channel,
+ sh_serial_funs,
+ sh_serial_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_CQ7708_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &sh_serial_out_buf[0],
+ sizeof(sh_serial_out_buf),
+ &sh_serial_in_buf[0],
+ sizeof(sh_serial_in_buf)
+ );
+#else
+static SERIAL_CHANNEL(sh_serial_channel,
+ sh_serial_funs,
+ sh_serial_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_CQ7708_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(sh_serial_io,
+ CYGDAT_IO_SERIAL_SH_CQ7708_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ sh_serial_init,
+ sh_serial_lookup, // Serial driver may need initializing
+ &sh_serial_channel
+ );
+
+#endif // CYGONCE_DEVS_SH_CQ7708_SCI_H
diff --git a/ecos/packages/devs/serial/sh/edk7708/current/ChangeLog b/ecos/packages/devs/serial/sh/edk7708/current/ChangeLog
new file mode 100644
index 0000000..6d6ee70
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/edk7708/current/ChangeLog
@@ -0,0 +1,1204 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_sh_edk7708.cdl: Remove irrelevant doc link.
+
+2002-05-08 Jesper Skov <jskov@redhat.com>
+
+ * include/sh_sh3_edk7708_sci.inl: Serial register renaming.
+
+2002-04-23 Jesper Skov <jskov@redhat.com>
+
+ * include/sh_sh3_edk7708_sci.inl (sh_serial_info): Use variant
+ register definition for base.
+
+2000-10-03 Jesper Skov <jskov@redhat.co.uk>
+
+ * cdl/ser_sh_edk7708.cdl: Added testing parameters.
+
+ * include/sh_sh3_edk7708_sci.inl: Use named elements in structure
+ initializer.
+
+2000-09-05 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_sci_serial.c: Moved to SCI package.
+ * src/sh_sci_7708.inl: Moved ...
+ * include/sh_sh3_edk7708_sci.inl: ... to here.
+ * cdl/ser_sh_edk7708.cdl: Matching changes.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/sh_sci_serial.c (sh_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_sh_edk7708.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-11 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Move compile statement into a
+ sub-component.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/sh/edk7708/current/cdl/ser_sh_edk7708.cdl b/ecos/packages/devs/serial/sh/edk7708/current/cdl/ser_sh_edk7708.cdl
new file mode 100644
index 0000000..e71d578
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/edk7708/current/cdl/ser_sh_edk7708.cdl
@@ -0,0 +1,130 @@
+# ====================================================================
+#
+# ser_sh_edk7708.cdl
+#
+# eCos serial SH/EDK7708 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors:
+# Date: 1999-07-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_SH_EDK7708 {
+ display "SH3 EDK7708 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_SH_EDK7708
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ Hitachi SH3 EDK7708 board, based on the generic SH SCI driver."
+
+ # FIXME: This really belongs in the SH_SCI package
+ cdl_interface CYGINT_IO_SERIAL_SH_SCI_REQUIRED {
+ display "SH SCI driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_SH_SCI_INL <cyg/io/sh_sh3_edk7708_sci.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_SH_SCI_CFG <pkgconf/io_serial_sh_edk7708.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_SH_EDK7708_SERIAL1 {
+ display "SH EDK7708 serial 1 driver (SCI)"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the SCI
+ port."
+
+ implements CYGINT_IO_SERIAL_SH_SCI_REQUIRED
+
+ cdl_option CYGDAT_IO_SERIAL_SH_EDK7708_SERIAL1_NAME {
+ display "Device name for SH3 EDK7708 SCI"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the SCI port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SH_EDK7708_SERIAL1_BAUD {
+ display "Baud rate for the SH SCI driver"
+ flavor data
+ legal_values { 4800 9600 14400 19200 38400 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the SCI port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SH_EDK7708_SERIAL1_BUFSIZE {
+ display "Buffer size for the SH SCI driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the SCI port."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_SH_EDK7708_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ no_define
+ active_if CYGPKG_IO_SERIAL_SH_EDK7708_SERIAL1
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"sh-edk7708\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_SER_DEV CYGDAT_IO_SERIAL_SH_EDK7708_SERIAL1_NAME"
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+# EOF ser_sh_edk7708.cdl
diff --git a/ecos/packages/devs/serial/sh/edk7708/current/include/sh_sh3_edk7708_sci.inl b/ecos/packages/devs/serial/sh/edk7708/current/include/sh_sh3_edk7708_sci.inl
new file mode 100644
index 0000000..12a1b67
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/edk7708/current/include/sh_sh3_edk7708_sci.inl
@@ -0,0 +1,104 @@
+#ifndef CYGONCE_DEVS_SH_EDK7708_SCI_H
+#define CYGONCE_DEVS_SH_EDK7708_SCI_H
+
+//==========================================================================
+//
+// io/serial/sh/sh_sh3_edk7708_sci.inl
+//
+// Serial I/O specification for Hitachi EDK7708 platform.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 1999-06-16
+// Purpose: Defines SCI serial resources for SH3/7708.
+// Description:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+#include <pkgconf/io_serial_sh_edk7708.h>
+
+static sh_sci_info sh_serial_info =
+{
+ data : CYGARC_REG_SCI_SCSPTR,
+ er_int_num : CYGNUM_HAL_INTERRUPT_SCI_ERI,
+ rx_int_num : CYGNUM_HAL_INTERRUPT_SCI_RXI,
+ tx_int_num : CYGNUM_HAL_INTERRUPT_SCI_TXI,
+ ctrl_base : CYGARC_REG_SCI_SCSMR
+};
+
+#if CYGNUM_IO_SERIAL_SH_EDK7708_SERIAL1_BUFSIZE > 0
+static unsigned char sh_serial_out_buf[CYGNUM_IO_SERIAL_SH_EDK7708_SERIAL1_BUFSIZE];
+static unsigned char sh_serial_in_buf[CYGNUM_IO_SERIAL_SH_EDK7708_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(sh_serial_channel,
+ sh_serial_funs,
+ sh_serial_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_EDK7708_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &sh_serial_out_buf[0],
+ sizeof(sh_serial_out_buf),
+ &sh_serial_in_buf[0],
+ sizeof(sh_serial_in_buf)
+ );
+#else
+static SERIAL_CHANNEL(sh_serial_channel,
+ sh_serial_funs,
+ sh_serial_info,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_EDK7708_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(sh_serial_io,
+ CYGDAT_IO_SERIAL_SH_EDK7708_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ sh_serial_init,
+ sh_serial_lookup, // Serial driver may need initializing
+ &sh_serial_channel
+ );
+
+#endif // CYGONCE_DEVS_SH_EDK7708_SCI_H
diff --git a/ecos/packages/devs/serial/sh/sci/current/ChangeLog b/ecos/packages/devs/serial/sh/sci/current/ChangeLog
new file mode 100644
index 0000000..34de3a0
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/sci/current/ChangeLog
@@ -0,0 +1,156 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_sh_sci.cdl: Remove irrelevant doc link.
+
+2002-05-08 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_sci_serial.c: Register renaming.
+
+2002-04-23 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_sci_serial.c: Compute register offsets from register
+ definitions. Don't define SCI base.
+
+2001-02-26 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_sci_serial.c (sh_serial_er_DSR): Enable interrupts on
+ exit.
+
+2000-09-26 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_sci.cdl: Minor hack to allow both SCI and SCIF
+ packages to be used at the same time.
+ * src/sh_sci_serial.c: Same.
+
+2000-09-05 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_sci_serial.c: Moved to generic SH SCI package.
+ * ChangeLog: Removed all non-SCI related references.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/sh_sci_serial.c (sh_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_sh_edk7708.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-11 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Move compile statement into a
+ sub-component.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ serial_devio => cyg_io_serial_devio
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/sh/sci/current/cdl/ser_sh_sci.cdl b/ecos/packages/devs/serial/sh/sci/current/cdl/ser_sh_sci.cdl
new file mode 100644
index 0000000..de85cc4
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/sci/current/cdl/ser_sh_sci.cdl
@@ -0,0 +1,112 @@
+# ====================================================================
+#
+# ser_sh_sci.cdl
+#
+# eCos serial SH/SCI configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors:
+# Date: 1999-07-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_SH_SCI {
+ display "SH SCI serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_SH
+
+ active_if CYGINT_IO_SERIAL_SH_SCI_REQUIRED
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ SCI module in Hitachi SH CPUs."
+
+ compile -library=libextras.a sh_sci_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#ifndef CYGDAT_IO_SERIAL_DEVICE_HEADER"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_sh_sci.h>"
+ puts $::cdl_system_header "#endif"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_IO_SERIAL_SH_SCI_CFG";
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_SH_SCI_OPTIONS {
+ display "SCI serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_IO_SERIAL_SH_SCI_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_SH_SCI_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+}
+
+# EOF ser_sh_sci.cdl
diff --git a/ecos/packages/devs/serial/sh/sci/current/src/sh_sci_serial.c b/ecos/packages/devs/serial/sh/sci/current/src/sh_sci_serial.c
new file mode 100644
index 0000000..79d7c73
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/sci/current/src/sh_sci_serial.c
@@ -0,0 +1,545 @@
+//==========================================================================
+//
+// io/serial/sh/sh_sci_serial.c
+//
+// SH Serial SCI I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:gthomas, jskov
+// Date: 1999-05-24
+// Purpose: SH Serial I/O module (interrupt driven version)
+// Description:
+//
+// Note: Since interrupt sources from the same SCI channel share the same
+// interrupt level, there is no risk of races when altering the
+// channel's control register from ISRs and DSRs. However, when
+// altering the control register from user-level code, interrupts
+// must be disabled while the register is being accessed.
+//
+// FIXME: Receiving in polled mode prevents duplex transfers from working for
+// some reason.
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+// FIXME: This is necessary since the SCIF driver may be overriding
+// CYGDAT_IO_SERIAL_DEVICE_HEADER. Need a better way to include two
+// different drivers.
+#include <pkgconf/io_serial_sh_sci.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/serial.h>
+
+#include <cyg/hal/sh_regs.h>
+
+// Only compile driver if an inline file with driver details was selected.
+#ifdef CYGDAT_IO_SERIAL_SH_SCI_INL
+
+// Find the SCI controller register layout from the SCI0 definitions
+#if defined(CYGARC_REG_SCI_SCSMR0)
+# define SCI_SCSMR (CYGARC_REG_SCI_SCSMR0-CYGARC_REG_SCI_SCSMR0) // serial mode register
+# define SCI_SCBRR (CYGARC_REG_SCI_SCBRR0-CYGARC_REG_SCI_SCSMR0) // bit rate register
+# define SCI_SCSCR (CYGARC_REG_SCI_SCSCR0-CYGARC_REG_SCI_SCSMR0) // serial control register
+# define SCI_SCTDR (CYGARC_REG_SCI_SCTDR0-CYGARC_REG_SCI_SCSMR0) // transmit data register
+# define SCI_SCSSR (CYGARC_REG_SCI_SCSSR0-CYGARC_REG_SCI_SCSMR0) // serial status register
+# define SCI_SCRDR (CYGARC_REG_SCI_SCRDR0-CYGARC_REG_SCI_SCSMR0) // receive data register
+# define SCI_SCSPTR (CYGARC_REG_SCI_SCSPTR0-CYGARC_REG_SCI_SCSMR0)// serial port register
+#elif defined(CYGARC_REG_SCI_SCSMR)
+# define SCI_SCSMR (CYGARC_REG_SCI_SCSMR-CYGARC_REG_SCI_SCSMR) // serial mode register
+# define SCI_SCBRR (CYGARC_REG_SCI_SCBRR-CYGARC_REG_SCI_SCSMR) // bit rate register
+# define SCI_SCSCR (CYGARC_REG_SCI_SCSCR-CYGARC_REG_SCI_SCSMR) // serial control register
+# define SCI_SCTDR (CYGARC_REG_SCI_SCTDR-CYGARC_REG_SCI_SCSMR) // transmit data register
+# define SCI_SCSSR (CYGARC_REG_SCI_SCSSR-CYGARC_REG_SCI_SCSMR) // serial status register
+# define SCI_SCRDR (CYGARC_REG_SCI_SCRDR-CYGARC_REG_SCI_SCSMR) // receive data register
+# define SCI_SCSPTR (CYGARC_REG_SCI_SCSPTR-CYGARC_REG_SCI_SCSMR) // serial port register
+#else
+# error "Missing register offsets"
+#endif
+
+static short select_word_length[] = {
+ -1,
+ -1,
+ CYGARC_REG_SCI_SCSMR_CHR, // 7 bits
+ 0 // 8 bits
+};
+
+static short select_stop_bits[] = {
+ -1,
+ 0, // 1 stop bit
+ -1,
+ CYGARC_REG_SCI_SCSMR_STOP // 2 stop bits
+};
+
+static short select_parity[] = {
+ 0, // No parity
+ CYGARC_REG_SCI_SCSMR_PE, // Even parity
+ CYGARC_REG_SCI_SCSMR_PE|CYGARC_REG_SCI_SCSMR_OE, // Odd parity
+ -1,
+ -1
+};
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ CYGARC_SCBRR_CKSx(50)<<8 | CYGARC_SCBRR_N(50),
+ CYGARC_SCBRR_CKSx(75)<<8 | CYGARC_SCBRR_N(75),
+ CYGARC_SCBRR_CKSx(110)<<8 | CYGARC_SCBRR_N(110),
+ CYGARC_SCBRR_CKSx(134)<<8 | CYGARC_SCBRR_N(134),
+ CYGARC_SCBRR_CKSx(150)<<8 | CYGARC_SCBRR_N(150),
+ CYGARC_SCBRR_CKSx(200)<<8 | CYGARC_SCBRR_N(200),
+ CYGARC_SCBRR_CKSx(300)<<8 | CYGARC_SCBRR_N(300),
+ CYGARC_SCBRR_CKSx(600)<<8 | CYGARC_SCBRR_N(600),
+ CYGARC_SCBRR_CKSx(1200)<<8 | CYGARC_SCBRR_N(1200),
+ CYGARC_SCBRR_CKSx(1800)<<8 | CYGARC_SCBRR_N(1800),
+ CYGARC_SCBRR_CKSx(2400)<<8 | CYGARC_SCBRR_N(2400),
+ CYGARC_SCBRR_CKSx(3600)<<8 | CYGARC_SCBRR_N(3600),
+ CYGARC_SCBRR_CKSx(4800)<<8 | CYGARC_SCBRR_N(4800),
+ CYGARC_SCBRR_CKSx(7200)<<8 | CYGARC_SCBRR_N(7200),
+ CYGARC_SCBRR_CKSx(9600)<<8 | CYGARC_SCBRR_N(9600),
+ CYGARC_SCBRR_CKSx(14400)<<8 | CYGARC_SCBRR_N(14400),
+ CYGARC_SCBRR_CKSx(19200)<<8 | CYGARC_SCBRR_N(19200),
+ CYGARC_SCBRR_CKSx(38400)<<8 | CYGARC_SCBRR_N(38400),
+ CYGARC_SCBRR_CKSx(57600)<<8 | CYGARC_SCBRR_N(57600),
+ CYGARC_SCBRR_CKSx(115200)<<8 | CYGARC_SCBRR_N(115200),
+ CYGARC_SCBRR_CKSx(230400)<<8 | CYGARC_SCBRR_N(230400)
+};
+
+
+typedef struct sh_sci_info {
+ CYG_ADDRWORD data; // Pointer to data register
+
+ CYG_WORD er_int_num, // Error interrupt number
+ rx_int_num, // Receive interrupt number
+ tx_int_num; // Transmit interrupt number
+
+ CYG_ADDRWORD ctrl_base; // Base address of SCI controller
+
+ cyg_interrupt serial_er_interrupt,
+ serial_rx_interrupt,
+ serial_tx_interrupt;
+ cyg_handle_t serial_er_interrupt_handle,
+ serial_rx_interrupt_handle,
+ serial_tx_interrupt_handle;
+
+ bool tx_enabled;
+} sh_sci_info;
+
+static bool sh_serial_init(struct cyg_devtab_entry *tab);
+static bool sh_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo sh_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char sh_serial_getc(serial_channel *chan);
+static Cyg_ErrNo sh_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void sh_serial_start_xmit(serial_channel *chan);
+static void sh_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 sh_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void sh_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+static cyg_uint32 sh_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void sh_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+static cyg_uint32 sh_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void sh_serial_er_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+
+static SERIAL_FUNS(sh_serial_funs,
+ sh_serial_putc,
+ sh_serial_getc,
+ sh_serial_set_config,
+ sh_serial_start_xmit,
+ sh_serial_stop_xmit
+ );
+
+#include CYGDAT_IO_SERIAL_SH_SCI_INL
+
+// Internal function to actually configure the hardware to desired baud rate,
+// etc.
+static bool
+sh_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config,
+ bool init)
+{
+ cyg_uint16 baud_divisor = select_baud[new_config->baud];
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+ cyg_uint8 _scr, _smr;
+
+ // Check configuration request
+ if ((-1 == select_word_length[(new_config->word_length -
+ CYGNUM_SERIAL_WORD_LENGTH_5)])
+ || -1 == select_stop_bits[new_config->stop]
+ || -1 == select_parity[new_config->parity]
+ || baud_divisor == 0)
+ return false;
+
+ // Disable SCI interrupts while changing hardware
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, 0);
+
+ // Set databits, stopbits and parity.
+ _smr = select_word_length[(new_config->word_length -
+ CYGNUM_SERIAL_WORD_LENGTH_5)] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSMR, _smr);
+
+ // Set baud rate.
+ _smr &= ~CYGARC_REG_SCI_SCSMR_CKSx_MASK;
+ _smr |= baud_divisor >> 8;
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSMR, _smr);
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCBRR, baud_divisor & 0xff);
+
+ // Clear the status register.
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, 0);
+
+ if (init) {
+ // Always enable transmitter and receiver.
+ _scr = CYGARC_REG_SCI_SCSCR_TE | CYGARC_REG_SCI_SCSCR_RE;
+
+ if (chan->out_cbuf.len != 0)
+ _scr |= CYGARC_REG_SCI_SCSCR_TIE; // enable tx interrupts
+
+ if (chan->in_cbuf.len != 0)
+ _scr |= CYGARC_REG_SCI_SCSCR_RIE; // enable rx interrupts
+ }
+
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+sh_serial_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("SH SERIAL init - dev: %x.%d\n",
+ sh_chan->data, sh_chan->rx_int_num);
+#endif
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(sh_chan->tx_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sh_serial_tx_ISR,
+ sh_serial_tx_DSR,
+ &sh_chan->serial_tx_interrupt_handle,
+ &sh_chan->serial_tx_interrupt);
+ cyg_drv_interrupt_attach(sh_chan->serial_tx_interrupt_handle);
+ cyg_drv_interrupt_unmask(sh_chan->tx_int_num);
+ sh_chan->tx_enabled = false;
+ }
+ if (chan->in_cbuf.len != 0) {
+ // Receive interrupt
+ cyg_drv_interrupt_create(sh_chan->rx_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sh_serial_rx_ISR,
+ sh_serial_rx_DSR,
+ &sh_chan->serial_rx_interrupt_handle,
+ &sh_chan->serial_rx_interrupt);
+ cyg_drv_interrupt_attach(sh_chan->serial_rx_interrupt_handle);
+ // Receive error interrupt
+ cyg_drv_interrupt_create(sh_chan->er_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sh_serial_er_ISR,
+ sh_serial_er_DSR,
+ &sh_chan->serial_er_interrupt_handle,
+ &sh_chan->serial_er_interrupt);
+ cyg_drv_interrupt_attach(sh_chan->serial_er_interrupt_handle);
+ // This unmasks both interrupt sources.
+ cyg_drv_interrupt_unmask(sh_chan->rx_int_num);
+ }
+ sh_serial_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+sh_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+sh_serial_putc(serial_channel *chan, unsigned char c)
+{
+ cyg_uint8 _ssr;
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr);
+ if (_ssr & CYGARC_REG_SCI_SCSSR_TDRE) {
+// Transmit buffer is empty
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCTDR, c);
+ // Clear empty flag.
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR,
+ CYGARC_REG_SCI_SCSSR_CLEARMASK & ~CYGARC_REG_SCI_SCSSR_TDRE);
+ return true;
+ } else {
+// No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+sh_serial_getc(serial_channel *chan)
+{
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+ unsigned char c;
+ cyg_uint8 _ssr;
+
+ do {
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr);
+ } while ((_ssr & CYGARC_REG_SCI_SCSSR_RDRF) == 0);
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCRDR, c);
+
+ // Clear buffer full flag.
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR,
+ CYGARC_REG_SCI_SCSSR_CLEARMASK & ~CYGARC_REG_SCI_SCSSR_RDRF);
+
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+sh_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != sh_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+sh_serial_start_xmit(serial_channel *chan)
+{
+ cyg_uint8 _scr;
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+
+ sh_chan->tx_enabled = true;
+
+ // Mask the interrupts (all sources of the unit) while changing
+ // the CR since a rx interrupt in the middle of this would result
+ // in a bad CR state.
+ cyg_drv_interrupt_mask(sh_chan->rx_int_num);
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCI_SCSCR_TIE; // Enable xmit interrupt
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+
+ cyg_drv_interrupt_unmask(sh_chan->rx_int_num);
+}
+
+// Disable the transmitter on the device
+static void
+sh_serial_stop_xmit(serial_channel *chan)
+{
+ cyg_uint8 _scr;
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+
+ sh_chan->tx_enabled = false;
+
+ // Mask the interrupts (all sources of the unit) while changing
+ // the CR since a rx interrupt in the middle of this would result
+ // in a bad CR state.
+ cyg_drv_interrupt_mask(sh_chan->rx_int_num);
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCI_SCSCR_TIE; // Disable xmit interrupt
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+
+ cyg_drv_interrupt_unmask(sh_chan->rx_int_num);
+}
+
+// Serial I/O - low level tx interrupt handler (ISR)
+static cyg_uint32
+sh_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+ cyg_uint8 _scr;
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCI_SCSCR_TIE; // mask out tx interrupts
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level tx interrupt handler (DSR)
+static void
+sh_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+
+ (chan->callbacks->xmt_char)(chan);
+
+ if (sh_chan->tx_enabled) {
+ cyg_uint8 _scr;
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCI_SCSCR_TIE; // unmask tx interrupts
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ }
+}
+
+// Serial I/O - low level RX interrupt handler (ISR)
+static cyg_uint32
+sh_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+ cyg_uint8 _scr;
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCI_SCSCR_RIE; // mask rx interrupts
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level rx interrupt handler (DSR)
+static void
+sh_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+ cyg_uint8 _ssr, _scr;
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr);
+ if (_ssr & CYGARC_REG_SCI_SCSSR_RDRF) {
+ cyg_uint8 _c;
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCRDR, _c);
+ // Clear buffer full flag.
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR,
+ CYGARC_REG_SCI_SCSSR_CLEARMASK & ~CYGARC_REG_SCI_SCSSR_RDRF);
+
+ (chan->callbacks->rcv_char)(chan, _c);
+ }
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCI_SCSCR_RIE; // unmask rx interrupts
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+}
+
+static volatile int sh_serial_error_orer = 0;
+static volatile int sh_serial_error_fer = 0;
+static volatile int sh_serial_error_per = 0;
+
+// Serial I/O - low level error interrupt handler (ISR)
+static cyg_uint32
+sh_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+ cyg_uint8 _scr;
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCI_SCSCR_RIE; // mask rx interrupts
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level error interrupt handler (DSR)
+static void
+sh_serial_er_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv;
+ cyg_uint8 _ssr, _ssr2, _scr;
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr);
+ _ssr2 = CYGARC_REG_SCI_SCSSR_CLEARMASK;
+
+ if (_ssr & CYGARC_REG_SCI_SCSSR_ORER) {
+ _ssr2 &= ~CYGARC_REG_SCI_SCSSR_ORER;
+ sh_serial_error_orer++;
+ }
+ if (_ssr & CYGARC_REG_SCI_SCSSR_FER) {
+ _ssr2 &= ~CYGARC_REG_SCI_SCSSR_FER;
+ sh_serial_error_fer++;
+ }
+ if (_ssr & CYGARC_REG_SCI_SCSSR_PER) {
+ _ssr2 &= ~CYGARC_REG_SCI_SCSSR_PER;
+ sh_serial_error_per++;
+ }
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr2);
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCI_SCSCR_RIE; // unmask rx interrupts
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr);
+}
+
+#endif // ifdef CYGDAT_IO_SERIAL_SH_SCI_INL
diff --git a/ecos/packages/devs/serial/sh/scif/current/ChangeLog b/ecos/packages/devs/serial/sh/scif/current/ChangeLog
new file mode 100644
index 0000000..1184485
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/scif/current/ChangeLog
@@ -0,0 +1,188 @@
+2005-08-04 Andrew Lunn <andrew.lunn@ascom.ch>
+2005-05-02 Hajime Ishitani <pigmon@mail.snd.co.jp>
+
+ * src/sh_scif_serial.c: support SH4 register access
+
+2003-03-18 Gary Thomas <gary@mlbassoc.com>
+
+ * src/sh_scif_serial.c (sh_scif_set_config):
+ Flag for CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE is 32 bits.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_sh_scif.cdl: Remove irrelevant doc link.
+
+2002-05-08 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_scif_serial.c: Added SH2 support. Added break interrupt
+ support. Added IrDA support. Added async RX/TX support. Added
+ support for platforms to add config keys and handle flow
+ control. Register renaming.
+
+ * cdl/ser_sh_scif.cdl: Added async RX/TX and IRDA support. Also
+ added interface for support of break interrupts.
+
+2002-01-30 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_scif_serial.c (sh3_scif_tx_DSR): Stop single-character
+ transmit if transmitter gets disabled. This does not change the
+ (output) semantics of the code, but does prevent it from looping
+ over the full size of the FIFO calling the (inactive) xmt_char
+ callback.
+
+2001-02-27 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_scif_serial.c (sh3_scif_er_DSR): Clear break flag.
+
+2001-02-26 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_scif_serial.c (sh3_scif_er_DSR): Enable interrupts on
+ exit. Clear ER flag.
+
+2000-10-23 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_scif_serial.c: Include cyg_ass.h
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_scif_serial.c (sh3_scif_set_config): Changes to the flow
+ control handling. Renamed DMA variables.
+
+2000-10-12 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/sh_scif_serial.c: return -EINVAL when unsupported flow control
+ mode requested.
+
+2000-10-06 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_scif_serial.c: Change to new block call syntax.
+ Clean up start_xmit code. Do block transfers in serial DSRs.
+
+2000-10-03 Jesper Skov <jskov@redhat.co.uk>
+
+ * src/sh_scif_serial.c: Fixed receive FIFO problem. Added Line
+ Status handling. Don't enable TX interrupts in initialization.
+ * src/sh_scif_serial.c: Added DMA support. Added RTS/CTS control.
+ * cdl/ser_sh_scif.cdl: Added DMA interface.
+
+2000-09-26 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_scif.cdl: Minor hack to allow both SCI and SCIF
+ packages to be used at the same time.
+ * src/sh_scif_serial.c: Same.
+
+2000-09-25 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_scif_serial.c: Use the SCI macros for baud rate
+ calculation.
+
+2000-09-05 Jesper Skov <jskov@redhat.com>
+
+ * src/sh_scif_serial.c: Moved to separate SCIF package.
+ * ChangeLog: Cleaned out all non-SCIF related entries.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/sh3_scif_serial.c (sh3_scif_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_sh_scif.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh3_scif_serial.c: Can't get input FIFO to work properly.
+ Disabled for now.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-10 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh3_scif_serial.c:
+ Working, but FIFO isn't enabled due to an interrupt problem.
+
+2000-04-04 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh3_scif_serial.c: FIFO related changes.
+
+2000-04-03 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_scif.cdl:
+ * src/sh/sh_scif_serial.c:
+ Added SCIF driver, based on SCI driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/sh/scif/current/cdl/ser_sh_scif.cdl b/ecos/packages/devs/serial/sh/scif/current/cdl/ser_sh_scif.cdl
new file mode 100644
index 0000000..49793f2
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/scif/current/cdl/ser_sh_scif.cdl
@@ -0,0 +1,176 @@
+# ====================================================================
+#
+# ser_sh_scif.cdl
+#
+# eCos serial SH/SCIF configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors:
+# Date: 2000-04-04
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_SH_SCIF {
+ display "SH SCIF serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_SH
+
+ active_if CYGINT_IO_SERIAL_SH_SCIF_REQUIRED
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ SCIF module in Hitachi SH CPUs."
+
+ compile -library=libextras.a sh_scif_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#ifndef CYGDAT_IO_SERIAL_DEVICE_HEADER"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_sh_scif.h>"
+ puts $::cdl_system_header "#endif"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+
+ puts $::cdl_header "#include <pkgconf/system.h>";
+ puts $::cdl_header "#include CYGDAT_IO_SERIAL_SH_SCIF_CFG";
+ }
+
+ # The driver tries to be effective with FIFO transfers
+ implements CYGINT_IO_SERIAL_BLOCK_TRANSFER
+
+ cdl_interface CYGINT_IO_SERIAL_SH_SCIF_DMA {
+ display "SCIF serial driver DMA support"
+ flavor booldata
+ description "
+ The serial driver can use DMA to move data from the
+ transmit buffer to the serial controller if the CPU
+ supports it."
+ }
+
+ cdl_interface CYGINT_IO_SERIAL_SH_SCIF_ASYNC_RXTX {
+ display "SCIF async RX/TX support"
+ flavor booldata
+ description "
+ By enabling this option, the SCIF driver will
+ be able to support controllers with transceivers
+ that are asynchronous (RS4xx). This will cause
+ RX to be disabled before TX is enabled, and vice
+ versa."
+ }
+
+ cdl_interface CYGINT_IO_SERIAL_SH_SCIF_IRDA {
+ display "SCIF IrDA support"
+ flavor booldata
+ description "
+ By enabling this option, the SCIF driver will
+ be able to support controllers in IrDA mode."
+ }
+
+ cdl_option CYGHWR_IO_SERIAL_SH_SH2_SCIF_IRDA_TXRX_COMPENSATION {
+ display "SCIF IrDA TX/RX switch compensation"
+ default_value 1
+ active_if CYGINT_IO_SERIAL_SH_SCIF_IRDA
+ description "
+ When switching from TX mode to RX mode, the controller causes
+ a spurious 0xff character to be received at speeds up to
+ 57600 baud. At higher baud rates, more spurious characters
+ may be received. Enabling this option tries to remove the
+ spurious characters, but since there are no errors reported
+ from the controller, it is impossible to do so with any kind
+ of precision.
+ Having this option enabled allows some eCos serial tests to
+ run. There is a matching option in the SH2 HAL controlling a
+ similar kludge for the polled driver, making RedBoot usable.
+ It is an incomplete kludge however, and for any real use of
+ the IrDA mode for data transmission, the option should be
+ disabled, and a protocol capable of handling the spurious
+ receive characters must be used on top of the driver.
+ Note that the problem is exaggerated when the baud rate is
+ changed."
+ }
+
+ cdl_interface CYGINT_IO_SERIAL_SH_SCIF_BR_INTERRUPT {
+ display "Controller uses BR interrupts"
+ flavor booldata
+ description "
+ Some controllers route BREAK interrupts to the
+ error interrupt vector. Others have a separate
+ vector. When this interface is implemented, the
+ driver will handle the separate BR vector."
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_SH_SCIF_OPTIONS {
+ display "SCIF serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_SH_SCIF_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ used in addition to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_SH_SCIF_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are
+ removed from the set of global flags if present."
+ }
+ }
+}
+# EOF ser_sh_scif.cdl
diff --git a/ecos/packages/devs/serial/sh/scif/current/src/sh_scif_serial.c b/ecos/packages/devs/serial/sh/scif/current/src/sh_scif_serial.c
new file mode 100644
index 0000000..1eb28a4
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/scif/current/src/sh_scif_serial.c
@@ -0,0 +1,1095 @@
+//==========================================================================
+//
+// io/serial/sh/scif/sh_scif_serial.c
+//
+// SH Serial IRDA/SCIF I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:gthomas, jskov
+// Date: 2000-04-04
+// Purpose: SH Serial IRDA/SCIF I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+
+// FIXME: This is necessary since the SCI driver may be overriding
+// CYGDAT_IO_SERIAL_DEVICE_HEADER. Need a better way to include two
+// different drivers.
+#include <pkgconf/io_serial_sh_scif.h>
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/io/serial.h>
+
+#include <cyg/hal/sh_regs.h>
+#include <cyg/hal/hal_cache.h>
+
+// Only compile driver if an inline file with driver details was selected.
+#ifdef CYGDAT_IO_SERIAL_SH_SCIF_INL
+
+#if defined(CYGPKG_HAL_SH_SH2)
+// The SCIF controller register layout on the SH2
+// The controller base is defined in the board specification file.
+# define SCIF_SCSMR 0x00 // serial mode register
+# define SCIF_SCBRR 0x02 // bit rate register
+# define SCIF_SCSCR 0x04 // serial control register
+# define SCIF_SCFTDR 0x06 // transmit data register
+# define SCIF_SC1SSR 0x08 // serial status register 1
+# define SCIF_SCSSR SCIF_SC1SSR
+# define SCIF_SC2SSR 0x0a // serial status register 2
+# define SCIF_SCFRDR 0x0c // receive data register
+# define SCIF_SCFCR 0x0e // FIFO control
+# define SCIF_SCFDR 0x10 // FIFO data count register
+# define SCIF_SCFER 0x12 // FIFO error register
+# define SCIF_SCIMR 0x14 // IrDA mode register
+# define HAL_READ(x,y) HAL_READ_UINT8(x,y)
+# define HAL_WRITE(x,y) HAL_WRITE_UINT8(x,y)
+
+#elif defined(CYGPKG_HAL_SH_SH3)
+// The SCIF controller register layout on the SH3
+// The controller base is defined in the board specification file.
+# define SCIF_SCSMR 0x00 // serial mode register
+# define SCIF_SCBRR 0x02 // bit rate register
+# define SCIF_SCSCR 0x04 // serial control register
+# define SCIF_SCFTDR 0x06 // transmit data register
+# define SCIF_SCSSR 0x08 // serial status register
+# define SCIF_SCFRDR 0x0a // receive data register
+# define SCIF_SCFCR 0x0c // FIFO control
+# define SCIF_SCFDR 0x0e // FIFO data count register
+# define HAL_READ(x,y) HAL_READ_UINT8(x,y)
+# define HAL_WRITE(x,y) HAL_WRITE_UINT8(x,y)
+#elif defined(CYGPKG_HAL_SH_SH4)
+// The SCIF controller register layout on the SH4
+// The controller base is defined in the board specification file.
+# define SCIF_SCSMR 0x00 // serial mode register
+# define SCIF_SCBRR 0x04 // bit rate register
+# define SCIF_SCSCR 0x08 // serial control register
+# define SCIF_SCFTDR 0x0C // transmit data register
+# define SCIF_SCSSR 0x10 // serial status register
+# define SCIF_SCFRDR 0x14 // receive data register
+# define SCIF_SCFCR 0x18 // FIFO control
+# define SCIF_SCFDR 0x1C // FIFO data count register
+# define HAL_READ(x,y) HAL_READ_UINT16(x,y)
+# define HAL_WRITE(x,y) HAL_WRITE_UINT16(x,y)
+#else
+# error "Unsupported variant"
+#endif
+
+static short select_word_length[] = {
+ -1,
+ -1,
+ CYGARC_REG_SCIF_SCSMR_CHR, // 7 bits
+ 0 // 8 bits
+};
+
+static short select_stop_bits[] = {
+ -1,
+ 0, // 1 stop bit
+ -1,
+ CYGARC_REG_SCIF_SCSMR_STOP // 2 stop bits
+};
+
+static short select_parity[] = {
+ 0, // No parity
+ CYGARC_REG_SCIF_SCSMR_PE, // Even parity
+ CYGARC_REG_SCIF_SCSMR_PE|CYGARC_REG_SCIF_SCSMR_OE, // Odd parity
+ -1,
+ -1
+};
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ CYGARC_SCBRR_CKSx(50)<<8 | CYGARC_SCBRR_N(50),
+ CYGARC_SCBRR_CKSx(75)<<8 | CYGARC_SCBRR_N(75),
+ CYGARC_SCBRR_CKSx(110)<<8 | CYGARC_SCBRR_N(110),
+ CYGARC_SCBRR_CKSx(134)<<8 | CYGARC_SCBRR_N(134),
+ CYGARC_SCBRR_CKSx(150)<<8 | CYGARC_SCBRR_N(150),
+ CYGARC_SCBRR_CKSx(200)<<8 | CYGARC_SCBRR_N(200),
+ CYGARC_SCBRR_CKSx(300)<<8 | CYGARC_SCBRR_N(300),
+ CYGARC_SCBRR_CKSx(600)<<8 | CYGARC_SCBRR_N(600),
+ CYGARC_SCBRR_CKSx(1200)<<8 | CYGARC_SCBRR_N(1200),
+ CYGARC_SCBRR_CKSx(1800)<<8 | CYGARC_SCBRR_N(1800),
+ CYGARC_SCBRR_CKSx(2400)<<8 | CYGARC_SCBRR_N(2400),
+ CYGARC_SCBRR_CKSx(3600)<<8 | CYGARC_SCBRR_N(3600),
+ CYGARC_SCBRR_CKSx(4800)<<8 | CYGARC_SCBRR_N(4800),
+ CYGARC_SCBRR_CKSx(7200)<<8 | CYGARC_SCBRR_N(7200),
+ CYGARC_SCBRR_CKSx(9600)<<8 | CYGARC_SCBRR_N(9600),
+ CYGARC_SCBRR_CKSx(14400)<<8 | CYGARC_SCBRR_N(14400),
+ CYGARC_SCBRR_CKSx(19200)<<8 | CYGARC_SCBRR_N(19200),
+ CYGARC_SCBRR_CKSx(38400)<<8 | CYGARC_SCBRR_N(38400),
+ CYGARC_SCBRR_CKSx(57600)<<8 | CYGARC_SCBRR_N(57600),
+ CYGARC_SCBRR_CKSx(115200)<<8 | CYGARC_SCBRR_N(115200),
+ CYGARC_SCBRR_CKSx(230400)<<8 | CYGARC_SCBRR_N(230400)
+};
+
+typedef struct sh_scif_info {
+ CYG_WORD er_int_num, // Error interrupt number
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_BR_INTERRUPT
+ br_int_num, // Break interrupt number
+#endif
+ rx_int_num, // Receive interrupt number
+ tx_int_num; // Transmit interrupt number
+
+ CYG_ADDRWORD ctrl_base; // Base address of SCI controller
+
+ cyg_interrupt serial_er_interrupt,
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_BR_INTERRUPT
+ serial_br_interrupt,
+#endif
+ serial_rx_interrupt,
+ serial_tx_interrupt;
+ cyg_handle_t serial_er_interrupt_handle,
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_BR_INTERRUPT
+ serial_br_interrupt_handle,
+#endif
+ serial_rx_interrupt_handle,
+ serial_tx_interrupt_handle;
+
+ volatile bool tx_enabled; // expect tx _serial_ interrupts
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_IRDA
+ bool irda_mode;
+#endif
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_ASYNC_RXTX
+ bool async_rxtx_mode;
+#endif
+
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_DMA
+ cyg_bool dma_enable; // Set if DMA mode
+ cyg_uint32 dma_xmt_cr_flags; // CR flags for DMA mode
+ CYG_WORD dma_xmt_int_num; // DMA xmt completion interrupt
+ CYG_ADDRWORD dma_xmt_base; // Base address of DMA channel
+ int dma_xmt_len; // length transferred by DMA
+ cyg_interrupt dma_xmt_interrupt;
+ cyg_handle_t dma_xmt_interrupt_handle;
+ volatile cyg_bool dma_xmt_running; // expect tx _dma_ interrupts
+#endif
+} sh_scif_info;
+
+static bool sh_scif_init(struct cyg_devtab_entry *tab);
+static bool sh_scif_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo sh_scif_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char sh_scif_getc(serial_channel *chan);
+static Cyg_ErrNo sh_scif_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void sh_scif_start_xmit(serial_channel *chan);
+static void sh_scif_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 sh_scif_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void sh_scif_tx_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+static cyg_uint32 sh_scif_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void sh_scif_rx_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+static cyg_uint32 sh_scif_er_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void sh_scif_er_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_DMA
+static cyg_uint32 sh_dma_xmt_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void sh_dma_xmt_DSR(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data);
+#endif
+
+static SERIAL_FUNS(sh_scif_funs,
+ sh_scif_putc,
+ sh_scif_getc,
+ sh_scif_set_config,
+ sh_scif_start_xmit,
+ sh_scif_stop_xmit
+ );
+
+// Get the board specification
+#include CYGDAT_IO_SERIAL_SH_SCIF_INL
+
+// Allow platform to define handling of additional config keys
+#ifndef CYGPRI_DEVS_SH_SCIF_SET_CONFIG_PLF
+# define CYGPRI_DEVS_SH_SCIF_SET_CONFIG_PLF
+#endif
+
+// Internal function to actually configure the hardware to desired baud rate,
+// etc.
+static bool
+sh_scif_config_port(serial_channel *chan, cyg_serial_info_t *new_config,
+ bool init)
+{
+ cyg_uint16 baud_divisor = select_baud[new_config->baud];
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_uint8 _scr, _smr;
+ cyg_uint16 _sr;
+ CYG_ADDRWORD base = sh_chan->ctrl_base;
+
+ // Check configuration request
+ if ((-1 == select_word_length[(new_config->word_length -
+ CYGNUM_SERIAL_WORD_LENGTH_5)])
+ || -1 == select_stop_bits[new_config->stop]
+ || -1 == select_parity[new_config->parity]
+ || baud_divisor == 0)
+ return false;
+
+ // Disable SCI interrupts while changing hardware
+ HAL_READ(base+SCIF_SCSCR, _scr);
+ HAL_WRITE(base+SCIF_SCSCR, 0);
+
+ // Reset FIFO.
+ HAL_WRITE(base+SCIF_SCFCR,
+ CYGARC_REG_SCIF_SCFCR_TFRST|CYGARC_REG_SCIF_SCFCR_RFRST);
+
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_ASYNC_RXTX
+ sh_chan->async_rxtx_mode = false;
+#endif
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_IRDA
+ if (sh_chan->irda_mode) {
+ // In IrDA mode, the configuration is hardwired and the mode
+ // bits should not be set
+#ifdef CYGARC_REG_SCIF_SCSMR_IRMOD
+ _smr = CYGARC_REG_SCIF_SCSMR_IRMOD;
+#elif defined(SCIF_SCIMR)
+ _smr = 0;
+ HAL_WRITE_UINT8(base+SCIF_SCIMR, CYGARC_REG_SCIF_SCIMR_IRMOD);
+#endif
+ } else
+#endif
+ {
+ // Set databits, stopbits and parity.
+ _smr = select_word_length[(new_config->word_length -
+ CYGNUM_SERIAL_WORD_LENGTH_5)] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_IRDA
+#ifdef SCIF_SCIMR
+ // Disable IrDA mode
+ HAL_WRITE(base+SCIF_SCIMR, 0);
+#endif
+#endif
+ }
+ HAL_WRITE(base+SCIF_SCSMR, _smr);
+
+ // Set baud rate.
+ _smr &= ~CYGARC_REG_SCIF_SCSMR_CKSx_MASK;
+ _smr |= baud_divisor >> 8;
+ HAL_WRITE(base+SCIF_SCSMR, _smr);
+ HAL_WRITE_UINT8(base+SCIF_SCBRR, baud_divisor & 0xff);
+
+ // FIXME: Should delay 1/<baud> second here.
+
+ // Clear the status register (read first).
+ HAL_READ_UINT16(base+SCIF_SCSSR, _sr);
+ HAL_WRITE_UINT16(base+SCIF_SCSSR, 0);
+
+ // Bring FIFO out of reset and set FIFO trigger marks
+ //
+ // Note that the RX FIFO size must be smaller when flow control is
+ // enabled. This due to observations made by running the flow2
+ // serial test. The automatic RTS de-assertion happens
+ // (apparently) when the FIFO fills past the trigger count -
+ // causing the sender to stop transmission. But there's a lag
+ // before transmission is stopped, and if the FIFO fills in that
+ // time, data will be lost. Thus, seeing as HW flow control is
+ // presumed used for prevention of data loss, set the trigger
+ // level so the sender has time to stop transmission before the
+ // FIFO fills up.
+ //
+ // The trigger setting of 8 allows test flow2 to complete without
+ // problems. It tests duplex data transmission at 115200
+ // baud. Depending on the lag time between the de-assertion of RTS
+ // and actual transmission stop, it may be necessary to reduce the
+ // trigger level further.
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+ HAL_WRITE(base+SCIF_SCFCR,
+ CYGARC_REG_SCIF_SCFCR_RTRG_8|CYGARC_REG_SCIF_SCFCR_TTRG_8);
+#else
+ HAL_WRITE(base+SCIF_SCFCR,
+ CYGARC_REG_SCIF_SCFCR_RTRG_14|CYGARC_REG_SCIF_SCFCR_TTRG_8);
+#endif
+
+ if (init) {
+ // Always enable received and (for normal mode) transmitter
+ _scr = CYGARC_REG_SCIF_SCSCR_TE | CYGARC_REG_SCIF_SCSCR_RE;
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_ASYNC_RXTX
+ if (sh_chan->async_rxtx_mode)
+ _scr = CYGARC_REG_SCIF_SCSCR_RE;
+#endif
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_IRDA
+ if (sh_chan->irda_mode)
+ _scr = CYGARC_REG_SCIF_SCSCR_RE;
+#endif
+
+ if (chan->in_cbuf.len != 0)
+ _scr |= CYGARC_REG_SCIF_SCSCR_RIE; // enable rx interrupts
+ }
+
+ HAL_WRITE(base+SCIF_SCSCR, _scr);
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+sh_scif_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("SH SERIAL init - dev: %x.%d\n",
+ sh_chan->ctrl_base, sh_chan->rx_int_num);
+#endif
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(sh_chan->tx_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sh_scif_tx_ISR,
+ sh_scif_tx_DSR,
+ &sh_chan->serial_tx_interrupt_handle,
+ &sh_chan->serial_tx_interrupt);
+ cyg_drv_interrupt_attach(sh_chan->serial_tx_interrupt_handle);
+ cyg_drv_interrupt_unmask(sh_chan->tx_int_num);
+ sh_chan->tx_enabled = false;
+ }
+ if (chan->in_cbuf.len != 0) {
+ // Receive interrupt
+ cyg_drv_interrupt_create(sh_chan->rx_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sh_scif_rx_ISR,
+ sh_scif_rx_DSR,
+ &sh_chan->serial_rx_interrupt_handle,
+ &sh_chan->serial_rx_interrupt);
+ cyg_drv_interrupt_attach(sh_chan->serial_rx_interrupt_handle);
+ // Receive error interrupt
+ cyg_drv_interrupt_create(sh_chan->er_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sh_scif_er_ISR,
+ sh_scif_er_DSR,
+ &sh_chan->serial_er_interrupt_handle,
+ &sh_chan->serial_er_interrupt);
+ cyg_drv_interrupt_attach(sh_chan->serial_er_interrupt_handle);
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_BR_INTERRUPT
+ // Break error interrupt
+ cyg_drv_interrupt_create(sh_chan->br_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sh_scif_er_ISR,
+ sh_scif_er_DSR,
+ &sh_chan->serial_br_interrupt_handle,
+ &sh_chan->serial_br_interrupt);
+ cyg_drv_interrupt_attach(sh_chan->serial_br_interrupt_handle);
+#endif
+ // This unmasks all interrupt sources.
+ cyg_drv_interrupt_unmask(sh_chan->rx_int_num);
+ }
+
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_DMA
+ // Assign DMA channel and interrupt if requested
+ if (sh_chan->dma_enable) {
+ // FIXME: Need a cleaner way to assign DMA channels
+ static int dma_channel = 0;
+#if defined(CYGPKG_HAL_SH_SH2)
+ sh_chan->dma_xmt_int_num = dma_channel+CYGNUM_HAL_INTERRUPT_DMAC0_TE;
+#elif defined(CYGPKG_HAL_SH_SH3)
+ sh_chan->dma_xmt_int_num = dma_channel+CYGNUM_HAL_INTERRUPT_DMAC_DEI0;
+#else
+# error "No interrupt defined for variant"
+#endif
+ sh_chan->dma_xmt_base = (dma_channel*0x10)+CYGARC_REG_SAR0;
+ dma_channel++;
+
+ // Enable the DMA engines.
+ HAL_WRITE_UINT16(CYGARC_REG_DMAOR, CYGARC_REG_DMAOR_DME);
+
+ cyg_drv_interrupt_create(sh_chan->dma_xmt_int_num,
+ 3,
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sh_dma_xmt_ISR,
+ sh_dma_xmt_DSR,
+ &sh_chan->dma_xmt_interrupt_handle,
+ &sh_chan->dma_xmt_interrupt);
+ cyg_drv_interrupt_attach(sh_chan->dma_xmt_interrupt_handle);
+ cyg_drv_interrupt_unmask(sh_chan->dma_xmt_int_num);
+ }
+ sh_chan->dma_xmt_running = false;
+#endif // CYGINT_IO_SERIAL_SH_SCIF_DMA
+
+ sh_scif_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+sh_scif_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+
+ // Really only required for interrupt driven devices
+ (chan->callbacks->serial_init)(chan);
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+sh_scif_putc(serial_channel *chan, unsigned char c)
+{
+ cyg_uint16 _fdr, _sr;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCFDR, _fdr);
+ if (((_fdr & CYGARC_REG_SCIF_SCFDR_TCOUNT_MASK) >> CYGARC_REG_SCIF_SCFDR_TCOUNT_shift) < 15) {
+// Transmit FIFO has room for another char
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCIF_SCFTDR, c);
+ // Clear FIFO-empty/transmit end flags (read back sr first)
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCSSR, _sr);
+ HAL_WRITE_UINT16(sh_chan->ctrl_base+SCIF_SCSSR,
+ CYGARC_REG_SCIF_SCSSR_CLEARMASK & ~CYGARC_REG_SCIF_SCSSR_TDFE);
+ return true;
+ } else {
+// No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+// Note: Input is running wo FIFO enabled, so the counter is not checked here.
+static unsigned char
+sh_scif_getc(serial_channel *chan)
+{
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ unsigned char c;
+ cyg_uint16 _sr;
+
+ do {
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCSSR, _sr);
+ } while ((_sr & CYGARC_REG_SCIF_SCSSR_RDF) == 0);
+
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCIF_SCFRDR, c);
+
+ // Clear buffer full flag (read back first)
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCSSR, _sr);
+ HAL_WRITE_UINT16(sh_chan->ctrl_base+SCIF_SCSSR,
+ CYGARC_REG_SCIF_SCSSR_CLEARMASK & ~CYGARC_REG_SCIF_SCSSR_RDF);
+
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+sh_scif_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != sh_scif_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW
+ case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE:
+ {
+ sh_scif_info *ser_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_addrword_t base = ser_chan->ctrl_base;
+ cyg_uint32 *f = (cyg_uint32 *)xbuf;
+ if ( *len < *f )
+ return -EINVAL;
+
+ if ( chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX ) {
+ // Control RX RTC/CTS flow control by disabling/enabling
+ // RX interrupt. When disabled, FIFO will fill up and
+ // clear RTS.
+ cyg_uint8 _scscr;
+ HAL_READ(base+SCIF_SCSCR, _scscr);
+ if (*f) // we should throttle
+ _scscr &= ~CYGARC_REG_SCIF_SCSCR_RIE;
+ else // we should no longer throttle
+ _scscr |= CYGARC_REG_SCIF_SCSCR_RIE;
+ HAL_WRITE(base+SCIF_SCSCR, _scscr);
+ }
+#ifdef CYGHWR_SH_SCIF_FLOW_DSRDTR
+ if ( chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_RX ) {
+ // Control RX DSR/DTR flow control via platform specific macro
+ CYGHWR_SH_SCIF_FLOW_DSRDTR_RX(chan, *f);
+ }
+#endif
+ }
+ break;
+ case CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG:
+ {
+ // Handle CTS/RTS flag
+ if ( chan->config.flags &
+ (CYGNUM_SERIAL_FLOW_RTSCTS_RX | CYGNUM_SERIAL_FLOW_RTSCTS_TX )){
+ cyg_uint8 _scfcr;
+ sh_scif_info *ser_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_addrword_t base = ser_chan->ctrl_base;
+ cyg_uint8 *f = (cyg_uint8 *)xbuf;
+
+ HAL_READ(base+SCIF_SCFCR, _scfcr);
+ if (*f) // enable RTS/CTS flow control
+ _scfcr |= CYGARC_REG_SCIF_SCFCR_MCE;
+ else // disable RTS/CTS flow control
+ _scfcr &= ~CYGARC_REG_SCIF_SCFCR_MCE;
+ HAL_WRITE(base+SCIF_SCFCR, _scfcr);
+ }
+#ifndef CYGHWR_SH_SCIF_FLOW_DSRDTR
+ // Clear DSR/DTR flag as it's not supported.
+ if (chan->config.flags &
+ (CYGNUM_SERIAL_FLOW_DSRDTR_RX|CYGNUM_SERIAL_FLOW_DSRDTR_TX)) {
+ chan->config.flags &= ~(CYGNUM_SERIAL_FLOW_DSRDTR_RX|
+ CYGNUM_SERIAL_FLOW_DSRDTR_TX);
+ return -EINVAL;
+ }
+#else
+ return CYGHWR_SH_SCIF_FLOW_DSRDTR_CONFIG(chan);
+#endif
+ }
+ break;
+#endif
+
+ CYGPRI_DEVS_SH_SCIF_SET_CONFIG_PLF
+
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_DMA
+
+// Must be called with serial interrupts disabled
+static xmt_req_reply_t
+sh_scif_start_dma_xmt(serial_channel *chan)
+{
+ int chars_avail;
+ unsigned char* chars;
+ xmt_req_reply_t res;
+
+ // We can transfer the full buffer - ask how much to transfer
+ res = (chan->callbacks->data_xmt_req)(chan, chan->out_cbuf.len,
+ &chars_avail, &chars);
+ if (CYG_XMT_OK == res) {
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_uint32 dma_base = sh_chan->dma_xmt_base;
+ cyg_uint32 scr;
+
+ // Save the length so it can be used in the DMA DSR
+ sh_chan->dma_xmt_len = chars_avail;
+
+ // Flush cache for the area
+ HAL_DCACHE_FLUSH((cyg_haladdress)chars, chars_avail);
+
+ // Program DMA
+ HAL_WRITE_UINT32(dma_base+CYGARC_REG_CHCR, 0); // disable and clear
+ HAL_WRITE_UINT32(dma_base+CYGARC_REG_SAR, (cyg_uint32)chars);
+ HAL_WRITE_UINT32(dma_base+CYGARC_REG_DAR,
+ (sh_chan->ctrl_base+SCIF_SCFTDR) & 0x0fffffff);
+ HAL_WRITE_UINT32(dma_base+CYGARC_REG_DMATCR, chars_avail);
+ // Source increments, dest static, byte transfer, enable
+ // interrupt on completion.
+ HAL_WRITE_UINT32(dma_base+CYGARC_REG_CHCR,
+ sh_chan->dma_xmt_cr_flags | CYGARC_REG_CHCR_SM0 \
+ | CYGARC_REG_CHCR_IE | CYGARC_REG_CHCR_DE);
+
+ // Enable serial interrupts
+ HAL_READ(sh_chan->ctrl_base+SCIF_SCSCR, scr);
+ scr |= CYGARC_REG_SCIF_SCSCR_TIE;
+ HAL_WRITE(sh_chan->ctrl_base+SCIF_SCSCR, scr);
+ }
+
+ return res;
+}
+
+// must be called with serial interrupts masked
+static void
+sh_scif_stop_dma_xmt(serial_channel *chan)
+{
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_uint32 dma_base = sh_chan->dma_xmt_base;
+ cyg_uint32 cr;
+
+ // Disable DMA engine and interrupt enable flag. Should be safe
+ // to do since it's triggered by the serial interrupt which has
+ // already been disabled.
+ HAL_READ_UINT32(dma_base+CYGARC_REG_CHCR, cr);
+ cr &= ~(CYGARC_REG_CHCR_IE | CYGARC_REG_CHCR_DE);
+ HAL_WRITE_UINT32(dma_base+CYGARC_REG_CHCR, cr);
+
+ // Did transfer complete?
+ HAL_READ_UINT32(dma_base+CYGARC_REG_CHCR, cr);
+ if (0 == (cr & CYGARC_REG_CHCR_TE)) {
+ // Transfer incomplete. Report actually transferred amount of data
+ // back to the serial driver.
+ int chars_left;
+ HAL_READ_UINT32(dma_base+CYGARC_REG_DMATCR, chars_left);
+ CYG_ASSERT(chars_left > 0, "DMA incomplete, but no data left");
+ CYG_ASSERT(chars_left <= sh_chan->dma_xmt_len,
+ "More data remaining than was attempted transferred");
+
+ (chan->callbacks->data_xmt_done)(chan,
+ sh_chan->dma_xmt_len - chars_left);
+ }
+
+#ifdef CYGDBG_USE_ASSERTS
+ {
+ cyg_uint32 dmaor;
+ HAL_READ_UINT32(CYGARC_REG_DMAOR, dmaor);
+ CYG_ASSERT(0== (dmaor & (CYGARC_REG_DMAOR_AE | CYGARC_REG_DMAOR_NMIF)),
+ "DMA error");
+ }
+#endif
+
+ // The DMA engine is free again.
+ sh_chan->dma_xmt_running = false;
+}
+
+// Serial xmt DMA completion interrupt handler (ISR)
+static cyg_uint32
+sh_dma_xmt_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_uint32 _cr;
+
+ // mask serial interrupt
+ HAL_READ(sh_chan->ctrl_base+SCIF_SCSCR, _cr);
+ _cr &= ~CYGARC_REG_SCIF_SCSCR_TIE; // Disable xmit interrupt
+ HAL_WRITE(sh_chan->ctrl_base+SCIF_SCSCR, _cr);
+
+ // mask DMA interrupt and disable engine
+ HAL_READ_UINT32(sh_chan->dma_xmt_base+CYGARC_REG_CHCR, _cr);
+ _cr &= ~(CYGARC_REG_CHCR_IE | CYGARC_REG_CHCR_DE);
+ HAL_WRITE_UINT32(sh_chan->dma_xmt_base+CYGARC_REG_CHCR, _cr);
+
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial xmt DMA completion interrupt handler (DSR)
+static void
+sh_dma_xmt_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+
+ (chan->callbacks->data_xmt_done)(chan, sh_chan->dma_xmt_len);
+
+ // Try to load the engine again.
+ sh_chan->dma_xmt_running =
+ (CYG_XMT_OK == sh_scif_start_dma_xmt(chan)) ? true : false;
+}
+#endif // CYGINT_IO_SERIAL_SH_SCIF_DMA
+
+
+// Enable the transmitter on the device
+static void
+sh_scif_start_xmit(serial_channel *chan)
+{
+ cyg_uint8 _scr;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ xmt_req_reply_t _block_status = CYG_XMT_DISABLED;
+
+ if (sh_chan->tx_enabled)
+ return;
+
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_DMA
+ // Check if the engine is already running. If so, return. Note
+ // that there will never be a race on this flag - the caller of
+ // this function is respecting a per-channel lock.
+ if (sh_chan->dma_xmt_running)
+ return;
+ // If the channel uses DMA, try to start a DMA job for this -
+ // but handle the case where the job doesn't start by falling
+ // back to the FIFO/interrupt based code.
+ if (sh_chan->dma_enable) {
+ _block_status = sh_scif_start_dma_xmt(chan);
+ CYG_ASSERT(_block_status != CYG_XMT_EMPTY,
+ "start_xmit called with empty buffers!");
+ sh_chan->dma_xmt_running =
+ (CYG_XMT_OK == _block_status) ? true : false;
+ }
+#endif // CYGINT_IO_SERIAL_SH_SCIF_DMA
+
+ if (CYG_XMT_DISABLED == _block_status) {
+ // Mask interrupts while changing the CR since a rx
+ // interrupt or another thread doing the same in the
+ // middle of this would result in a bad CR state.
+ cyg_drv_isr_lock();
+ {
+ HAL_READ(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCIF_SCSCR_TIE; // Enable xmit interrupt
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_IRDA
+ if (sh_chan->irda_mode) {
+ // Enable transmitter - this automatically disables
+ // the receiver in the hardware. Doing it explicitly
+ // (like for async RX/TX below) causes more spurious
+ // characters to be read when re-enabling the
+ // receiver.
+ _scr |= CYGARC_REG_SCIF_SCSCR_TE;
+ }
+#endif
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_ASYNC_RXTX
+ if (sh_chan->async_rxtx_mode) {
+ // Enable transmitter
+ _scr |= CYGARC_REG_SCIF_SCSCR_TE;
+ // Disable receiver
+ _scr &= ~CYGARC_REG_SCIF_SCSCR_RE;
+ }
+#endif
+ HAL_WRITE(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ sh_chan->tx_enabled = true;
+ }
+ cyg_drv_isr_unlock();
+ }
+}
+
+// Disable the transmitter on the device
+static void
+sh_scif_stop_xmit(serial_channel *chan)
+{
+ cyg_uint8 _scr;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+
+ // In IrDA and async mode the transmitter needs to be disabled, so
+ // wait for transmission to complete within reason: disable it
+ // after 0.1s
+ if (0
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_IRDA
+ || sh_chan->irda_mode
+#endif
+#if defined(CYGINT_IO_SERIAL_SH_SCIF_ASYNC_RXTX)
+ || sh_chan->async_rxtx_mode
+#endif
+ ) {
+ cyg_uint16 sr;
+ int i = 1000;
+ do {
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCSSR, sr);
+ if (sr & CYGARC_REG_SCIF_SCSSR_TEND) break;
+ HAL_DELAY_US(100);
+ } while (i-- > 0);
+ }
+
+ // Mask interrupts while changing the CR since a rx interrupt or
+ // another thread doing the same in the middle of this would
+ // result in a bad CR state.
+ cyg_drv_isr_lock();
+ {
+ HAL_READ(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCIF_SCSCR_TIE; // Disable xmit interrupt
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_IRDA
+ if (sh_chan->irda_mode) {
+#ifdef CYGHWR_IO_SERIAL_SH_SCIF_IRDA_TXRX_COMPENSATION
+ // In IrDA mode there will be generated spurious RX
+ // events when the TX unit is switched on. Eat that
+ // character.
+ cyg_uint8 _junk;
+ cyg_uint16 _sr;
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCIF_SCFRDR, _junk);
+
+ // Clear buffer full flag (read back first)
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCSSR, _sr);
+ HAL_WRITE_UINT16(sh_chan->ctrl_base+SCIF_SCSSR,
+ CYGARC_REG_SCIF_SCSSR_CLEARMASK & ~(CYGARC_REG_SCIF_SCSSR_RDF|CYGARC_REG_SCIF_SCSSR_DR));
+#endif
+ // Disable transmitter
+ _scr &= ~CYGARC_REG_SCIF_SCSCR_TE;
+ }
+#endif
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_ASYNC_RXTX
+ if (sh_chan->async_rxtx_mode) {
+ // Enable receiver again
+ _scr |= CYGARC_REG_SCIF_SCSCR_RE;
+ // Disable transmitter
+ _scr &= ~CYGARC_REG_SCIF_SCSCR_TE;
+ }
+#endif
+ HAL_WRITE(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ }
+ cyg_drv_isr_unlock();
+
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_DMA
+ // If the channel uses DMA, stop the DMA engine.
+ if (sh_chan->dma_xmt_running)
+ sh_scif_stop_dma_xmt(chan);
+ else // dangling else!
+#endif // CYGINT_IO_SERIAL_SH_SCIF_DMA
+ sh_chan->tx_enabled = false;
+}
+
+// Serial I/O - low level tx interrupt handler (ISR)
+static cyg_uint32
+sh_scif_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_uint8 _scr;
+
+ HAL_READ(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCIF_SCSCR_TIE; // mask out tx interrupts
+ HAL_WRITE(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level tx interrupt handler (DSR)
+static void
+sh_scif_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ xmt_req_reply_t _block_status = CYG_XMT_DISABLED;
+ cyg_uint16 _fdr, _sr;
+ int _space, _chars_avail;
+ unsigned char* _chars;
+ CYG_ADDRWORD _base = sh_chan->ctrl_base;
+
+ // Always check if we're supposed to be enabled; the driver runs
+ // with DSRs disabled, and a DSR may have been posted (but not
+ // executed) before the interrupt was masked.
+ if (!sh_chan->tx_enabled)
+ return;
+
+#ifdef CYGHWR_SH_SCIF_FLOW_DSRDTR
+ CYGHWR_SH_SCIF_FLOW_DSRDTR_TX(chan);
+#endif
+
+ // How many chars can we stuff into the FIFO?
+ HAL_READ_UINT16(_base+SCIF_SCFDR, _fdr);
+ _space = 16 - ((_fdr & CYGARC_REG_SCIF_SCFDR_TCOUNT_MASK) >> CYGARC_REG_SCIF_SCFDR_TCOUNT_shift);
+
+ // Try to do the transfer most efficiently
+ _block_status = (chan->callbacks->data_xmt_req)(chan, _space,
+ &_chars_avail, &_chars);
+ if (CYG_XMT_OK == _block_status) {
+ // Transfer the data in block(s).
+ do {
+ int i = _chars_avail;
+ while (i--) {
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCIF_SCFTDR, *_chars++);
+ _space--;
+ }
+ (chan->callbacks->data_xmt_done)(chan, _chars_avail);
+ } while (_space > 0 &&
+ (CYG_XMT_OK == (chan->callbacks->data_xmt_req)(chan, _space,
+ &_chars_avail,
+ &_chars)));
+ } else if (CYG_XMT_DISABLED == _block_status) {
+ // Transfer char-by-char, but stop if the transmitter
+ // gets disabled.
+ while (_space-- && sh_chan->tx_enabled)
+ (chan->callbacks->xmt_char)(chan);
+ }
+
+ // Clear FIFO-empty/transmit end flags (read back sr first)
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCSSR, _sr);
+ HAL_WRITE_UINT16(sh_chan->ctrl_base+SCIF_SCSSR,
+ CYGARC_REG_SCIF_SCSSR_CLEARMASK & ~CYGARC_REG_SCIF_SCSSR_TDFE);
+
+ if (sh_chan->tx_enabled) {
+ cyg_uint8 _scr;
+ HAL_READ(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCIF_SCSCR_TIE; // unmask tx interrupts
+ HAL_WRITE(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ }
+}
+
+// Serial I/O - low level RX interrupt handler (ISR)
+static cyg_uint32
+sh_scif_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_uint8 _scr;
+
+ HAL_READ(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCIF_SCSCR_RIE; // mask rx interrupts
+ HAL_WRITE(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level rx interrupt handler (DSR)
+static void
+sh_scif_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_uint8 _scr;
+ cyg_uint16 _fdr, _sr;
+ int _avail, _space_avail;
+ unsigned char* _space;
+ rcv_req_reply_t _block_status;
+
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCFDR, _fdr);
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCSSR, _sr);
+
+ _avail = _fdr & CYGARC_REG_SCIF_SCFDR_RCOUNT_MASK;
+ if (_avail > 0) {
+ _block_status = (chan->callbacks->data_rcv_req)(chan, _avail,
+ &_space_avail, &_space);
+ if (CYG_RCV_OK == _block_status) {
+ // Transfer the data in block(s).
+ do {
+ int i = _space_avail;
+ while(i--) {
+ cyg_uint8 _c;
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCIF_SCFRDR, _c);
+ *_space++ = _c;
+ _avail--;
+ }
+ (chan->callbacks->data_rcv_done)(chan, _space_avail);
+ } while (_avail > 0 &&
+ (CYG_RCV_OK == (chan->callbacks->data_rcv_req)(chan, _avail,
+ &_space_avail,
+ &_space)));
+ } else {
+ // Transfer the data char-by-char both for CYG_RCV_FULL
+ // and CYG_RCV_DISABLED, leaving all policy decisions with
+ // the IO driver.
+ while(_avail--) {
+ cyg_uint8 _c;
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCIF_SCFRDR, _c);
+ (chan->callbacks->rcv_char)(chan, _c);
+ }
+ }
+ } else {
+ CYG_ASSERT(_avail > 0, "No data to be read in RX DSR");
+ }
+
+ // Clear buffer full flag (read back first)
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCSSR, _sr);
+ HAL_WRITE_UINT16(sh_chan->ctrl_base+SCIF_SCSSR,
+ CYGARC_REG_SCIF_SCSSR_CLEARMASK & ~(CYGARC_REG_SCIF_SCSSR_RDF|CYGARC_REG_SCIF_SCSSR_DR));
+
+ HAL_READ(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCIF_SCSCR_RIE; // unmask rx interrupts
+ HAL_WRITE(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+}
+
+// Serial I/O - low level error interrupt handler (ISR)
+static cyg_uint32
+sh_scif_er_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_uint8 _scr;
+
+ HAL_READ(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ _scr &= ~CYGARC_REG_SCIF_SCSCR_RIE; // mask rx interrupts
+ HAL_WRITE(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level error interrupt handler (DSR)
+static void
+sh_scif_er_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sh_scif_info *sh_chan = (sh_scif_info *)chan->dev_priv;
+ cyg_uint16 _ssr, _ssr_mask;
+#ifdef SCIF_SC2SSR
+ cyg_uint8 _ssr2;
+#endif
+ cyg_uint8 _scr;
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ cyg_serial_line_status_t stat;
+#endif
+
+ HAL_READ_UINT16(sh_chan->ctrl_base+SCIF_SCSSR, _ssr);
+ _ssr_mask = CYGARC_REG_SCIF_SCSSR_CLEARMASK;
+ // Clear the ER bit
+ _ssr_mask &= ~CYGARC_REG_SCIF_SCSSR_ER;
+
+
+#ifdef SCIF_SC2SSR
+ HAL_READ_UINT8(sh_chan->ctrl_base+SCIF_SC2SSR, _ssr2);
+ if (_ssr2 & CYGARC_REG_SCIF_SC2SSR_ORER) {
+ _ssr2 &= ~CYGARC_REG_SCIF_SC2SSR_ORER;
+ HAL_WRITE_UINT8(sh_chan->ctrl_base+SCIF_SC2SSR, _ssr2);
+ stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;
+ (chan->callbacks->indicate_status)(chan, &stat );
+ }
+#endif
+ if (_ssr & CYGARC_REG_SCIF_SCSSR_FER) {
+ // _ssr_mask &= ~CYGARC_REG_SCIF_SCSSR_FER; // FER is read-only
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ stat.which = CYGNUM_SERIAL_STATUS_FRAMEERR;
+ (chan->callbacks->indicate_status)(chan, &stat );
+#endif
+ }
+ if (_ssr & CYGARC_REG_SCIF_SCSSR_PER) {
+ // _ssr_mask &= ~CYGARC_REG_SCIF_SCSSR_PER; // PER is read-only
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ stat.which = CYGNUM_SERIAL_STATUS_PARITYERR;
+ (chan->callbacks->indicate_status)(chan, &stat );
+#endif
+ }
+ if (_ssr & CYGARC_REG_SCIF_SCSSR_BRK) {
+ _ssr_mask &= ~CYGARC_REG_SCIF_SCSSR_BRK;
+#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
+ stat.which = CYGNUM_SERIAL_STATUS_BREAK;
+ (chan->callbacks->indicate_status)(chan, &stat );
+#endif
+ }
+ HAL_WRITE_UINT16(sh_chan->ctrl_base+SCIF_SCSSR, _ssr_mask);
+
+ HAL_READ(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+ _scr |= CYGARC_REG_SCIF_SCSCR_RIE; // unmask rx interrupts
+ HAL_WRITE(sh_chan->ctrl_base+SCIF_SCSCR, _scr);
+}
+
+#endif // ifdef CYGDAT_IO_SERIAL_SH_SCIF_INL
diff --git a/ecos/packages/devs/serial/sh/se77x9/current/ChangeLog b/ecos/packages/devs/serial/sh/se77x9/current/ChangeLog
new file mode 100644
index 0000000..a8fab66
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/se77x9/current/ChangeLog
@@ -0,0 +1,41 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_sh_se77x9.cdl: Remove irrelevant doc link.
+
+2002-05-08 Jesper Skov <jskov@redhat.com>
+
+ * include/sh_sh3_se77x9_scif.inl: CYGINT_IO_SERIAL_SH_SCIF_DMA is
+ now booldata. Rename sh3_scif to sh_scif. Register renaming.
+
+2001-06-19 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_se77x9.cdl: Disable COM1 driver for now since it
+ breaks eCos.
+
+2001-06-18 Jesper Skov <jskov@redhat.com>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/sh/se77x9/current/cdl/ser_sh_se77x9.cdl b/ecos/packages/devs/serial/sh/se77x9/current/cdl/ser_sh_se77x9.cdl
new file mode 100644
index 0000000..aac93f0
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/se77x9/current/cdl/ser_sh_se77x9.cdl
@@ -0,0 +1,193 @@
+# ====================================================================
+#
+# ser_sh_se77x9.cdl
+#
+# eCos serial SH/SE77X9 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors:
+# Date: 2001-06-18
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_SH_SE77X9 {
+ display "SH3 SE77X9 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_SH_SH77X9_SE77X9
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ Hitachi SH3 SE77X9 board, based on the generic SH SCI driver."
+
+
+ # FIXME: This really belongs in the SH_SCIF package
+ cdl_interface CYGINT_IO_SERIAL_SH_SCIF_REQUIRED {
+ display "SH SCI driver required"
+ }
+
+ # FIXME: This really belongs in the GENERIC_16X5X package
+ cdl_interface CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED {
+ display "Generic 16x5x serial driver required"
+ }
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_INL <cyg/io/sh_sh3_se77x9_16x5x.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_GENERIC_16X5X_CFG <pkgconf/io_serial_sh_se77x9.h>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_SH_SCIF_INL <cyg/io/sh_sh3_se77x9_scif.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_SH_SCIF_CFG <pkgconf/io_serial_sh_se77x9.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_SH_SE77X9_COM1 {
+ display "SH SE77X9 serial 1 driver (SuperIO)"
+ flavor bool
+ calculated 0
+ description "
+ This option includes the serial device driver for the COM1
+ port. FIXME: Disabled due to being broken."
+
+ implements CYGINT_IO_SERIAL_GENERIC_16X5X_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ cdl_option CYGDAT_IO_SERIAL_SH_SE77X9_COM1_NAME {
+ display "Device name for COM1"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for COM1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SH_SE77X9_COM1_BAUD {
+ display "Baud rate for COM1"
+ flavor data
+ legal_values { 4800 9600 14400 19200 38400 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the COM1 port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SH_SE77X9_COM1_BUFSIZE {
+ display "Buffer size for COM1"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the COM1 port."
+ }
+ }
+
+ # SCIF port
+ cdl_component CYGPKG_IO_SERIAL_SH_SE77X9_COM2 {
+ display "SE77X9 serial, SCIF port 2 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for SCIF
+ port 2."
+
+ implements CYGINT_IO_SERIAL_SH_SCIF_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+
+ cdl_option CYGDAT_IO_SERIAL_SH_SE77X9_COM2_NAME {
+ display "Device name"
+ flavor data
+ default_value {"\"/dev/ser2\""}
+ description "
+ This option specifies the device name for the serial
+ port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SH_SE77X9_COM2_BAUD {
+ display "Baud rate"
+ flavor data
+ legal_values { 4800 9600 14400 19200 38400 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the serial driver."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SH_SE77X9_COM2_BUFSIZE {
+ display "Buffer size"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the serial driver."
+ }
+
+ cdl_option CYGSEM_IO_SERIAL_SH_SE77X9_COM2_DMA {
+ display "Enable SCIF serial driver DMA"
+ active_if CYGINT_HAL_SH_DMA_CHANNELS
+ implements CYGINT_HAL_SH_DMA_CHANNELS_USED
+ implements CYGINT_IO_SERIAL_SH_SCIF_DMA
+ default_value 1
+ description "
+ Enable DMA for this port."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_SH_SE77X9_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ no_define
+ active_if CYGPKG_IO_SERIAL_SH_SE77X9_COM2
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"sh-se77x9\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_SER_DEV CYGDAT_IO_SERIAL_SH_SE77X9_COM2_NAME"
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty2\""
+ }
+ }
+}
+# EOF ser_sh_se77x9.cdl
diff --git a/ecos/packages/devs/serial/sh/se77x9/current/include/sh_sh3_se77x9_16x5x.inl b/ecos/packages/devs/serial/sh/se77x9/current/include/sh_sh3_se77x9_16x5x.inl
new file mode 100644
index 0000000..5ec4e5b
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/se77x9/current/include/sh_sh3_se77x9_16x5x.inl
@@ -0,0 +1,123 @@
+#ifndef CYGONCE_DEVS_SH_SE77X9_16X5X_H
+#define CYGONCE_DEVS_SH_SE77X9_16X5X_H
+
+//==========================================================================
+//
+// io/serial/sh/sh_sh3_se77x9_16x5x.inl
+//
+// Serial I/O specification for Hitachi SE77X9 platform.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-06-18
+// Purpose: Specifies serial resources for the platform.
+// Description: This file can be include from the 16x5x driver sources.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/io_serial_sh_se77x9.h>
+
+//-----------------------------------------------------------------------------
+// Baud rate specification, based on raw 1.8462MHz clock (/16)
+
+static unsigned short select_baud[] = {
+ 0, // Unused
+ 2307, // 50
+ 1538, // 75
+ 1048, // 110
+ 857, // 134.5
+ 769, // 150
+ 576, // 200
+ 384, // 300
+ 192, // 600
+ 96, // 1200
+ 64, // 1800
+ 48, // 2400
+ 32, // 3600
+ 24, // 4800
+ 16, // 7200
+ 12, // 9600
+ 8, // 14400
+ 6, // 19200
+ 3, // 38400
+ 2, // 57600
+ 1, // 115200
+ 0, // 230400
+};
+
+#ifdef CYGPKG_IO_SERIAL_SH_SE77X9_COM1
+static pc_serial_info se77x9_serial_info1 = {0xb04007f0, CYGNUM_HAL_INTERRUPT_COM1};
+#if CYGNUM_IO_SERIAL_SH_SE77X9_COM1_BUFSIZE > 0
+static unsigned char se77x9_serial_out_buf1[CYGNUM_IO_SERIAL_SH_SE77X9_COM1_BUFSIZE];
+static unsigned char se77x9_serial_in_buf1[CYGNUM_IO_SERIAL_SH_SE77X9_COM1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(se77x9_serial_channel1,
+ pc_serial_funs,
+ se77x9_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_SE77X9_COM1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &se77x9_serial_out_buf1[0], sizeof(se77x9_serial_out_buf1),
+ &se77x9_serial_in_buf1[0], sizeof(se77x9_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(se77x9_serial_channel1,
+ pc_serial_funs,
+ se77x9_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_SE77X9_COM1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(se77x9_serial_io1,
+ CYGDAT_IO_SERIAL_SH_SE77X9_COM1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ pc_serial_init,
+ pc_serial_lookup, // Serial driver may need initializing
+ &se77x9_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_SH_SE77X9_COM1
+
+#endif // CYGONCE_DEVS_SH_SE77X9_SCIF_H
diff --git a/ecos/packages/devs/serial/sh/se77x9/current/include/sh_sh3_se77x9_scif.inl b/ecos/packages/devs/serial/sh/se77x9/current/include/sh_sh3_se77x9_scif.inl
new file mode 100644
index 0000000..a9905f0
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/se77x9/current/include/sh_sh3_se77x9_scif.inl
@@ -0,0 +1,113 @@
+#ifndef CYGONCE_DEVS_SH_SE77X9_SCIF_H
+#define CYGONCE_DEVS_SH_SE77X9_SCIF_H
+
+//==========================================================================
+//
+// io/serial/sh/sh_sh3_se77x9_scif.inl
+//
+// Serial I/O specification for Hitachi SE77X9 platform.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-06-18
+// Purpose: Specifies serial resources for the platform.
+// Description: This file can be include from either SCI or SCIF/IRDA driver
+// sources and should specify driver information as required
+// for the platform.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/io_serial_sh_se77x9.h>
+
+#ifdef CYGPKG_IO_SERIAL_SH_SE77X9_COM2
+static sh_scif_info se77x9_serial_info2 = {
+ er_int_num : CYGNUM_HAL_INTERRUPT_SCIF_ERI2,
+ rx_int_num : CYGNUM_HAL_INTERRUPT_SCIF_RXI2,
+ tx_int_num : CYGNUM_HAL_INTERRUPT_SCIF_TXI2,
+ ctrl_base : CYGARC_REG_SCIF_SCSMR2,
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_DMA
+# ifdef CYGSEM_IO_SERIAL_SH_SE77X9_COM2_DMA
+ dma_enable : true,// we want DMA for this channel
+ dma_xmt_cr_flags : CYGARC_REG_CHCR_RS_SCIF_TX
+# else
+ dma_enable : false // No DMA
+# endif
+#endif
+};
+
+#if CYGNUM_IO_SERIAL_SH_SE77X9_COM2_BUFSIZE > 0
+static unsigned char se77x9_serial_out_buf2[CYGNUM_IO_SERIAL_SH_SE77X9_COM2_BUFSIZE];
+static unsigned char se77x9_serial_in_buf2[CYGNUM_IO_SERIAL_SH_SE77X9_COM2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(se77x9_serial_channel2,
+ sh_scif_funs,
+ se77x9_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_SE77X9_COM2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &se77x9_serial_out_buf2[0],
+ sizeof(se77x9_serial_out_buf2),
+ &se77x9_serial_in_buf2[0],
+ sizeof(se77x9_serial_in_buf2)
+ );
+#else
+static SERIAL_CHANNEL(se77x9_serial_channel2,
+ sh_scif_funs,
+ se77x9_serial_info2,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_SE77X9_COM2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(sh_serial_io2,
+ CYGDAT_IO_SERIAL_SH_SE77X9_COM2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ sh_scif_init,
+ sh_scif_lookup, // Serial driver may need initializing
+ &se77x9_serial_channel2
+ );
+#endif // CYGPKG_IO_SERIAL_SH_SE77X9_COM2
+
+#endif // CYGONCE_DEVS_SH_SE77X9_SCIF_H
diff --git a/ecos/packages/devs/serial/sh/sh4_202_md/current/ChangeLog b/ecos/packages/devs/serial/sh/sh4_202_md/current/ChangeLog
new file mode 100644
index 0000000..5a1f496
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/sh4_202_md/current/ChangeLog
@@ -0,0 +1,27 @@
+2003-09-18 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * New package, based on se77x9 driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/sh/sh4_202_md/current/cdl/ser_sh4_202_md.cdl b/ecos/packages/devs/serial/sh/sh4_202_md/current/cdl/ser_sh4_202_md.cdl
new file mode 100644
index 0000000..e365b57
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/sh4_202_md/current/cdl/ser_sh4_202_md.cdl
@@ -0,0 +1,149 @@
+# ====================================================================
+#
+# ser_sh4_202_md.cdl
+#
+# eCos SH4-202 MicroDev serial configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jlarmour
+# Contributors:
+# Date: 2003-09-18
+# Description: Based on se77x9 driver by jskov.
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+
+cdl_package CYGPKG_IO_SERIAL_SH_SH4_202_MD {
+ display "SH4-202 MicroDev serial device driver"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_SH_SH4_202_MD
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+
+ description "
+ This option enables the serial device drivers for the
+ SuperH SH4-202 MicroDev board, based on the generic SH SCIF driver."
+
+
+ # FIXME: This really belongs in the SH_SCIF package
+ cdl_interface CYGINT_IO_SERIAL_SH_SCIF_REQUIRED {
+ display "SH SCIF driver required"
+ }
+
+ # SCIF port
+ cdl_component CYGPKG_IO_SERIAL_SH_SH4_202_MD_SERIAL1 {
+ display "SH4-202 MicroDev SCIF serial port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the SCIF
+ port on the SH4-202 MicroDev development board."
+
+ implements CYGINT_IO_SERIAL_SH_SCIF_REQUIRED
+ implements CYGINT_IO_SERIAL_FLOW_CONTROL_HW
+ implements CYGINT_IO_SERIAL_LINE_STATUS_HW
+ implements CYGINT_IO_SERIAL_SH_SCIF_ASYNC_RXTX
+ implements CYGINT_IO_SERIAL_SH_SCIF_BR_INTERRUPT
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_SH_SCIF_INL <cyg/io/sh4_202_md_scif.inl>"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_SH_SCIF_CFG <pkgconf/io_serial_sh_sh4_202_md.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_option CYGDAT_IO_SERIAL_SH_SH4_202_MD_SERIAL1_NAME {
+ display "Device name"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the serial
+ port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SH_SH4_202_MD_SERIAL1_BAUD {
+ display "Baud rate"
+ flavor data
+ legal_values { 4800 9600 14400 19200 38400 57600 115200 }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed)
+ for the serial driver."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SH_SH4_202_MD_SERIAL1_BUFSIZE {
+ display "Buffer size"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers
+ used for the serial driver."
+ }
+
+# DMA not yet implemented
+# cdl_option CYGSEM_IO_SERIAL_SH_SH4_202_MD_SERIAL1_DMA {
+# display "Enable SCIF serial driver DMA"
+# active_if CYGINT_HAL_SH_DMA_CHANNELS
+# implements CYGINT_HAL_SH_DMA_CHANNELS_USED
+# implements CYGINT_IO_SERIAL_SH_SCIF_DMA
+# default_value 1
+# description "
+# Enable DMA for this port."
+# }
+# }
+
+ cdl_component CYGPKG_IO_SERIAL_SH_SH4_202_MD_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ no_define
+ active_if CYGPKG_IO_SERIAL_SH_SH4_202_MD_SERIAL1
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"sh-sh4_202_md\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_SER_DEV CYGDAT_IO_SERIAL_SH_SH4_202_MD_SERIAL1_NAME"
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty1\""
+ }
+ }
+}
+# EOF ser_sh_sh4_202_md.cdl
diff --git a/ecos/packages/devs/serial/sh/sh4_202_md/current/include/sh4_202_md_scif.inl b/ecos/packages/devs/serial/sh/sh4_202_md/current/include/sh4_202_md_scif.inl
new file mode 100644
index 0000000..6745f61
--- /dev/null
+++ b/ecos/packages/devs/serial/sh/sh4_202_md/current/include/sh4_202_md_scif.inl
@@ -0,0 +1,117 @@
+#ifndef CYGONCE_DEVS_SH_SH4_202_MD_SCIF_H
+#define CYGONCE_DEVS_SH_SH4_202_MD_SCIF_H
+
+//==========================================================================
+//
+// devs/serial/sh/sh4_202_md_scif.inl
+//
+// Serial I/O specification for SuperH SH4-202 MicroDev development board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2003-09-18
+// Purpose: Specifies serial resources for the platform.
+// Description: This file can be include from either SCI or SCIF/IRDA driver
+// sources and should specify driver information as required
+// for the platform. This file was derived from the se77x9
+// driver.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/io_serial_sh_sh4_202_md.h>
+
+#ifdef CYGPKG_IO_SERIAL_SH_SH4_202_MD_SERIAL1
+static sh_scif_info sh4_202_md_serial_info1 = {
+ er_int_num : CYGNUM_HAL_INTERRUPT_SCIF_ERI,
+ rx_int_num : CYGNUM_HAL_INTERRUPT_SCIF_RXI,
+ br_int_num : CYGNUM_HAL_INTERRUPT_SCIF_BRI,
+ tx_int_num : CYGNUM_HAL_INTERRUPT_SCIF_TXI,
+ ctrl_base : CYGARC_REG_SCIF_SCSMR2,
+#ifdef CYGINT_IO_SERIAL_SH_SCIF_DMA
+# ifdef CYGSEM_IO_SERIAL_SH_SH4_202_MD_SERIAL1_DMA
+ dma_enable : true,// we want DMA for this channel
+ dma_xmt_cr_flags : CYGARC_REG_CHCR_RS_SCIF_TX
+# else
+ dma_enable : false // No DMA
+# endif
+#endif
+};
+
+#if CYGNUM_IO_SERIAL_SH_SH4_202_MD_SERIAL1_BUFSIZE > 0
+static unsigned char sh4_202_md_serial_out_buf1[CYGNUM_IO_SERIAL_SH_SH4_202_MD_SERIAL1_BUFSIZE];
+static unsigned char sh4_202_md_serial_in_buf1[CYGNUM_IO_SERIAL_SH_SH4_202_MD_SERIAL1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(sh4_202_md_serial_channel1,
+ sh_scif_funs,
+ sh4_202_md_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_SH4_202_MD_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &sh4_202_md_serial_out_buf1[0],
+ sizeof(sh4_202_md_serial_out_buf1),
+ &sh4_202_md_serial_in_buf1[0],
+ sizeof(sh4_202_md_serial_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(sh4_202_md_serial_channel1,
+ sh_scif_funs,
+ sh4_202_md_serial_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_SH4_202_MD_SERIAL1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(sh_serial_io1,
+ CYGDAT_IO_SERIAL_SH_SH4_202_MD_SERIAL1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ sh_scif_init,
+ sh_scif_lookup, // Serial driver may need initializing
+ &sh4_202_md_serial_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_SH_SH4_202_MD_SERIAL1
+
+#endif // CYGONCE_DEVS_SH_SH4_202_MD_SCIF_H
+
+// EOF sh4_202_md_scif.inl
diff --git a/ecos/packages/devs/serial/sparclite/sleb/current/ChangeLog b/ecos/packages/devs/serial/sparclite/sleb/current/ChangeLog
new file mode 100644
index 0000000..eab025c
--- /dev/null
+++ b/ecos/packages/devs/serial/sparclite/sleb/current/ChangeLog
@@ -0,0 +1,1187 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_sparclite_sleb.cdl: Remove irrelevant doc link.
+
+2001-09-10 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_sparclite_sleb.cdl:
+ Fix 234000->230400 typo.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sparclite_sleb.cdl: Moved testing parameters here.
+
+ * src/sleb_sdtr.c: Removed obsolete sleb_sdtr_set_config function.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/sleb_sdtr.c (sleb_sdtr_set_config): Now use keys to make
+ more flexible.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-04-11 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/ser_sparclite_sleb.cdl: Change the parent from CYGPKG_IO_SERIAL
+ (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES
+ (which is not...) thus allowing convenient control independent of
+ platform. Also enable all individual devices by default, now, so
+ that they can be enabled simply by enabling the above new parent.
+
+2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * ecos.db: Re-organize device packages. This is a massive change
+ involving deleting all the sources for serial and ethernet drivers
+ from where they used to live in
+ packages/io/serial/current/src/ARCH/PLATFORM.[ch]
+ packages/net/drivers/eth/PLATFORM/current/src/...
+ and reinstating them in
+ packages/devs/serial/ARCH/PLATFORM/current/src/...
+ packages/devs/eth/ARCH/PLATFORM/current/src/...
+
+ All these new packages are properly defined in ecos.db, and are
+ all of type "hardware" so that a "target" can grab them.
+
+ This directory layout is descriptive of the devices we have right
+ now, arch and platform are separate levels just to make it easier
+ to navigate in the filesystem and similar to the HAL structure in
+ the filesystem.
+
+ It is *not* prescriptive of future work; for example, the mythical
+ common highly-portable 16550 serial driver which works on many
+ targets would be called "devs/serial/s16550/current", or a serial
+ device for a particular board (cogent springs to mind) that can
+ work with different CPUs fitted is "devs/serial/cogent/current".
+
+ Changelogs have been preserved and replicated over all the new
+ packages, so that no history is lost.
+
+ The contents of individual source files are unchanged; they build
+ in just the same emvironment except for a very few cases where the
+ config file name changed in this movement.
+
+ Targets in ecos.db have been redefined to bring in all relevant
+ hardware packages including net and serial drivers (but the newly
+ included packages are only active if their desired parent is
+ available.)
+
+ The names of CDL options (and their #defines of course) stay the
+ same for the serial drivers, for backward compatibility.
+
+ * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
+ rather than it being in (almost) all target definitions.
+
+2000-04-05 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r
+ (tty_write): Similarly
+
+ * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and
+ CYG_TTY_IN_FLAGS_CRLF to match
+
+2000-03-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range.
+ * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired
+ constants.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl,
+ cdl/ser_arm_aeb.cdl,
+ cdl/ser_arm_cma230.cdl,
+ cdl/ser_arm_edb7xxx.cdl,
+ cdl/ser_arm_pid.cdl,
+ cdl/ser_i386_pc.cdl,
+ cdl/ser_mips_jmr3904.cdl,
+ cdl/ser_mips_vrc4373.cdl,
+ cdl/ser_mn10300.cdl,
+ cdl/ser_powerpc_cogent.cdl,
+ cdl/ser_quicc_smc.cdl,
+ cdl/ser_sh_edk7708.cdl,
+ cdl/ser_sparclite_sleb.cdl,
+ cdl/tty.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/serialio.h: Correct baud rate typo: 230400 rather than
+ 234000. Thanks to Grant Edwards for the report.
+
+2000-02-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'.
+
+2000-02-28 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent
+ again. Fixed interrupt problem.
+
+2000-02-22 Jesper Skov <jskov@redhat.com>
+
+ * tests/ser_test_protocol.inl: Don't use 115200 baud on
+ Cogent. Our slower boards can't keep up.
+
+2000-02-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency.
+
+2000-02-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Added configury for PC serial device drivers.
+
+ * cdl/ser_i386_pc.cdl:
+ * src/i386/pc_serial.c:
+ * src/i386/pc_serial.h:
+ Added these files to implement PC serial line drivers.
+
+ * cdl/io_serial.cdl:
+ Added CYGPKG_IO_SERIAL_I386_PC.
+
+ * tests/ser_test_protocol.inl:
+ Added support for PC serial line testing.
+
+2000-02-11 Jesper Skov <jskov@redhat.com>
+
+ * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY):
+ * src/sparclite/sleb_sdtr.c:
+ serial_devio => cyg_io_serial_devio
+
+2000-02-10 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_*
+ preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form
+ now.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-02 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper
+ case macros
+
+ * src/arm/aeb_serial.c: Update to reflect above
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/*.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Fix problem with backspace at start
+ of line (size must be 'signed' for compare to work).
+
+2000-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/*.cdl: Add descriptions to a number of options &c which were
+ lacking same, also tidied up other typos as noticed en passant.
+
+2000-01-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at
+ start of line.
+
+2000-01-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write): Avoid potential deadlock if
+ transmit start actually sends enough characters to signal cond wait.
+
+2000-01-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+ serial_callbacks => cyg_io_serial_callbacks
+
+ * src/mips/tx3904_serial.c:
+ * src/mips/vrc4373_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/quicc_smc_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/edb7xxx_serial.c:
+ * src/arm/cma230_serial.c:
+ * src/arm/ebsa285_serial.c:
+ * src/common/haldiag.c:
+ * src/common/serial.c: Fix namespace pollution -
+ serial_devio => cyg_io_serial_devio
+
+1999-12-06 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle
+ case where an interrupt represents multiple events.
+
+1999-11-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong.
+
+1999-11-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Remove mention of 7209/7212.
+
+1999-11-03 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/io_serial.cdl: Define build options.
+
+1999-10-26 Jesper Skov <jskov@cygnus.co.uk>
+ * tests/serial5.c (serial_test): Reduce speed in thumb mode.
+
+ * src/arm/pid_serial.h: Added BE support.
+
+ * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what
+ needs to be compiled.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial.h (ISR_RxTO): Define - character received but
+ not handled "promptly".
+
+ * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts
+ properly (can't ignore them even with TO bit set).
+
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all
+ input (empty input FIFO) otherwise characters get dropped.
+
+1999-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus.
+
+1999-10-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added configury for VR4300 testing.
+
+ * src/mips/vrc4373_serial.c: Added Bi-endian support.
+
+ * include/pkgconf/io_serial.h: Adjusted default baud rates to
+ 38400.
+
+1999-10-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Run tests on AEB rev C as well.
+
+1999-09-28 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct
+ value supplied for interrupt priority - it may be unused, but it
+ is asserted for range. Initialize the diagnostic channel if on an
+ MBX and if NOT using SMC1 ourselves, to ensure that diag output
+ and built-in stubs work correctly; otherwise reset the quicc and
+ ignore SMC1 as before. Fix various warnings, mostly about
+ casting/arg-passing/assigning away volatile.
+
+1999-08-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Define dummy crash ID.
+
+1999-08-30 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added crash information which
+ should help track down repeating errors.
+
+1999-08-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/README: Added.
+
+1999-08-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c:
+ * tests/tty2.c:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/PKGconf.mak:
+ Require kernel and kernel C API.
+
+1999-08-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Added a simple implementation of a
+ receive FIFO to try and reduce the overhead of receiving bytes.
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mn10300/mn10300_serial.c:
+ * tests/ser_test_protocol.inl:
+ Rename all am32 -> am31
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from development branch:
+
+ 1999-08-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/serial5.c: Modified config test for boards that need a lower
+ speed for this test.
+
+ * tests/ser_test_protocol.inl: Removed 14400 baud tests for all
+ MN10300 variants. The MN10300 cannot currently do this speed.
+
+ * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt
+ enable/disable code to be variant specific.
+
+ * include/pkgconf/io_serial.h: Undid Jonathan's change, since the
+ same options are used for all MN10300 variants.
+
+ 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to
+ CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific
+
+ 1999-08-04 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Changed names of MN10300 defines tested. Added AM33 definitions.
+
+ * src/mn10300/mn10300_serial.c:
+ Modified driver to work on am33 too. This simply requires some
+ alternate definitions of things like register addresses and some
+ bits in them plus some extra parameterization of some register
+ values.
+
+ * src/PKGconf.mak:
+ Added am33 to list of architectures supporting serial lines.
+
+1999-07-28 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Update descriptions to be more
+ generic (CL7x11 instead of CL7211).
+
+1999-07-28 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct typos in CDL description
+ for serial port 2 driver
+
+1999-07-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/arm/ebsa285_serial.c: New file: device driver for the serial
+ device of the Intel StrongARM EBSA-285 evaluation board.
+
+ * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285):
+ Config for it.
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Compile it.
+
+ * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it.
+
+1999-07-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl (change_config): Changed implementation.
+
+1999-06-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust
+ initialization, with data cache disabled. This seems to fix the
+ random failures described below.
+
+ * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860.
+ Added some delays in the configuration change code to make QUICC
+ happy [didn't help much although the manual says they are required].
+
+ * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to
+ match what the Linux driver uses - still doesn't work well, though.
+
+ * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the
+ serial driver working and robust. At this point it works quite well,
+ using the default buffer sizes. Changing from the defaults seem to
+ easily break it though, certainly on input. Also, changing the baud
+ rate seems to not work reliably.
+
+ * src/common/serial.c: Add some tracing/debug info to try and debug
+ problems with QUICC serial driver. These are hard disabled with
+ "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information
+ about how/when data are delivered from the serial driver.
+
+ * include/pkgconf/io_serial.h: Adjust limits and defaults on number and
+ size of buffers with values that seem to work.
+
+1999-06-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit
+ to avoid compiler warnings.
+
+1999-06-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CDL for number of buffers.
+
+ * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1.
+
+1999-06-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Some clean up (removed commented
+ obsolete CDL parenting structure).
+ Add support for Motorola PowerPC QUICC/SMC.
+
+ * src/arm/cma230_serial.c:
+ * src/arm/cl7211_serial.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()'
+ prototypes.
+
+1999-06-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which
+ cause xmitter to get stuck.
+
+1999-06-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: [removed]
+ * src/sh/sh_sci_serial.c: [added]
+ * src/sh/sh_sci_7708.inl: [added]
+ * include/pkgconf/io_serial.h:
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ * tests/ser_test_protocol.inl:
+ Renamed CDL options and restructered driver.
+ Fixed CDL typo.
+
+1999-06-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option.
+
+1999-06-04 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Disable testing at 115200
+ for Cogent CMA230 (ARM).
+
+ * src/arm/cma230_serial.c: Fix interrupt for port B.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Fixed receive interrupts and added handler for
+ error interrupts.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * io/serial/current/src/PKGconf.mak:
+ * io/serial/current/tests/ser_test_protocol.inl:
+ * include/pkgconf/io_serial.h:
+ Renamed SH platform package to edk7708.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added ability to change options in
+ host software.
+
+1999-05-27 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ Wait for the serial device to become acquiescent before disabling
+ it. This prevents cygmon's outgoing characters getting corrupted
+ due to transmission being disabled.
+ Fix for PR 20047
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * tests/ser_test_protocol.inl: Add Cogent CMA230 setup.
+
+ * src/arm/cma230_serial.c: Make names compatible with Cogent
+ PowerPC board.
+
+1999-05-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup.
+1999-05-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh/sh_serial.c: Added more baud rate values. Disabled
+ interrupt driven receive. Fixed config_port to enable proper
+ interrupt flags.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Change all mentions of CYGPKG_HAL_TX39_JMR3904 to
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to
+ CYG_HAL_MIPS_TX39
+1999-05-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added sh entry.
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * include/pkgconf/io_serial.h:
+ * src/sh/sh_serial.c:
+ Added sh driver.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if
+ there is one.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19926
+ * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char
+ if there is one.
+
+1999-05-16 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Clean up, first working version.
+
+1999-05-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Removed workaround for spurious
+ Cogent reads.
+
+ * src/arm/aeb_serial.c:
+ * src/arm/aeb_serial.h:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/pid_serial.h:
+ * src/powerpc/cogent_serial.h:
+ * src/powerpc/cogent_serial_with_ints.c:
+ Check for receive interrupt before reading.
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The follow changes were made in a branch an have now been merged:
+
+ 1999-04-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mips/vrc4373_serial.c: Small changes to get working with
+ interrupts.
+
+ 1999-04-20 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904
+ parent attribute.
+
+1999-05-11 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/cl7211_serial.c: Fix compile problems from merged code.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Tidied up a bit and added
+ description of protocol.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/serial.c (serial_write, serial_read): Clear abort
+ flag at entry.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test): Handle config fails correctly.
+
+ * tests/ser_test_protocol.inl: Better change_config
+ handling. Simple recovery and negotiation isn't timing
+ dependant.
+
+1999-05-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/timeout.inl: Updated with the below changes.
+
+1999-05-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * misc/timeout.inl (timeout): Timeouts are relative, but alarms
+ need absolute time values.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 20018
+ * tests/serial1.c (serial_test): Always PASS, regardless of
+ configuration.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Reverse order of configurations -
+ run tests with slow baud rate first.
+ Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup.
+
+1999-05-04 Jesper Skov <jskov@cygnus.co.uk>
+ * src/mn10300/mn10300_serial.c:
+ Use interrupt enable/disable feature of serial port2 to allow
+ coexistence with CygMon/hal_diag.
+
+ * tests/ser_test_protocol.inl: Use port2 for MN10300.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak (EXTRAS_COMPILE):
+ Use the new rules for generating libextras.a
+
+1999-04-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211.
+
+
+1999-04-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered.
+1999-04-20 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added some comments. Disabled 38400
+ for SLEB. Only run test on SLEB if CygMon isn't used for diag
+ output.
+
+1999-04-15 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19752
+ * tests/serial3.c:
+ * tests/serial5.c:
+ Run these tests at a lower baud rate on ARM AEB.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19839
+ * src/mn10300/mn10300_serial.c:
+ Fix compiler warnings.
+
+1999-04-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ Reparent the board-specific serial devices below the actual boards.
+
+1999-04-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ NA when run from simulator.
+
+1999-04-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl:
+ Disabled 115200 for MN10300.
+ Reclaim interrupt vectors from CygMon when testing on SLEB.
+
+1999-04-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serial.h: Change SERIAL_CHANNEL setup so all channels
+ have serial callbacks, regardless of buffering.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/tty.c:
+ * include/pkgconf/io_serial.h:
+ Added new ttydiag device layered on top of haldiag, so that tty0
+ can be layered on top of ser0.
+
+1999-04-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/tty1.c: [added]
+ * tests/tty2.c: [added]
+ * tests/PKGconf.mak:
+ * tests/ser_test_protocol.inl:
+ Added two simple TTY tests.
+
+1999-04-07 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O
+ macros instead of hal_diag.h where they had evolved before.
+
+1999-04-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial4.c (serial_test):
+ * tests/serial3.c (serial_test):
+ Reduce packet sizes.
+
+1999-03-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Added remaining targets to the
+ test.
+
+1999-03-31 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race
+ when enabling xmit interrupts.
+
+1999-03-26 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter
+ is now always enabled, just the interrupts are masked/unmasked to control it.
+ This lets the serial driver cooperate with Cygmon on the port used for GDB.
+ Note that currently serial input does not work for CON1 since Cygmon is
+ taking all of the receive interrupts for itself.
+ (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be
+ enabled - otherwise it can get enabled incorrectly and we get interrupted
+ to death!
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Send a DONE message after a no-echo
+ binary packet.
+
+1999-03-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Make these build when no kernel present; include of testcase
+ was the wrong side of the ifdef.
+
+1999-03-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/serial5.c:
+ * tests/serial4.c:
+ * tests/serial3.c:
+ * tests/serial2.c:
+ * tests/serial1.c:
+ Moved NOP check to ser_test_protocol open call.
+
+ * tests/ser_test_protocol.inl: Make sure the proper device is
+ selected for testing. Do NOP check in open call.
+
+1999-03-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h:
+ * misc/console.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/tty.c:
+ * src/mips/tx3904_serial.c:
+ * src/mn10300/mn10300_serial.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions.
+
+ * src/mips/tx3904_serial.c (tx3904_serial_config_port):
+ Make sure port is enabled (CDL) before using it.
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_config_port):
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ * src/arm/aeb_serial.c (aeb_serial_config_port):
+ * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that
+ the physical port is not modified unless the provided configuration is valid.
+
+ * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port):
+ Using wrong config data.
+
+ * include/serialio.h: Add macros to support baud rate from CDL.
+
+ * include/pkgconf/io_serial.h:
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c (tx3904_serial_ISR):
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Add configury for baud rate and buffer size.
+
+1999-03-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU
+ frequency. This is a little more accurate than using
+ CYGHWR_HAL_MIPS_CPU_FREQ.
+
+1999-03-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness.
+
+ * src/arm/aeb_serial.c (aeb_serial_stop_xmit):
+ * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment.
+
+1999-03-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't
+ like.
+
+ * src/powerpc/cogent_serial.h:
+ Added copyright header.
+
+ * tests/ser_test_protocol.inl:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ Don't try to run tests when no IO device has been specified.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c,
+ * misc/serial5.c, misc/ser_test_protocol.inl
+ Deleted.
+
+1999-03-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * tests/timeout.inl:
+ * tests/PKGconf.mak:
+ * tests/serial1.c:
+ * tests/serial2.c:
+ * tests/serial3.c:
+ * tests/serial4.c:
+ * tests/serial5.c:
+ * tests/ser_test_protocol.inl:
+ Moved the serial tests from the misc directory to the tests
+ directory.
+
+1999-03-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts
+ at initialization and unmask/remask in start/stop xmit
+ routines. This has no real effect on the hardware, but the
+ simulator does not implement the LCR_TXE bit properly, resulting
+ in spurious TX interrupts during diagnostic output.
+ This was the cause of the slow output reported in PR 19559.
+
+1999-03-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate
+ case - mostly lower case.
+
+1999-03-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * misc/console.c:
+ * misc/serial.c:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+ CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-03-22 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ * src/mips/tx3904_serial.c: Add CDL configury.
+
+ * include/pkgconf/io_serial.h: Update CDL to add device name
+ configurability for all devices.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Use CDL configured device names.
+
+1999-03-22 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * misc/serial1.c:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ * misc/serial5.c:
+ Requires kernel as well.
+
+1999-03-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sparclite/sleb_sdtr.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial5.c:
+ * misc/PKGconf.mak:
+ Replace complex and not very stable duplex test with a simpler
+ test that works better.
+ Added serial5 using that test.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/serial1.c:
+ * misc/serial2.c:
+ Added API test and made serial2 do simple string output.
+
+1999-03-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment.
+
+1999-03-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ Moved include statement to avoid warnings.
+
+1999-03-19 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: More CDL problems.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/arm/aeb_serial.c: Update device names to match CDL.
+
+ * include/pkgconf/io_serial.h: Change names for serial ports to
+ be CYGPKG_IO_SERIAL_<arch>_<platform>_<port>.
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ First stab at the duplex binary test. Still much fun to be had...
+
+1999-03-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/ser_test_protocol.inl: Added timeout for PING.
+
+1999-03-18 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change ABORT functionality to be DSR safe.
+ (serial_get_config): Fix typo!
+
+ * include/pkgconf/io_serial.h: Small change in CDL to make serial
+ devices tied to the platform and not the serial I/O package. This
+ means that only the devices appropriate to a given platform can be
+ enabled.
+
+ * misc/serial.c: Better use of alarms - only trigger at the time of
+ the next timeout. Moved timeout functions to new file "timeout.inl".
+
+ * src/common/serial.c (serial_get_config): Add support for
+ CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT.
+
+ * misc/serial.c: Add simple timeout mechanisms.
+
+1999-03-17 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL.
+
+ * include/pkgconf/io_serial.h: Add some CDL configury - not perfect
+ because of current ~CDL limitations.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Cleaned up a bit. Used for hacking new tests.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/PKGconf.mak:
+ * misc/ser_test_protocol.inl:
+ * misc/serial2.c:
+ * misc/serial3.c:
+ * misc/serial4.c:
+ Put testing protocol implementation in a separate file. Split the
+ tests in serial2 into separate files.
+
+1999-03-16 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c: Fixed some compiler warnings.
+
+1999-03-15 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Change default configurations.
+ No serial drivers enabled for PID port A or AEB.
+
+ * src/sparclite/sleb_sdtr.c:
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c:
+ * src/common/haldiag.c:
+ * src/common/tty.c:
+ * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init
+ messages.
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * src/sparclite/sleb_sdtr.c:
+ * src/arm/aeb_serial.c:
+ * src/arm/pid_serial_with_ints.c: Don't include <cyg/kernel/kapi.h>
+
+1999-03-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part
+ of binary protocol.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Play a bit with timing. Think I broke it :(
+ Added DONE to BINARY packet.
+ Proper call to DRAIN.
+
+1999-03-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c: Tidied away some debugging code.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Removed bogus config changes.
+
+1999-03-12 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Check for ser_filter on host (PING
+ packet).
+
+1999-03-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Added note.
+
+ * misc/serial2.c:
+ Added (almost) proper configuration handling.
+ Run tests on varying configurations.
+
+1999-03-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mips/tx3904_serial.c:
+ Many changes to get working.
+
+ * misc/console.c (console_test): Fixed compiler warning.
+
+ * misc/serial2.c:
+ Added device name for TX39 testing.
+ Fixed some bugs in Tcyg_io_write() macro.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: Added target specific test device name.
+
+1999-03-10 John Dallaway <jld@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Correct CDL description spelling.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ * misc/console.c:
+ Fixed compiler warnings.
+
+1999-03-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Improve CDL descriptions.
+
+1999-03-10 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Do some more tests with changed
+ baud rates.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Added workaround for spurious byte
+ problem. Added a few more tests to run.
+
+ * src/powerpc/cogent_serial_with_ints.c
+ (cogent_serial_config_port): Remove interrupt enabling.
+
+1999-03-09 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/mips/tx3904_serial.c:
+ Added initial version of TX39 device driver. Currently untested
+ but eliminates PR19445.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c: DRAIN function works now.
+
+1999-03-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/io_serial.h: Only enable one serial driver per
+ default.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial2.c (serial_test): Be a bit more aggressive.
+
+ * src/powerpc/cogent_serial_with_ints.c: Check that configuration
+ is sensible.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c:
+ Added support for both ports.
+
+ * include/pkgconf/io_serial.h: Added simple defines for cogent
+ serial ports. No CDL yet.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * misc/serial.c: Removed PID references. Fixed compiler warnings.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c: Cleaned up a
+ bit. Actually works now.
+
+1999-03-08 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour
+ means DSR lock should be left alone.
+
+1999-03-08 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19400
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set
+ valid interrupt priority.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c (mn10300_serial_init):
+ Added extra test to avoid initializing serial 2 when CYGMON is
+ present.
+ Include hal_intr.h explicitly for use in non-kernel
+ configurations.
+
+ * src/common/serial.c:
+ Added extra test before calls to cyg_drv_cond_wait() to avoid race
+ condition. This is not, however, a complete solution to this
+ problem. A better solution will be forthcoming.
+
+ * include/serial.h:
+ Changed include files used to permit non-kernel configurations to
+ be built.
+
+1999-03-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/common/haldiag.c: Removed diag_printf declaration.
+
+1999-03-05 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300/mn10300_serial.c:
+ Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile!
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port):
+ Fix renaming of interrupt vectors.
+
+1999-03-05 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/arm/pid_serial_with_ints.c: Fix interrupt vectors.
+
+1999-03-03 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * serial/current/src/arm/pid_serial_with_ints.c:
+ New [somewhat] configurable drivers for PID.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/sparclite/sleb/current/cdl/ser_sparclite_sleb.cdl b/ecos/packages/devs/serial/sparclite/sleb/current/cdl/ser_sparclite_sleb.cdl
new file mode 100644
index 0000000..6e40576
--- /dev/null
+++ b/ecos/packages/devs/serial/sparclite/sleb/current/cdl/ser_sparclite_sleb.cdl
@@ -0,0 +1,209 @@
+# ====================================================================
+#
+# ser_sparclite_sleb.cdl
+#
+# eCos serial SPARClite/SLEB configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: gthomas
+# Contributors:
+# Date: 1999-07-14
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_SPARCLITE_SLEB {
+ display "SPARClite SLEB serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_SPARCLITE_SLEB
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ SPARClite SLEB."
+
+ compile -library=libextras.a sleb_sdtr.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_sparclite_sleb.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+cdl_component CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1 {
+ display "SPARClite SLEB serial CON1 port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the SPARClite
+ SLEB CON1 port."
+
+ cdl_option CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME {
+ display "Device name for SPARClite SLEB serial CON1 port"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the device name for the SPARClite SLEB
+ CON1 port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BAUD {
+ display "Baud rate for the SPARClite SLEB serial CON1 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 19200
+ description "
+ This option specifies the default baud rate (speed) for the
+ SPARClite SLEB CON1."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE {
+ display "Buffer size for the SPARClite SLEB serial CON1 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the SPARClite SLEB CON1."
+ }
+}
+cdl_component CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON2 {
+ display "SPARClite SLEB serial CON2 port driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the SPARClite
+ SLEB CON2 port."
+
+ cdl_option CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON2_NAME {
+ display "Device name for SPARClite SLEB serial CON2 port"
+ flavor data
+ default_value {"\"/dev/ser1\""}
+ description "
+ This option specifies the device name for the SPARClite SLEB
+ CON2 port."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BAUD {
+ display "Baud rate for the SPARClite SLEB serial CON2 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200 230400
+ }
+ default_value 19200
+ description "
+ This option specifies the default baud rate (speed) for the
+ SPARClite SLEB CON2."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE {
+ display "Buffer size for the SPARClite SLEB serial CON2 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used for
+ the SPARClite SLEB CON2."
+ }
+}
+
+ cdl_component CYGPKG_IO_SERIAL_SPARCLITE_SLEB_OPTIONS {
+ display "Serial device driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building these serial device drivers. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_SPARCLITE_SLEB_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1
+
+ implements CYGINT_IO_SERIAL_TEST_SKIP_38400
+ implements CYGINT_IO_SERIAL_TEST_SKIP_57600
+ implements CYGINT_IO_SERIAL_TEST_SKIP_115200
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"sparcl\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_OVERRIDE_INT_1 CYGNUM_HAL_INTERRUPT_9"
+ puts $::cdl_header "#define CYGPRI_SER_TEST_OVERRIDE_INT_2 CYGNUM_HAL_INTERRUPT_10"
+ }
+ }
+}
+
+# EOF ser_sparclite_sleb.cdl
diff --git a/ecos/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.c b/ecos/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.c
new file mode 100644
index 0000000..847625e
--- /dev/null
+++ b/ecos/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.c
@@ -0,0 +1,400 @@
+//==========================================================================
+//
+// io/serial/sparclite/sleb_sdtr.c
+//
+// Serial I/O interface module for SPARClite Eval Board (SLEB)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-02-04
+// Purpose: SLEB serial I/O module
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/io.h>
+#include <pkgconf/io_serial.h>
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+
+#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB
+
+#include "sleb_sdtr.h"
+
+extern void diag_printf(const char *fmt, ...);
+
+#define BUFSIZE 128
+
+typedef struct sleb_sdtr_info {
+ CYG_ADDRWORD base;
+ CYG_WORD tx_int_num;
+ CYG_WORD rx_int_num;
+ cyg_interrupt tx_serial_interrupt;
+ cyg_handle_t tx_serial_interrupt_handle;
+ cyg_interrupt rx_serial_interrupt;
+ cyg_handle_t rx_serial_interrupt_handle;
+ cyg_uint8 cmd_reg;
+ bool xmit_enabled;
+} sleb_sdtr_info;
+
+static bool sleb_sdtr_init(struct cyg_devtab_entry *tab);
+static bool sleb_sdtr_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo sleb_sdtr_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char sleb_sdtr_getc(serial_channel *chan);
+static Cyg_ErrNo sleb_sdtr_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void sleb_sdtr_start_xmit(serial_channel *chan);
+static void sleb_sdtr_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 sleb_sdtr_tx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void sleb_sdtr_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+static cyg_uint32 sleb_sdtr_rx_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void sleb_sdtr_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(sleb_sdtr_funs,
+ sleb_sdtr_putc,
+ sleb_sdtr_getc,
+ sleb_sdtr_set_config,
+ sleb_sdtr_start_xmit,
+ sleb_sdtr_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1
+static sleb_sdtr_info sleb_sdtr_info0 = {SLEB_SDTR0_BASE, SLEB_SDTR0_TX_INT, SLEB_SDTR0_RX_INT};
+#if CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE > 0
+static unsigned char sleb_sdtr_out_buf0[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE];
+static unsigned char sleb_sdtr_in_buf0[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(sleb_sdtr_channel0,
+ sleb_sdtr_funs,
+ sleb_sdtr_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &sleb_sdtr_out_buf0[0], sizeof(sleb_sdtr_out_buf0),
+ &sleb_sdtr_in_buf0[0], sizeof(sleb_sdtr_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(sleb_sdtr_channel0,
+ sleb_sdtr_funs,
+ sleb_sdtr_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(sleb_sdtr_io0,
+ CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ sleb_sdtr_init,
+ sleb_sdtr_lookup, // Serial driver may need initializing
+ &sleb_sdtr_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1
+
+#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON2
+static sleb_sdtr_info sleb_sdtr_info1 = {SLEB_SDTR1_BASE, SLEB_SDTR1_TX_INT, SLEB_SDTR1_RX_INT};
+#if CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE > 0
+static unsigned char sleb_sdtr_out_buf1[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE];
+static unsigned char sleb_sdtr_in_buf1[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(sleb_sdtr_channel1,
+ sleb_sdtr_funs,
+ sleb_sdtr_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &sleb_sdtr_out_buf1[0], sizeof(sleb_sdtr_out_buf1),
+ &sleb_sdtr_in_buf1[0], sizeof(sleb_sdtr_in_buf1)
+ );
+#else
+static SERIAL_CHANNEL(sleb_sdtr_channel1,
+ sleb_sdtr_funs,
+ sleb_sdtr_info1,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(sleb_sdtr_io1,
+ CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON2_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ sleb_sdtr_init,
+ sleb_sdtr_lookup, // Serial driver may need initializing
+ &sleb_sdtr_channel1
+ );
+#endif // CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON2
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+sleb_sdtr_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv;
+ CYG_ADDRWORD port = sdtr_chan->base;
+ cyg_int32 baud_divisor;
+ cyg_int32 clk, tval;
+ unsigned char mode;
+#if 0
+ if ((new_config->baud < CYGNUM_SERIAL_BAUD_MIN) || (new_config->baud > CYGNUM_SERIAL_BAUD_MAX))
+ return false; // Invalid baud rate
+#endif
+ baud_divisor = select_baud[new_config->baud];
+ if (baud_divisor == 0)
+ return false; // Unsupported baud rate
+ // Reset the port
+ HAL_SPARC_86940_WRITE(SDTR_CONTROL(port), SDTR_CMD_RST);
+ // Write the mode
+ mode = SDTR_MODE_MODE_ASYNC16 |
+ select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
+ select_stop_bits[new_config->stop] |
+ select_parity[new_config->parity];
+ HAL_SPARC_86940_WRITE(SDTR_CONTROL(port), mode);
+ // Set baud rate clock.
+ // ***** CAUTION! Both ports use the same time, thus they must both run at the same baud rate!
+ clk = *SLEB_CLOCK_SWITCH; // Compute board speed
+ if (clk & 0x80) clk = 10;
+ clk = (clk & 0x3F) * 1000000; // in MHz
+ tval = (clk / (baud_divisor * 32)) - 1;
+ HAL_SPARC_86940_WRITE(SLEB_TIMER3_RELOAD, tval);
+ // Set up control register
+ sdtr_chan->cmd_reg = SDTR_CMD_RTS | SDTR_CMD_DTR | SDTR_CMD_TxEN;
+#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1
+ // Cygmon needs the receiver
+ if ((chan->out_cbuf.len != 0) || (chan == &sleb_sdtr_channel0)) {
+#else
+ if (chan->out_cbuf.len != 0) {
+#endif
+ sdtr_chan->cmd_reg |= SDTR_CMD_RxEN;
+ }
+ if (init) {
+ sdtr_chan->xmit_enabled = false;
+ }
+ HAL_SPARC_86940_WRITE(SDTR_CONTROL(port), sdtr_chan->cmd_reg);
+ if (new_config != &chan->config)
+ chan->config = *new_config;
+ return true;
+}
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+sleb_sdtr_init(struct cyg_devtab_entry *tab)
+{
+ serial_channel *chan = (serial_channel *)tab->priv;
+ sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv;
+#ifdef CYGDBG_IO_INIT
+ diag_printf("SLEB SERIAL init - dev: %x.%d.%d\n", sdtr_chan->base, sdtr_chan->tx_int_num, sdtr_chan->rx_int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ cyg_drv_interrupt_create(sdtr_chan->tx_int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sleb_sdtr_tx_ISR,
+ sleb_sdtr_tx_DSR,
+ &sdtr_chan->tx_serial_interrupt_handle,
+ &sdtr_chan->tx_serial_interrupt);
+ cyg_drv_interrupt_attach(sdtr_chan->tx_serial_interrupt_handle);
+ cyg_drv_interrupt_mask(sdtr_chan->tx_int_num);
+ cyg_drv_interrupt_create(sdtr_chan->rx_int_num,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ sleb_sdtr_rx_ISR,
+ sleb_sdtr_rx_DSR,
+ &sdtr_chan->rx_serial_interrupt_handle,
+ &sdtr_chan->rx_serial_interrupt);
+ cyg_drv_interrupt_attach(sdtr_chan->rx_serial_interrupt_handle);
+ cyg_drv_interrupt_unmask(sdtr_chan->rx_int_num);
+ }
+ sleb_sdtr_config_port(chan, &chan->config, true);
+ return true;
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+sleb_sdtr_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+sleb_sdtr_putc(serial_channel *chan, unsigned char c)
+{
+ sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv;
+ CYG_ADDRWORD port = sdtr_chan->base;
+ cyg_uint8 status;
+ HAL_SPARC_86940_READ(SDTR_STATUS(port), status);
+ if (status & SDTR_STAT_TxRDY) {
+// Transmit buffer is empty
+ HAL_SPARC_86940_WRITE(SDTR_TXDATA(port), c);
+ return true;
+ } else {
+// No space
+ return false;
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+sleb_sdtr_getc(serial_channel *chan)
+{
+ unsigned char c;
+ sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv;
+ CYG_ADDRWORD port = sdtr_chan->base;
+ cyg_uint8 status;
+ HAL_SPARC_86940_READ(SDTR_STATUS(port), status);
+ while ((status & SDTR_STAT_RxRDY) == 0)
+ HAL_SPARC_86940_READ(SDTR_STATUS(port), status); // Wait for char
+ HAL_SPARC_86940_READ(SDTR_RXDATA(port), c);
+ return c;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+sleb_sdtr_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != sleb_sdtr_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+sleb_sdtr_start_xmit(serial_channel *chan)
+{
+ sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv;
+ sdtr_chan->xmit_enabled = true;
+ cyg_drv_interrupt_unmask(sdtr_chan->tx_int_num);
+}
+
+// Disable the transmitter on the device
+static void
+sleb_sdtr_stop_xmit(serial_channel *chan)
+{
+ sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(sdtr_chan->tx_int_num);
+ sdtr_chan->xmit_enabled = false;
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+sleb_sdtr_tx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(sdtr_chan->tx_int_num);
+ cyg_drv_interrupt_acknowledge(sdtr_chan->tx_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+sleb_sdtr_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv;
+ (chan->callbacks->xmt_char)(chan);
+ if (sdtr_chan->xmit_enabled)
+ cyg_drv_interrupt_unmask(sdtr_chan->tx_int_num);
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+sleb_sdtr_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(sdtr_chan->rx_int_num);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+sleb_sdtr_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv;
+ CYG_ADDRWORD port = sdtr_chan->base;
+ cyg_uint8 status, c;
+ HAL_SPARC_86940_READ(SDTR_STATUS(port), status);
+ if ((status & SDTR_STAT_RxRDY) != 0) {
+ HAL_SPARC_86940_READ(SDTR_RXDATA(port), c);
+ (chan->callbacks->rcv_char)(chan, c);
+ }
+ cyg_drv_interrupt_acknowledge(sdtr_chan->rx_int_num);
+ cyg_drv_interrupt_unmask(sdtr_chan->rx_int_num);
+}
+
+#endif // CYGPKG_IO_SERIAL_SPARCLITE_SLEB
diff --git a/ecos/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.h b/ecos/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.h
new file mode 100644
index 0000000..d9c0b5f
--- /dev/null
+++ b/ecos/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.h
@@ -0,0 +1,166 @@
+#ifndef CYGONCE_SLEB_SDTR_H
+#define CYGONCE_SLEB_SDTR_H
+//==========================================================================
+//
+// io/serial/sparclite/sleb_sdtr.c
+//
+// Serial I/O interface module for SPARClite Eval Board (SLEB)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 1999-02-04
+// Purpose: SLEB serial I/O module
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_io.h> // For I/O macros
+
+#define reg(n) ((n)*4)
+
+// SDTR Registers
+#define SDTR_TXDATA(base) base+reg(0)
+#define SDTR_RXDATA(base) base+reg(0)
+#define SDTR_STATUS(base) base+reg(1)
+#define SDTR_CONTROL(base) base+reg(1)
+
+// Mode register
+#define SDTR_MODE_MODE_MASK 0x03 // Mode selection bits (mask)
+#define SDTR_MODE_MODE_SYNC 0x00 // Synchronous mode
+#define SDTR_MODE_MODE_ASYNC1 0x01 // Async - clock/1
+#define SDTR_MODE_MODE_ASYNC16 0x02 // Async - clock/16
+#define SDTR_MODE_MODE_ASYNC64 0x03 // Async - clock/64
+#define SDTR_MODE_DTB_MASK 0x0C // Number of data bits (mask)
+#define SDTR_MODE_DTB_5 0x00 // 5 bits / char
+#define SDTR_MODE_DTB_6 0x04 // 6 bits / char
+#define SDTR_MODE_DTB_7 0x08 // 7 bits / char
+#define SDTR_MODE_DTB_8 0x0C // 8 bits / char
+#define SDTR_MODE_PARITY_MASK 0x30 // Parity modes (mask)
+#define SDTR_MODE_PARITY_ENABLE 0x10 // Enable parity
+#define SDTR_MODE_PARITY_NONE 0x00 // No parity (parity disabled)
+#define SDTR_MODE_PARITY_ODD 0x00 // Odd parity
+#define SDTR_MODE_PARITY_EVEN 0x20 // Even parity
+#define SDTR_MODE_STOP_BITS_MASK 0xC0 // Number of stop bits (mask)
+#define SDTR_MODE_STOP_BITS_1 0x40 // 1 stop bit
+#define SDTR_MODE_STOP_BITS_1_5 0x80 // 1.5 stop bits
+#define SDTR_MODE_STOP_BITS_2 0xC0 // 2 stop bits
+
+// Command register
+#define SDTR_CMD_TxEN 0x01 // Enable transmitter
+#define SDTR_CMD_DTR 0x02 // Assert DTR
+#define SDTR_CMD_RxEN 0x04 // Enable receiver
+#define SDTR_CMD_BREAK 0x08 // Send break
+#define SDTR_CMD_EFR 0x10 // Error flag reset
+#define SDTR_CMD_RTS 0x20 // Assert RTS
+#define SDTR_CMD_RST 0x40 // Internal RESET
+#define SDTR_CMD_EHM 0x80 // Enable Hunt mode
+
+// Status register
+#define SDTR_STAT_TxRDY 0x01 // Transmitter ready
+#define SDTR_STAT_RxRDY 0x02 // Receiver ready
+#define SDTR_STAT_TxEMP 0x04 // Transmitter empty
+#define SDTR_STAT_PERR 0x08 // Parity error
+#define SDTR_STAT_OERR 0x10 // Overrun error
+#define SDTR_STAT_FERR 0x20 // Framing error
+#define SDTR_STAT_SYBRK 0x40 // Break
+#define SDTR_STAT_DSR 0x80 // State of DSR signal
+
+// Offsets to standard SDTR elements
+#define SLEB_SDTR0_BASE (8*4)
+#define SLEB_SDTR0_TX_INT 9
+#define SLEB_SDTR0_RX_INT 10
+#define SLEB_SDTR1_BASE (12*4)
+#define SLEB_SDTR1_TX_INT 6
+#define SLEB_SDTR1_RX_INT 7
+#define SLEB_TIMER3_CONTROL reg(29)
+#define SLEB_TIMER3_RELOAD reg(30)
+
+// On-board switch, used to determine baud rate
+#define SLEB_CLOCK_SWITCH (volatile unsigned char *)0x01000003
+
+static unsigned char select_word_length[] = {
+ SDTR_MODE_DTB_5, // 5 bits / word (char)
+ SDTR_MODE_DTB_6,
+ SDTR_MODE_DTB_7,
+ SDTR_MODE_DTB_8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ SDTR_MODE_STOP_BITS_1, // 1 stop bit
+ SDTR_MODE_STOP_BITS_1_5, // 1.5 stop bit
+ SDTR_MODE_STOP_BITS_2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ SDTR_MODE_PARITY_NONE, // No parity
+ SDTR_MODE_PARITY_ENABLE|SDTR_MODE_PARITY_EVEN, // Even parity
+ SDTR_MODE_PARITY_ENABLE|SDTR_MODE_PARITY_ODD, // ODD parity
+ 0xFF, // Mark parity
+ 0xFF, // Space parity
+};
+
+static cyg_int32 select_baud[] = {
+ 0, // Unused
+ 50, // 50
+ 75, // 75
+ 110, // 110
+ 0, // 134.5
+ 150, // 150
+ 200, // 200
+ 300, // 300
+ 600, // 600
+ 1200, // 1200
+ 1800, // 1800
+ 2400, // 2400
+ 3600, // 3600
+ 4800, // 4800
+ 7200, // 7200
+ 9600, // 9600
+ 14400, // 14400
+ 19200, // 19200
+ 38400, // 38400
+ 57600, // 57600
+ 115200, // 115200
+ 230400, // 230400
+};
+
+#endif // CYGONCE_SLEB_SDTR_H
+
diff --git a/ecos/packages/devs/serial/v85x/v850/current/ChangeLog b/ecos/packages/devs/serial/v85x/v850/current/ChangeLog
new file mode 100644
index 0000000..c40ada1
--- /dev/null
+++ b/ecos/packages/devs/serial/v85x/v850/current/ChangeLog
@@ -0,0 +1,83 @@
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/ser_v85x_v850.cdl: Remove irrelevant doc link.
+
+2001-03-21 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/ser_v85x_v850.cdl: Default driver on if CYGPKG_IO_SERIAL_DEVICES
+ enabled - like other drivers.
+ Descriptions should not be specific to SA1.
+
+ * src/v85x_v850_serial.h: Generate baud table dependent on CPU
+ frequency always.
+ * src/v85x_v850_serial.c (v850_serial_config_port): Normalize
+ baud settings from above table before setting.
+ (v850_serial_putc): Silence warning.
+
+2000-10-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/ser_v85x_v850.cdl: Moved testing parameters here.
+
+2000-10-09 Gary Thomas <gthomas@redhat.com>
+
+ * src/v85x_v850_serial.c (v850_serial_config_port): Fix baud clock
+ setup.
+
+2000-10-04 Gary Thomas <gthomas@redhat.com>
+
+ * src/v85x_v850_serial.c (v850_serial_tx_timeout): Correct arguments.
+
+2000-09-06 Gary Thomas <gthomas@redhat.com>
+
+ * src/v85x_v850_serial.h:
+ * src/v85x_v850_serial.c: Better handling of V850 variants (SA1,SB1)
+
+2000-08-31 Gary Thomas <gthomas@redhat.com>
+
+ * src/v85x_v850_serial.c (v850_serial_config_port): Better handling
+ of cpu xtal frequency for baud rate calculations.
+
+2000-08-01 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/v85x_v850_serial.c (v850_serial_set_config): Now use keys to make
+ more flexible.
+
+2000-07-19 Gary Thomas <gthomas@redhat.com>
+
+ * src/v85x_v850_serial.h: Base baud rate calculations on CPU frequency.
+
+2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * cdl/<yournamehere>.cdl: Remove the comment on the empty
+ include_files directive; the tools now support this correctly.
+ This keeps internal include files internal.
+
+2000-05-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/v85x_v850_serial.h:
+ * src/v85x_v850_serial.c:
+ * cdl/ser_v85x_v850.cdl: New file(s).
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/serial/v85x/v850/current/cdl/ser_v85x_v850.cdl b/ecos/packages/devs/serial/v85x/v850/current/cdl/ser_v85x_v850.cdl
new file mode 100644
index 0000000..c9eb9c6
--- /dev/null
+++ b/ecos/packages/devs/serial/v85x/v850/current/cdl/ser_v85x_v850.cdl
@@ -0,0 +1,131 @@
+# ====================================================================
+#
+# ser_v85x_v850.cdl
+#
+# eCos serial NEC/V850 configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Original data: gthomas
+# Contributors: jlarmour
+# Date: 2000-05-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_IO_SERIAL_V85X_V850 {
+ display "NEC V850 serial device drivers"
+
+ parent CYGPKG_IO_SERIAL_DEVICES
+ active_if CYGPKG_IO_SERIAL
+ active_if CYGPKG_HAL_V85X_V850
+
+ requires CYGPKG_ERROR
+ include_dir cyg/io
+ include_files ; # none _exported_ whatsoever
+ description "
+ This option enables the serial device drivers for the
+ NEC V850."
+
+ compile -library=libextras.a v85x_v850_serial.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** serial driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER <pkgconf/io_serial_v85x_v850.h>"
+ puts $::cdl_system_header "/***** serial driver proc output end *****/"
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_V85X_V850_SERIAL0 {
+ display "NEC V850 serial port 0 driver"
+ flavor bool
+ default_value 1
+ description "
+ This option includes the serial device driver for the NEC V850
+ SA1 (70F3017) and SB1 (70F3033) devices, port 0."
+
+ cdl_option CYGDAT_IO_SERIAL_V85X_V850_SERIAL0_NAME {
+ display "Device name for NEC V850 serial port 0 driver"
+ flavor data
+ default_value {"\"/dev/ser0\""}
+ description "
+ This option specifies the name of the serial device for the
+ NEC V850, port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_V85X_V850_SERIAL0_BAUD {
+ display "Baud rate for the NEC V850 serial port 0 driver"
+ flavor data
+ legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600
+ 4800 7200 9600 14400 19200 38400 57600 115200
+ }
+ default_value 38400
+ description "
+ This option specifies the default baud rate (speed) for the
+ NEC V850, port 0."
+ }
+
+ cdl_option CYGNUM_IO_SERIAL_V85X_V850_SERIAL0_BUFSIZE {
+ display "Buffer size for the NEC V850 serial port 0 driver"
+ flavor data
+ legal_values 0 to 8192
+ default_value 128
+ description "
+ This option specifies the size of the internal buffers used
+ for the NEC V850, port 0."
+ }
+ }
+
+ cdl_component CYGPKG_IO_SERIAL_V85X_V850_TESTING {
+ display "Testing parameters"
+ flavor bool
+ calculated 1
+ active_if CYGPKG_IO_SERIAL_V85X_V850_SERIAL0
+
+ cdl_option CYGPRI_SER_TEST_SER_DEV {
+ display "Serial device used for testing"
+ flavor data
+ default_value { CYGDAT_IO_SERIAL_V85X_V850_SERIAL0_NAME }
+ }
+
+ define_proc {
+ puts $::cdl_header "#define CYGPRI_SER_TEST_CRASH_ID \"v85x/v850\""
+ puts $::cdl_header "#define CYGPRI_SER_TEST_TTY_DEV \"/dev/tty0\""
+ }
+ }
+
+}
diff --git a/ecos/packages/devs/serial/v85x/v850/current/src/v85x_v850_serial.c b/ecos/packages/devs/serial/v85x/v850/current/src/v85x_v850_serial.c
new file mode 100644
index 0000000..6818f07
--- /dev/null
+++ b/ecos/packages/devs/serial/v85x/v850/current/src/v85x_v850_serial.c
@@ -0,0 +1,359 @@
+//==========================================================================
+//
+// io/serial/v85x/v85x_v850_serial.c
+//
+// NEC V850 Serial I/O Interface Module (interrupt driven)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas,jlarmour
+// Date: 2001-03-21
+// Purpose: V850 Serial I/O module (interrupt driven version)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/io_serial.h>
+#include <pkgconf/io.h>
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#endif
+#include CYGBLD_HAL_TARGET_H
+
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/serial.h>
+#include <cyg/infra/diag.h>
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+#include <cyg/kernel/kapi.h>
+#endif
+
+#ifdef CYGPKG_IO_SERIAL_V85X_V850
+
+#include "v85x_v850_serial.h"
+
+typedef struct v850_serial_info {
+ CYG_ADDRWORD base;
+ CYG_WORD int_num;
+ cyg_interrupt serial_interrupt[3];
+ cyg_handle_t serial_interrupt_handle[3];
+ cyg_bool tx_busy;
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+ cyg_alarm tx_timeout;
+ cyg_handle_t tx_timeout_handle;
+#endif
+} v850_serial_info;
+
+static bool v850_serial_init(struct cyg_devtab_entry *tab);
+static bool v850_serial_putc(serial_channel *chan, unsigned char c);
+static Cyg_ErrNo v850_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name);
+static unsigned char v850_serial_getc(serial_channel *chan);
+static Cyg_ErrNo v850_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len);
+static void v850_serial_start_xmit(serial_channel *chan);
+static void v850_serial_stop_xmit(serial_channel *chan);
+
+static cyg_uint32 v850_serial_ISR(cyg_vector_t vector, cyg_addrword_t data);
+static void v850_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data);
+
+static SERIAL_FUNS(v850_serial_funs,
+ v850_serial_putc,
+ v850_serial_getc,
+ v850_serial_set_config,
+ v850_serial_start_xmit,
+ v850_serial_stop_xmit
+ );
+
+#ifdef CYGPKG_IO_SERIAL_V85X_V850_SERIAL0
+static v850_serial_info v850_serial_info0 = {V850_REG_ASIM0,
+ CYGNUM_HAL_VECTOR_INTSER0};
+#if CYGNUM_IO_SERIAL_V85X_V850_SERIAL0_BUFSIZE > 0
+static unsigned char v850_serial_out_buf0[CYGNUM_IO_SERIAL_V85X_V850_SERIAL0_BUFSIZE];
+static unsigned char v850_serial_in_buf0[CYGNUM_IO_SERIAL_V85X_V850_SERIAL0_BUFSIZE];
+
+static SERIAL_CHANNEL_USING_INTERRUPTS(v850_serial_channel0,
+ v850_serial_funs,
+ v850_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_V85X_V850_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT,
+ &v850_serial_out_buf0[0], sizeof(v850_serial_out_buf0),
+ &v850_serial_in_buf0[0], sizeof(v850_serial_in_buf0)
+ );
+#else
+static SERIAL_CHANNEL(v850_serial_channel0,
+ v850_serial_funs,
+ v850_serial_info0,
+ CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_V85X_V850_SERIAL0_BAUD),
+ CYG_SERIAL_STOP_DEFAULT,
+ CYG_SERIAL_PARITY_DEFAULT,
+ CYG_SERIAL_WORD_LENGTH_DEFAULT,
+ CYG_SERIAL_FLAGS_DEFAULT
+ );
+#endif
+
+DEVTAB_ENTRY(v850_serial_io0,
+ CYGDAT_IO_SERIAL_V85X_V850_SERIAL0_NAME,
+ 0, // Does not depend on a lower level interface
+ &cyg_io_serial_devio,
+ v850_serial_init,
+ v850_serial_lookup, // Serial driver may need initializing
+ &v850_serial_channel0
+ );
+#endif // CYGPKG_IO_SERIAL_V85X_V850_SERIAL0
+
+// Internal function to actually configure the hardware to desired baud rate, etc.
+static bool
+v850_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
+{
+ v850_serial_info *v850_chan = (v850_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)v850_chan->base;
+ unsigned char parity = select_parity[new_config->parity];
+ unsigned char word_length = select_word_length[new_config->word_length-CYGNUM_SERIAL_WORD_LENGTH_5];
+ unsigned char stop_bits = select_stop_bits[new_config->stop];
+ int divisor, count;
+
+ if ((select_baud[new_config->baud].count == 0) ||
+ (word_length == 0xFF) ||
+ (parity == 0xFF) ||
+ (stop_bits == 0xFF)) {
+ return false; // Unsupported configuration
+ }
+ port->asim = ASIM_TxRx_Tx | ASIM_TxRx_Rx | parity | word_length | stop_bits;
+ count = select_baud[new_config->baud].count;
+ divisor = select_baud[new_config->baud].divisor;
+
+ while (count > 0xFF) {
+ count >>= 1;
+ divisor++;
+ }
+
+ port->brgc = count;
+
+ port->brgm = divisor & 0x07;
+#if CYGINT_HAL_V850_VARIANT_SB1
+ port->brgm1 = divisor >> 3;
+#endif
+
+ if (new_config != &chan->config) {
+ chan->config = *new_config;
+ }
+ return true;
+}
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+//
+// The serial ports on the V850 are incredibly stupid. There is no
+// interface status register which can tell you if it is possible to
+// read or write a character! The only way to discern this is by using
+// interrupts [or at least an interrupt register and polling it]. Thus
+// the serial transmit code has a problem in that it will be required by
+// upper layers to "send until full". The only way to decide "not full" is
+// that an interrupt has happened. If the serial driver is being mixed
+// with diagnostic I/O, then serial transmit interrupts will possibly be
+// lost.
+//
+// This code attempts to compenstate by using a kernel alarm to reset the
+// "device is busy" flag after some timeout. The timeout period will be
+// sufficiently long so as to not interfere with normal interrupt handling.
+//
+static void
+v850_serial_tx_timeout(cyg_handle_t alarm, cyg_addrword_t p)
+{
+ v850_serial_info *v850_chan = (v850_serial_info *)p;
+ v850_chan->tx_busy = false;
+}
+#endif
+
+// Function to initialize the device. Called at bootstrap time.
+static bool
+v850_serial_init(struct cyg_devtab_entry *tab)
+{
+ int i;
+ serial_channel *chan = (serial_channel *)tab->priv;
+ v850_serial_info *v850_chan = (v850_serial_info *)chan->dev_priv;
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+ cyg_handle_t h;
+#endif
+#ifdef CYGDBG_IO_INIT
+ diag_printf("V850 SERIAL init - dev: %x.%d\n", v850_chan->base, v850_chan->int_num);
+#endif
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ if (chan->out_cbuf.len != 0) {
+ for (i = 0; i < 3; i++) {
+ cyg_drv_interrupt_create(v850_chan->int_num+i,
+ 99, // Priority - unused
+ (cyg_addrword_t)chan, // Data item passed to interrupt handler
+ v850_serial_ISR,
+ v850_serial_DSR,
+ &v850_chan->serial_interrupt_handle[i],
+ &v850_chan->serial_interrupt[i]);
+ cyg_drv_interrupt_attach(v850_chan->serial_interrupt_handle[i]);
+ cyg_drv_interrupt_unmask(v850_chan->int_num+i);
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+ cyg_clock_to_counter(cyg_real_time_clock(), &h);
+ cyg_alarm_create(h, v850_serial_tx_timeout, (cyg_addrword_t)v850_chan,
+ &v850_chan->tx_timeout_handle, &v850_chan->tx_timeout);
+#endif
+ }
+ }
+ v850_chan->tx_busy = false;
+ return v850_serial_config_port(chan, &chan->config, true);
+}
+
+// This routine is called when the device is "looked" up (i.e. attached)
+static Cyg_ErrNo
+v850_serial_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *sub_tab,
+ const char *name)
+{
+ serial_channel *chan = (serial_channel *)(*tab)->priv;
+ (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
+ return ENOERR;
+}
+
+// Send a character to the device output buffer.
+// Return 'true' if character is sent to device
+static bool
+v850_serial_putc(serial_channel *chan, unsigned char c)
+{
+ v850_serial_info *v850_chan = (v850_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)v850_chan->base;
+ if (!v850_chan->tx_busy) {
+ v850_chan->tx_busy = true;
+ port->txs = c;
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+ cyg_alarm_initialize(v850_chan->tx_timeout_handle, cyg_current_time()+10, 0);
+#endif
+ return true;
+ } else {
+ return false; // Couldn't send, tx was busy
+ }
+}
+
+// Fetch a character from the device input buffer, waiting if necessary
+static unsigned char
+v850_serial_getc(serial_channel *chan)
+{
+ v850_serial_info *v850_chan = (v850_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)v850_chan->base;
+ return port->rxs;
+}
+
+// Set up the device characteristics; baud rate, etc.
+static Cyg_ErrNo
+v850_serial_set_config(serial_channel *chan, cyg_uint32 key,
+ const void *xbuf, cyg_uint32 *len)
+{
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SERIAL_INFO:
+ {
+ cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
+ if ( *len < sizeof(cyg_serial_info_t) ) {
+ return -EINVAL;
+ }
+ *len = sizeof(cyg_serial_info_t);
+ if ( true != v850_serial_config_port(chan, config, false) )
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// Enable the transmitter on the device
+static void
+v850_serial_start_xmit(serial_channel *chan)
+{
+ v850_serial_info *v850_chan = (v850_serial_info *)chan->dev_priv;
+ (chan->callbacks->xmt_char)(chan); // Kick transmitter (if necessary)
+ cyg_drv_interrupt_unmask(v850_chan->int_num+INT_Tx); // Enable Tx interrupt
+}
+
+// Disable the transmitter on the device
+static void
+v850_serial_stop_xmit(serial_channel *chan)
+{
+ v850_serial_info *v850_chan = (v850_serial_info *)chan->dev_priv;
+ cyg_drv_interrupt_mask(v850_chan->int_num+INT_Tx); // Disable Tx interrupt
+}
+
+// Serial I/O - low level interrupt handler (ISR)
+static cyg_uint32
+v850_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+ return CYG_ISR_CALL_DSR; // Cause DSR to be run
+}
+
+// Serial I/O - high level interrupt handler (DSR)
+static void
+v850_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ serial_channel *chan = (serial_channel *)data;
+ v850_serial_info *v850_chan = (v850_serial_info *)chan->dev_priv;
+ volatile struct serial_port *port = (volatile struct serial_port *)v850_chan->base;
+ switch (vector-(v850_chan->int_num)) {
+ case INT_ERR:
+ case INT_Rx:
+ (chan->callbacks->rcv_char)(chan, port->rxs);
+ break;
+ case INT_Tx:
+ v850_chan->tx_busy = false;
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+ cyg_alarm_initialize(v850_chan->tx_timeout_handle, 0, 0);
+#endif
+ (chan->callbacks->xmt_char)(chan);
+ break;
+ }
+ cyg_drv_interrupt_unmask(vector);
+}
+#endif
+
+// EOF v85x_v850_serial.c
diff --git a/ecos/packages/devs/serial/v85x/v850/current/src/v85x_v850_serial.h b/ecos/packages/devs/serial/v85x/v850/current/src/v85x_v850_serial.h
new file mode 100644
index 0000000..9ad39c7
--- /dev/null
+++ b/ecos/packages/devs/serial/v85x/v850/current/src/v85x_v850_serial.h
@@ -0,0 +1,164 @@
+#ifndef CYGONCE_V85X_V850_SERIAL_H
+#define CYGONCE_V85X_V850_SERIAL_H
+
+// ====================================================================
+//
+// v850_ceb_serial.h
+//
+// Device I/O - Description of NEC V850 serial hardware
+//
+// ====================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas,jlarmour
+// Date: 2001-03-21
+// Purpose: Internal interfaces for serial I/O drivers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Description of serial ports on NEC V850/SA1 & SB1
+
+#include <pkgconf/system.h>
+#include CYGBLD_HAL_TARGET_H
+
+#include <cyg/hal/v850_common.h>
+
+struct serial_port {
+ unsigned char asim; // Serial interface mode
+ unsigned char _filler0;
+ unsigned char asis; // Serial interface status
+ unsigned char _filler1;
+ unsigned char brgc; // Baud rate control
+ unsigned char _filler2;
+ unsigned char txs; // Transmit shift register
+ unsigned char _filler3;
+ unsigned char rxs; // Receive shift register
+ unsigned char _filler4[5];
+ unsigned char brgm; // Baud rate mode
+ unsigned char _filler5;
+#if CYGINT_HAL_V850_VARIANT_SB1
+ unsigned char _filler6[0x10];
+ unsigned char brgm1; // Baud rate overflow
+#endif
+};
+
+// Relative interrupt numbers
+#define INT_ERR 0 // Receive error condition
+#define INT_Rx 1 // Receive data
+#define INT_Tx 2 // Transmit data
+
+// Serial interface mode
+#define ASIM_TxRx_MASK (3<<6) // Receive & Transmit enables
+#define ASIM_TxRx_Rx (1<<6) // Receive enable
+#define ASIM_TxRx_Tx (2<<6) // Transmit enable
+#define ASIM_Parity_MASK (3<<4) // Parity mode bits
+#define ASIM_Parity_none (0<<4) // No parity
+#define ASIM_Parity_space (1<<4) // Send zero bit, ignore errors
+#define ASIM_Parity_odd (2<<4) // Odd parity
+#define ASIM_Parity_even (3<<4) // Even parity
+#define ASIM_Length_MASK (1<<3) // Character length select
+#define ASIM_Length_7 (0<<3) // 7 bit chars
+#define ASIM_Length_8 (1<<3) // 8 bit chars
+#define ASIM_Stop_MASK (1<<2) // Stop bit select
+#define ASIM_Stop_1 (0<<2) // 1 stop bit
+#define ASIM_Stop_2 (1<<2) // 2 stop bits
+#define ASIM_Error_MASK (1<<1) // Receive error select
+#define ASIM_Error_enable (0<<1) // Issue interrupt on receive error
+#define ASIM_Error_disable (1<<1) // No interrupts on receive error
+
+// Serial interface status (errors only)
+#define ASIS_OVE (1<<0) // Overrun error
+#define ASIS_FE (1<<1) // Framing error
+#define ASIS_PE (1<<2) // Parity error
+
+static unsigned char select_word_length[] = {
+ 0xFF, // 5 bits / word (char)
+ 0xFF,
+ ASIM_Length_7,
+ ASIM_Length_8
+};
+
+static unsigned char select_stop_bits[] = {
+ 0,
+ ASIM_Stop_1, // 1 stop bit
+ 0xFF, // 1.5 stop bit
+ ASIM_Stop_2 // 2 stop bits
+};
+
+static unsigned char select_parity[] = {
+ ASIM_Parity_none, // No parity
+ ASIM_Parity_even, // Even parity
+ ASIM_Parity_odd, // Odd parity
+ 0xFF, // Mark parity
+ ASIM_Parity_space, // Space parity
+};
+
+static struct v850_baud {
+ unsigned int count;
+ unsigned int divisor;
+} select_baud[] = {
+// Baud rate values, using defined system clock
+#define BAUDCOUNT(X) ((CYGHWR_HAL_V85X_CPU_FREQ/2)/(X))
+ {0, 0}, // Unused
+ {0, 0}, // 50
+ {0, 0}, // 75
+ {0, 0}, // 110
+ {0, 0}, // 134.5
+ {0, 0}, // 150
+ {0, 0}, // 200
+ {0, 0}, // 300
+ {0, 0}, // 600
+ {BAUDCOUNT(1200), 1}, // 1200
+ {0, 0}, // 1800
+ {BAUDCOUNT(2400), 1}, // 2400
+ {0, 0}, // 3600
+ {BAUDCOUNT(4800), 1}, // 4800
+ {0, 0}, // 7200
+ {BAUDCOUNT(9600), 1}, // 9600
+ {0, 0}, // 14400
+ {BAUDCOUNT(19200), 1}, // 19200
+ {BAUDCOUNT(38400), 1}, // 38400
+ {0, 0}, // 57600
+ {0, 0}, // 115200
+ {0, 0}, // 230400
+};
+
+#endif // CYGONCE_V85X_V850_SERIAL_H
+
+// EOF v85x_v850_serial.h
diff --git a/ecos/packages/devs/spi/arm/at91/current/ChangeLog b/ecos/packages/devs/spi/arm/at91/current/ChangeLog
new file mode 100644
index 0000000..23cfb31
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/at91/current/ChangeLog
@@ -0,0 +1,113 @@
+2009-04-02 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/spi_at91.cdl: Fix typographical error for
+ CYGINT_DEVS_SPI_ARM_AT91_HAS_BUS1. [ Bugzilla 1000737 ]
+
+2009-02-16 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/spi_at91.c (cyg_spi_at91_bus_init): Partially revert change of
+ 2009-02-11. Define an empty CYGBLD_ATTRIB_C_INIT_PRI and rely on
+ spi_at91_init.cxx to call, in case the compiler does not supply
+ that macro (e.g. if too old).
+ * cdl/spi_at91.cdl: Revert change of 2009-02-11.
+ * src/spi_at91_init.cxx: Revive. Set priority to CYG_INIT_BUS_SPI.
+ Conditionalise on CYGBLD_ATTRIB_C_INIT_PRI.
+
+2009-02-12 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/spi_at91.cdl: Add a requires for CYGPKG_ERROR.
+
+2009-02-11 Bart Veer <bartv@ecoscentric.com>
+
+ * src/spi_at91.c (cyg_spi_at91_bus_init): turn into a prioritized
+ constructor, make it a static and rename.
+
+ * cdl/spi_at91.cdl: remove src/spi_at91_init.cxx
+
+ * src/spi_at91_init.cxx: removed, no longer needed.
+
+2008-10-19 Igor B. Poretsky <poretsky@mlbox.ru>
+
+ * src/spi_at91.c: Typo fixes from var_io.h. Correctly calculate
+ the board rate. Before it was two times too fast.
+
+2006-09-27 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/spi_at91.c (spi_at91_transaction_begin): Don't use #ifdef
+ inside a macro invocation. The compiler throws a wobbly.
+
+2006-09-07 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * src/spi_at91.c: Fixed the chip select functions.
+ Changed the Mode Register setup as to disable the Mode Failure
+ Detaction for variants that support it. The Mode Failure Detection
+ breaks because NPCS0 is not connected, we are using GPIO, and is
+ thus floating.
+
+2006-06-01 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * src/spi_at91.c:
+ * cdl/spi_at91.cdl:
+ * include/spi_at91.h: Generalize so that multiple SPI
+ busses can be driven.
+
+2006-05-19 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/spi_at91.c: Use the AT91 GPIO/PIO macros to aid
+ portability between different AT91 device.
+
+2004-11-11 Sebastian Block <sebastianblock@gmx.net>
+
+ * src/spi_at91.c: Fixed negation of the chip select signal when
+ not using a 4 to 16 decoder
+
+2004-10-13 Savin Zlobec <savin@elatec.si>
+
+ * src/spi_at91.c: Fixed a typo in spi_at91_transfer reported by
+ Nicolas Brouard.
+
+2004-08-31 Savin Zlobec <savin@elatec.si>
+
+ * include/spi_at91.h:
+ * src/spi_at91.c:
+ Moved SPI registers and bits defines to HAL headers, added support
+ for 4 to 16 decoder of chip select signals, support for transfers
+ larger than 2^16 and per device configurable delay between two
+ transfers.
+ * cdl/spi_at91.cdl:
+ Added option to enable support for 4 to 16 decoder of chip select
+ signals.
+
+2004-08-27 Savin Zlobec <savin@elatec.si>
+
+ * cdl/spi_at91.cdl:
+ * include/spi_at91.h:
+ * src/spi_at91.c:
+ * src/spi_at91_init.cxx:
+ Atmel AT91 SPI bus driver implementation.
+
+
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/spi/arm/at91/current/cdl/spi_at91.cdl b/ecos/packages/devs/spi/arm/at91/current/cdl/spi_at91.cdl
new file mode 100644
index 0000000..e366daf
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/at91/current/cdl/spi_at91.cdl
@@ -0,0 +1,225 @@
+# ====================================================================
+#
+# spi_at91.cdl
+#
+# Atmel AT91 (ARM) SPI driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Savin Zlobec <savin@elatec.si>
+# Date: 2004-08-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_SPI_ARM_AT91 {
+ parent CYGPKG_IO_SPI
+ active_if CYGPKG_IO_SPI
+ display "Atmel AT91 SPI driver"
+ requires CYGPKG_HAL_ARM_AT91
+ requires CYGPKG_ERROR
+ hardware
+ include_dir cyg/io
+ compile spi_at91.c
+ compile -library=libextras.a spi_at91_init.cxx
+
+ cdl_option CYGHWR_DEVS_SPI_ARM_AT91_BUS0 {
+ display "Enable support for SPI bus 0"
+ flavor bool
+ default_value 1
+ description "Enable this option to add support for the first
+ SPI peripheral. The most AT91 devices only have one bus"
+ }
+
+ cdl_interface CYGINT_DEVS_SPI_ARM_AT91_HAS_BUS1 {
+ description "
+ This interface is implemented by HALs for devices which have
+ the second SPI bus controller."
+ }
+
+
+ cdl_option CYGHWR_DEVS_SPI_ARM_AT91_BUS1 {
+ active_if CYGINT_DEVS_SPI_ARM_AT91_HAS_BUS1
+ display "Enable support for SPI bus 1"
+ flavor bool
+ default_value 0
+ description "Enable this option to add support for the second
+ SPI peripheral. The most AT91 devices only have one bus"
+ }
+
+ cdl_component CYGPKG_DEVS_SPI_ARM_AT91_BUS0_CFG {
+ active_if CYGHWR_DEVS_SPI_ARM_AT91_BUS0
+ display "Configuration options for SPI Bus 0"
+ flavor none
+ description "This is the configuration options for SPI Bus 0"
+
+ cdl_option CYGHWR_DEVS_SPI_ARM_AT91_BUS0_PCSDEC {
+ display "Support 4 to 16 decoder of chip select signals."
+ flavor bool
+ default_value 0
+ description "Enable this option if SPI peripheral chip
+ selects are connected through an 4 to 16 decoder."
+ }
+
+ cdl_option CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS0 {
+ display "PIO-Pin used for NPSC0"
+ flavor data
+ default_value {"AT91_SPI_NPCS0"}
+ description "Any GPIO pin is able to be used as the SPI driver
+ uses GPIO to control the chip selects. Specify the pin
+ as \"AT91_GPIO_PA13\" or \"AT91_GPIO_PB5\" etc. Specify
+ \"NONE\" if this chip select is to be disabled"
+ }
+
+ cdl_option CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS1 {
+ display "PIO-Pin used for NPSC1"
+ flavor data
+ default_value {"AT91_SPI_NPCS1"}
+ description "Any GPIO pin is able to be used as the SPI driver
+ uses GPIO to control the chip selects. Specify the pin
+ as \"AT91_GPIO_PA13\" or \"AT91_GPIO_PB5\" etc. Specify
+ \"NONE\" if this chip select is to be disabled"
+ }
+ cdl_option CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS2 {
+ display "PIO-Pin used for NPSC2"
+ flavor data
+ default_value {"AT91_SPI_NPCS2"}
+ description "Any GPIO pin is able to be used as the SPI driver
+ uses GPIO to control the chip selects. Specify the pin
+ as \"AT91_GPIO_PA13\" or \"AT91_GPIO_PB5\" etc. Specify
+ \"NONE\" if this chip select is to be disabled"
+ }
+ cdl_option CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS3 {
+ display "PIO-Pin used for NPSC3"
+ flavor data
+ default_value {"AT91_SPI_NPCS3"}
+ description "Any GPIO pin is able to be used as the SPI driver
+ uses GPIO to control the chip selects. Specify the pin
+ as \"AT91_GPIO_PA13\" or \"AT91_GPIO_PB5\" etc. Specify
+ \"NONE\" if this chip select is to be disabled"
+ }
+
+ }
+
+ cdl_component CYGPKG_DEVS_SPI_ARM_AT91_BUS1_CFG {
+ active_if CYGHWR_DEVS_SPI_ARM_AT91_BUS1
+ display "Configuration options for SPI Bus 1"
+ flavor none
+ description "This is the configuration options for SPI Bus 1"
+
+ cdl_option CYGHWR_DEVS_SPI_ARM_AT91_BUS1_PCSDEC {
+ display "Support 4 to 16 decoder of chip select signals."
+ flavor bool
+ default_value 0
+ description "Enable this option if SPI peripheral chip
+ selects are connected through an 4 to 16 decoder."
+ }
+
+ cdl_option CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS0 {
+ display "PIO-Pin used for NPSC0"
+ flavor data
+ default_value {"AT91_SPI1_NPCS0"}
+ description "Any GPIO pin is able to be used as the SPI driver
+ uses GPIO to control the chip selects. Specify the pin
+ as \"AT91_GPIO_PA13\" or \"AT91_GPIO_PB5\" etc. Specify
+ \"NONE\" if this chip select is to be disabled"
+ }
+
+ cdl_option CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS1 {
+ display "PIO-Pin used for NPSC1"
+ flavor data
+ default_value {"AT91_SPI1_NPCS1"}
+ description "Any GPIO pin is able to be used as the SPI driver
+ uses GPIO to control the chip selects. Specify the pin
+ as \"AT91_GPIO_PA13\" or \"AT91_GPIO_PB5\" etc. Specify
+ \"NONE\" if this chip select is to be disabled"
+ }
+ cdl_option CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS2 {
+ display "PIO-Pin used for NPSC2"
+ flavor data
+ default_value {"AT91_SPI1_NPCS2"}
+ description "Any GPIO pin is able to be used as the SPI driver
+ uses GPIO to control the chip selects. Specify the pin
+ as \"AT91_GPIO_PA13\" or \"AT91_GPIO_PB5\" etc. Specify
+ \"NONE\" if this chip select is to be disabled"
+ }
+ cdl_option CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS3 {
+ display "PIO-Pin used for NPSC3"
+ flavor data
+ default_value {"AT91_SPI1_NPCS3"}
+ description "Any GPIO pin is able to be used as the SPI driver
+ uses GPIO to control the chip selects. Specify the pin
+ as \"AT91_GPIO_PA13\" or \"AT91_GPIO_PB5\" etc. Specify
+ \"NONE\" if this chip select is to be disabled"
+ }
+
+ }
+
+
+ cdl_component CYGPKG_DEVS_SPI_ARM_AT91_OPTIONS {
+ display "Atmel AT91 SPI driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_DEVS_SPI_ARM_AT91_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the SPI device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_SPI_ARM_AT91_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the SPI device. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF spi_at91.cdl
diff --git a/ecos/packages/devs/spi/arm/at91/current/include/spi_at91.h b/ecos/packages/devs/spi/arm/at91/current/include/spi_at91.h
new file mode 100644
index 0000000..e64f63c
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/at91/current/include/spi_at91.h
@@ -0,0 +1,121 @@
+#ifndef CYGONCE_DEVS_SPI_ARM_AT91_H
+#define CYGONCE_DEVS_SPI_ARM_AT91_H
+//==========================================================================
+//
+// spi_at91.h
+//
+// Atmel AT91 (ARM) SPI driver defines
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Savin Zlobec <savin@elatec.si>
+// Date: 2004-08-25
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+
+//-----------------------------------------------------------------------------
+// AT91 SPI BUS
+
+typedef struct cyg_spi_at91_bus_s
+{
+ // ---- Upper layer data ----
+
+ cyg_spi_bus spi_bus; // Upper layer SPI bus data
+
+ // ---- Lower layer data ----
+
+ cyg_interrupt spi_interrupt; // SPI interrupt object
+ cyg_handle_t spi_interrupt_handle; // SPI interrupt handle
+ cyg_drv_mutex_t transfer_mx; // Transfer mutex
+ cyg_drv_cond_t transfer_cond; // Transfer condition
+ cyg_bool transfer_end; // Transfer end flag
+ cyg_bool cs_up; // Chip Select up flag
+ cyg_vector_t interrupt_number; // SPI Interrupt Number
+ cyg_addrword_t base; // Base Address of the SPI peripheral
+ cyg_uint8 cs_en[4]; // The Configurations state for the CS
+ cyg_uint32 cs_gpio[4]; // The GPIO Configurations for the CS
+} cyg_spi_at91_bus_t;
+
+//-----------------------------------------------------------------------------
+// AT91 SPI DEVICE
+
+typedef struct cyg_spi_at91_device_s
+{
+ // ---- Upper layer data ----
+
+ cyg_spi_device spi_device; // Upper layer SPI device data
+
+ // ---- Lower layer data (configurable) ----
+
+ cyg_uint8 dev_num; // Device number
+ cyg_uint8 cl_pol; // Clock polarity (0 or 1)
+ cyg_uint8 cl_pha; // Clock phase (0 or 1)
+ cyg_uint32 cl_brate; // Clock baud rate
+ cyg_uint16 cs_up_udly; // Delay in us between CS up and transfer start
+ cyg_uint16 cs_dw_udly; // Delay in us between transfer end and CS down
+ cyg_uint16 tr_bt_udly; // Delay in us between two transfers
+
+ // ---- Lower layer data (internal) ----
+
+ cyg_bool init; // Is device initialized
+ cyg_uint8 cl_scbr; // Value of SCBR (SPI clock) reg field
+ cyg_uint8 cl_div32; // Divide SPI master clock by 32
+} cyg_spi_at91_device_t;
+
+//-----------------------------------------------------------------------------
+// AT91 SPI exported busses
+
+/* For backwards compatability */
+#define cyg_spi_at91_bus cyg_spi_at91_bus0
+
+externC cyg_spi_at91_bus_t cyg_spi_at91_bus0;
+externC cyg_spi_at91_bus_t cyg_spi_at91_bus1;
+
+//-----------------------------------------------------------------------------
+
+#endif // CYGONCE_DEVS_SPI_ARM_AT91_H
+
+//-----------------------------------------------------------------------------
+// End of spi_at91.h
diff --git a/ecos/packages/devs/spi/arm/at91/current/src/spi_at91.c b/ecos/packages/devs/spi/arm/at91/current/src/spi_at91.c
new file mode 100644
index 0000000..a64bec8
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/at91/current/src/spi_at91.c
@@ -0,0 +1,707 @@
+//==========================================================================
+//
+// spi_at91.c
+//
+// Atmel AT91 (ARM) SPI driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Savin Zlobec <savin@elatec.si>
+// Date: 2004-08-25
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+#include <pkgconf/devs_spi_arm_at91.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/spi_at91.h>
+#include <cyg/error/codes.h>
+
+// -------------------------------------------------------------------------
+static void spi_at91_init_bus(cyg_spi_at91_bus_t * bus);
+
+static cyg_uint32 spi_at91_ISR(cyg_vector_t vector, cyg_addrword_t data);
+
+static void spi_at91_DSR(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+
+static void spi_at91_transaction_begin(cyg_spi_device *dev);
+
+static void spi_at91_transaction_transfer(cyg_spi_device *dev,
+ cyg_bool polled,
+ cyg_uint32 count,
+ const cyg_uint8 *tx_data,
+ cyg_uint8 *rx_data,
+ cyg_bool drop_cs);
+
+static void spi_at91_transaction_tick(cyg_spi_device *dev,
+ cyg_bool polled,
+ cyg_uint32 count);
+
+static void spi_at91_transaction_end(cyg_spi_device* dev);
+
+static int spi_at91_get_config(cyg_spi_device *dev,
+ cyg_uint32 key,
+ void *buf,
+ cyg_uint32 *len);
+
+static int spi_at91_set_config(cyg_spi_device *dev,
+ cyg_uint32 key,
+ const void *buf,
+ cyg_uint32 *len);
+
+// -------------------------------------------------------------------------
+// AT91 SPI BUS
+
+#ifdef CYGHWR_DEVS_SPI_ARM_AT91_BUS0
+cyg_spi_at91_bus_t cyg_spi_at91_bus0 = {
+ .spi_bus.spi_transaction_begin = spi_at91_transaction_begin,
+ .spi_bus.spi_transaction_transfer = spi_at91_transaction_transfer,
+ .spi_bus.spi_transaction_tick = spi_at91_transaction_tick,
+ .spi_bus.spi_transaction_end = spi_at91_transaction_end,
+ .spi_bus.spi_get_config = spi_at91_get_config,
+ .spi_bus.spi_set_config = spi_at91_set_config,
+ .interrupt_number = CYGNUM_HAL_INTERRUPT_SPI,
+ .base = AT91_SPI,
+#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS0_NONE
+ .cs_en[0] = true,
+ .cs_gpio[0] = CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS0,
+#else
+ .cs_en[0] = false,
+#endif
+#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS1_NONE
+ .cs_en[1] = true,
+ .cs_gpio[1] = CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS1,
+#else
+ .cs_en[1] = false,
+#endif
+#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS2_NONE
+ .cs_en[2] = true,
+ .cs_gpio[2] = CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS2,
+#else
+ .cs_en[2] = false,
+#endif
+#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS3_NONE
+ .cs_en[3] = true,
+ .cs_gpio[3] = CYGDAT_DEVS_SPI_ARM_AT91_BUS0_NPCS3,
+#else
+ .cs_en[3] = false,
+#endif
+};
+
+CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_at91_device_t, 0);
+#endif
+#ifdef CYGHWR_DEVS_SPI_ARM_AT91_BUS1
+cyg_spi_at91_bus_t cyg_spi_at91_bus1 = {
+ .spi_bus.spi_transaction_begin = spi_at91_transaction_begin,
+ .spi_bus.spi_transaction_transfer = spi_at91_transaction_transfer,
+ .spi_bus.spi_transaction_tick = spi_at91_transaction_tick,
+ .spi_bus.spi_transaction_end = spi_at91_transaction_end,
+ .spi_bus.spi_get_config = spi_at91_get_config,
+ .spi_bus.spi_set_config = spi_at91_set_config,
+ .interrupt_number = CYGNUM_HAL_INTERRUPT_SPI1,
+ .base = AT91_SPI1,
+#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS0_NONE
+ .cs_en[0] = true,
+ .cs_gpio[0] = CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS0,
+#else
+ .cs_en[0] = false,
+#endif
+#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS1_NONE
+ .cs_en[1] = true,
+ .cs_gpio[1] = CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS1,
+#else
+ .cs_en[1] = false,
+#endif
+#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS2_NONE
+ .cs_en[2] = true,
+ .cs_gpio[2] = CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS2,
+#else
+ .cs_en[2] = false,
+#endif
+#ifndef CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS3_NONE
+ .cs_en[3] = true,
+ .cs_gpio[3] = CYGDAT_DEVS_SPI_ARM_AT91_BUS1_NPCS3,
+#else
+ .cs_en[3] = false,
+#endif
+};
+
+CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_at91_device_t, 1);
+#endif
+// -------------------------------------------------------------------------
+
+// If C constructor with init priority functionality is not in compiler,
+// rely on spi_at91_init.cxx to init us.
+#ifndef CYGBLD_ATTRIB_C_INIT_PRI
+# define CYGBLD_ATTRIB_C_INIT_PRI(x)
+#endif
+
+void CYGBLD_ATTRIB_C_INIT_PRI(CYG_INIT_BUS_SPI)
+cyg_spi_at91_bus_init(void)
+{
+
+#ifdef CYGHWR_DEVS_SPI_ARM_AT91_BUS0
+ // NOTE: here we let the SPI controller control
+ // the data in, out and clock signals, but
+ // we need to handle the chip selects manually
+ // in order to achieve better chip select control
+ // in between transactions.
+
+ // Put SPI MISO, MOSI and SPCK pins into peripheral mode
+ HAL_ARM_AT91_PIO_CFG(AT91_SPI_SPCK);
+ HAL_ARM_AT91_PIO_CFG(AT91_SPI_MISO);
+ HAL_ARM_AT91_PIO_CFG(AT91_SPI_MOSI);
+ spi_at91_init_bus(&cyg_spi_at91_bus0);
+#endif
+#ifdef CYGHWR_DEVS_SPI_ARM_AT91_BUS1
+ // NOTE: here we let the SPI controller control
+ // the data in, out and clock signals, but
+ // we need to handle the chip selects manually
+ // in order to achieve better chip select control
+ // in between transactions.
+
+ // Put SPI MISO, MOSI and SPCK pins into peripheral mode
+ HAL_ARM_AT91_PIO_CFG(AT91_SPI1_SPCK);
+ HAL_ARM_AT91_PIO_CFG(AT91_SPI1_MISO);
+ HAL_ARM_AT91_PIO_CFG(AT91_SPI1_MOSI);
+ spi_at91_init_bus(&cyg_spi_at91_bus1);
+#endif
+}
+
+// -------------------------------------------------------------------------
+
+static void spi_at91_init_bus(cyg_spi_at91_bus_t * spi_bus)
+{
+ cyg_uint32 ctr;
+ // Create and attach SPI interrupt object
+ cyg_drv_interrupt_create(spi_bus->interrupt_number,
+ 4,
+ (cyg_addrword_t)spi_bus,
+ spi_at91_ISR,
+ spi_at91_DSR,
+ &spi_bus->spi_interrupt_handle,
+ &spi_bus->spi_interrupt);
+
+ cyg_drv_interrupt_attach(spi_bus->spi_interrupt_handle);
+
+ // Init transfer mutex and condition
+ cyg_drv_mutex_init(&spi_bus->transfer_mx);
+ cyg_drv_cond_init(&spi_bus->transfer_cond,
+ &spi_bus->transfer_mx);
+
+ // Init flags
+ spi_bus->transfer_end = true;
+ spi_bus->cs_up = false;
+
+ // Soft reset the SPI controller
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_CR, AT91_SPI_CR_SWRST);
+
+ // Configure SPI pins
+
+
+ // Put SPI chip select pins in IO output mode
+ for(ctr = 0;ctr<4;ctr++)
+ {
+ if(spi_bus->cs_en[ctr])
+ {
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(spi_bus->cs_gpio[ctr],AT91_PIN_OUT);
+ HAL_ARM_AT91_GPIO_SET(spi_bus->cs_gpio[ctr]);
+ }
+ }
+ // Call upper layer bus init
+ CYG_SPI_BUS_COMMON_INIT(&spi_bus->spi_bus);
+}
+
+static cyg_uint32
+spi_at91_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_uint32 stat;
+ cyg_spi_at91_bus_t * spi_bus = (cyg_spi_at91_bus_t *)data;
+ // Read the status register and disable
+ // the SPI int events that have occurred
+
+ HAL_READ_UINT32(spi_bus->base+AT91_SPI_SR, stat);
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_IDR, stat);
+
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+
+ return CYG_ISR_CALL_DSR;
+}
+
+static void
+spi_at91_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *) data;
+ cyg_uint32 stat;
+
+ // Read the status register and
+ // check for transfer completion
+
+ HAL_READ_UINT32(spi_bus->base+AT91_SPI_SR, stat);
+
+ if((stat & AT91_SPI_SR_ENDRX) && (stat & AT91_SPI_SR_ENDTX))
+ {
+ // Transfer ended
+ spi_bus->transfer_end = true;
+ cyg_drv_cond_signal(&spi_bus->transfer_cond);
+ }
+ else
+ {
+ // Transfer still in progress - unmask the SPI
+ // int so we can get more SPI int events
+ cyg_drv_interrupt_unmask(vector);
+ }
+}
+
+static cyg_bool
+spi_at91_calc_scbr(cyg_spi_at91_device_t *dev)
+{
+ cyg_uint32 scbr;
+ cyg_bool res = true;
+
+ // Calculate SCBR from baud rate
+
+ scbr = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / dev->cl_brate;
+ if ((2*(CYGNUM_HAL_ARM_AT91_CLOCK_SPEED % dev->cl_brate)) >= dev->cl_brate)
+ scbr++;
+
+ if (scbr < 2)
+ {
+ dev->cl_scbr = 2;
+ dev->cl_div32 = 0;
+ res = false;
+ }
+ else if (scbr > 255)
+ {
+ dev->cl_div32 = 1;
+
+ scbr = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED / (32*dev->cl_brate);
+
+ if (scbr < 2)
+ {
+ dev->cl_scbr = 2;
+ res = false;
+ }
+ else if (scbr > 255)
+ {
+ dev->cl_scbr = 255;
+ res = false;
+ }
+ else
+ dev->cl_scbr = (cyg_uint8)scbr;
+ }
+ else
+ {
+ dev->cl_scbr = (cyg_uint8)scbr;
+ dev->cl_div32 = 0;
+ }
+
+ return res;
+}
+
+static void
+spi_at91_set_npcs(cyg_spi_at91_bus_t *spi_bus,int val)
+{
+ cyg_uint32 ctr;
+ for(ctr=0;ctr<4;ctr++)
+ {
+ if(spi_bus->cs_en[ctr])
+ {
+ HAL_ARM_AT91_GPIO_PUT(spi_bus->cs_gpio[ctr], (val & (1<<ctr)));
+ }
+ }
+}
+
+static void
+spi_at91_start_transfer(cyg_spi_at91_device_t *dev)
+{
+ cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
+
+ if (spi_bus->cs_up)
+ return;
+
+ // Force minimal delay between two transfers - in case two transfers
+ // follow each other w/o delay, then we have to wait here in order for
+ // the peripheral device to detect cs transition from inactive to active.
+ CYGACC_CALL_IF_DELAY_US(dev->tr_bt_udly);
+
+ // Raise CS
+
+#ifdef CYGHWR_DEVS_SPI_ARM_AT91_PCSDEC
+ spi_at91_set_npcs(spi_bus,~dev->dev_num);
+#else
+ spi_at91_set_npcs(spi_bus,~(1<<dev->dev_num));
+#endif
+ CYGACC_CALL_IF_DELAY_US(dev->cs_up_udly);
+
+ spi_bus->cs_up = true;
+}
+
+static void
+spi_at91_drop_cs(cyg_spi_at91_device_t *dev)
+{
+ cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
+
+ if (!spi_bus->cs_up)
+ return;
+
+ // Drop CS
+
+ CYGACC_CALL_IF_DELAY_US(dev->cs_dw_udly);
+ spi_at91_set_npcs(spi_bus,0x0F);
+ spi_bus->cs_up = false;
+}
+
+static void
+spi_at91_transfer(cyg_spi_at91_device_t *dev,
+ cyg_uint32 count,
+ const cyg_uint8 *tx_data,
+ cyg_uint8 *rx_data)
+{
+ cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
+
+ // Since PDC transfer buffer counters are 16 bit long,
+ // we have to split longer transfers into chunks.
+ while (count > 0)
+ {
+ cyg_uint16 tr_count = count > 0xFFFF ? 0xFFFF : count;
+
+ // Set rx buf pointer and counter
+ if (NULL != rx_data)
+ {
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_RPR, (cyg_uint32)rx_data);
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_RCR, (cyg_uint32)tr_count);
+ }
+
+ // Set tx buf pointer and counter
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_TPR, (cyg_uint32)tx_data);
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_TCR, (cyg_uint32)tr_count);
+
+#ifdef AT91_SPI_PTCR
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_PTCR,
+ AT91_SPI_PTCR_RXTEN | AT91_SPI_PTCR_TXTEN);
+#endif
+ // Enable the SPI int events we are interested in
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_IER,
+ AT91_SPI_SR_ENDRX | AT91_SPI_SR_ENDTX);
+
+ cyg_drv_mutex_lock(&spi_bus->transfer_mx);
+ {
+ spi_bus->transfer_end = false;
+
+ // Unmask the SPI int
+ cyg_drv_interrupt_unmask(spi_bus->interrupt_number);
+
+ // Wait for its completion
+ cyg_drv_dsr_lock();
+ {
+ while (!spi_bus->transfer_end)
+ cyg_drv_cond_wait(&spi_bus->transfer_cond);
+ }
+ cyg_drv_dsr_unlock();
+ }
+ cyg_drv_mutex_unlock(&spi_bus->transfer_mx);
+
+ if (NULL == rx_data)
+ {
+ cyg_uint32 val;
+
+ // If rx buffer was NULL, then the PDC receiver data transfer
+ // was not started and we didn't wait for ENDRX, but only for
+ // ENDTX. Meaning that right now the last byte is being serialized
+ // over the line and when finished input data will appear in
+ // rx data reg. We have to wait for this to happen here, if we
+ // don't we'll get the last received byte as the first one in the
+ // next transfer!
+
+ // FIXME: is there any better way to do this?
+ // If not, then precalculate this value.
+ val = 8000000/dev->cl_brate;
+ CYGACC_CALL_IF_DELAY_US(val > 1 ? val : 1);
+
+ // Clear the rx data reg
+ HAL_READ_UINT32(spi_bus->base+AT91_SPI_RDR, val);
+ }
+
+ // Adjust running variables
+
+ if (NULL != rx_data)
+ rx_data += tr_count;
+ tx_data += tr_count;
+ count -= tr_count;
+ }
+}
+
+static void
+spi_at91_transfer_polled(cyg_spi_at91_device_t *dev,
+ cyg_uint32 count,
+ const cyg_uint8 *tx_data,
+ cyg_uint8 *rx_data)
+{
+ cyg_uint32 val;
+ cyg_spi_at91_bus_t *spi_bus = (cyg_spi_at91_bus_t *)dev->spi_device.spi_bus;
+
+ // Transmit and receive byte by byte
+ while (count-- > 0)
+ {
+ // Wait for transmit data register empty
+ do
+ {
+ HAL_READ_UINT32(spi_bus->base+AT91_SPI_SR, val);
+ } while ( !(val & AT91_SPI_SR_TDRE) );
+
+ // Send next byte over the wire
+ val = *tx_data++;
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_TDR, val);
+
+ // Wait for reveive data register full
+ do
+ {
+ HAL_READ_UINT32(spi_bus->base+AT91_SPI_SR, val);
+ } while ( !(val & AT91_SPI_SR_RDRF) );
+
+ // Store received byte
+ HAL_READ_UINT32(spi_bus->base+AT91_SPI_RDR, val);
+ if (NULL != rx_data)
+ *rx_data++ = val;
+ }
+}
+
+// -------------------------------------------------------------------------
+
+static void
+spi_at91_transaction_begin(cyg_spi_device *dev)
+{
+ cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
+ cyg_spi_at91_bus_t *spi_bus =
+ (cyg_spi_at91_bus_t *)at91_spi_dev->spi_device.spi_bus;
+ cyg_uint32 val;
+
+ if (!at91_spi_dev->init)
+ {
+ at91_spi_dev->init = true;
+ spi_at91_calc_scbr(at91_spi_dev);
+ }
+
+ // Configure SPI channel 0 - this is the only channel we
+ // use for all devices since we drive chip selects manually
+
+ val = AT91_SPI_CSR_BITS8;
+
+ if (1 == at91_spi_dev->cl_pol)
+ val |= AT91_SPI_CSR_CPOL;
+
+ if (1 == at91_spi_dev->cl_pha)
+ val |= AT91_SPI_CSR_NCPHA;
+
+ val |= AT91_SPI_CSR_SCBR(at91_spi_dev->cl_scbr);
+
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_CSR0, val);
+
+ // Enable SPI clock
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCER, 1<<spi_bus->interrupt_number);
+
+ // Enable the SPI controller
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_CR, AT91_SPI_CR_SPIEN);
+
+ /* As we are using this driver only in master mode with NPCS0
+ configured as GPIO instead of a peripheral pin, it is necessary
+ for the Mode Failure detection to be switched off as this will
+ cause havoc with the driver */
+
+ // Put SPI bus into master mode
+ if (1 == at91_spi_dev->cl_div32) {
+ val = AT91_SPI_MR_MSTR | AT91_SPI_MR_DIV32;
+#ifdef AT91_SPI_MR_MODFDIS
+ val |= AT91_SPI_MR_MODFDIS;
+#endif
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_MR, val);
+ } else {
+ val = AT91_SPI_MR_MSTR;
+#ifdef AT91_SPI_MR_MODFDIS
+ val |= AT91_SPI_MR_MODFDIS;
+#endif
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_MR, val);
+ }
+}
+
+static void
+spi_at91_transaction_transfer(cyg_spi_device *dev,
+ cyg_bool polled,
+ cyg_uint32 count,
+ const cyg_uint8 *tx_data,
+ cyg_uint8 *rx_data,
+ cyg_bool drop_cs)
+{
+ cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
+
+ // Select the device if not already selected
+ spi_at91_start_transfer(at91_spi_dev);
+
+ // Perform the transfer
+ if (polled)
+ spi_at91_transfer_polled(at91_spi_dev, count, tx_data, rx_data);
+ else
+ spi_at91_transfer(at91_spi_dev, count, tx_data, rx_data);
+
+ // Deselect the device if requested
+ if (drop_cs)
+ spi_at91_drop_cs(at91_spi_dev);
+}
+
+static void
+spi_at91_transaction_tick(cyg_spi_device *dev,
+ cyg_bool polled,
+ cyg_uint32 count)
+{
+ const cyg_uint32 zeros[10] = { 0,0,0,0,0,0,0,0,0,0 };
+
+ cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
+
+ // Transfer count zeros to the device - we don't touch the
+ // chip select, the device could be selected or deselected.
+ // It is up to the device driver to decide in wich state the
+ // device will be ticked.
+
+ while (count > 0)
+ {
+ int tcnt = count > 40 ? 40 : count;
+
+ if (polled)
+ spi_at91_transfer_polled(at91_spi_dev, tcnt,
+ (const cyg_uint8 *) zeros, NULL);
+ else
+ spi_at91_transfer(at91_spi_dev, tcnt,
+ (const cyg_uint8 *) zeros, NULL);
+
+ count -= tcnt;
+ }
+}
+
+static void
+spi_at91_transaction_end(cyg_spi_device* dev)
+{
+ cyg_spi_at91_device_t * at91_spi_dev = (cyg_spi_at91_device_t *)dev;
+ cyg_spi_at91_bus_t *spi_bus =
+ (cyg_spi_at91_bus_t *)at91_spi_dev->spi_device.spi_bus;
+
+ // Disable the SPI controller
+ HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_CR, AT91_SPI_CR_SPIDIS);
+
+ // Disable SPI clock
+ HAL_WRITE_UINT32(AT91_PMC+AT91_PMC_PCDR,1<<spi_bus->interrupt_number);
+
+ spi_at91_drop_cs((cyg_spi_at91_device_t *) dev);
+}
+
+static int
+spi_at91_get_config(cyg_spi_device *dev,
+ cyg_uint32 key,
+ void *buf,
+ cyg_uint32 *len)
+{
+ cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
+
+ switch (key)
+ {
+ case CYG_IO_GET_CONFIG_SPI_CLOCKRATE:
+ {
+ if (*len != sizeof(cyg_uint32))
+ return -EINVAL;
+ else
+ {
+ cyg_uint32 *cl_brate = (cyg_uint32 *)buf;
+ *cl_brate = at91_spi_dev->cl_brate;
+ }
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+static int
+spi_at91_set_config(cyg_spi_device *dev,
+ cyg_uint32 key,
+ const void *buf,
+ cyg_uint32 *len)
+{
+ cyg_spi_at91_device_t *at91_spi_dev = (cyg_spi_at91_device_t *) dev;
+
+ switch (key)
+ {
+ case CYG_IO_SET_CONFIG_SPI_CLOCKRATE:
+ {
+ if (*len != sizeof(cyg_uint32))
+ return -EINVAL;
+ else
+ {
+ cyg_uint32 cl_brate = *((cyg_uint32 *)buf);
+ cyg_uint32 old_cl_brate = at91_spi_dev->cl_brate;
+
+ at91_spi_dev->cl_brate = cl_brate;
+
+ if (!spi_at91_calc_scbr(at91_spi_dev))
+ {
+ at91_spi_dev->cl_brate = old_cl_brate;
+ spi_at91_calc_scbr(at91_spi_dev);
+ return -EINVAL;
+ }
+ }
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ENOERR;
+}
+
+// -------------------------------------------------------------------------
+// EOF spi_at91.c
diff --git a/ecos/packages/devs/spi/arm/at91/current/src/spi_at91_init.cxx b/ecos/packages/devs/spi/arm/at91/current/src/spi_at91_init.cxx
new file mode 100644
index 0000000..b8fc586
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/at91/current/src/spi_at91_init.cxx
@@ -0,0 +1,73 @@
+//==========================================================================
+//
+// spi_at91_init.cxx
+//
+// Atmel AT91 (ARM) SPI bus init
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Savin Zlobec <savin@elatec.si>
+// Date: 2004-08-25
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+// This file is not needed if we support CYGBLD_ATTRIB_C_INIT_PRI, as the
+// init happens directly in spi_at91.c then.
+#ifndef CYGBLD_ATTRIB_C_INIT_PRI
+
+// -------------------------------------------------------------------------
+
+externC void cyg_spi_at91_bus_init(void);
+
+class cyg_spi_at91_bus_init_class {
+public:
+ cyg_spi_at91_bus_init_class(void) {
+ cyg_spi_at91_bus_init();
+ }
+};
+
+// -------------------------------------------------------------------------
+
+static cyg_spi_at91_bus_init_class spi_at91_bus_init CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_BUS_SPI);
+
+#endif // ifndef CYGBLD_ATTRIB_C_INIT_PRI
+
+// -------------------------------------------------------------------------
+// EOF spi_at91_init.cxx
diff --git a/ecos/packages/devs/spi/arm/eb55/current/ChangeLog b/ecos/packages/devs/spi/arm/eb55/current/ChangeLog
new file mode 100644
index 0000000..bc7a855
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/eb55/current/ChangeLog
@@ -0,0 +1,50 @@
+2009-02-12 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/spi_eb55.c: Export static structure for dataflash SPI device
+ rather than pointer. The latter cannot be used in the initializer
+ for a dataflash flash driver.
+
+2006-06-01 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/spi_eb55.cdl: Updates needed for recent changes to AT91 SPI
+ driver.
+
+2004-08-31 Savin Zlobec <savin@elatec.si>
+
+ * cdl/spi_eb55.cdl:
+ Added a require for 4 to 16 decoder of chip select signals option.
+ * src/spi_eb55.c:
+ Defined time between two transfers.
+
+2004-08-27 Savin Zlobec <savin@elatec.si>
+
+ * cdl/spi_eb55.cdl:
+ * include/spi_eb55.h:
+ * src/spi_eb55.c:
+ Atmel AT91EB55 SPI devices.
+
+
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/spi/arm/eb55/current/cdl/spi_eb55.cdl b/ecos/packages/devs/spi/arm/eb55/current/cdl/spi_eb55.cdl
new file mode 100644
index 0000000..9a77825
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/eb55/current/cdl/spi_eb55.cdl
@@ -0,0 +1,97 @@
+# ====================================================================
+#
+# spi_eb55.cdl
+#
+# Atmel AT91EB55 SPI devices configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Savin Zlobec <savin@elatec.si>
+# Date: 2004-08-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_SPI_ARM_EB55 {
+ parent CYGPKG_IO_SPI
+ active_if CYGPKG_IO_SPI
+ active_if CYGPKG_DEVS_SPI_ARM_AT91
+ display "Atmel AT91EB55 SPI devices"
+ requires CYGHWR_DEVS_SPI_ARM_AT91_BUS0_PCSDEC
+ hardware
+ include_dir cyg/io
+ compile spi_eb55.c
+
+ define_proc {
+ puts $::cdl_system_header "/***** SPI exported devices begin *****/"
+ puts $::cdl_system_header "#include <cyg/io/spi_eb55.h>"
+ puts $::cdl_system_header "/***** SPI exported devices end *****/"
+ }
+
+ cdl_component CYGPKG_DEVS_SPI_ARM_EB55_OPTIONS {
+ display "Atmel AT91EB55 SPI devices build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_DEVS_SPI_ARM_EB55_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the SPI device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_SPI_ARM_EB55_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the SPI device. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF spi_eb55.cdl
diff --git a/ecos/packages/devs/spi/arm/eb55/current/include/spi_eb55.h b/ecos/packages/devs/spi/arm/eb55/current/include/spi_eb55.h
new file mode 100644
index 0000000..d5df99f
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/eb55/current/include/spi_eb55.h
@@ -0,0 +1,62 @@
+#ifndef CYGONCE_DEVS_SPI_ARM_EB55_H
+#define CYGONCE_DEVS_SPI_ARM_EB55_H
+//==========================================================================
+//
+// spi_eb55.h
+//
+// Atmel AT91EB55 SPI devices defines
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Savin Zlobec <savin@elatec.si>
+// Date: 2004-08-27
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+//-----------------------------------------------------------------------------
+// AT91EB55 SPI exported devices
+
+#define HAL_SPI_EXPORTED_DEVICES \
+ externC cyg_spi_device *cyg_spi_dataflash_dev0;
+
+//-----------------------------------------------------------------------------
+
+#endif // CYGONCE_DEVS_SPI_ARM_EB55_H
+
+//-----------------------------------------------------------------------------
+// End of spi_eb55.h
diff --git a/ecos/packages/devs/spi/arm/eb55/current/src/spi_eb55.c b/ecos/packages/devs/spi/arm/eb55/current/src/spi_eb55.c
new file mode 100644
index 0000000..81772b5
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/eb55/current/src/spi_eb55.c
@@ -0,0 +1,74 @@
+//==========================================================================
+//
+// spi_eb55.c
+//
+// Atmel AT91EB55 SPI devices
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Savin Zlobec <savin@elatec.si>
+// Date: 2004-08-27
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/spi_at91.h>
+
+// -------------------------------------------------------------------------
+// AT91EB55 SPI exported devices
+
+// AT45DB321B DataFlash
+cyg_spi_at91_device_t spi_dataflash_dev0 CYG_SPI_DEVICE_ON_BUS(0) =
+{
+ .spi_device.spi_bus = &cyg_spi_at91_bus.spi_bus,
+
+ .dev_num = 0, // Device number
+ .cl_pol = 1, // Clock polarity (0 or 1)
+ .cl_pha = 0, // Clock phase (0 or 1)
+ .cl_brate = 8192000, // Clock baud rate
+ .cs_up_udly = 1, // Delay in usec between CS up and transfer start
+ .cs_dw_udly = 1, // Delay in usec between transfer end and CS down
+ .tr_bt_udly = 1 // Delay in usec between two transfers
+};
+
+// -------------------------------------------------------------------------
+// EOF spi_eb55.c
diff --git a/ecos/packages/devs/spi/arm/lpc2xxx/current/ChangeLog b/ecos/packages/devs/spi/arm/lpc2xxx/current/ChangeLog
new file mode 100644
index 0000000..df50e0f
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/lpc2xxx/current/ChangeLog
@@ -0,0 +1,45 @@
+2009-02-18 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/spi_lpc2xxx.cdl: Fix my mistake in below change and make
+ CDL requires match option names.
+
+2009-02-17 Jonathan Larmour <jifl@eCosCentric.com>
+2009-01-27 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * cdl/spi_lpc2xxx.cdl: Ensure the SPI interrupts are using different
+ priorities: CYGNUM_IO_SPI_ARM_LPC2XXX_SPI{0,1}_INTPRIO entered.
+ * include/spi_lpc2xxx.h: cyg_spi_lpc2xxx_bus_t: spi_prio field added.
+ * src/spi_lpc2xxx.cxx: spi_lpc2xxx_set_config(): fixed copy & paste
+ typo, spi_lpc2xxx_init_bus(): added 'prio' argument to initializer.
+
+2009-02-10 Bart Veer <bartv@ecoscentric.com>
+
+ * src/spi_lpc2xxx.cxx: update init priority.
+
+2007-07-12 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+
+ * lpc2xxx: driver for on-chip SPI units
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/spi/arm/lpc2xxx/current/cdl/spi_lpc2xxx.cdl b/ecos/packages/devs/spi/arm/lpc2xxx/current/cdl/spi_lpc2xxx.cdl
new file mode 100644
index 0000000..b802c2b
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/lpc2xxx/current/cdl/spi_lpc2xxx.cdl
@@ -0,0 +1,103 @@
+# ====================================================================
+#
+# spi_lpc2xxx.cdl
+#
+# SPI driver for LPC2xxx
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 ,2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors:
+# Date: 2007-07-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_SPI_ARM_LPC2XXX {
+ display "LPC2xxx SPI driver"
+ requires CYGPKG_HAL_ARM_LPC2XXX
+
+ parent CYGPKG_IO_SPI
+ active_if CYGPKG_IO_SPI
+
+ include_dir cyg/io
+ compile spi_lpc2xxx.cxx
+
+ cdl_component CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0 {
+ display "Enable SPI interface 0"
+ flavor bool
+ default_value 1
+ description "The LPC2xxx controllers contain two SPI interfaces.
+ Enable this component to get support for SPI
+ interface 0."
+
+ cdl_option CYGNUM_IO_SPI_ARM_LPC2XXX_BUS0_INTPRIO {
+ display "Interrupt priority of the SPI bus 0 ISR"
+ flavor data
+ legal_values 0 to 15
+ default_value 12
+ requires { is_active(CYGNUM_IO_SPI_ARM_LPC2XXX_BUS1_INTPRIO)
+ implies (CYGNUM_IO_SPI_ARM_LPC2XXX_BUS0_INTPRIO !=
+ CYGNUM_IO_SPI_ARM_LPC2XXX_BUS1_INTPRIO)
+ }
+ description "
+ This option specifies the interrupt priority of the ISR of
+ the SPI bus 0 interrupt in the VIC. Slot 0 has the highest
+ priority and slot 15 the lowest."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1 {
+ display "Enable SPI interface 1"
+ flavor bool
+ default_value 1
+ description "The LPC2xxx controllers contain two SPI interfaces.
+ Enable this component to get support for SPI
+ interface 1."
+
+ cdl_option CYGNUM_IO_SPI_ARM_LPC2XXX_BUS1_INTPRIO {
+ display "Interrupt priority of the SPI bus 1 ISR"
+ flavor data
+ legal_values 0 to 15
+ default_value 13
+ description "
+ This option specifies the interrupt priority of the ISR of
+ the SPI bus 1 interrupt in the VIC. Slot 0 has the highest
+ priority and slot 15 the lowest."
+ }
+ }
+}
diff --git a/ecos/packages/devs/spi/arm/lpc2xxx/current/include/spi_lpc2xxx.h b/ecos/packages/devs/spi/arm/lpc2xxx/current/include/spi_lpc2xxx.h
new file mode 100644
index 0000000..17eee8e
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/lpc2xxx/current/include/spi_lpc2xxx.h
@@ -0,0 +1,108 @@
+#ifndef CYGONCE_DEVS_SPI_ARM_LPC2XXX_H
+#define CYGONCE_DEVS_SPI_ARM_LPC2XXX_H
+
+//==========================================================================
+//
+// spi_lpc2xxx.h
+//
+// SPI driver for LPC2xxx
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:
+// Date: 2007-07-12
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+#include <pkgconf/devs_spi_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+
+struct spi_dev {
+ volatile cyg_uint32 spcr;
+ volatile cyg_uint32 spsr;
+ volatile cyg_uint32 spdr;
+ volatile cyg_uint32 spccr;
+ cyg_uint32 d1, d2, d3;
+ volatile cyg_uint32 spint;
+};
+
+typedef struct {
+ cyg_spi_bus spi_bus;
+
+ cyg_interrupt spi_intr;
+ cyg_handle_t spi_hand;
+ cyg_vector_t spi_vect;
+ cyg_priority_t spi_prio;
+ cyg_drv_mutex_t spi_lock;
+ cyg_drv_cond_t spi_wait;
+
+ struct spi_dev *spi_dev;
+
+ volatile cyg_uint32 count;
+ volatile const cyg_uint8 *tx;
+ volatile cyg_uint8 *rx;
+} cyg_spi_lpc2xxx_bus_t;
+
+typedef struct {
+ cyg_spi_device spi_device;
+
+ cyg_uint8 spi_cpha;
+ cyg_uint8 spi_cpol;
+ cyg_uint8 spi_lsbf;
+ cyg_uint32 spi_baud;
+
+ void (*spi_cs)(int);
+} cyg_spi_lpc2xxx_dev_t;
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0
+externC cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus0;
+#endif
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1
+externC cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus1;
+#endif
+
+#endif
diff --git a/ecos/packages/devs/spi/arm/lpc2xxx/current/src/spi_lpc2xxx.cxx b/ecos/packages/devs/spi/arm/lpc2xxx/current/src/spi_lpc2xxx.cxx
new file mode 100644
index 0000000..e6cc9e1
--- /dev/null
+++ b/ecos/packages/devs/spi/arm/lpc2xxx/current/src/spi_lpc2xxx.cxx
@@ -0,0 +1,367 @@
+//==========================================================================
+//
+// spi_lpc2xxx.cxx
+//
+// SPI driver for LPC2xxx
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:
+// Date: 2007-07-12
+// Purpose:
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+#include <pkgconf/devs_spi_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/spi_lpc2xxx.h>
+#include <cyg/error/codes.h>
+
+#define SPI_SPCR_SPIE 0x80
+#define SPI_SPCR_LSBF 0x40
+#define SPI_SPCR_MSTR 0x20
+#define SPI_SPCR_CPOL 0x10
+#define SPI_SPCR_CPHA 0x08
+
+#define SPI_SPSR_SPIF 0x80
+#define SPI_SPSR_WCOL 0x40
+#define SPI_SPSR_ROVR 0x20
+#define SPI_SPSR_MODF 0x10
+#define SPI_SPSR_ABRT 0x08
+
+#define SPI_SPINT 0x01
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0
+cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus0;
+CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_lpc2xxx_dev_t, 0);
+#endif
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1
+cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus1;
+CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_lpc2xxx_dev_t, 1);
+#endif
+
+/*
+ * Interrupt routine
+ * read & write the next byte until count reaches zero
+ */
+static cyg_uint32
+spi_lpc2xxx_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+ cyg_spi_lpc2xxx_bus_t *bus = (cyg_spi_lpc2xxx_bus_t *) data;
+ cyg_uint8 tmp;
+
+ tmp = bus->spi_dev->spsr;
+
+ if(tmp & SPI_SPSR_MODF)
+ bus->spi_dev->spcr = bus->spi_dev->spcr | SPI_SPCR_MSTR;
+
+ tmp = bus->spi_dev->spdr;
+
+ if(bus->count) {
+ if(bus->rx)
+ *bus->rx++ = tmp;
+ if(--bus->count) {
+ bus->spi_dev->spint = SPI_SPINT;
+ bus->spi_dev->spdr = bus->tx ? *bus->tx++ : 0;
+ cyg_drv_interrupt_acknowledge(bus->spi_vect);
+ return CYG_ISR_HANDLED;
+ }
+ }
+
+ bus->count = 0;
+ bus->tx = NULL;
+ bus->rx = NULL;
+
+ bus->spi_dev->spint = SPI_SPINT;
+ cyg_drv_interrupt_acknowledge(bus->spi_vect);
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+
+static void
+spi_lpc2xxx_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_drv_cond_signal(&((cyg_spi_lpc2xxx_bus_t *) data)->spi_wait);
+}
+
+
+/*
+ * Configure bus for a specific baud rate
+ */
+static void
+spi_lpc2xxx_baud(cyg_spi_lpc2xxx_bus_t *bus, cyg_uint32 baud)
+{
+ cyg_uint32 ccr = 8;
+
+ if(baud) {
+ ccr = (CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED
+ / CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) / baud;
+ if(((CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED
+ / CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) / ccr) > baud)
+ ccr++;
+ ccr++;
+ ccr &= 0xfe;
+ }
+
+ bus->spi_dev->spccr = ccr < 8 ? 8 : ccr;
+}
+
+/*
+ * get/set configuration
+ */
+static int
+spi_lpc2xxx_get_config(cyg_spi_device *device, cyg_uint32 key, void *buf,
+ cyg_uint32 *len)
+{
+ cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+
+ switch(key) {
+ case CYG_IO_GET_CONFIG_SPI_CLOCKRATE:
+ if(*len == sizeof(cyg_uint32)) {
+ cyg_uint32 *b = (cyg_uint32 *) buf;
+ *b = dev->spi_baud;
+ } else return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ENOERR;
+}
+
+static int
+spi_lpc2xxx_set_config(cyg_spi_device *device, cyg_uint32 key, const void *buf,
+ cyg_uint32 *len)
+{
+ cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+
+ switch(key) {
+ case CYG_IO_SET_CONFIG_SPI_CLOCKRATE:
+ if(*len == sizeof(cyg_uint32)) {
+ dev->spi_baud = * (cyg_uint32 *) buf;
+ spi_lpc2xxx_baud((cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus,
+ dev->spi_baud);
+ }
+ else return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ENOERR;
+}
+
+
+/*
+ * Begin transaction
+ * configure bus for device and drive CS by calling device cs() function
+ */
+static void
+spi_lpc2xxx_begin(cyg_spi_device *device)
+{
+ cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+ cyg_spi_lpc2xxx_bus_t *bus =
+ (cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus;
+
+ cyg_uint8 cr =
+ (dev->spi_cpha ? SPI_SPCR_CPHA : 0) |
+ (dev->spi_cpol ? SPI_SPCR_CPOL : 0) |
+ (dev->spi_lsbf ? SPI_SPCR_LSBF : 0);
+
+ bus->spi_dev->spcr = SPI_SPCR_MSTR | cr;
+
+ spi_lpc2xxx_baud(bus, dev->spi_baud);
+
+ dev->spi_cs(1);
+}
+
+
+/*
+ * Transfer a buffer to a device,
+ * fill another buffer with data from the device
+ */
+static void
+spi_lpc2xxx_transfer(cyg_spi_device *device, cyg_bool polled, cyg_uint32 count,
+ const cyg_uint8 *tx_data, cyg_uint8 *rx_data,
+ cyg_bool drop_cs)
+{
+ cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+ cyg_spi_lpc2xxx_bus_t *bus =
+ (cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus;
+ cyg_uint8 tmp;
+
+ if(!count) return;
+
+ if(!polled) {
+ bus->count = count;
+ bus->tx = tx_data;
+ bus->rx = rx_data;
+
+ bus->spi_dev->spcr |= SPI_SPCR_SPIE;
+ bus->spi_dev->spdr = bus->tx ? *bus->tx++ : 0;
+
+ cyg_drv_mutex_lock(&bus->spi_lock);
+ cyg_drv_dsr_lock();
+ cyg_drv_interrupt_unmask(bus->spi_vect);
+ while(bus->count)
+ cyg_drv_cond_wait(&bus->spi_wait);
+ cyg_drv_interrupt_mask(bus->spi_vect);
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&bus->spi_lock);
+ } else do {
+ bus->spi_dev->spdr = tx_data ? *tx_data++ : 0;
+ while(!(bus->spi_dev->spsr & SPI_SPSR_SPIF));
+ tmp = bus->spi_dev->spdr;
+ if(rx_data)
+ *rx_data++ = tmp;
+ count--;
+ } while(count);
+
+ if(drop_cs)
+ dev->spi_cs(0);
+
+ return;
+}
+
+
+/*
+ * Tick
+ */
+static void
+spi_lpc2xxx_tick(cyg_spi_device *device, cyg_bool polled, cyg_uint32 count)
+{
+ spi_lpc2xxx_transfer(device, polled, count, NULL, NULL, false);
+}
+
+
+/*
+ * End transaction
+ * disable SPI bus, drop CS, reset transfer variables
+ */
+static void
+spi_lpc2xxx_end(cyg_spi_device *device)
+{
+ cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+ cyg_spi_lpc2xxx_bus_t *bus =
+ (cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus;
+
+ bus->spi_dev->spcr = 0;
+ dev->spi_cs(0);
+
+ bus->count = 0;
+ bus->tx = NULL;
+ bus->rx = NULL;
+}
+
+
+/*
+ * Driver & bus initialization
+ */
+static void
+spi_lpc2xxx_init_bus(cyg_spi_lpc2xxx_bus_t *bus,
+ cyg_addrword_t dev,
+ cyg_vector_t vec,
+ cyg_priority_t prio)
+{
+ bus->spi_bus.spi_transaction_begin = spi_lpc2xxx_begin;
+ bus->spi_bus.spi_transaction_transfer = spi_lpc2xxx_transfer;
+ bus->spi_bus.spi_transaction_tick = spi_lpc2xxx_tick;
+ bus->spi_bus.spi_transaction_end = spi_lpc2xxx_end;
+ bus->spi_bus.spi_get_config = spi_lpc2xxx_get_config;
+ bus->spi_bus.spi_set_config = spi_lpc2xxx_set_config;
+ CYG_SPI_BUS_COMMON_INIT(&bus->spi_bus);
+
+ cyg_drv_mutex_init(&bus->spi_lock);
+ cyg_drv_cond_init(&bus->spi_wait, &bus->spi_lock);
+
+ bus->spi_dev = (struct spi_dev *) dev;
+ bus->spi_vect = vec;
+ bus->spi_prio = prio;
+ cyg_drv_interrupt_create(
+ vec, prio, (cyg_addrword_t) bus,
+ &spi_lpc2xxx_isr, &spi_lpc2xxx_dsr,
+ &bus->spi_hand, &bus->spi_intr);
+ cyg_drv_interrupt_attach(bus->spi_hand);
+}
+
+/*
+ * initialization class
+ */
+class cyg_spi_lpc2xxx_init_class {
+public:
+ cyg_spi_lpc2xxx_init_class(void) {
+ cyg_uint32 addr, tmp;
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0
+ addr = (CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+ + CYGARC_HAL_LPC2XXX_REG_PINSEL0);
+ HAL_READ_UINT32(addr, tmp);
+ tmp |= 0x5500;
+ HAL_WRITE_UINT32(addr, tmp);
+
+ spi_lpc2xxx_init_bus(&cyg_spi_lpc2xxx_bus0,
+ CYGARC_HAL_LPC2XXX_REG_SPI0_BASE,
+ CYGNUM_HAL_INTERRUPT_SPI0,
+ CYGNUM_IO_SPI_ARM_LPC2XXX_BUS0_INTPRIO);
+#endif
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1
+ addr = (CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+ + CYGARC_HAL_LPC2XXX_REG_PINSEL1);
+ HAL_READ_UINT32(addr, tmp);
+ tmp |= 0x2a8;
+ HAL_WRITE_UINT32(addr, tmp);
+ spi_lpc2xxx_init_bus(&cyg_spi_lpc2xxx_bus1,
+ CYGARC_HAL_LPC2XXX_REG_SPI1_BASE,
+ CYGNUM_HAL_INTERRUPT_SPI1,
+ CYGNUM_IO_SPI_ARM_LPC2XXX_BUS1_INTPRIO);
+#endif
+ }
+};
+
+static cyg_spi_lpc2xxx_init_class spi_lpc2xxx_init
+ CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_BUS_SPI);
+
diff --git a/ecos/packages/devs/spi/cortexm/a2fxxx/current/ChangeLog b/ecos/packages/devs/spi/cortexm/a2fxxx/current/ChangeLog
new file mode 100644
index 0000000..80da248
--- /dev/null
+++ b/ecos/packages/devs/spi/cortexm/a2fxxx/current/ChangeLog
@@ -0,0 +1,35 @@
+2012-01-04 Christophe Coutand <ecos@hotmail.co.uk>
+ * src/spi_a2fxxx.c:
+ Fix compiler warning, used uninitialized variable in a2fxxx_spi_set_ss().
+
+2011-04-13 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * cdl/spi_a2fxxx.cdl:
+ * include/spi_a2fxxx.h:
+ * src/spi_a2fxxx.c:
+ New package -- Smartfusion Cortex-M3 SPI driver package.
+ [Bugzilla 1001291]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/spi/cortexm/a2fxxx/current/cdl/spi_a2fxxx.cdl b/ecos/packages/devs/spi/cortexm/a2fxxx/current/cdl/spi_a2fxxx.cdl
new file mode 100644
index 0000000..8d16000
--- /dev/null
+++ b/ecos/packages/devs/spi/cortexm/a2fxxx/current/cdl/spi_a2fxxx.cdl
@@ -0,0 +1,175 @@
+##=============================================================================
+##
+## spi_a2fxxx.cdl
+##
+## Smartfusion Cortex-M3 SPI driver configuration options.
+##
+##=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): ccoutand, updated for Smartfusion Cortex-M3
+## Original(s): Chris Holgate
+## Date: 2011-04-25
+## Purpose: Configure Smartfusion Cortex-M3 SPI driver.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+cdl_package CYGPKG_DEVS_SPI_CORTEXM_A2FXXX {
+ display "Actel Smartfusion SPI driver"
+ description "
+ This package provides SPI driver support for the Smartfusion Cortex-M3
+ series of microcontrollers.
+ "
+ parent CYGPKG_IO_SPI
+ active_if CYGPKG_IO_SPI
+ requires CYGPKG_HAL_CORTEXM_A2FXXX
+ hardware
+ include_dir cyg/io
+ compile -library=libextras.a spi_a2fxxx.c
+
+ cdl_option CYGDBG_DEVS_SPI_CORTEXM_A2FXXX_TRACE {
+ display "Display status messages during SPI operations"
+ flavor bool
+ default_value 0
+ description "
+ Selecting this option will cause the SPI driver to print status
+ messages as various SPI operations are undertaken."
+ }
+
+ cdl_component CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS1 {
+ display "Actel Smartfusion SPI bus 1"
+ description "
+ Enable SPI bus 1 on the A2FXXX device.
+ "
+ flavor bool
+ default_value false
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS1_TX_DMA {
+ display "Transmit DMA channel number"
+ flavor data
+ default_value 0
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS1_RX_DMA {
+ display "Receive DMA channel number"
+ flavor data
+ default_value 1
+ }
+
+ cdl_option CYGDAT_DEVS_SPI_CORTEXM_A2FXXX_BUS1_TX_DMA_PRI {
+ display "Transmit DMA channel priority"
+ legal_values { "HIGH" "LOW" }
+ flavor data
+ default_value { "HIGH" }
+ }
+
+ cdl_option CYGDAT_DEVS_SPI_CORTEXM_A2FXXX_BUS1_RX_DMA_PRI {
+ display "Receive DMA channel priority"
+ legal_values { "HIGH" "LOW" }
+ flavor data
+ default_value { "HIGH" }
+ }
+ }
+
+ cdl_component CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS2 {
+ display "Actel Smartfusion SPI bus 2"
+ description "
+ Enable SPI bus 2 on the A2FXXX device.
+ "
+ flavor bool
+ default_value false
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS2_TX_DMA {
+ display "Transmit DMA channel number"
+ flavor data
+ default_value 2
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS2_RX_DMA {
+ display "Receive DMA channel number"
+ flavor data
+ default_value 3
+ }
+
+ cdl_option CYGDAT_DEVS_SPI_CORTEXM_A2FXXX_BUS2_TX_DMA_PRI {
+ display "Transmit DMA channel priority"
+ legal_values { "HIGH" "LOW" }
+ flavor data
+ default_value { "HIGH" }
+ }
+
+ cdl_option CYGDAT_DEVS_SPI_CORTEXM_A2FXXX_BUS2_RX_DMA_PRI {
+ display "Receive DMA channel priority"
+ legal_values { "HIGH" "LOW" }
+ flavor data
+ default_value { "HIGH" }
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_SPI_CORTEXM_A2FXXX_OPTIONS {
+ display "Actel Smartfusion SPI driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_DEVS_SPI_CORTEXM_A2FXXX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the A2FXXX SPI driver. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_SPI_CORTEXM_A2FXXX_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the A2FXXX SPI driver. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+
+}
+# EOF spi_a2fxxx.cdl
diff --git a/ecos/packages/devs/spi/cortexm/a2fxxx/current/include/spi_a2fxxx.h b/ecos/packages/devs/spi/cortexm/a2fxxx/current/include/spi_a2fxxx.h
new file mode 100644
index 0000000..a871b9a
--- /dev/null
+++ b/ecos/packages/devs/spi/cortexm/a2fxxx/current/include/spi_a2fxxx.h
@@ -0,0 +1,195 @@
+#ifndef CYGONCE_DEVS_SPI_CORTEXM_STM32_H
+# define CYGONCE_DEVS_SPI_CORTEXM_STM32_H
+//=============================================================================
+//
+// spi_a2fxxx.h
+//
+// Header definitions for Smartfusion Cortex-M3 SPI driver.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand, updated for Smartfusion Cortex-M3
+// Original(s): Chris Holgate
+// Date: 2011-04-25
+// Purpose: Smartfusion Cortex-M3 SPI driver definitions.
+// Description:
+// Usage: #include <cyg/io/spi_a2fxxx.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+# include <pkgconf/hal.h>
+# include <pkgconf/io_spi.h>
+# include <pkgconf/devs_spi_cortexm_a2fxxx.h>
+
+# include <cyg/infra/cyg_type.h>
+# include <cyg/hal/drv_api.h>
+# include <cyg/io/spi.h>
+
+__externC cyg_uint32 a2fxxx_dma_ch_attach(cyg_uint8, cyg_ISR_t *, cyg_DSR_t *,
+ cyg_addrword_t);
+
+typedef enum a2fxxx_spi_mode {
+ A2FXXX_SPI_MOTOROLA = 0x00,
+ A2FXXX_SPI_TI_SYNC_SERIAL = 0x01,
+ A2FXXX_SPI_NS_MICROWIRE = 0x02
+} a2fxxx_spi_mode;
+
+//-----------------------------------------------------------------------------
+// Macro for defining a SPI device and attaching it to the appropriate bus.
+//
+// _name_ is the name of the SPI device. This will be used to reference a
+// data structure of type cyg_spi_device which can be passed to the
+// SPI driver API without needing a cast.
+// _bus_ is the bus number to which this device is attached (1, 2 or 3).
+// _csnum_ when _csgpio_ is set to false : is the chip select line used for
+// this device, numbered from 0.
+// when _csgpio_ is set to true : is the GPIO number used to drive the
+// device chip select line.
+// _csgpio_ when set to false, the device chip select line is controlled by the
+// SPI controller.
+// when set to true, the device chip select line is a GPIO of the processor
+// control by the SPI driver.
+// _proto_ is the SPI bus protocol:
+// 0 -> Motorola SPI Protocol (_clpol_ and _clpha_ are valid in this mode)
+// 1 -> National Semiconductor MICROWIRE Protocol
+// 2 -> Texas Instruments (TI) Synchronous Serial Protocol
+// _clpol_ is the SPI bus clock polarity used by the device. This must be
+// set to 1 if a clock line pullup resistor is used and 0 if a
+// clock line pulldown resistor is used.
+// _clpha_ is the SPI bus clock phase used by the device.
+// _brate_ is the SPI bus clock baud rate used by the device, measured in Hz.
+// _csup_dly_ is the minimum delay between chip select assert and transfer
+// start, measured in microseconds.
+// _csdw_dly_ is the minimum delay between transfer end and chip select deassert,
+// measured in microseconds.
+// _trbt_dly_ is the minimum delay between consecutive transfers.
+
+# define CYG_DEVS_SPI_CORTEXM_A2FXXX_DEVICE( \
+ _name_, _bus_, _csnum_, _csgpio_, _proto_, _clpol_, _clpha_, _brate_, _csup_dly_, _csdw_dly_, _trbt_dly_\
+) \
+cyg_spi_cortexm_a2fxxx_device_t _name_ ##_a2fxxx CYG_SPI_DEVICE_ON_BUS(_bus_) = { \
+{ .spi_bus = (cyg_spi_bus*) &cyg_spi_a2fxxx_bus## _bus_ }, \
+ .dev_num = _csnum_, \
+ .cs_gpio = _csgpio_, \
+ .cs_gpio_n = _csnum_, \
+ .proto = _proto_, \
+ .cl_pol = _clpol_, \
+ .cl_pha = _clpha_, \
+ .cl_brate = _brate_, \
+ .cs_up_udly = _csup_dly_, \
+ .cs_dw_udly = _csdw_dly_, \
+ .tr_bt_udly = _trbt_dly_, \
+ .spi_cr_val = 0, \
+}; \
+extern cyg_spi_device _name_ __attribute__((alias ( #_name_ "_a2fxxx" )));
+
+//-----------------------------------------------------------------------------
+// A2FXXX SPI bus configuration and state.
+
+typedef struct cyg_spi_cortexm_a2fxxx_bus_setup_s {
+ cyg_uint32 apb_freq; // Peripheral bus frequency (fp).
+ cyg_haladdress spi_reg_base; // Base address of SPI register block.
+ cyg_haladdress dma_reg_base; // Base address of DMA register block.
+ cyg_uint8 dma_tx_channel; // TX DMA channel for this bus.
+ cyg_uint8 dma_rx_channel; // RX DMA channel for this bus.
+ cyg_uint8 cs_gpio_num; // Number of chip selects for this bus.
+ const cyg_uint8 *cs_gpio_list; // List of GPIOs used as chip selects.
+ const cyg_uint8 *spi_gpio_list; // List of GPIOs used by the SPI interface.
+ cyg_bool dma_tx_pri; // Priority for DMA transmit.
+ cyg_bool dma_rx_pri; // Priority for DMA receive.
+ cyg_haladdress *rx_dma_null;
+ cyg_haladdress *tx_dma_null;
+} cyg_spi_cortexm_a2fxxx_bus_setup_t;
+
+typedef struct cyg_spi_cortexm_a2fxxx_bus_s {
+ // ---- Upper layer data ----
+ cyg_spi_bus spi_bus; // Upper layer SPI bus data.
+
+ // ---- Bus configuration constants ----
+ const cyg_spi_cortexm_a2fxxx_bus_setup_t *setup;
+
+ // ---- Driver state (private) ----
+ cyg_interrupt tx_intr_data; // DMA interrupt data (TX).
+ cyg_interrupt rx_intr_data; // DMA interrupt data (RX).
+ cyg_handle_t tx_intr_handle; // DMA interrupt handle (TX).
+ cyg_handle_t rx_intr_handle; // DMA interrupt handle (RX).
+ cyg_drv_mutex_t mutex; // Transfer mutex.
+ cyg_drv_cond_t condvar; // Transfer condition variable.
+ cyg_bool tx_dma_done; // Flags used to signal completion.
+ cyg_bool rx_dma_done; // Flags used to signal completion.
+ cyg_bool cs_up; // Chip select asserted flag.
+
+} cyg_spi_cortexm_a2fxxx_bus_t;
+
+//-----------------------------------------------------------------------------
+// A2FXXX SPI device.
+
+typedef struct cyg_spi_cortexm_a2fxxx_device_s {
+ // ---- Upper layer data ----
+ cyg_spi_device spi_device; // Upper layer SPI device data.
+
+ // ---- Device setup (user configurable) ----
+ cyg_uint8 dev_num; // Device number.
+ a2fxxx_spi_mode proto; // Protocol
+ cyg_bool cs_gpio; // True = use GPIO to control CS line
+ cyg_uint32 cs_gpio_n; // GPIO #
+ cyg_uint8 cl_pol; // Clock polarity (0 or 1).
+ cyg_uint8 cl_pha; // Clock phase (0 or 1).
+ cyg_uint32 cl_brate; // Clock baud rate.
+ cyg_uint16 cs_up_udly; // Minimum delay in us between CS up and transfer start.
+ cyg_uint16 cs_dw_udly; // Minimum delay in us between transfer end and CS down.
+ cyg_uint16 tr_bt_udly; // Minimum delay in us between two transfers.
+
+ // ---- Device state (private) ----
+ cyg_uint32 spi_cr_val; // SPI configuration register (initialised to 0).
+
+} cyg_spi_cortexm_a2fxxx_device_t;
+
+//-----------------------------------------------------------------------------
+// Exported bus data structures.
+
+# ifdef CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS1
+externC cyg_spi_cortexm_a2fxxx_bus_t cyg_spi_a2fxxx_bus1;
+# endif
+
+# ifdef CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS2
+externC cyg_spi_cortexm_a2fxxx_bus_t cyg_spi_a2fxxx_bus2;
+# endif
+
+//=============================================================================
+#endif // CYGONCE_DEVS_SPI_CORTEXM_A2FXXX_H
diff --git a/ecos/packages/devs/spi/cortexm/a2fxxx/current/src/spi_a2fxxx.c b/ecos/packages/devs/spi/cortexm/a2fxxx/current/src/spi_a2fxxx.c
new file mode 100644
index 0000000..3459fdc
--- /dev/null
+++ b/ecos/packages/devs/spi/cortexm/a2fxxx/current/src/spi_a2fxxx.c
@@ -0,0 +1,638 @@
+//=============================================================================
+//
+// spi_a2fxxx.c
+//
+// SPI driver implementation for Smartfusion Cortex-M3
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ccoutand, updated for Smartfusion Cortex-M3
+// Original(s): Chris Holgate
+// Date: 2011-04-25
+// Purpose: Smartfusion Cortex-M3 SPI driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/spi.h>
+#include <cyg/io/spi_a2fxxx.h>
+
+#include <pkgconf/devs_spi_cortexm_a2fxxx.h>
+
+#include <string.h>
+
+#if defined(CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS1) || \
+ defined(CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS2)
+
+#ifdef CYGDBG_DEVS_SPI_CORTEXM_A2FXXX_TRACE
+# define SPI_TRACE(args...) diag_printf(args)
+#else
+# define SPI_TRACE(args...)
+#endif
+
+//-----------------------------------------------------------------------------
+// API function call forward references.
+
+static void a2fxxx_transaction_begin (cyg_spi_device*);
+static void a2fxxx_transaction_transfer (cyg_spi_device*, cyg_bool, cyg_uint32, const cyg_uint8*, cyg_uint8*, cyg_bool);
+static void a2fxxx_transaction_tick (cyg_spi_device*, cyg_bool, cyg_uint32);
+static void a2fxxx_transaction_end (cyg_spi_device*);
+static int a2fxxx_get_config (cyg_spi_device*, cyg_uint32, void*, cyg_uint32*);
+static int a2fxxx_set_config (cyg_spi_device*, cyg_uint32, const void*, cyg_uint32*);
+
+//-----------------------------------------------------------------------------
+// Instantiate the bus state data structures.
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS1
+
+static cyg_haladdress rx1_dma_null = 0x0;
+static cyg_haladdress tx1_dma_null = 0x0;
+
+static const cyg_spi_cortexm_a2fxxx_bus_setup_t bus1_setup = {
+ .spi_reg_base = CYGHWR_HAL_A2FXXX_SPI0,
+ .dma_reg_base = CYGHWR_HAL_A2FXXX_DMA,
+ .dma_tx_channel = CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS1_TX_DMA,
+ .dma_rx_channel = CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS1_RX_DMA,
+#ifdef CYGDAT_DEVS_SPI_CORTEXM_A2FXXX_BUS1_TX_DMA_PRI_HIGH
+ .dma_tx_pri = true,
+#else
+ .dma_tx_pri = false,
+#endif
+#ifdef CYGDAT_DEVS_SPI_CORTEXM_A2FXXX_BUS1_RX_DMA_PRI_HIGH
+ .dma_rx_pri = true,
+#else
+ .dma_rx_pri = false,
+#endif
+ .rx_dma_null = &rx1_dma_null,
+ .tx_dma_null = &tx1_dma_null,
+};
+
+cyg_spi_cortexm_a2fxxx_bus_t cyg_spi_a2fxxx_bus1 = {
+ .spi_bus.spi_transaction_begin = a2fxxx_transaction_begin,
+ .spi_bus.spi_transaction_transfer = a2fxxx_transaction_transfer,
+ .spi_bus.spi_transaction_tick = a2fxxx_transaction_tick,
+ .spi_bus.spi_transaction_end = a2fxxx_transaction_end,
+ .spi_bus.spi_get_config = a2fxxx_get_config,
+ .spi_bus.spi_set_config = a2fxxx_set_config,
+ .setup = &bus1_setup,
+ .cs_up = false
+};
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS2
+
+static cyg_haladdress rx2_dma_null = 0x0;
+static cyg_haladdress tx2_dma_null = 0x0;
+
+static const cyg_spi_cortexm_a2fxxx_bus_setup_t bus2_setup = {
+ .spi_reg_base = CYGHWR_HAL_A2FXXX_SPI1,
+ .dma_reg_base = CYGHWR_HAL_A2FXXX_DMA,
+ .dma_tx_channel = CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS2_TX_DMA,
+ .dma_rx_channel = CYGNUM_DEVS_SPI_CORTEXM_A2FXXX_BUS2_RX_DMA,
+#ifdef CYGDAT_DEVS_SPI_CORTEXM_A2FXXX_BUS2_TX_DMA_PRI_HIGH
+ .dma_tx_pri = true,
+#else
+ .dma_tx_pri = false,
+#endif
+#ifdef CYGDAT_DEVS_SPI_CORTEXM_A2FXXX_BUS2_RX_DMA_PRI_HIGH
+ .dma_rx_pri = true,
+#else
+ .dma_rx_pri = false,
+#endif
+ .rx_dma_null = &rx2_dma_null,
+ .tx_dma_null = &tx2_dma_null,
+};
+
+cyg_spi_cortexm_a2fxxx_bus_t cyg_spi_a2fxxx_bus2 = {
+ .spi_bus.spi_transaction_begin = a2fxxx_transaction_begin,
+ .spi_bus.spi_transaction_transfer = a2fxxx_transaction_transfer,
+ .spi_bus.spi_transaction_tick = a2fxxx_transaction_tick,
+ .spi_bus.spi_transaction_end = a2fxxx_transaction_end,
+ .spi_bus.spi_get_config = a2fxxx_get_config,
+ .spi_bus.spi_set_config = a2fxxx_set_config,
+ .setup = &bus2_setup,
+ .cs_up = false
+};
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Implement DMA ISRs. These clear the DMA channel interrupts and
+// schedule their respective DSRs.
+
+static cyg_uint32 a2fxxx_tx_ISR
+ (cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_spi_cortexm_a2fxxx_bus_t* a2fxxx_bus =
+ (cyg_spi_cortexm_a2fxxx_bus_t*) data;
+ cyg_uint8 chan = a2fxxx_bus->setup->dma_tx_channel;
+ SPI_TRACE("SPI : Handle TX ISR\n");
+ a2fxxx_dma_clear_interrupt ( chan );
+ return (CYG_ISR_CALL_DSR | CYG_ISR_HANDLED);
+}
+
+static cyg_uint32 a2fxxx_rx_ISR
+ (cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_spi_cortexm_a2fxxx_bus_t* a2fxxx_bus =
+ (cyg_spi_cortexm_a2fxxx_bus_t*) data;
+ cyg_uint8 chan = a2fxxx_bus->setup->dma_rx_channel;
+ SPI_TRACE("SPI : Handle RX ISR\n");
+ a2fxxx_dma_clear_interrupt ( chan );
+ return (CYG_ISR_CALL_DSR | CYG_ISR_HANDLED);
+}
+
+//-----------------------------------------------------------------------------
+// Implement DMA DSRs. These clear down the interrupt conditions and assert
+// their respective 'transaction complete' flags.
+
+static void a2fxxx_tx_DSR
+ (cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_spi_cortexm_a2fxxx_bus_t* a2fxxx_bus =
+ (cyg_spi_cortexm_a2fxxx_bus_t*) data;
+ SPI_TRACE("SPI : Handle TX DSR\n");
+ cyg_drv_dsr_lock ();
+ a2fxxx_bus->tx_dma_done = true;
+ cyg_drv_cond_signal (&a2fxxx_bus->condvar);
+ cyg_drv_dsr_unlock ();
+}
+
+static void a2fxxx_rx_DSR
+ (cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_spi_cortexm_a2fxxx_bus_t* a2fxxx_bus =
+ (cyg_spi_cortexm_a2fxxx_bus_t*) data;
+ SPI_TRACE("SPI : Handle RX DSR\n");
+ cyg_drv_dsr_lock ();
+ a2fxxx_bus->rx_dma_done = true;
+ cyg_drv_cond_signal (&a2fxxx_bus->condvar);
+ cyg_drv_dsr_unlock ();
+}
+
+//-----------------------------------------------------------------------------
+// Set up a new SPI bus on initialization.
+
+static void a2fxxx_spi_bus_setup
+ (cyg_spi_cortexm_a2fxxx_bus_t* a2fxxx_bus)
+{
+ cyg_uint8 dma_tx_type, dma_rx_type;
+
+ if( a2fxxx_bus->setup->spi_reg_base == CYGHWR_HAL_A2FXXX_SPI1 ){
+ CYGHWR_HAL_A2FXXX_GPIO_SET( CYGHWR_HAL_A2FXXX_SPI1_DO );
+ CYGHWR_HAL_A2FXXX_GPIO_SET( CYGHWR_HAL_A2FXXX_SPI1_DI );
+ CYGHWR_HAL_A2FXXX_GPIO_SET( CYGHWR_HAL_A2FXXX_SPI1_CLK );
+ dma_tx_type = CYGHWR_HAL_A2FXXX_DMA_XFER(TO_SPI1);
+ dma_rx_type = CYGHWR_HAL_A2FXXX_DMA_XFER(FROM_SPI1);
+ }
+ else {
+ CYGHWR_HAL_A2FXXX_GPIO_SET( CYGHWR_HAL_A2FXXX_SPI0_DO );
+ CYGHWR_HAL_A2FXXX_GPIO_SET( CYGHWR_HAL_A2FXXX_SPI0_DI );
+ CYGHWR_HAL_A2FXXX_GPIO_SET( CYGHWR_HAL_A2FXXX_SPI0_CLK );
+ dma_tx_type = CYGHWR_HAL_A2FXXX_DMA_XFER(TO_SPI0);
+ dma_rx_type = CYGHWR_HAL_A2FXXX_DMA_XFER(FROM_SPI0);
+ }
+
+ // Initialize the synchronization primitives.
+ cyg_drv_mutex_init (&a2fxxx_bus->mutex);
+ cyg_drv_cond_init (&a2fxxx_bus->condvar, &a2fxxx_bus->mutex);
+
+ // Setup DMA channel
+ a2fxxx_dma_ch_setup(a2fxxx_bus->setup->dma_tx_channel, dma_tx_type,
+ CYGHWR_HAL_A2FXXX_DMA_OUTBOUND, sizeof(cyg_uint8), 0,
+ a2fxxx_bus->setup->dma_tx_pri, 9);
+ a2fxxx_dma_ch_setup(a2fxxx_bus->setup->dma_rx_channel, dma_rx_type,
+ CYGHWR_HAL_A2FXXX_DMA_INBOUND, 0, sizeof(cyg_uint8),
+ a2fxxx_bus->setup->dma_rx_pri, 9);
+
+ // Register ISR /DSR
+ a2fxxx_dma_ch_attach(a2fxxx_bus->setup->dma_tx_channel,
+ a2fxxx_tx_ISR, a2fxxx_tx_DSR, (cyg_addrword_t) a2fxxx_bus);
+
+ a2fxxx_dma_ch_attach(a2fxxx_bus->setup->dma_rx_channel,
+ a2fxxx_rx_ISR, a2fxxx_rx_DSR, (cyg_addrword_t) a2fxxx_bus);
+
+ // Call upper layer bus init.
+ CYG_SPI_BUS_COMMON_INIT(&a2fxxx_bus->spi_bus);
+}
+
+//-----------------------------------------------------------------------------
+// Drive a GPIO pin as a SPI chip select line.
+
+static inline void a2fxxx_spi_chip_select
+ (cyg_spi_device* device, cyg_bool assert)
+{
+ cyg_spi_cortexm_a2fxxx_device_t* a2fxxx_device =
+ (cyg_spi_cortexm_a2fxxx_device_t*) device;
+ cyg_spi_cortexm_a2fxxx_bus_t* a2fxxx_bus =
+ (cyg_spi_cortexm_a2fxxx_bus_t*) device->spi_bus;
+
+ // CS is driven from GPIO
+ if( a2fxxx_device->cs_gpio == true) {
+ if (assert == true)
+ CYGHWR_HAL_A2FXXX_GPIO_OUT( a2fxxx_device->cs_gpio_n, 0 );
+ else
+ CYGHWR_HAL_A2FXXX_GPIO_OUT( a2fxxx_device->cs_gpio_n, 1 );
+ }
+ // CS is driven from controller
+ else {
+ cyg_uint32 reg_addr = a2fxxx_bus->setup->spi_reg_base +
+ CYGHWR_HAL_A2FXXX_SPI_SLAVE_SEL;
+ cyg_uint32 reg_data;
+ HAL_READ_UINT32 (reg_addr, reg_data);
+ if (assert == true)
+ reg_data |= CYGHWR_HAL_A2FXXX_SPI_CS_SEL(a2fxxx_device->dev_num);
+ else
+ reg_data &= ~CYGHWR_HAL_A2FXXX_SPI_CS_SEL(a2fxxx_device->dev_num);
+ HAL_WRITE_UINT32 (reg_addr, reg_data);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Configure build-in SPI chip select line
+
+static inline void a2fxxx_spi_set_ss
+ (cyg_spi_cortexm_a2fxxx_bus_t* a2fxxx_bus, cyg_uint8 ss_num)
+{
+ cyg_uint32 ss;
+
+ if( a2fxxx_bus->setup->spi_reg_base == CYGHWR_HAL_A2FXXX_SPI0 ){
+ if ( ss_num == 0 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI0_SS0;
+ } else if( ss_num == 1 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI0_SS1;
+ } else if( ss_num == 2 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI0_SS2;
+ } else if( ss_num == 3 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI0_SS3;
+ } else {
+ CYG_ASSERT (ss < 4, "SPI : SPI0 SS out of range.");
+ return;
+ }
+ }
+ else {
+ if ( ss_num == 0 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI1_SS0;
+ } else if( ss_num == 1 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI1_SS1;
+ } else if( ss_num == 2 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI1_SS2;
+ } else if( ss_num == 3 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI1_SS3;
+ } else if( ss_num == 4 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI1_SS4;
+ } else if( ss_num == 5 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI1_SS5;
+ } else if( ss_num == 6 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI1_SS6;
+ } else if( ss_num == 7 ) {
+ ss = CYGHWR_HAL_A2FXXX_SPI1_SS7;
+ } else {
+ CYG_ASSERT (ss < 8, "SPI : SPI1 SS out of range.");
+ return;
+ }
+ }
+
+ CYGHWR_HAL_A2FXXX_GPIO_SET( ss );
+}
+
+//-----------------------------------------------------------------------------
+// Initiate a DMA transfer over the SPI interface.
+
+static void spi_transaction_dma
+ (cyg_spi_device* device, cyg_bool tick_only, cyg_bool polled, cyg_uint32 count,
+ const cyg_uint8* tx_data, cyg_uint8* rx_data, cyg_bool drop_cs)
+{
+ cyg_spi_cortexm_a2fxxx_bus_t* a2fxxx_bus =
+ (cyg_spi_cortexm_a2fxxx_bus_t*) device->spi_bus;
+ cyg_spi_cortexm_a2fxxx_device_t* a2fxxx_device =
+ (cyg_spi_cortexm_a2fxxx_device_t*) device;
+ cyg_haladdress reg_addr;
+ cyg_uint32 spi_cr_val = a2fxxx_device->spi_cr_val;
+ cyg_haladdress spi_reg_base = a2fxxx_bus->setup->spi_reg_base;
+
+ SPI_TRACE("SPI : Transfer start\n");
+
+ // Drive chip select low, either from GPIO or build in SS signal
+ if( !a2fxxx_bus->cs_up && !tick_only ){
+ SPI_TRACE("SPI : Setup CS\n");
+ CYGACC_CALL_IF_DELAY_US (a2fxxx_device->tr_bt_udly);
+ a2fxxx_spi_chip_select (device, true);
+ CYGACC_CALL_IF_DELAY_US (a2fxxx_device->cs_up_udly);
+ a2fxxx_bus->cs_up = true;
+ }
+
+ // Disable the SPI controller.
+ reg_addr = spi_reg_base + CYGHWR_HAL_A2FXXX_SPI_CTRL;
+ HAL_WRITE_UINT32 (reg_addr, a2fxxx_device->spi_cr_val);
+
+ // Write down transfer count
+ spi_cr_val |= CYGHWR_HAL_A2FXXX_SPI_CTRL_COUNT( count );
+ reg_addr = spi_reg_base + CYGHWR_HAL_A2FXXX_SPI_CTRL;
+ HAL_WRITE_UINT32 (reg_addr, spi_cr_val);
+
+ //
+ // Setup DMA channels
+ // For null source or destination pointer, replace the buffer with the SPI driver
+ // dummy buffer and set the DMA address increment to 0
+ //
+ if(tx_data == NULL)
+ a2fxxx_dma_update_incr(a2fxxx_bus->setup->dma_tx_channel, false, 0);
+ else
+ a2fxxx_dma_update_incr(a2fxxx_bus->setup->dma_tx_channel, false,
+ sizeof(cyg_uint8));
+
+ if(rx_data == NULL)
+ a2fxxx_dma_update_incr(a2fxxx_bus->setup->dma_rx_channel, true, 0);
+ else
+ a2fxxx_dma_update_incr(a2fxxx_bus->setup->dma_rx_channel, true,
+ sizeof(cyg_uint8));
+
+ a2fxxx_bus->tx_dma_done = false;
+ a2fxxx_dma_xfer (a2fxxx_bus->setup->dma_tx_channel, polled, count,
+ ((tx_data == NULL) ? (cyg_uint8*) a2fxxx_bus->setup->tx_dma_null :
+ (cyg_uint8*) tx_data),
+ (cyg_uint8*)(a2fxxx_bus->setup->spi_reg_base + CYGHWR_HAL_A2FXXX_SPI_TX));
+
+ a2fxxx_bus->rx_dma_done = false;
+ a2fxxx_dma_xfer (a2fxxx_bus->setup->dma_rx_channel, polled, count,
+ (cyg_uint8*)(a2fxxx_bus->setup->spi_reg_base + CYGHWR_HAL_A2FXXX_SPI_RX),
+ ((rx_data == NULL) ? (cyg_uint8*) a2fxxx_bus->setup->rx_dma_null :
+ (cyg_uint8*) rx_data));
+
+ //
+ // Run the DMA (polling for completion).
+ //
+ if (polled)
+ {
+ // Enable the SPI controller.
+ SPI_TRACE("SPI : Control Register 0x%x, 0x%x, %d\n", reg_addr,
+ spi_cr_val, count);
+ HAL_WRITE_UINT32 (reg_addr, spi_cr_val | CYGHWR_HAL_A2FXXX_SPI_CTRL_EN);
+
+ // Wait transfer completed.
+ do {
+ if(a2fxxx_dma_get_comp_flag(a2fxxx_bus->setup->dma_rx_channel))
+ a2fxxx_bus->rx_dma_done = true;
+ if(a2fxxx_dma_get_comp_flag(a2fxxx_bus->setup->dma_tx_channel))
+ a2fxxx_bus->tx_dma_done = true;
+ } while ( !(a2fxxx_bus->tx_dma_done && a2fxxx_bus->rx_dma_done) );
+
+ // Acknowledge transfer
+ a2fxxx_dma_clear_interrupt (a2fxxx_bus->setup->dma_rx_channel);
+ a2fxxx_dma_clear_interrupt (a2fxxx_bus->setup->dma_tx_channel);
+
+ } else {
+ cyg_drv_mutex_lock (&a2fxxx_bus->mutex);
+ cyg_drv_dsr_lock ();
+
+ // Enable the SPI controller.
+ SPI_TRACE("SPI : Control Register 0x%x, 0x%x, %d\n", reg_addr,
+ spi_cr_val, count);
+ HAL_WRITE_UINT32 (reg_addr, spi_cr_val | CYGHWR_HAL_A2FXXX_SPI_CTRL_EN);
+
+ // Sit back and wait for the ISR/DSRs to signal completion.
+ do {
+ cyg_drv_cond_wait (&a2fxxx_bus->condvar);
+ } while (!(a2fxxx_bus->tx_dma_done && a2fxxx_bus->rx_dma_done));
+
+ cyg_drv_dsr_unlock ();
+ cyg_drv_mutex_unlock (&a2fxxx_bus->mutex);
+ }
+
+ SPI_TRACE("SPI : Transfer completed\n");
+
+ if (drop_cs && !tick_only) {
+ SPI_TRACE("SPI : Release chip select\n");
+ CYGACC_CALL_IF_DELAY_US (a2fxxx_device->cs_dw_udly);
+ a2fxxx_spi_chip_select (device, false);
+ a2fxxx_bus->cs_up = false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Initialize SPI interfaces on startup.
+
+static void CYGBLD_ATTRIB_C_INIT_PRI(CYG_INIT_BUS_SPI)
+a2fxxx_spi_init(void)
+{
+ hal_dma_init();
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS1
+ CYGHWR_HAL_A2FXXX_PERIPH_RELEASE( CYGHWR_HAL_A2FXXX_PERIPH_SOFTRST(SPI0) );
+ a2fxxx_spi_bus_setup (&cyg_spi_a2fxxx_bus1);
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_A2FXXX_BUS2
+ CYGHWR_HAL_A2FXXX_PERIPH_RELEASE( CYGHWR_HAL_A2FXXX_PERIPH_SOFTRST(SPI1) );
+ a2fxxx_spi_bus_setup (&cyg_spi_a2fxxx_bus2);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Start a SPI transaction.
+
+static void a2fxxx_transaction_begin
+ (cyg_spi_device* device)
+{
+ cyg_spi_cortexm_a2fxxx_bus_t* a2fxxx_bus =
+ (cyg_spi_cortexm_a2fxxx_bus_t*) device->spi_bus;
+ cyg_spi_cortexm_a2fxxx_device_t* a2fxxx_device =
+ (cyg_spi_cortexm_a2fxxx_device_t*) device;
+
+ cyg_haladdress reg_addr;
+ cyg_uint32 reg_data, divided_clk, br, cs_gpio_n;
+
+ SPI_TRACE("SPI : Transfer begin\n");
+ SPI_TRACE("SPI : Device baud rate = %d\n", a2fxxx_device->cl_brate);
+ SPI_TRACE("SPI : Device clock polarity = %d\n", a2fxxx_device->cl_pol);
+ SPI_TRACE("SPI : Device clock phase = %d\n", a2fxxx_device->cl_pha);
+
+ // On the first transaction, generate the values to be programmed into the
+ // SPI configuration registers for this device and cache them. This avoids
+ // having to recalculate the values for every transaction.
+ if (!a2fxxx_device->spi_cr_val) {
+
+ // SPI bus protocol
+ switch( a2fxxx_device->proto ) {
+ case A2FXXX_SPI_TI_SYNC_SERIAL:
+ reg_data = CYGHWR_HAL_A2FXXX_SPI_CTRL_PROTO_TI;
+ break;
+ case A2FXXX_SPI_NS_MICROWIRE:
+ reg_data = CYGHWR_HAL_A2FXXX_SPI_CTRL_PROTO_NS;
+ break;
+ default:
+ reg_data = CYGHWR_HAL_A2FXXX_SPI_CTRL_PROTO_MOTOROLA;
+ break;
+ }
+
+ // Bus polarity
+ if (a2fxxx_device->cl_pol)
+ reg_data |= CYGHWR_HAL_A2FXXX_SPI_CTRL_SPO;
+ if (a2fxxx_device->cl_pha)
+ reg_data |= CYGHWR_HAL_A2FXXX_SPI_CTRL_SPH;
+
+ // Master mode
+ reg_data |= CYGHWR_HAL_A2FXXX_SPI_CTRL_MASTER;
+
+ // Calculate the maximum viable bus speed.
+ divided_clk = hal_a2fxxx_spi_clock(a2fxxx_bus->setup->spi_reg_base) >> 1;
+ for (br = 0; (br < 7) && (divided_clk > a2fxxx_device->cl_brate); br++)
+ divided_clk >>= 1;
+
+ CYG_ASSERT (divided_clk <= a2fxxx_device->cl_brate,
+ "A2FXXX SPI : Cannot run bus slowly enough for peripheral.");
+
+ SPI_TRACE("SPI : Clock divider = %d\n", divided_clk);
+
+ reg_addr = a2fxxx_bus->setup->spi_reg_base +
+ CYGHWR_HAL_A2FXXX_SPI_CLK_GEN;
+ HAL_WRITE_UINT32 (reg_addr, br);
+
+ // Set transfer size (byte mode)
+ reg_addr = a2fxxx_bus->setup->spi_reg_base +
+ CYGHWR_HAL_A2FXXX_SPI_TXRXDF_SIZE;
+ HAL_WRITE_UINT32 (reg_addr, 8);
+
+ // Cache the configuration register settings.
+ a2fxxx_device->spi_cr_val = reg_data;
+
+ // Configure GPIO as chip select
+ if(a2fxxx_device->cs_gpio == true) {
+ cs_gpio_n = a2fxxx_device->cs_gpio_n;
+ SPI_TRACE("SPI : Setup GPIO for CS => %d\n", cs_gpio_n);
+ a2fxxx_device->cs_gpio_n =
+ CYGHWR_HAL_A2FXXX_CS_GPIO( cs_gpio_n, OUT, cs_gpio_n, DISABLE );
+ CYGHWR_HAL_A2FXXX_GPIO_SET( a2fxxx_device->cs_gpio_n );
+ CYGHWR_HAL_A2FXXX_GPIO_OUT( a2fxxx_device->cs_gpio_n, 1);
+ }
+ // Configure build-in SPI chip select line
+ else {
+ SPI_TRACE("SPI : Setup SPI SS => %d\n", a2fxxx_device->dev_num);
+ a2fxxx_spi_set_ss(a2fxxx_bus, a2fxxx_device->dev_num);
+ }
+ }
+
+ // Set up the SPI controller.
+ reg_addr = a2fxxx_bus->setup->spi_reg_base + CYGHWR_HAL_A2FXXX_SPI_CTRL;
+ HAL_WRITE_UINT32 (reg_addr, a2fxxx_device->spi_cr_val);
+}
+
+//-----------------------------------------------------------------------------
+// Run a transaction transfer.
+
+static void a2fxxx_transaction_transfer
+ (cyg_spi_device* device, cyg_bool polled, cyg_uint32 count,
+ const cyg_uint8* tx_data, cyg_uint8* rx_data, cyg_bool drop_cs)
+{
+ // Check for unsupported transactions.
+ CYG_ASSERT (count > 0, "A2FXXX SPI : Null transfer requested.");
+
+ // Perform transfer
+ spi_transaction_dma (device, false, polled, count, tx_data, rx_data, drop_cs);
+}
+
+//-----------------------------------------------------------------------------
+// Carry out a bus tick operation - this just pushes the required number of
+// zeros onto the bus, leaving the chip select in its current state.
+
+static void a2fxxx_transaction_tick
+ (cyg_spi_device* device, cyg_bool polled, cyg_uint32 count)
+{
+ // Check for unsupported transactions.
+ CYG_ASSERT (count > 0, "A2FXXX SPI : Null transfer requested.");
+
+ SPI_TRACE("SPI : Transfer tick\n");
+
+ // Perform null transfer.
+ spi_transaction_dma (device, true, polled, count, NULL, NULL, false);
+}
+
+//-----------------------------------------------------------------------------
+// Terminate a SPI transaction, disabling the SPI controller.
+
+static void a2fxxx_transaction_end
+ (cyg_spi_device* device)
+{
+ cyg_spi_cortexm_a2fxxx_bus_t* a2fxxx_bus =
+ (cyg_spi_cortexm_a2fxxx_bus_t*) device->spi_bus;
+ cyg_spi_cortexm_a2fxxx_device_t* a2fxxx_device =
+ (cyg_spi_cortexm_a2fxxx_device_t*) device;
+ cyg_haladdress reg_addr;
+
+ SPI_TRACE("SPI : Transfer end\n");
+
+ // De-assert chip select
+ if( a2fxxx_bus->cs_up == true ){
+ SPI_TRACE("SPI : Release chip select\n");
+ CYGACC_CALL_IF_DELAY_US (a2fxxx_device->cs_dw_udly);
+ a2fxxx_spi_chip_select (device, false);
+ a2fxxx_bus->cs_up = false;
+ }
+
+ // Disable controller
+ reg_addr = a2fxxx_bus->setup->spi_reg_base + CYGHWR_HAL_A2FXXX_SPI_CTRL;
+ HAL_WRITE_UINT32 (reg_addr, a2fxxx_device->spi_cr_val);
+}
+
+//-----------------------------------------------------------------------------
+// Note that no dynamic configuration options are currently defined.
+
+static int a2fxxx_get_config
+ (cyg_spi_device* dev, cyg_uint32 key, void* buf, cyg_uint32* len)
+{
+ return -1;
+}
+
+static int a2fxxx_set_config
+ (cyg_spi_device* dev, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ return -1;
+}
+
+#endif
+
+//=============================================================================
diff --git a/ecos/packages/devs/spi/cortexm/stm32/current/ChangeLog b/ecos/packages/devs/spi/cortexm/stm32/current/ChangeLog
new file mode 100644
index 0000000..ef60956
--- /dev/null
+++ b/ecos/packages/devs/spi/cortexm/stm32/current/ChangeLog
@@ -0,0 +1,140 @@
+2012-03-28 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/spi_stm32.c (bus3_rx_bbuf): Fix typo in attribute.
+
+2012-03-23 James Smith <jsmith@ecoscentric.com>
+
+ * src/spi_stm32.c (CYGHWR_HAL_STM32_GPIO_MODE_OUT_SPEED_SPI):
+ Rename CYGHWR_HAL_STM32_GPIO_MODE_OUT_SPI to allow the same
+ SPEED_SPI value to be used for F1 and F2/F4 targets.
+ (SPI_CS): Use new wrapper macros to provide a single common SPI_CS
+ manifest.
+
+2012-03-15 James Smith <jsmith@ecoscentric.com>
+
+ * src/spi_stm32.c: Use HIPERFORMANCE manifest to allow F2 and F4
+ device GPIO initialisation support.
+ (dma_channel_setup): Avoid compiler pointer type warning.
+
+2012-03-05 James Smith <jsmith@ecoscentric.com>
+
+ * src/spi_stm32.c (spi_transaction_dma): Avoid race condition by
+ seting the TX and RX DMA done flags to false prior to configuring
+ (and starting) the DMA transfer.
+
+2012-01-12 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/spi_stm32.cdl: Select pin toggle rate based on STM32
+ family. Define interrupt priorities to include DMA channel
+ priorities. Undo 2011-12-09 change, F2 now supported.
+
+ * include/spi_stm32.h (cyg_spi_cortexm_stm32_bus_s):
+ * src/spi_stm32.c: Substantial reorganization to use DMA API.
+ NOTE: Currently only fully tested on F2 parts.
+
+2011-12-09 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/spi_stm32.cdl: For now, only allow this package to be
+ active with F1 family processors.
+
+2011-09-27 Ilija Stanislevik <ilijas@siva.mk>
+
+ * src/spi_stm32.c: Add support for CYG_IO_GET_CONFIG_SPI_CLOCKRATE and
+ CYG_IO_SET_CONFIG_SPI_CLOCKRATE (possibility to retrieve and to set
+ the SPI clockrate).
+
+2011-03-10 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/spi_stm32.cdl: Add build options for CFLAGS and loopback test.
+
+2009-10-22 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/spi_stm32.cdl: Fix descriptions for chip select
+ options. Only build local test if SPI bus 1 is active.
+
+ * include/spi_stm32.h (cyg_spi_cortexm_stm32_bus_setup_s): Add
+ spi_gpio_remap field.
+
+ * src/spi_stm32.c (bus1_setup, bus2_setup, bus3_setup): Fix CS
+ number calculation, add remap to each bus.
+ (stm32_spi_bus_setup): Move enables to correct place. Add code to
+ remap SPI pins if defined.
+
+2009-08-24 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * cdl/spi_stm32.cdl: added testcase.
+ * include/spi_stm32.h: initializing spi_cr1_val with zero.
+
+2009-06-29 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/spi_stm32.cdl:
+ * include/spi_stm32.h (cyg_spi_cortexm_stm32_bus_setup_s):
+ * src/spi_stm32.c: Add support for individual device clock
+ enables. Also change mechanism for specifying CS lines that is
+ more in keeping with other devices.
+
+2009-03-23 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/spi_stm32.cdl: Fix up a few oddities.
+
+ * src/spi_stm32.c (spi_diag): Add some diagnostics.
+
+2009-02-10 Bart Veer <bartv@ecoscentric.com>
+
+ * src/spi_stm32.c (cyg_spi_cortexm_stm32_init): mark as
+ prioritized constructor and rename.
+
+ * cdl/spi_stm32.cdl: stop building spi_stm32_init.cxx
+
+ * src/spi_stm32_init.cxx: removed, no longer needed.
+
+2009-02-10 Chris Holgate <chris@zynaptic.com>
+
+ * src/spi_stm32.c:
+ * cdl/spi_stm32.cdl:
+ Add option to automatically disable JTAG port when initialising SPI3.
+
+2009-02-10 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/spi_stm32.c (bus3_setup): Fix typo.
+
+2009-02-05 Nick Garnett <nickg@ecoscentric.com>
+
+ * include/spi_stm32.h: Add macro to define an STM32 SPI device.
+
+ * src/spi_stm32.c: Fix potential compile error.
+
+ * src/spi_stm32_init.cxx: Change constructor init priority to use
+ CYG_INIT_BUS_SPI.
+
+2009-01-30 Nick Garnett <nickg@ecoscentric.com>
+
+ * cdl/spi_stm32.cdl:
+ * include/spi_stm32.h:
+ * src/spi_stm32.c:
+ * src/spi_stm32_init.cxx:
+ New package, STM32 SPI driver contributed by Chris Holgate.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/spi/cortexm/stm32/current/cdl/spi_stm32.cdl b/ecos/packages/devs/spi/cortexm/stm32/current/cdl/spi_stm32.cdl
new file mode 100644
index 0000000..32d5b24
--- /dev/null
+++ b/ecos/packages/devs/spi/cortexm/stm32/current/cdl/spi_stm32.cdl
@@ -0,0 +1,272 @@
+##=============================================================================
+##
+## spi_stm32.cdl
+##
+## STM32 SPI driver configuration options.
+##
+##=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): Chris Holgate
+## Contributor: jld
+## Date: 2008-11-27
+## Purpose: Configure STM32 SPI driver.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+cdl_package CYGPKG_DEVS_SPI_CORTEXM_STM32 {
+ display "ST STM32 SPI driver"
+ description "
+ This package provides SPI driver support for the ST STM32 series
+ of microcontrollers.
+ "
+ parent CYGPKG_IO_SPI
+ active_if CYGPKG_IO_SPI
+ requires CYGPKG_HAL_CORTEXM_STM32
+ hardware
+ include_dir cyg/io
+ compile spi_stm32.c
+
+cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE {
+ display "Pin toggle rate"
+ description "
+ Selects the pin toggle rate in MHz to be used for the SPI interfaces. Higher toggle
+ rates allow increased baud rates at the expense of power and EMI. Only certain rates
+ are valid on different STM32 families, check part documentation for which may be used."
+ flavor data
+ default_value { (CYGHWR_HAL_CORTEXM_STM32_FAMILY == "F1") ? 10 : 25 }
+ legal_values { 2 10 25 50 80 100 }
+}
+
+cdl_component CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1 {
+ display "ST STM32 SPI bus 1"
+ description "
+ Enable SPI bus 1 on the STM32 device.
+ "
+ flavor bool
+ default_value 0
+
+ cdl_option CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1_CS_GPIOS {
+ display "SPI chip selects"
+ description "
+ This is a comma separated list of GPIOs which are to be used as chip
+ select lines for the SPI bus. Each GPIO is defined by the SPI_CS()
+ macro which gives the port and pin number.
+ "
+ flavor data
+ default_value { "SPI_CS(A, 4)" }
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE {
+ display "Bounce buffer size"
+ description "
+ DMA bounce buffers are required when running out of external
+ memory. Set this to the maximum SPI packet size which will be
+ used to enable the DMA bounce buffers. Set to 0 to disable
+ bounce buffers when running from on-chip memory.
+ "
+ flavor data
+ default_value 0
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_TXINTR_PRI {
+ display "Transmit DMA interrupt priority"
+ flavor data
+ default_value 64+5
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_RXINTR_PRI {
+ display "Receive DMA interrupt priority"
+ flavor data
+ default_value 128+6
+ }
+}
+
+cdl_component CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2 {
+ display "ST STM32 SPI bus 2"
+ description "
+ Enable SPI bus 2 on the STM32 device.
+ "
+ flavor bool
+ default_value 0
+
+ cdl_option CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2_CS_GPIOS {
+ display "SPI chip selects"
+ description "
+ This is a comma separated list of GPIOs which are to be used as chip
+ select lines for the SPI bus. Each GPIO is defined by the SPI_CS()
+ macro which gives the port and pin number.
+ "
+ flavor data
+ default_value { "SPI_CS(B, 12)" }
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE {
+ display "Bounce buffer size"
+ description "
+ DMA bounce buffers are required when running out of external
+ memory. Set this to the maximum SPI packet size which will be
+ used to enable the DMA bounce buffers. Set to 0 to disable
+ bounce buffers when running from on-chip memory.
+ "
+ flavor data
+ default_value 0
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_TXINTR_PRI {
+ display "Transmit DMA interrupt priority"
+ flavor data
+ default_value 64+7
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_RXINTR_PRI {
+ display "Receive DMA interrupt priority"
+ flavor data
+ default_value 128+8
+ }
+}
+
+cdl_component CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3 {
+ display "ST STM32 SPI bus 3"
+ description "
+ Enable SPI bus 3 on the STM32 device. Note that SPI bus 3 shares pins
+ with the JTAG port which means that debug should ideally be disabled
+ on startup. However, there is also the option of disabling it during
+ SPI bus initialisation instead.
+ "
+ flavor bool
+ default_value 0
+
+ cdl_option CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3_DISABLE_DEBUG_PORT {
+ display "Disable debug port"
+ description "
+ When set the debug port will automatically be disabled on
+ initialising SPI bus 3, freeing up the SPI interface pins.
+ "
+ flavor bool
+ default_value 0
+ }
+
+ cdl_option CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3_CS_GPIOS {
+ display "SPI chip selects"
+ description "
+ This is a comma separated list of GPIOs which are to be used as chip
+ select lines for the SPI bus. Each GPIO is defined by the SPI_CS()
+ macro which gives the port and pin number.
+ "
+ flavor data
+ default_value { "SPI_CS(A, 15)" }
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE {
+ display "Bounce buffer size"
+ description "
+ DMA bounce buffers are required when running out of external
+ memory. Set this to the maximum SPI packet size which will be
+ used to enable the DMA bounce buffers. Set to 0 to disable
+ bounce buffers when running from on-chip memory.
+ "
+ flavor data
+ default_value 0
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_TXINTR_PRI {
+ display "Transmit DMA interrupt priority"
+ flavor data
+ default_value 64+9
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_RXINTR_PRI {
+ display "Receive DMA interrupt priority"
+ flavor data
+ default_value 128+10
+ }
+}
+
+cdl_component CYGPKG_DEVS_SPI_CORTEXM_STM32_OPTIONS {
+ display "ST STM32 SPI driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_DEVS_SPI_CORTEXM_STM32_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the STM32 SPI driver. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_SPI_CORTEXM_STM32_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the STM32 SPI driver. These flags are removed from
+ the set of global flags if present."
+ }
+
+ cdl_option CYGBLD_DEVS_SPI_CORTEXM_STM32_LOOPBACK_TEST {
+ display "Build STM32 SPI loopback test"
+ flavor bool
+ no_define
+ default_value 0
+ requires CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1
+ description "
+ This option enables the building of the STM32 SPI loopback test.
+ Refer to the comments in tests/loopback.c for details of how to
+ use this test."
+ }
+
+ cdl_option CYGPKG_DEVS_SPI_CORTEXM_STM32_TESTS {
+ display "SPI tests"
+ active_if CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1
+ flavor data
+ no_define
+ calculated { CYGBLD_DEVS_SPI_CORTEXM_STM32_LOOPBACK_TEST ? "tests/loopback" : "" }
+ }
+}
+
+}
+# EOF spi_stm32.cdl
diff --git a/ecos/packages/devs/spi/cortexm/stm32/current/include/spi_stm32.h b/ecos/packages/devs/spi/cortexm/stm32/current/include/spi_stm32.h
new file mode 100644
index 0000000..a1370e2
--- /dev/null
+++ b/ecos/packages/devs/spi/cortexm/stm32/current/include/spi_stm32.h
@@ -0,0 +1,182 @@
+#ifndef CYGONCE_DEVS_SPI_CORTEXM_STM32_H
+#define CYGONCE_DEVS_SPI_CORTEXM_STM32_H
+//=============================================================================
+//
+// spi_stm32.h
+//
+// Header definitions for STM32 SPI driver.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Chris Holgate, nickg
+// Date: 2008-11-27
+// Purpose: STM32 SPI driver definitions.
+// Description:
+// Usage: #include <cyg/io/spi_stm32.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+#include <pkgconf/devs_spi_cortexm_stm32.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+
+#include <cyg/hal/var_dma.h>
+
+//-----------------------------------------------------------------------------
+// Macro for defining a SPI device and attaching it to the appropriate bus.
+//
+// _name_ is the name of the SPI device. This will be used to reference a
+// data structure of type cyg_spi_device which can be passed to the
+// SPI driver API without needing a cast.
+// _bus_ is the bus number to which this device is attached (1, 2 or 3).
+// _csnum_ is the chip select line used for this device, numbered from 0.
+// _16bit_ is set to true if the device uses 16 bit transactions and false
+// if the bus uses 8 bit transactions.
+// _clpol_ is the SPI bus clock polarity used by the device. This must be
+// set to 1 if a clock line pullup resistor is used and 0 if a
+// clock line pulldown resistor is used.
+// _clpha_ is the SPI bus clock phase used by the device.
+// _brate_ is the SPI bus clock baud rate used by the device, measured in Hz.
+// _csup_dly_ is the minimum delay between chip select assert and transfer
+// start, measured in microseconds.
+// _csdw_dly_ is the minimum delay between transfer end and chip select deassert,
+// measured in microseconds.
+// _trbt_dly_ is the minimum delay between consecutive transfers.
+
+#define CYG_DEVS_SPI_CORTEXM_STM32_DEVICE( \
+ _name_, _bus_, _csnum_, _16bit_, _clpol_, _clpha_, _brate_, _csup_dly_, _csdw_dly_, _trbt_dly_\
+) \
+cyg_spi_cortexm_stm32_device_t _name_ ##_stm32 CYG_SPI_DEVICE_ON_BUS(_bus_) = { \
+{ .spi_bus = (cyg_spi_bus*) &cyg_spi_stm32_bus## _bus_ }, \
+ .dev_num = _csnum_, \
+ .bus_16bit = _16bit_ ? 1 : 0, \
+ .cl_pol = _clpol_, \
+ .cl_pha = _clpha_, \
+ .cl_brate = _brate_, \
+ .cs_up_udly = _csup_dly_, \
+ .cs_dw_udly = _csdw_dly_, \
+ .tr_bt_udly = _trbt_dly_, \
+ .spi_cr1_val = 0, \
+}; \
+extern cyg_spi_device _name_ __attribute__((alias ( #_name_ "_stm32" )));
+
+//-----------------------------------------------------------------------------
+// STM32 SPI bus configuration and state.
+
+typedef struct cyg_spi_cortexm_stm32_bus_setup_s
+{
+ cyg_uint32 *apb_freq; // Peripheral bus frequency.
+ cyg_haladdress spi_reg_base; // Base address of SPI register block.
+
+ cyg_uint32 spi_enable; // SPI bus clock enable
+ cyg_uint8 cs_gpio_num; // Number of chip selects for this bus.
+ const cyg_uint32* cs_gpio_list; // List of GPIOs used as chip selects.
+ const cyg_uint32* spi_gpio_list; // List of GPIOs used by the SPI interface.
+ cyg_uint32 spi_gpio_remap; // Remap GPIO lines to alternate pins.
+ cyg_priority_t dma_tx_intr_pri; // Interrupt priority for DMA transmit.
+ cyg_priority_t dma_rx_intr_pri; // Interrupt priority for DMA receive.
+ cyg_uint32 bbuf_size; // Size of bounce buffers.
+ cyg_uint8* bbuf_tx; // Pointer to transmit bounce buffer.
+ cyg_uint8* bbuf_rx; // Pointer to receive bounce buffer.
+
+} cyg_spi_cortexm_stm32_bus_setup_t;
+
+typedef struct cyg_spi_cortexm_stm32_bus_s
+{
+ // ---- Upper layer data ----
+ cyg_spi_bus spi_bus; // Upper layer SPI bus data.
+
+ // ---- Bus configuration constants ----
+ const cyg_spi_cortexm_stm32_bus_setup_t* setup;
+
+ // ---- Driver state (private) ----
+
+ hal_stm32_dma_stream dma_tx_stream; // TX DMA stream for this bus.
+ hal_stm32_dma_stream dma_rx_stream; // RX DMA stream for this bus.
+ cyg_drv_mutex_t mutex; // Transfer mutex.
+ cyg_drv_cond_t condvar; // Transfer condition variable.
+ cyg_bool tx_dma_done; // Flags used to signal completion.
+ cyg_bool rx_dma_done; // Flags used to signal completion.
+ cyg_bool cs_up; // Chip select asserted flag.
+
+} cyg_spi_cortexm_stm32_bus_t;
+
+//-----------------------------------------------------------------------------
+// STM32 SPI device.
+
+typedef struct cyg_spi_cortexm_stm32_device_s
+{
+ // ---- Upper layer data ----
+ cyg_spi_device spi_device; // Upper layer SPI device data.
+
+ // ---- Device setup (user configurable) ----
+ cyg_uint8 dev_num; // Device number.
+ cyg_uint8 bus_16bit; // Use 16 bit (1) or 8 bit (0) transfers.
+ cyg_uint8 cl_pol; // Clock polarity (0 or 1).
+ cyg_uint8 cl_pha; // Clock phase (0 or 1).
+ cyg_uint32 cl_brate; // Clock baud rate.
+ cyg_uint16 cs_up_udly; // Minimum delay in us between CS up and transfer start.
+ cyg_uint16 cs_dw_udly; // Minimum delay in us between transfer end and CS down.
+ cyg_uint16 tr_bt_udly; // Minimum delay in us between two transfers.
+
+ // ---- Device state (private) ----
+ cyg_uint32 spi_cr1_val; // SPI configuration register (initialised to 0).
+
+} cyg_spi_cortexm_stm32_device_t;
+
+//-----------------------------------------------------------------------------
+// Exported bus data structures.
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1
+externC cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus1;
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2
+externC cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus2;
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3
+externC cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus3;
+#endif
+
+//=============================================================================
+#endif // CYGONCE_DEVS_SPI_CORTEXM_STM32_H
diff --git a/ecos/packages/devs/spi/cortexm/stm32/current/src/spi_stm32.c b/ecos/packages/devs/spi/cortexm/stm32/current/src/spi_stm32.c
new file mode 100644
index 0000000..54a97b1
--- /dev/null
+++ b/ecos/packages/devs/spi/cortexm/stm32/current/src/spi_stm32.c
@@ -0,0 +1,805 @@
+//=============================================================================
+//
+// spi_stm32.c
+//
+// SPI driver implementation for STM32
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Chris Holgate, nickg
+// Date: 2008-11-27
+// Purpose: STM32 SPI driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/spi.h>
+#include <cyg/io/spi_stm32.h>
+
+#include <pkgconf/devs_spi_cortexm_stm32.h>
+
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// Diagnostics
+
+#if 0
+#define spi_diag( __fmt, ... ) diag_printf("SPI: %30s[%3d]: " __fmt, __FUNCTION__, __LINE__, ## __VA_ARGS__ );
+#define spi_dump_buf( __addr, __size ) diag_dump_buf( __addr, __size )
+#else
+#define spi_diag( __fmt, ... )
+#define spi_dump_buf( __addr, __size )
+#endif
+
+//-----------------------------------------------------------------------------
+// Bus frequencies
+
+__externC cyg_uint32 hal_stm32_pclk1;
+__externC cyg_uint32 hal_stm32_pclk2;
+
+//-----------------------------------------------------------------------------
+// API function call forward references.
+
+static void stm32_transaction_begin (cyg_spi_device*);
+static void stm32_transaction_transfer (cyg_spi_device*, cyg_bool, cyg_uint32, const cyg_uint8*, cyg_uint8*, cyg_bool);
+static void stm32_transaction_tick (cyg_spi_device*, cyg_bool, cyg_uint32);
+static void stm32_transaction_end (cyg_spi_device*);
+static int stm32_get_config (cyg_spi_device*, cyg_uint32, void*, cyg_uint32*);
+static int stm32_set_config (cyg_spi_device*, cyg_uint32, const void*, cyg_uint32*);
+
+//-----------------------------------------------------------------------------
+// DMA callbacks
+
+static void stm32_dma_tx_callback( hal_stm32_dma_stream *stream, cyg_uint32 count, CYG_ADDRWORD data );
+static void stm32_dma_rx_callback( hal_stm32_dma_stream *stream, cyg_uint32 count, CYG_ADDRWORD data );
+
+//-----------------------------------------------------------------------------
+// Null data source and sink must be placed in the on-chip SRAM. This is
+// either done explicitly (bounce buffers instantiated) or implicitly (no
+// bounce buffers implies that the data area is already on SRAM).
+
+#if (defined (CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1) && (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE > 0)) || \
+ (defined (CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2) && (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE > 0)) || \
+ (defined (CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3) && (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE > 0))
+static cyg_uint16 dma_tx_null __attribute__((section (".sram"))) = 0xFFFF;
+static cyg_uint16 dma_rx_null __attribute__((section (".sram"))) = 0xFFFF;
+
+#else
+static cyg_uint16 dma_tx_null = 0xFFFF;
+static cyg_uint16 dma_rx_null = 0xFFFF;
+#endif
+
+//-----------------------------------------------------------------------------
+// Useful GPIO macros for 'dynamic' pin setup.
+
+#if defined (CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1)
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 2)
+#define CYGHWR_HAL_STM32_GPIO_MODE_OUT_SPEED_SPI CYGHWR_HAL_STM32_GPIO_MODE_OUT_2MHZ
+
+#elif (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 10)
+#define CYGHWR_HAL_STM32_GPIO_MODE_OUT_SPEED_SPI CYGHWR_HAL_STM32_GPIO_MODE_OUT_10MHZ
+
+#elif (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 50)
+#define CYGHWR_HAL_STM32_GPIO_MODE_OUT_SPEED_SPI CYGHWR_HAL_STM32_GPIO_MODE_OUT_50MHZ
+
+#else
+#error "Invalid SPI bus toggle rate."
+#endif
+
+#elif defined (CYGHWR_HAL_CORTEXM_STM32_FAMILY_HIPERFORMANCE)
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 2)
+#define CYGHWR_HAL_STM32_GPIO_OSPEED_SPEED_SPI CYGHWR_HAL_STM32_GPIO_OSPEED_2MHZ
+
+#elif (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 25)
+#define CYGHWR_HAL_STM32_GPIO_OSPEED_SPEED_SPI CYGHWR_HAL_STM32_GPIO_OSPEED_25MHZ
+
+#elif (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 50)
+#define CYGHWR_HAL_STM32_GPIO_OSPEED_SPEED_SPI CYGHWR_HAL_STM32_GPIO_OSPEED_50MHZ
+
+#elif (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 80)
+#define CYGHWR_HAL_STM32_GPIO_OSPEED_SPEED_SPI CYGHWR_HAL_STM32_GPIO_OSPEED_HIGH
+
+#elif (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 100)
+#define CYGHWR_HAL_STM32_GPIO_OSPEED_SPEED_SPI CYGHWR_HAL_STM32_GPIO_OSPEED_HIGH
+
+#else
+#error "Invalid SPI bus toggle rate."
+#endif
+
+#else
+
+#error "Unknown STM32 family"
+
+#endif
+
+#define SPI_CS( __port, __bit ) CYGHWR_HAL_STM32_PIN_OUT( __port, __bit, PUSHPULL, NONE, SPEED_SPI )
+
+//-----------------------------------------------------------------------------
+
+// Instantiate the bus state data structures.
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1
+static const cyg_uint32 bus1_cs_gpio_list[] = { CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1_CS_GPIOS };
+static const cyg_uint32 bus1_spi_gpio_list[] = { CYGHWR_HAL_STM32_SPI1_SCK,
+ CYGHWR_HAL_STM32_SPI1_MISO,
+ CYGHWR_HAL_STM32_SPI1_MOSI };
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE > 0)
+static cyg_uint8 bus1_tx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE]
+ __attribute__((aligned (2), section (".sram"))) = { 0 };
+static cyg_uint8 bus1_rx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE]
+ __attribute__((aligned (2), section (".sram"))) = { 0 };
+#endif
+
+static const cyg_spi_cortexm_stm32_bus_setup_t bus1_setup = {
+ .apb_freq = &hal_stm32_pclk2,
+ .spi_reg_base = CYGHWR_HAL_STM32_SPI1,
+ .spi_enable = CYGHWR_HAL_STM32_SPI1_CLOCK,
+ .cs_gpio_num = sizeof (bus1_cs_gpio_list)/sizeof(cyg_uint32),
+ .cs_gpio_list = bus1_cs_gpio_list,
+ .spi_gpio_list = bus1_spi_gpio_list,
+ .spi_gpio_remap = CYGHWR_HAL_STM32_SPI1_REMAP_CONFIG,
+ .dma_tx_intr_pri = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_TXINTR_PRI,
+ .dma_rx_intr_pri = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_RXINTR_PRI,
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE > 0)
+ .bbuf_size = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE,
+ .bbuf_tx = bus1_tx_bbuf,
+ .bbuf_rx = bus1_rx_bbuf,
+#else
+ .bbuf_size = 0,
+#endif
+};
+
+cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus1 = {
+ .spi_bus.spi_transaction_begin = stm32_transaction_begin,
+ .spi_bus.spi_transaction_transfer = stm32_transaction_transfer,
+ .spi_bus.spi_transaction_tick = stm32_transaction_tick,
+ .spi_bus.spi_transaction_end = stm32_transaction_end,
+ .spi_bus.spi_get_config = stm32_get_config,
+ .spi_bus.spi_set_config = stm32_set_config,
+ .setup = &bus1_setup,
+ .cs_up = false,
+
+ .dma_tx_stream.desc = CYGHWR_HAL_STM32_SPI1_DMA_TX,
+ .dma_tx_stream.callback = stm32_dma_tx_callback,
+ .dma_tx_stream.data = (CYG_ADDRWORD)&cyg_spi_stm32_bus1,
+
+ .dma_rx_stream.desc = CYGHWR_HAL_STM32_SPI1_DMA_RX,
+ .dma_rx_stream.callback = stm32_dma_rx_callback,
+ .dma_rx_stream.data = (CYG_ADDRWORD)&cyg_spi_stm32_bus1,
+
+
+
+};
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2
+static const cyg_uint32 bus2_cs_gpio_list[] = { CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2_CS_GPIOS };
+static const cyg_uint32 bus2_spi_gpio_list[] = { CYGHWR_HAL_STM32_SPI2_SCK,
+ CYGHWR_HAL_STM32_SPI2_MISO,
+ CYGHWR_HAL_STM32_SPI2_MOSI };
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE > 0)
+static cyg_uint8 bus2_tx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE]
+ __attribute__((aligned (2), section (".sram"))) = { 0 };
+static cyg_uint8 bus2_rx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE]
+ __attribute__((aligned (2), section (".sram"))) = { 0 };
+#endif
+
+static const cyg_spi_cortexm_stm32_bus_setup_t bus2_setup = {
+ .apb_freq = &hal_stm32_pclk1,
+ .spi_reg_base = CYGHWR_HAL_STM32_SPI2,
+ .spi_enable = CYGHWR_HAL_STM32_SPI2_CLOCK,
+ .cs_gpio_num = sizeof (bus2_cs_gpio_list)/sizeof(cyg_uint32),
+ .cs_gpio_list = bus2_cs_gpio_list,
+ .spi_gpio_list = bus2_spi_gpio_list,
+ .spi_gpio_remap = CYGHWR_HAL_STM32_SPI2_REMAP_CONFIG,
+ .dma_tx_intr_pri = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_TXINTR_PRI,
+ .dma_rx_intr_pri = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_RXINTR_PRI,
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE > 0)
+ .bbuf_size = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE,
+ .bbuf_tx = bus2_tx_bbuf,
+ .bbuf_rx = bus2_rx_bbuf,
+#else
+ .bbuf_size = 0,
+#endif
+};
+
+cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus2 = {
+ .spi_bus.spi_transaction_begin = stm32_transaction_begin,
+ .spi_bus.spi_transaction_transfer = stm32_transaction_transfer,
+ .spi_bus.spi_transaction_tick = stm32_transaction_tick,
+ .spi_bus.spi_transaction_end = stm32_transaction_end,
+ .spi_bus.spi_get_config = stm32_get_config,
+ .spi_bus.spi_set_config = stm32_set_config,
+ .setup = &bus2_setup,
+ .cs_up = false,
+
+ .dma_tx_stream.desc = CYGHWR_HAL_STM32_SPI2_DMA_TX,
+ .dma_tx_stream.callback = stm32_dma_tx_callback,
+ .dma_tx_stream.data = (CYG_ADDRWORD)&cyg_spi_stm32_bus2,
+
+ .dma_rx_stream.desc = CYGHWR_HAL_STM32_SPI2_DMA_RX,
+ .dma_rx_stream.callback = stm32_dma_rx_callback,
+ .dma_rx_stream.data = (CYG_ADDRWORD)&cyg_spi_stm32_bus2,
+
+
+};
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3
+static const cyg_uint32 bus3_cs_gpio_list[] = { CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3_CS_GPIOS };
+static const cyg_uint32 bus3_spi_gpio_list[] = { CYGHWR_HAL_STM32_SPI3_SCK,
+ CYGHWR_HAL_STM32_SPI3_MISO,
+ CYGHWR_HAL_STM32_SPI3_MOSI };
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE > 0)
+static cyg_uint8 bus3_tx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE]
+ __attribute__((aligned (2), section (".sram"))) = { 0 };
+static cyg_uint8 bus3_rx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE]
+ __attribute__((aligned (2), section (".sram"))) = { 0 };
+#endif
+
+static const cyg_spi_cortexm_stm32_bus_setup_t bus3_setup = {
+ .apb_freq = &hal_stm32_pclk1,
+ .spi_reg_base = CYGHWR_HAL_STM32_SPI3,
+ .spi_enable = CYGHWR_HAL_STM32_SPI3_CLOCK,
+ .cs_gpio_num = sizeof (bus3_cs_gpio_list)/sizeof(cyg_uint32),
+ .cs_gpio_list = bus3_cs_gpio_list,
+ .spi_gpio_list = bus3_spi_gpio_list,
+ .spi_gpio_remap = CYGHWR_HAL_STM32_SPI3_REMAP_CONFIG,
+ .dma_tx_intr_pri = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_TXINTR_PRI,
+ .dma_rx_intr_pri = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_RXINTR_PRI,
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE > 0)
+ .bbuf_size = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE,
+ .bbuf_tx = bus3_tx_bbuf,
+ .bbuf_rx = bus3_rx_bbuf,
+#else
+ .bbuf_size = 0,
+#endif
+};
+
+cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus3 = {
+ .spi_bus.spi_transaction_begin = stm32_transaction_begin,
+ .spi_bus.spi_transaction_transfer = stm32_transaction_transfer,
+ .spi_bus.spi_transaction_tick = stm32_transaction_tick,
+ .spi_bus.spi_transaction_end = stm32_transaction_end,
+ .spi_bus.spi_get_config = stm32_get_config,
+ .spi_bus.spi_set_config = stm32_set_config,
+ .setup = &bus3_setup,
+ .cs_up = false,
+
+ .dma_tx_stream.desc = CYGHWR_HAL_STM32_SPI3_DMA_TX,
+ .dma_tx_stream.callback = stm32_dma_tx_callback,
+ .dma_tx_stream.data = (CYG_ADDRWORD)&cyg_spi_stm32_bus3,
+
+ .dma_rx_stream.desc = CYGHWR_HAL_STM32_SPI3_DMA_RX,
+ .dma_rx_stream.callback = stm32_dma_rx_callback,
+ .dma_rx_stream.data = (CYG_ADDRWORD)&cyg_spi_stm32_bus3,
+
+
+};
+#endif
+
+//-----------------------------------------------------------------------------
+// Configure a GPIO pin as a SPI chip select line.
+
+static inline void stm32_spi_gpio_cs_setup
+ (cyg_uint32 gpio_num)
+{
+ CYGHWR_HAL_STM32_GPIO_SET (gpio_num);
+ CYGHWR_HAL_STM32_GPIO_OUT (gpio_num, 1);
+}
+
+//-----------------------------------------------------------------------------
+// Drive a GPIO pin as a SPI chip select line.
+
+static inline void stm32_spi_chip_select
+ (cyg_uint32 gpio_num, cyg_bool assert)
+{
+ CYGHWR_HAL_STM32_GPIO_OUT( gpio_num, assert ? 0 : 1);
+}
+
+//-----------------------------------------------------------------------------
+// DMA Callbacks. The DMA driver has disabled the DMA channel and
+// masked the interrupt condition, here we need to wake up the client
+// thread.
+
+static void stm32_dma_tx_callback( hal_stm32_dma_stream *stream, cyg_uint32 count, CYG_ADDRWORD data )
+{
+ cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) data;
+
+ cyg_drv_dsr_lock ();
+ stm32_bus->tx_dma_done = true;
+ cyg_drv_cond_signal (&stm32_bus->condvar);
+ cyg_drv_dsr_unlock ();
+}
+
+static void stm32_dma_rx_callback( hal_stm32_dma_stream *stream, cyg_uint32 count, CYG_ADDRWORD data )
+{
+ cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) data;
+
+ cyg_drv_dsr_lock ();
+ stm32_bus->rx_dma_done = true;
+ cyg_drv_cond_signal (&stm32_bus->condvar);
+ cyg_drv_dsr_unlock ();
+}
+
+//-----------------------------------------------------------------------------
+// Set up a new SPI bus on initialisation.
+
+static void stm32_spi_bus_setup
+ (cyg_spi_cortexm_stm32_bus_t* stm32_bus)
+{
+ int i;
+ cyg_haladdress reg_addr;
+ cyg_uint32 reg_data;
+
+ spi_diag("bus %p\n", stm32_bus );
+ // Set up the GPIOs for use as chip select lines.
+ for (i = 0; i < stm32_bus->setup->cs_gpio_num; i ++) {
+ stm32_spi_gpio_cs_setup (stm32_bus->setup->cs_gpio_list[i]);
+ }
+
+#if defined (CYGHWR_HAL_CORTEXM_STM32_FAMILY_F1)
+ // Remap GPIO pins if required
+ if( stm32_bus->setup->spi_gpio_remap )
+ {
+ CYG_ADDRESS afio = CYGHWR_HAL_STM32_AFIO;
+ cyg_uint32 mapr;
+ spi_diag("remap %08x\n", stm32_bus->setup->spi_gpio_remap );
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( CYGHWR_HAL_STM32_AFIO_CLOCK );
+ HAL_READ_UINT32( afio+CYGHWR_HAL_STM32_AFIO_MAPR, mapr );
+ mapr |= stm32_bus->setup->spi_gpio_remap;
+ HAL_WRITE_UINT32( afio+CYGHWR_HAL_STM32_AFIO_MAPR, mapr );
+ }
+#endif
+
+ CYGHWR_HAL_STM32_GPIO_SET( stm32_bus->setup->spi_gpio_list[0] );
+ CYGHWR_HAL_STM32_GPIO_SET( stm32_bus->setup->spi_gpio_list[1] );
+ CYGHWR_HAL_STM32_GPIO_SET( stm32_bus->setup->spi_gpio_list[2] );
+
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( stm32_bus->setup->spi_enable );
+ //CYGHWR_HAL_STM32_CLOCK_ENABLE( stm32_bus->setup->dma_enable );
+
+ // Set up SPI default configuration.
+ reg_addr = stm32_bus->setup->spi_reg_base + CYGHWR_HAL_STM32_SPI_CR2;
+ reg_data = CYGHWR_HAL_STM32_SPI_CR2_TXDMAEN | CYGHWR_HAL_STM32_SPI_CR2_RXDMAEN;
+ HAL_WRITE_UINT32 (reg_addr, reg_data);
+
+ // Initialise the synchronisation primitivies.
+ cyg_drv_mutex_init (&stm32_bus->mutex);
+ cyg_drv_cond_init (&stm32_bus->condvar, &stm32_bus->mutex);
+
+ // Initialize DMA streams
+ hal_stm32_dma_init( &stm32_bus->dma_tx_stream, stm32_bus->setup->dma_tx_intr_pri );
+ hal_stm32_dma_init( &stm32_bus->dma_rx_stream, stm32_bus->setup->dma_rx_intr_pri );
+
+ // Call upper layer bus init.
+ CYG_SPI_BUS_COMMON_INIT(&stm32_bus->spi_bus);
+}
+
+//-----------------------------------------------------------------------------
+// Set up a DMA channel.
+
+static void dma_channel_setup
+ (cyg_spi_device* device, cyg_uint8* data_buf, cyg_uint32 count, cyg_bool is_tx, cyg_bool polled)
+{
+ cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+ cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+ hal_stm32_dma_stream *stream = is_tx ? &stm32_bus->dma_tx_stream : &stm32_bus->dma_rx_stream;
+
+ hal_stm32_dma_configure( stream,
+ stm32_device->bus_16bit ? 16 : 8,
+ (data_buf==NULL),
+ polled );
+
+ if( data_buf == NULL )
+ data_buf = (cyg_uint8 *)(is_tx ? &dma_tx_null : &dma_rx_null);
+
+ hal_stm32_dma_start( stream,
+ data_buf,
+ stm32_bus->setup->spi_reg_base+CYGHWR_HAL_STM32_SPI_DR,
+ count );
+
+ hal_stm32_dma_show( stream );
+}
+
+//-----------------------------------------------------------------------------
+// Initiate a DMA transfer over the SPI interface.
+
+static void spi_transaction_dma
+ (cyg_spi_device* device, cyg_bool tick_only, cyg_bool polled, cyg_uint32 count,
+ const cyg_uint8* tx_data, cyg_uint8* rx_data, cyg_bool drop_cs)
+{
+ cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+ cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+ cyg_haladdress reg_addr;
+
+ cyg_haladdress spi_reg_base = stm32_bus->setup->spi_reg_base;
+
+ spi_diag("device %p\n", device );
+ // Ensure the chip select is asserted, inserting inter-transaction guard
+ // time if required. Note that when ticking the device we do not touch the CS.
+ if (!stm32_bus->cs_up && !tick_only) {
+ CYGACC_CALL_IF_DELAY_US (stm32_device->tr_bt_udly);
+ stm32_spi_chip_select (stm32_bus->setup->cs_gpio_list[stm32_device->dev_num], true);
+ stm32_bus->cs_up = true;
+ CYGACC_CALL_IF_DELAY_US (stm32_device->cs_up_udly);
+ }
+
+ // Clear done flags prior to configuring DMA:
+ stm32_bus->tx_dma_done = false;
+ stm32_bus->rx_dma_done = false;
+
+ // Set up the DMA channels.
+ dma_channel_setup (device, (cyg_uint8*) tx_data, count, true, polled);
+ dma_channel_setup (device, rx_data, count, false, polled);
+
+ // Run the DMA (polling for completion).
+ if (polled) {
+ // Enable the SPI controller.
+ reg_addr = spi_reg_base + CYGHWR_HAL_STM32_SPI_CR1;
+ HAL_WRITE_UINT32 (reg_addr, stm32_device->spi_cr1_val | CYGHWR_HAL_STM32_SPI_CR1_SPE);
+
+ while( !(stm32_bus->tx_dma_done && stm32_bus->rx_dma_done) )
+ {
+ hal_stm32_dma_poll( &stm32_bus->dma_tx_stream );
+ hal_stm32_dma_poll( &stm32_bus->dma_rx_stream );
+ }
+ }
+ // Run the DMA (interrupt driven).
+ else {
+ cyg_drv_mutex_lock (&stm32_bus->mutex);
+ cyg_drv_dsr_lock ();
+
+ // Enable the SPI controller.
+ reg_addr = spi_reg_base + CYGHWR_HAL_STM32_SPI_CR1;
+ HAL_WRITE_UINT32 (reg_addr, stm32_device->spi_cr1_val | CYGHWR_HAL_STM32_SPI_CR1_SPE);
+
+ // Sit back and wait for the ISR/DSRs to signal completion.
+ do {
+ cyg_drv_cond_wait (&stm32_bus->condvar);
+ } while (!(stm32_bus->tx_dma_done && stm32_bus->rx_dma_done));
+
+ cyg_drv_dsr_unlock ();
+ cyg_drv_mutex_unlock (&stm32_bus->mutex);
+ }
+
+
+ // Disable the SPI controller.
+ reg_addr = spi_reg_base + CYGHWR_HAL_STM32_SPI_CR1;
+ HAL_WRITE_UINT32 (reg_addr, stm32_device->spi_cr1_val);
+
+ // Deassert the chip select.
+ if (drop_cs && !tick_only) {
+ CYGACC_CALL_IF_DELAY_US (stm32_device->cs_dw_udly);
+ stm32_spi_chip_select (stm32_bus->setup->cs_gpio_list[stm32_device->dev_num], false);
+ stm32_bus->cs_up = false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Calculate BR bits for SPI_CR1.
+static int calculate_br_bits
+ (cyg_spi_cortexm_stm32_bus_t* bus, cyg_uint32 *target_clockrate, cyg_uint32 *br)
+{
+ cyg_uint32 divided_clk;
+
+ // Calculate the maximum viable bus speed.
+ divided_clk = *bus->setup->apb_freq / 2;
+ for (*br = 0; (*br < 7) && (divided_clk > *target_clockrate); (*br)++)
+ divided_clk >>= 1;
+
+ if ( divided_clk <= *target_clockrate )
+ return 0;
+
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// Initialise SPI interfaces on startup.
+
+static void CYGBLD_ATTRIB_C_INIT_PRI(CYG_INIT_BUS_SPI)
+stm32_spi_init(void)
+{
+ spi_diag("\n");
+#if defined(CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3) && \
+ defined(CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3_DISABLE_DEBUG_PORT)
+ // Disable debug port, freeing up SPI bus 3 pins.
+ cyg_uint32 reg_val;
+ HAL_READ_UINT32 (CYGHWR_HAL_STM32_AFIO + CYGHWR_HAL_STM32_AFIO_MAPR, reg_val);
+ reg_val &= ~((cyg_uint32) CYGHWR_HAL_STM32_AFIO_MAPR_SWJ_MASK);
+ reg_val |= CYGHWR_HAL_STM32_AFIO_MAPR_SWJ_SWDPDIS;
+ HAL_WRITE_UINT32 (CYGHWR_HAL_STM32_AFIO + CYGHWR_HAL_STM32_AFIO_MAPR, reg_val);
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1
+ stm32_spi_bus_setup (&cyg_spi_stm32_bus1);
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2
+ stm32_spi_bus_setup (&cyg_spi_stm32_bus2);
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3
+ stm32_spi_bus_setup (&cyg_spi_stm32_bus3);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Start a SPI transaction.
+
+static void stm32_transaction_begin
+ (cyg_spi_device* device)
+{
+ cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+ cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+ cyg_haladdress reg_addr;
+ cyg_uint32 reg_data, br;
+
+ spi_diag("\n");
+ // On the first transaction, generate the values to be programmed into the
+ // SPI configuration registers for this device and cache them. This avoids
+ // having to recalculate the prescaler for every transaction.
+ if (!stm32_device->spi_cr1_val) {
+ reg_data = CYGHWR_HAL_STM32_SPI_CR1_MSTR |
+ CYGHWR_HAL_STM32_SPI_CR1_SSI | CYGHWR_HAL_STM32_SPI_CR1_SSM;
+ if (stm32_device->cl_pol)
+ reg_data |= CYGHWR_HAL_STM32_SPI_CR1_CPOL;
+ if (stm32_device->cl_pha)
+ reg_data |= CYGHWR_HAL_STM32_SPI_CR1_CPHA;
+ if (stm32_device->bus_16bit)
+ reg_data |= CYGHWR_HAL_STM32_SPI_CR1_DFF;
+
+ // Get divider bits
+ if ( 0 != calculate_br_bits(stm32_bus, (cyg_uint32 *)&(stm32_device->cl_brate), &br) )
+ CYG_ASSERT (false, "STM32 SPI : Cannot run bus slowly enough for peripheral.");
+
+ reg_data |= CYGHWR_HAL_STM32_SPI_CR1_BR (br);
+
+ // Cache the configuration register settings.
+ stm32_device->spi_cr1_val = reg_data;
+ }
+
+ // Set up the SPI controller.
+ reg_addr = stm32_bus->setup->spi_reg_base + CYGHWR_HAL_STM32_SPI_CR1;
+ HAL_WRITE_UINT32 (reg_addr, stm32_device->spi_cr1_val);
+}
+
+//-----------------------------------------------------------------------------
+// Run a transaction transfer.
+
+static void stm32_transaction_transfer
+ (cyg_spi_device* device, cyg_bool polled, cyg_uint32 count,
+ const cyg_uint8* tx_data, cyg_uint8* rx_data, cyg_bool drop_cs)
+{
+ cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+ cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+ // Check for unsupported transactions.
+ CYG_ASSERT (count > 0, "STM32 SPI : Null transfer requested.");
+
+ spi_diag("count %d\n", count);
+ if( tx_data ) spi_dump_buf(tx_data, count );
+
+ // We check that the buffers are half-word aligned and that count is a
+ // multiple of two in order to carry out the 16-bit transfer.
+ if (stm32_device->bus_16bit) {
+ CYG_ASSERT (!(count & 1) && !((cyg_uint32) tx_data & 1) && !((cyg_uint32) rx_data & 1),
+ "STM32 SPI : Misaligned data in 16-bit transfer.");
+ }
+
+ // Perform transfer via the bounce buffers.
+ if (stm32_bus->setup->bbuf_size != 0) {
+ cyg_uint8* tx_local = NULL;
+ cyg_uint8* rx_local = NULL;
+
+ // If the requested transfer is too large for the bounce buffer we assert
+ // in debug builds and truncate in production builds.
+ if (count > stm32_bus->setup->bbuf_size) {
+ CYG_ASSERT (false, "STM32 SPI : Transfer exceeds bounce buffer size.");
+ count = stm32_bus->setup->bbuf_size;
+ }
+ if (tx_data != NULL) {
+ tx_local = stm32_bus->setup->bbuf_tx;
+ memcpy (tx_local, tx_data, count);
+ }
+ if (rx_data != NULL) {
+ rx_local = stm32_bus->setup->bbuf_rx;
+ }
+ spi_transaction_dma (device, false, polled, count, tx_local, rx_local, drop_cs);
+ if (rx_data != NULL) {
+ memcpy (rx_data, rx_local, count);
+ }
+ }
+
+ // Perform conventional transfer.
+ else {
+ spi_transaction_dma (device, false, polled, count, tx_data, rx_data, drop_cs);
+ }
+
+ spi_diag("done\n");
+ if( rx_data ) spi_dump_buf(rx_data, count );
+
+}
+
+//-----------------------------------------------------------------------------
+// Carry out a bus tick operation - this just pushes the required number of
+// zeros onto the bus, leaving the chip select in its current state.
+
+static void stm32_transaction_tick
+ (cyg_spi_device* device, cyg_bool polled, cyg_uint32 count)
+{
+ cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+ // Check for unsupported transactions.
+ CYG_ASSERT (count > 0, "STM32 SPI : Null transfer requested.");
+
+ spi_diag("count %d\n", count);
+
+ // We check that count is a multiple of two in order to carry out the 16-bit transfer.
+ if (stm32_device->bus_16bit) {
+ CYG_ASSERT (!(count & 1),
+ "STM32 SPI : Misaligned data in 16-bit transfer.");
+ }
+
+ // Perform null transfer.
+ spi_transaction_dma (device, true, polled, count, NULL, NULL, false);
+}
+
+//-----------------------------------------------------------------------------
+// Terminate a SPI transaction, disabling the SPI controller.
+
+static void stm32_transaction_end
+ (cyg_spi_device* device)
+{
+ cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+ cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+ cyg_haladdress reg_addr;
+
+ spi_diag("\n");
+ // Ensure that the chip select is deasserted.
+ if (stm32_bus->cs_up) {
+ CYGACC_CALL_IF_DELAY_US (stm32_device->cs_dw_udly);
+ stm32_spi_chip_select (stm32_bus->setup->cs_gpio_list[stm32_device->dev_num], false);
+ stm32_bus->cs_up = false;
+ }
+
+ // Ensure the SPI controller is disabled.
+ reg_addr = stm32_bus->setup->spi_reg_base + CYGHWR_HAL_STM32_SPI_CR1;
+ HAL_WRITE_UINT32 (reg_addr, stm32_device->spi_cr1_val);
+}
+
+//-----------------------------------------------------------------------------
+static int stm32_get_config
+ (cyg_spi_device* device, cyg_uint32 key, void* buf, cyg_uint32* len)
+{
+ cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+ cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+ cyg_uint32* data_p = buf;
+
+ switch (key)
+ {
+ case CYG_IO_GET_CONFIG_SPI_CLOCKRATE :
+ // Sanity check
+ if (NULL == len) {
+ CYG_ASSERT (false, "STM32 SPI : Null pointer as len argument for stm32_get_config().");
+ return -1;
+ }
+ if (sizeof(cyg_uint32) != *len) {
+ CYG_ASSERT (false, "STM32 SPI : Invalid length with stm32_get_config().");
+ return -1;
+ }
+ if (NULL == buf) {
+ CYG_ASSERT (false, "STM32 SPI : Null poiter as buf argument for stm32_get_config().");
+ return -1;
+ }
+
+ *data_p = *stm32_bus->setup->apb_freq >> ((( stm32_device->spi_cr1_val >> 3 ) & 7) + 1 ) ;
+ return 0;
+
+ default :
+ break;
+ }
+
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+static int stm32_set_config
+ (cyg_spi_device* device, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+ cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+ cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+ cyg_uint32 br;
+
+ switch (key)
+ {
+ case CYG_IO_SET_CONFIG_SPI_CLOCKRATE :
+ // Sanity check
+ if (NULL == len) {
+ CYG_ASSERT (false, "STM32 SPI : Null pointer as len argument for stm32_set_config().");
+ return -1;
+ }
+ if (sizeof(cyg_uint32) != *len) {
+ CYG_ASSERT (false, "STM32 SPI : Invalid length with stm32_set_config().");
+ return -1;
+ }
+ if (NULL == buf) {
+ CYG_ASSERT (false, "STM32 SPI : Null pointer as buf argument for stm32_set_config().");
+ return -1;
+ }
+
+ // Get divider bits
+ if ( 0 != calculate_br_bits(stm32_bus, (cyg_uint32 *)buf, &br) ) {
+ CYG_ASSERT (false, "STM32 SPI : Cannot run bus as slowly as requested.");
+ return -1;
+ }
+
+ // Update the cache of the configuration register settings.
+ stm32_device->spi_cr1_val &= ~CYGHWR_HAL_STM32_SPI_CR1_BR(7);
+ stm32_device->spi_cr1_val |= CYGHWR_HAL_STM32_SPI_CR1_BR(br);
+
+ return 0;
+
+ default :
+ break;
+ }
+
+ return -1;
+}
+
+//=============================================================================
diff --git a/ecos/packages/devs/spi/cortexm/stm32/current/tests/loopback.c b/ecos/packages/devs/spi/cortexm/stm32/current/tests/loopback.c
new file mode 100644
index 0000000..876ab45
--- /dev/null
+++ b/ecos/packages/devs/spi/cortexm/stm32/current/tests/loopback.c
@@ -0,0 +1,185 @@
+//=============================================================================
+//
+// loopback.c
+//
+// Standalone SPI loopback test.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Chris Holgate
+// Date: 2008-11-27
+// Purpose: STM32 SPI loopback test
+// Description: Standalone SPI loopback test.
+// Usage: Compile as a standalone application.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//=============================================================================
+// This is a quick loopback test for the STM32 SPI driver. It only checks
+// the data transfer functionality - chip select handling will require
+// testing with external devices. In order to run the test, the MOSI and
+// MISO pins for the test port need to be shorted together to provide an
+// external loopback. Don't do this on a bus which has external devices
+// attached unless you first make sure that none of them are connected to
+// the chip select used by the test harness.
+// The default port and chip select used for this test are SPI bus 1,
+// chip select 0. These can be changed by editing the loopback_device
+// data structure directly.
+// Note that this is intended to be run as a standalone test and not as part
+// of the standard board tests since it requires a hardware modification.
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/testcase.h> // Test macros
+#include <cyg/infra/cyg_ass.h> // Assertion macros
+#include <cyg/infra/diag.h> // Diagnostic output
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/io/spi.h> // Common SPI API
+#include <cyg/io/spi_stm32.h> // STM32 data structures
+
+#include <string.h>
+
+//---------------------------------------------------------------------------
+// Thread data structures.
+
+cyg_uint8 stack [CYGNUM_HAL_STACK_SIZE_TYPICAL];
+cyg_thread thread_data;
+cyg_handle_t thread_handle;
+
+externC cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus2;
+
+//---------------------------------------------------------------------------
+// SPI loopback device driver data structures.
+
+cyg_spi_cortexm_stm32_device_t loopback_device = {
+ .spi_device.spi_bus = &cyg_spi_stm32_bus1.spi_bus,
+ .dev_num = 0 , // Only 1 device.
+ .cl_pol = 1,
+ .cl_pha = 1,
+ .cl_brate = 8000000, // Nominal 8Mhz.
+ .cs_up_udly = 1,
+ .cs_dw_udly = 1,
+ .tr_bt_udly = 1,
+ .bus_16bit = false,
+};
+
+//---------------------------------------------------------------------------
+
+const char tx_data[] = "Testing, testing, 12, 123.";
+const char tx_data1[] = "Testing extended API...";
+const char tx_data2[] = "Testing extended API for a second transaction.";
+
+char rx_data [sizeof(tx_data)];
+char rx_data1 [sizeof(tx_data1)];
+char rx_data2 [sizeof(tx_data2)];
+
+//---------------------------------------------------------------------------
+// Run single loopback transaction using simple transfer API call.
+
+void run_test_1 (cyg_bool polled)
+{
+ diag_printf ("Test 1 : Simple transfer test (polled = %d).\n", polled ? 1 : 0);
+ cyg_spi_transfer (&loopback_device.spi_device, polled, sizeof (tx_data),
+ (const cyg_uint8*) &tx_data[0], (cyg_uint8*) &rx_data[0]);
+
+ diag_printf (" Tx data : %s\n", tx_data);
+ diag_printf (" Rx data : %s\n", rx_data);
+ CYG_ASSERT (memcmp (tx_data, rx_data, sizeof (tx_data)) == 0,
+ "Simple transfer loopback failed - mismatched data.\n");
+}
+
+//---------------------------------------------------------------------------
+// Run two loopback transactions using extended transfer API.
+
+void run_test_2 (cyg_bool polled)
+{
+ diag_printf ("Test 2 : Extended API test (polled = %d).\n", polled ? 1 : 0);
+ cyg_spi_transaction_begin (&loopback_device.spi_device);
+ cyg_spi_transaction_transfer (&loopback_device.spi_device, polled, sizeof (tx_data1),
+ (const cyg_uint8*) &tx_data1[0], (cyg_uint8*) &rx_data1[0], false);
+ cyg_spi_transaction_transfer (&loopback_device.spi_device, polled, sizeof (tx_data2),
+ (const cyg_uint8*) &tx_data2[0], (cyg_uint8*) &rx_data2[0], false);
+ cyg_spi_transaction_end (&loopback_device.spi_device);
+
+ diag_printf (" Tx data 1 : %s\n", tx_data1);
+ diag_printf (" Rx data 1 : %s\n", rx_data1);
+ diag_printf (" Tx data 2 : %s\n", tx_data2);
+ diag_printf (" Rx data 2 : %s\n", rx_data2);
+ CYG_ASSERT (memcmp (tx_data1, rx_data1, sizeof (tx_data1)) == 0,
+ "Simple transfer loopback failed - mismatched data (transfer 1).\n");
+ CYG_ASSERT (memcmp (tx_data2, rx_data2, sizeof (tx_data2)) == 0,
+ "Simple transfer loopback failed - mismatched data (transfer 2).\n");
+}
+
+//---------------------------------------------------------------------------
+// Run all PL022 SPI interface loopback tests.
+
+void run_tests (void)
+{
+ diag_printf ("Running STM32 SPI driver loopback tests.\n");
+ run_test_1 (true);
+ run_test_1 (false);
+ run_test_2 (true);
+ run_test_2 (false);
+ CYG_TEST_PASS_FINISH ("Loopback tests ran OK");
+}
+
+//---------------------------------------------------------------------------
+// User startup - tests are run in their own thread.
+
+void cyg_user_start(void)
+{
+ CYG_TEST_INIT();
+ cyg_thread_create(
+ 10, // Arbitrary priority
+ (cyg_thread_entry_t*) run_tests, // Thread entry point
+ 0, //
+ "test_thread", // Thread name
+ &stack[0], // Stack
+ CYGNUM_HAL_STACK_SIZE_TYPICAL, // Stack size
+ &thread_handle, // Thread handle
+ &thread_data // Thread data structure
+ );
+ cyg_thread_resume(thread_handle);
+ cyg_scheduler_start();
+}
+
+//=============================================================================
diff --git a/ecos/packages/devs/spi/freescale/dspi/current/ChangeLog b/ecos/packages/devs/spi/freescale/dspi/current/ChangeLog
new file mode 100644
index 0000000..ca08fc7
--- /dev/null
+++ b/ecos/packages/devs/spi/freescale/dspi/current/ChangeLog
@@ -0,0 +1,79 @@
+2013-07-09 Mike Jones <mjones@proclivis.com>
+
+ * src/spi_freescale_dspi.c: Fix: Kinetis DSPI infinite polling
+ [ Bugzilla 10011879 ]
+
+2013-05-08 Ilija Kocho <ilijak@siva.com.mk>
+
+ * src/spi_freescale_dspi.cdl: Add CYGINT_DEVS_SPI_DMA_USE
+ * src/spi_freescale_dspi.c: Fix: Disable DMA requests for transfers
+ that don't use DMA. [ Bugzilla 1001815 ]
+
+2013-04-01 Ilija Kocho <ilijak@siva.com.mk>
+
+ * include/spi_freescale_dspi.h, include/spi_freescale_busses.inl
+ * include/spi_freescale_dspi_io.h, src/spi_freescale_dspi.c:
+ Optimised receiving of messages that fit in FIFO. Add clock gating.
+ Fix race condition bug in dspi_transaction_end(). [ Bugzilla 1001815 ]
+
+2013-02-06 Stefan Singer <stefan.singer@freescale.com>
+ Ilija Kocho <ilijak@siva.com.mk>
+
+ * include/spi_freescale_dspi.h, include/spi_freescale_busses.inl
+ * include/spi_freescale_dspi_io.h, include/spi_freescale_dspi_bd.h,
+ * src/spi_freescale_dspi.c:
+ enhanced endianness support for devices with big and little endian
+ added support for MPC5xxx in addition to Kinetis
+ extended support for up to 8 DSPIs
+ (see Bugzilla 1001752).
+
+2012-12-28 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/spi_freescale_dspi.cdl, src/spi_freescale_dspi.c:
+ Tick-only now has option to beehive like other drivers
+ rather than RM (see Bugzilla 1001676).
+ Fixed bug with dropping CS. Chip select options consolidated in a for loop.
+
+ * tests/spi_loopback.c: New file. Add looback test.
+ [Bugzilla 1001719]
+
+2012-05-04 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/spi_freescale_dspi.cdl:
+ * include/spi_freescale_dspi_buses.inl
+ * src/spi_freescale_dspi.c:
+ Add: support for 32 channel eDMA, support for cached memory.
+ [Bugzilla 1001579]
+
+2012-01-06 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/spi_freescale_dspi.cdl:
+ * include/spi_freescale_dspi.h
+ * include/spi_freescale_dspi_io.h:
+ * include/spi_freescale_dspi_buses.inl
+ * src/spi_freescale_dspi.c:
+ New package -- Freescale DSPI SPI driver. [Bugzilla 1001450]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/spi/freescale/dspi/current/cdl/spi_freescale_dspi.cdl b/ecos/packages/devs/spi/freescale/dspi/current/cdl/spi_freescale_dspi.cdl
new file mode 100644
index 0000000..f1be8ba
--- /dev/null
+++ b/ecos/packages/devs/spi/freescale/dspi/current/cdl/spi_freescale_dspi.cdl
@@ -0,0 +1,387 @@
+##=============================================================================
+##
+## spi_freescale_dspi.cdl
+##
+## Freescale DSPI driver configuration options.
+##
+##=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): Ilija Kocho
+## Date: 2011-11-03
+## Purpose: Configure Freescale DSPI driver.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+cdl_package CYGPKG_DEVS_SPI_FREESCALE_DSPI {
+ display "Freescale DSPI driver"
+ description "
+ This package provides SPI driver support for the Freescale
+ microcontrollers that employ DSPI interface."
+
+ parent CYGPKG_IO_SPI
+ active_if CYGPKG_IO_SPI
+ requires CYGPKG_HAL_CORTEXM_KINETIS || CYGPKG_HAL_POWERPC_MPC5xxx
+
+ hardware
+ include_dir cyg/io
+ compile spi_freescale_dspi.c
+
+ cdl_option CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE {
+ display "DSPI FIFO size"
+ flavor data
+ default_value 4
+ legal_values { 4 5 6 7 8 }
+ }
+
+ cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI_CTAR_NUM {
+ display "CTAR registers"
+ flavor data
+ calculated 2
+
+ description "DSPI can have from 2 to 8 CTAR registers that keep
+ transfer communication settings. In eCos CTAR0 is used for
+ all normal transfers while CTAR1 is used as auxiliary for
+ 'transaction end' (non)transfer."
+
+ cdl_component CYGHWR_DEVS_SPI_FREESCALEDSPI_DSPI_CTAR1_AUX {
+ display "CTAR1 Aux settings"
+ flavor none
+ no_define
+
+ cdl_component CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_SPEED {
+ display "Nominal clock speed Hz"
+ flavor data
+ default_value 25000000
+
+ cdl_option CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_USE_DBR {
+ display "Use double baud rate"
+ flavor bool
+ default_value 1
+ description "Double baud rate is a feature of Freescale DSPI
+ that may provide higher baud rates but duty the cycle may be
+ different than 50/50 depdent on scaler/prescaler setting
+ for achieved baud rate."
+ }
+ }
+
+ cdl_option CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_CS_DELAY {
+ display "Nominal chip select delay (units)"
+ flavor data
+ legal_values { 1 to 1000 }
+ default_value 1
+ }
+
+ cdl_option CYGHWR_DEVS_FREESCALE_DSPI_DSPI_CTAR1_AUX_DELAY_UNIT {
+ display "Chip select delay unit (ns)"
+ flavor data
+ calculated 100
+ }
+ }
+ }
+
+ cdl_interface CYGINT_DEVS_SPI_DSPI_DMA_USE {
+ display "DSPI DMA use"
+ flavor data
+ description "Number of DMA channels used by DSPI buses."
+ }
+
+ for { set ::spibus 0 } { $::spibus < 8 } { incr ::spibus } {
+
+ cdl_interface CYGINT_DEVS_SPI_FREESCALE_DSPI[set ::spibus] {
+ display "Number of devices using DSPI bus [set ::spibus]"
+ }
+
+ cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus] {
+ display "Freescale DSPI bus [set ::spibus]"
+ description "Enable DSPI bus [set :: spibus]."
+ flavor bool
+ default_value CYGINT_DEVS_SPI_FREESCALE_DSPI[set ::spibus]
+ active_if CYGINT_DEVS_SPI_FREESCALE_DSPI[set ::spibus]
+
+ implements CYGINT_HAL_DMA
+ requires CYGPKG_HAL_FREESCALE_EDMA
+
+ cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_CS {
+ display "Chip-selects"
+ flavor none
+ no_define
+ cdl_option CYHGWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PCSS {
+ display "Chip-select Strobe enable"
+ flavor bool
+ default_value 0
+
+ requires CYHGWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PCSS == 1 \
+ implies CYGHWR_FREESCALE_DSPI[set ::spibus]_CS5 == 0
+ }
+
+ for { set ::spics 0 } { $::spics < 5 } { incr ::spics } {
+ cdl_interface CYGINT_FREESCALE_DSPI[set ::spibus]_CS[set ::spics] {
+ flavor bool
+ requires CYGHWR_FREESCALE_DSPI[set ::spibus]_CS[set ::spics] == 1
+ display "Use CS[set ::spics]"
+ }
+
+ cdl_component CYGHWR_FREESCALE_DSPI[set ::spibus]_CS[set ::spics] {
+ display "CS[set ::spics]"
+ flavor bool
+ default_value 0
+ cdl_option CYGHWR_FREESCALE_DSPI[set ::spibus]_CS[set ::spics]_IS {
+ display "CS[set ::spics] Inactive state Hi(1) Lo(0)"
+ flavor data
+ no_define
+ default_value { 1 }
+ legal_values { 0 1 }
+ }
+ }
+ }
+
+ cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PCSIS {
+ display "Peripheral CS inactive states"
+ flavor data
+ calculated (0x0 + \
+ (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS0_IS) == 1 ? 1 : 0) + \
+ (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS1_IS) == 1 ? 2 : 0) + \
+ (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS2_IS) == 1 ? 4 : 0) + \
+ (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS3_IS) == 1 ? 8 : 0) + \
+ (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS4_IS) == 1 ? 16 : 0) + \
+ (get_data(CYGHWR_FREESCALE_DSPI[set ::spibus]_CS5_IS) == 1 ? 32 : 0))
+ }
+ }
+
+ cdl_interface CYGINT_FREESCALE_DSPI[set ::spibus]_HAS_MASS {
+ description "SPI bus serves mass data device(s)."
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PUSHQUE_SIZE {
+ display "Queue buffer size"
+ description "
+ DSPI requires a command for every transfer so output
+ data must be re-packed in additional buffer prior to
+ being submitted to DMA.
+ If Queue capacity is same as DSPI FIFO size, the minimal
+ legal value, the DMA is not needed so no buffer memory
+ is allocated. Note: For every entry, byte (8 bit transfer)
+ or half word (16 bit transfer) a whole 32 bit word
+ is being allocated."
+
+ legal_values { CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE to 2048 }
+ flavor data
+ default_value CYGINT_FREESCALE_DSPI[set ::spibus]_HAS_MASS ? 128 : \
+ CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE
+ }
+
+ cdl_interface CYGINT_DEVS_SPI_DSPI[set ::spibus]_USES_DMA {
+ flavor bool
+ }
+
+ cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_TX_DMA_CHAN {
+ display "TX DMA channel"
+ flavor data
+ implements CYGINT_DEVS_SPI_DSPI_DMA_USE
+ implements CYGINT_DEVS_SPI_DSPI[set ::spibus]_USES_DMA
+
+ active_if CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PUSHQUE_SIZE > \
+ CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE
+ default_value 4 + [set ::spibus] * 2
+ legal_values { 0 to (CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM-1) }
+ description "DMA channel assigned to the trasmitter of SPI bus"
+
+ cdl_component CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_TX_DMA_PRI {
+ display "Transmit DMA channel priority"
+ flavor data
+ legal_values { 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 255 }
+ default_value 255
+ description "
+ DMA can work in either round robin or preeptve arbitration
+ mode. In preemptive mode, DMA each channel has unique priority,
+ lower number meaning lower priority.
+ 255 is a phony meaning \"default channel priority\"."
+
+ cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_TX_DMA_ECP {
+ display "Enable channel preemption"
+ flavor data
+ legal_values { 0 1 }
+ default_value 0
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_TX_DMA_DPA {
+ display "Disable preempt ability"
+ flavor data
+ legal_values { 0 1 }
+ default_value 0
+ }
+
+ }
+
+ cdl_option CYGOPT_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_TCD_SECTION {
+ display "DMA TCD section"
+ flavor data
+ default_value CYGHWR_HAL_EDMA_TCD_SECTION
+
+ description "
+ Section in which will be DMA Transfer Control
+ Descriptors shall reside"
+ }
+ }
+
+ cdl_component CYGHWR_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_RX_DMA_CHAN {
+ display "RX DMA channel"
+ flavor data
+ implements CYGINT_DEVS_SPI_DSPI_DMA_USE
+ implements CYGINT_DEVS_SPI_DSPI[set ::spibus]_USES_DMA
+
+ active_if CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_PUSHQUE_SIZE > \
+ CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE
+ default_value 5 + [set ::spibus] * 2
+ legal_values { 0 to (CYGNUM_HAL_FREESCALE_EDMA_CHAN_NUM-1) }
+ description "DMA channel assigned to the receiver of SPI bus"
+
+ cdl_component CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_RX_DMA_PRI {
+ display "Receive DMA channel priority"
+ flavor data
+ legal_values { 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 255 }
+ default_value 255
+ description "
+ DMA can work in either round robin or preeptve arbitration
+ mode. In preemptive mode, DMA each channel has unique priority,
+ lower number meaning lower priority.
+ 255 is a phony meaning \"default channel priority\"."
+
+ cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_RX_DMA_ECP {
+ display "Enable channel preemption"
+ flavor data
+ legal_values { 0 1 }
+ default_value 0
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_RX_DMA_DPA {
+ display "Disable preempt ability"
+ flavor data
+ legal_values { 0 1 }
+ default_value 0
+ }
+ }
+ }
+
+ cdl_option CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_ISR_PRI {
+ display "Interrupt priority"
+ flavor data
+ requires CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_ISR_PRI_SP
+ calculated CYGNUM_DEVS_SPI_FREESCALE_DSPI[set ::spibus]_ISR_PRI_SP
+ description "Interrupt priority set-point is provided by HAL"
+ }
+ }
+ }
+
+ cdl_option CYGOPT_DEVS_SPI_FREESCALE_DSPI_TICK_ONLY_DROPS_CS {
+ display "Tick-only drops CS"
+ default_value 0
+
+ description "
+ eCos Reference Manual states that CS should drop prior to sending ticks,
+ but other drivers (so far) do not touch the CS. This option selects
+ between conformance with manual or compatibility with other drivers."
+ }
+
+ cdl_option CYGPKG_DEVS_SPI_FREESCALE_DSPI_DEBUG_LEVEL {
+ display "Driver debug output level"
+ flavor data
+ legal_values { 0 1 2 3 }
+ default_value 0
+ description "
+ This option specifies the level of debug data output by
+ the Freescale DSPI device driver. A value of 0 signifies
+ no debug data output; 1 signifies normal debug data
+ output; and 2 signifies maximum debug data output."
+ }
+
+
+ cdl_component CYGPKG_DEVS_SPI_FREESCALE_DSPI_OPTIONS {
+ display "Freescale DSPI driver build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_DEVS_SPI_FREESCALE_DSPI_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Freescale DSPI driver. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_SPI_FREESCALE_DSPI_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the Freescale DSPI driver. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+
+ cdl_component CYGPKG_DEVS_SPI_FREESCALE_DSPI_TESTS {
+ display "Freescale DSPI tests"
+ flavor data
+ no_define
+ calculated { CYGBLD_DEVS_SPI_FREESCALE_DSPI_LOOPBACK_TEST ? "tests/spi_loopback" : "" }
+
+ cdl_option CYGBLD_DEVS_SPI_FREESCALE_DSPI_LOOPBACK_TEST {
+ display "Build Freescale DSPI loopback test"
+ flavor bool
+ no_define
+ default_value 0
+ requires { CYGHWR_DEVS_SPI_FREESCALE_DSPI0 ||
+ CYGHWR_DEVS_SPI_FREESCALE_DSPI1 ||
+ CYGHWR_DEVS_SPI_FREESCALE_DSPI2 }
+ description "
+ This option enables the building of the Freescale DSPI loopback test.
+ Refer to the comments in tests/loopback.c for details of how to
+ use this test."
+ }
+ }
+}
+# EOF spi_freescale_dspi.cdl
diff --git a/ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi.h b/ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi.h
new file mode 100644
index 0000000..f1fe610
--- /dev/null
+++ b/ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi.h
@@ -0,0 +1,207 @@
+#ifndef CYGONCE_DEVS_SPI_FREESCALE_DSPI_H
+#define CYGONCE_DEVS_SPI_FREESCALE_DSPI_H
+//=============================================================================
+//
+// spi_freescale_dspi.h
+//
+// Header definitions for Freescale DSPI driver.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ilijak
+// Date: 2011-11-03
+// Purpose: Freescale DSPI driver definitions.
+// Description:
+// Usage: #include <cyg/io/spi_freescale_dspi.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+#include <pkgconf/devs_spi_freescale_dspi.h>
+#include <pkgconf/hal_freescale_edma.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+#include <cyg/hal/freescale_edma.h>
+#include <cyg/io/spi_freescale_dspi_io.h>
+
+//-----------------------------------------------------------------------------
+// Macro for defining a SPI device and attaching it to the appropriate bus.
+//
+// _name_ is the name of the SPI device. This will be used to reference a
+// data structure of type cyg_spi_device which can be passed to the
+// SPI driver API without needing a cast.
+// _bus_ is the bus number to which this device is attached (0, 1 or 2).
+// _csnum_ is the chip select line used for this device, numbered from 0.
+// _fmsz_ is set device SPI frame size (bits)
+// _clpol_ is the SPI bus clock polarity used by the device. This must be
+// set to 1 if clock inactive state is high, 0 if clock inactive
+// state is low.
+// _clpha_ is the SPI bus clock phase used by the device.
+// _brate_ is the SPI bus clock baud rate used by the device, measured in Hz.
+// _csup_dly_ is the minimum delay between chip select assert and transfer
+// start, measured in microseconds.
+// _csdw_dly_ is the minimum delay between transfer end and chip select deassert,
+// measured in delay units.
+// _trbt_dly_ is the minimum delay between consecutive transfers.
+// _dlu_ is delay unit in ns
+// _dbr_ is enabling double baud rate feature
+
+
+#define CYGNUM_DSPI_DELAY_UNIT(__val) (__val/10)
+
+#define CYG_SPI_BUS_NAME(_b_) cyg_spi_dspi_bus ## _b_
+
+#define CYG_DEVS_SPI_FREESCALE_DSPI_DEVICE( \
+ _name_, _bus_, _csnum_, _fmsz_, _clpol_, _clpha_, _brate_, _csup_dly_, _csdw_dly_, _trbt_dly_, _dlu_, _dbr_ \
+) \
+ cyg_spi_freescale_dspi_device_t _name_ ##_fs_dspi CYG_SPI_DEVICE_ON_BUS(_bus_) = { \
+{ .spi_bus = (cyg_spi_bus*) &CYG_SPI_BUS_NAME(_bus_) }, \
+ .dev_num = _csnum_, \
+ .clocking.bus_16bit = _fmsz_ > 8 ? 1 : 0, \
+ .clocking.frame_size = _fmsz_, \
+ .clocking.cl_pol = _clpol_, \
+ .clocking.cl_pha = _clpha_, \
+ .clocking.cl_brate = _brate_, \
+ .clocking.cs_up_udly = _csup_dly_, \
+ .clocking.cs_dw_udly = _csdw_dly_, \
+ .clocking.tr_bt_udly = _trbt_dly_, \
+ .clocking.dl_unit = CYGNUM_DSPI_DELAY_UNIT(_dlu_), \
+ .clocking.cl_dbr = _dbr_, \
+ .clocking.dspi_ctar = 0 \
+}; \
+extern cyg_spi_device _name_ __attribute__((alias ( #_name_ "_fs_dspi" )))
+
+enum { SPI_DMA_CHAN_TX_I, SPI_DMA_CHAN_RX_I };
+
+//-----------------------------------------------------------------------------
+// Freescale DSPI bus configuration and state.
+
+typedef struct cyg_spi_freescale_dspi_bus_setup_s
+{
+ cyghwr_devs_freescale_dspi_t* dspi_p; // Base address of SPI register block.
+ cyghwr_hal_freescale_dma_set_t* dma_set_p; // DMA configuration block.
+ cyg_vector_t intr_num; // DSPI interrupt vector
+ cyg_priority_t intr_prio; // Interrupt priority
+ cyg_uint32 mcr_opt ; // Module Configuratyon Register options
+ const cyg_uint32* spi_pin_list_p; // List of GPIOs used by the SPI interface.
+ const cyg_uint32* cs_pin_list_p; // List of GPIOs used as chip selects.
+ cyg_uint16 clk_gate; // Clock gate
+ cyg_uint8 cs_pin_num; // Number of chip selects for this bus.
+} cyg_spi_freescale_dspi_bus_setup_t;
+
+#define SPI_DMA_CHAN_I(__dma_set,__rt) (__dma_set->chan_p[SPI_DMA_CHAN_ ## __rt ## _I].dma_chan_i)
+
+typedef struct cyg_spi_freescale_dspi_bus_s
+{
+ // ---- Upper layer data ----
+ cyg_spi_bus spi_bus; // Upper layer SPI bus data.
+
+ // ---- Bus configuration constants ----
+ const cyg_spi_freescale_dspi_bus_setup_t* setup_p;
+ // ---- Driver state (private) ----
+ // DMA transfer control descriptors
+ const cyghwr_hal_freescale_edma_tcd_t* tx_dma_tcd_ini_p; // TCD init.
+ const cyghwr_hal_freescale_edma_tcd_t* rx_dma_tcd_ini_p; // data
+ volatile cyghwr_hal_freescale_edma_tcd_t* rx_dma_tcd_p; // DMA TCD (RX)
+ volatile cyghwr_hal_freescale_edma_tcd_t* tx_dma_tcd_p; // DMA TCD (TX)
+ volatile cyg_uint32* pushque_p; // Tx command queue
+ cyg_uint16 pushque_n; // Tx command buffer size
+ cyg_uint8 txfifo_n; // TxFIFO size
+ cyg_uint8 rxfifo_n; // RxFIFO size
+ cyg_interrupt intr_data; // Interrupt state
+ cyg_handle_t intr_handle; // Interrupt handle
+ cyg_drv_mutex_t transfer_mutex; // Transfer mutex.
+ cyg_drv_cond_t transfer_done; // Transfer condition variable.
+ cyg_uint32 clock_freq; // Clock provided by hal
+} cyg_spi_freescale_dspi_bus_t;
+
+//-----------------------------------------------------------------------------
+// Freescale DSPI device.
+
+typedef struct cyg_freescale_dspi_clocking_s {
+ cyg_uint32 dspi_ctar; // DSPI Clock and Transfer Attributes Rregister shadow.
+ cyg_uint32 cl_brate; // Clock baud rate.
+ cyg_uint8 bus_16bit; // Use 16 bit (1) or 8 bit (0) transfers.
+ cyg_uint8 cl_pol; // Clock polarity (0 or 1).
+ cyg_uint8 cl_pha; // Clock phase (0 or 1).
+ cyg_uint8 cl_dbr; // Use double baud-rate feature if needed
+ cyg_uint8 cs_up_udly; // Minimum delay in us/ns between CS up and transfer start.
+ cyg_uint8 cs_dw_udly; // Minimum delay in us/ns between transfer end and CS down.
+ cyg_uint8 tr_bt_udly; // Minimum delay in us/ns between two transfers.
+ cyg_uint8 dl_unit; // Delay unit (1/10 * ns)
+ cyg_uint8 lsb_first; // LSbit shifted first.
+ cyg_uint8 frame_size; // Device SPI frame size (bits).
+} cyg_freescale_dspi_clocking_t;;
+
+typedef struct cyg_spi_freescale_dspi_device_s
+{
+ // ---- Upper layer data ----
+ cyg_spi_device spi_device; // Upper layer SPI device data.
+
+ // ---- Device setup (user configurable) ----
+ cyg_freescale_dspi_clocking_t clocking;
+ cyg_uint8 dev_num; // Device SPI select.
+ cyg_uint8 chip_sel;
+ // ---- Device state (private) ----
+} cyg_spi_freescale_dspi_device_t;
+
+//-----------------------------------------------------------------------------
+// Exported bus data structures.
+
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI0
+externC cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus0;
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI1
+externC cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus1;
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI2
+externC cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus2;
+#endif
+
+__externC void cyghwr_devs_freescale_dspi_diag(cyg_spi_freescale_dspi_bus_t* spi_bus_p);
+__externC void cyghwr_devs_freescale_dspi_diag_array(char* name_p,
+ volatile cyg_uint32* fifo_p,
+ cyg_uint32 fifo_n);
+
+//=============================================================================
+#endif // CYGONCE_DEVS_SPI_FREESCALE_DSPI_H
diff --git a/ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_buses.inl b/ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_buses.inl
new file mode 100644
index 0000000..5fb16f2
--- /dev/null
+++ b/ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_buses.inl
@@ -0,0 +1,586 @@
+#ifndef SPI_FREESCALE_DSPI_BUSES_INL
+#define SPI_FREESCALE_DSPI_BUSES_INL
+//=============================================================================
+//
+// spi_freescale_dspi_buses.inl
+//
+// SPI bus instantiation for Freescale DSPI
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ilijak
+// Date: 2011-11-09
+// Purpose: Freescale DSPI DSPI bus instantiation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#define PUSHQUE_ALIGN CYGBLD_ATTRIB_ALIGN(4)
+
+#define DSPI_DMA_BANDWIDTH FREESCALE_EDMA_CSR_BWC_0
+
+//-----------------------------------------------------------------------------
+// Instantiate the bus state data structures.
+
+// Some auxiliary macros
+
+#if (CYG_BYTEORDER == CYG_MSBFIRST) // AKA Big endian
+#define EDMA_TCD_SADDR(__bus) \
+ .saddr = (void *)(((unsigned int)&CYGADDR_IO_SPI_FREESCALE_DSPI ## __bus ## _P->popr) + 3)
+#else // AKA Little endian
+#define EDMA_TCD_SADDR(__bus) \
+ .saddr = (cyg_uint32 *)&CYGADDR_IO_SPI_FREESCALE_DSPI ## __bus ## _P->popr
+#endif
+
+#define DSPI_EDMA_CHAN_SET(__bus) \
+static volatile cyg_uint32 \
+dspi ## __bus ## _pushque[CYGNUM_DEVS_SPI_FREESCALE_DSPI ## __bus ## _PUSHQUE_SIZE+4] \
+PUSHQUE_ALIGN EDMA_RAM_BUF_SECTION; \
+ \
+static const cyghwr_hal_freescale_dma_chan_set_t dspi ## __bus ## _dma_chan[2] = \
+{ \
+ { \
+ .dma_src = FREESCALE_DMAMUX_SRC_SPI ## __bus ## _TX \
+ | FREESCALE_DMAMUX_CHCFG_ENBL_M, \
+ .dma_chan_i = CYGHWR_DEVS_SPI_FREESCALE_DSPI ## __bus ## _TX_DMA_CHAN, \
+ .dma_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI ## __bus ## _TX_DMA_PRI, \
+ }, \
+ { \
+ .dma_src = FREESCALE_DMAMUX_SRC_SPI ## __bus ## _RX \
+ | FREESCALE_DMAMUX_CHCFG_ENBL_M, \
+ .dma_chan_i = CYGHWR_DEVS_SPI_FREESCALE_DSPI ## __bus ## _RX_DMA_CHAN, \
+ .dma_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI ## __bus ## _RX_DMA_PRI, \
+ } \
+}; \
+ \
+static cyghwr_hal_freescale_dma_set_t dspi ## __bus ## _dma_set = { \
+ .chan_p = dspi ## __bus ## _dma_chan, \
+ .chan_n = 2 \
+}; \
+ \
+static const cyghwr_hal_freescale_edma_tcd_t dspi ## __bus ## _dma_tcd_tx_ini = \
+{ \
+ .saddr = (cyg_uint32 *) dspi ## __bus ## _pushque, \
+ .soff = 4, \
+ .attr = FREESCALE_EDMA_ATTR_SSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | \
+ FREESCALE_EDMA_ATTR_DSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | \
+ FREESCALE_EDMA_ATTR_SMOD(0) | \
+ FREESCALE_EDMA_ATTR_DMOD(0), \
+ .daddr = (cyg_uint32 *) \
+ &CYGADDR_IO_SPI_FREESCALE_DSPI ## __bus ## _P->pushr, \
+ .doff = 0, \
+ .nbytes.mlno = 4, \
+ .slast = 0, \
+ .citer.elinkno = 1, \
+ .dlast_sga.dlast = 0, \
+ .biter.elinkno = 1, \
+ .csr = DSPI_DMA_BANDWIDTH \
+}; \
+ \
+static const cyghwr_hal_freescale_edma_tcd_t dspi ## __bus ## _dma_tcd_rx_ini = \
+{ \
+ EDMA_TCD_SADDR(__bus), \
+ .soff = 0, \
+ .attr = FREESCALE_EDMA_ATTR_SSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | \
+ FREESCALE_EDMA_ATTR_DSIZE(FREESCALE_EDMA_ATTR_SIZE_32) | \
+ FREESCALE_EDMA_ATTR_SMOD(0) | \
+ FREESCALE_EDMA_ATTR_DMOD(0), \
+ .daddr = NULL, \
+ .doff = 4, \
+ .nbytes.mlno = 4, \
+ .slast = 0, \
+ .citer.elinkno = 1, \
+ .dlast_sga.dlast = 0, \
+ .biter.elinkno = 1, \
+ .csr = DSPI_DMA_BANDWIDTH \
+}
+
+#define DSPI_EDMA_SET_P_YES(__bus) .dma_set_p = &dspi ## __bus ## _dma_set
+#define DSPI_EDMA_SET_P_NULL(__bus) .dma_set_p = NULL
+
+#define DSPI_EDMA_TCD_YES(__bus) \
+ .tx_dma_tcd_p = &CYGHWR_IO_FREESCALE_EDMA0_P-> \
+ tcd[CYGHWR_DEVS_SPI_FREESCALE_DSPI ## __bus ## _TX_DMA_CHAN], \
+ .rx_dma_tcd_p = &CYGHWR_IO_FREESCALE_EDMA0_P-> \
+ tcd[CYGHWR_DEVS_SPI_FREESCALE_DSPI ## __bus ## _RX_DMA_CHAN], \
+ .tx_dma_tcd_ini_p = &dspi ## __bus ## _dma_tcd_tx_ini, \
+ .rx_dma_tcd_ini_p = &dspi ## __bus ## _dma_tcd_rx_ini, \
+ .pushque_p = dspi ## __bus ## _pushque
+
+#define DSPI_EDMA_TCD_NULL(__bus) \
+ .tx_dma_tcd_p = NULL, \
+ .rx_dma_tcd_p = NULL, \
+ .tx_dma_tcd_ini_p = NULL, \
+ .rx_dma_tcd_ini_p = NULL, \
+ .pushque_p = NULL
+
+// End DSPI_EDMA
+
+#define DSPI_BUS_SETUP(__bus) \
+static const cyg_spi_freescale_dspi_bus_setup_t dspi ## __bus ## _setup = { \
+ .dspi_p = CYGADDR_IO_SPI_FREESCALE_DSPI ## __bus ## _P, \
+ .intr_num = CYGNUM_HAL_INTERRUPT_SPI ## __bus, \
+ .intr_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI ## __bus ## _ISR_PRI, \
+ .spi_pin_list_p = spi ## __bus ## _pins, \
+ .cs_pin_list_p = spi ## __bus ## _cs_pins, \
+ .clk_gate = CYGHWR_IO_FREESCALE_DSPI ## __bus ## _CLK, \
+ .cs_pin_num = sizeof(spi ## __bus ## _cs_pins)/ \
+ sizeof(spi ## __bus ## _cs_pins[0]), \
+ .mcr_opt = CYGHWR_FREESCALE_DSPI ## __bus ## _MCR_PCSSE | \
+ FREESCALE_DSPI_MCR_PCSIS( \
+ CYGHWR_DEVS_SPI_FREESCALE_DSPI ## __bus ## _PCSIS), \
+ DSPI ## __bus ## _EDMA_SET_P \
+}
+
+#define DSPI_BUS(__bus) \
+cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus ## __bus = { \
+ .spi_bus.spi_transaction_begin = dspi_transaction_begin, \
+ .spi_bus.spi_transaction_transfer = dspi_transaction_transfer, \
+ .spi_bus.spi_transaction_tick = dspi_transaction_tick, \
+ .spi_bus.spi_transaction_end = dspi_transaction_end, \
+ .spi_bus.spi_get_config = dspi_get_config, \
+ .spi_bus.spi_set_config = dspi_set_config, \
+ .setup_p = &dspi ## __bus ## _setup, \
+ DSPI ## __bus ## _EDMA_TCD, \
+ .pushque_n = CYGNUM_DEVS_SPI_FREESCALE_DSPI ## __bus ## _PUSHQUE_SIZE, \
+ .txfifo_n = CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE, \
+ .rxfifo_n = CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE \
+}
+
+#define DSPI_BUS_PINS(__bus) \
+static const cyg_uint32 spi ## __bus ## _pins[] = { \
+ CYGHWR_IO_FREESCALE_SPI ## __bus ## _PIN_SIN, \
+ CYGHWR_IO_FREESCALE_SPI ## __bus ## _PIN_SOUT, \
+ CYGHWR_IO_FREESCALE_SPI ## __bus ## _PIN_SCK \
+}
+
+// DSPI BUS Instances =======================================================
+
+// DSPI BUS 0 ================================================================
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI0
+
+#define CYGBLD_DSPI0_TCD_SECTION \
+ CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI0_TCD_SECTION)
+
+#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI0_PCSS
+#define CYGHWR_FREESCALE_DSPI0_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M
+#else
+#define CYGHWR_FREESCALE_DSPI0_MCR_PCSSE 0
+#endif
+
+// SPI chip select pins.
+static const cyg_uint32 spi0_cs_pins[] = {
+#ifdef CYGHWR_FREESCALE_DSPI0_CS0
+ CYGHWR_IO_FREESCALE_SPI0_PIN_CS0,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI0_CS1
+ CYGHWR_IO_FREESCALE_SPI0_PIN_CS1,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI0_CS2
+ CYGHWR_IO_FREESCALE_SPI0_PIN_CS2,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI0_CS3
+ CYGHWR_IO_FREESCALE_SPI0_PIN_CS3,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI0_CS4
+ CYGHWR_IO_FREESCALE_SPI0_PIN_CS4,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI0_CS5
+ CYGHWR_IO_FREESCALE_SPI0_PIN_CS5
+#endif
+};
+
+#ifdef CYGINT_DEVS_SPI_DSPI0_USES_DMA
+ DSPI_EDMA_CHAN_SET(0);
+# define DSPI0_EDMA_SET_P DSPI_EDMA_SET_P_YES(0)
+# define DSPI0_EDMA_TCD DSPI_EDMA_TCD_YES(0)
+#else
+# define DSPI0_EDMA_SET_P DSPI_EDMA_SET_P_NULL(0)
+# define DSPI0_EDMA_TCD DSPI_EDMA_TCD_NULL(0)
+#endif // CYGINT_DEVS_SPI_DSPI0_USES_DMA
+
+DSPI_BUS_PINS(0);
+DSPI_BUS_SETUP(0);
+DSPI_BUS(0);
+
+#endif // CYGHWR_DEVS_SPI_FREESCALE_DSPI0
+
+// DSPI BUS 1 ================================================================
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI1
+
+#define CYGBLD_DSPI1_TCD_SECTION \
+ CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI1_TCD_SECTION)
+
+#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI1_PCSS
+#define CYGHWR_FREESCALE_DSPI1_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M
+#else
+#define CYGHWR_FREESCALE_DSPI1_MCR_PCSSE 0
+#endif
+
+// SPI chip select pins.
+static const cyg_uint32 spi1_cs_pins[] = {
+#ifdef CYGHWR_FREESCALE_DSPI1_CS0
+ CYGHWR_IO_FREESCALE_SPI1_PIN_CS0,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI1_CS1
+ CYGHWR_IO_FREESCALE_SPI1_PIN_CS1,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI1_CS2
+ CYGHWR_IO_FREESCALE_SPI1_PIN_CS2,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI1_CS3
+ CYGHWR_IO_FREESCALE_SPI1_PIN_CS3,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI1_CS4
+ CYGHWR_IO_FREESCALE_SPI1_PIN_CS4,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI1_CS5
+ CYGHWR_IO_FREESCALE_SPI1_PIN_CS5
+#endif
+};
+
+#ifdef CYGINT_DEVS_SPI_DSPI1_USES_DMA
+ DSPI_EDMA_CHAN_SET(1);
+# define DSPI1_EDMA_SET_P DSPI_EDMA_SET_P_YES(1)
+# define DSPI1_EDMA_TCD DSPI_EDMA_TCD_YES(1)
+#else
+# define DSPI1_EDMA_SET_P DSPI_EDMA_SET_P_NULL(1)
+# define DSPI1_EDMA_TCD DSPI_EDMA_TCD_NULL(1)
+#endif // CYGINT_DEVS_SPI_DSPI1_USES_DMA
+
+DSPI_BUS_PINS(1);
+DSPI_BUS_SETUP(1);
+DSPI_BUS(1);
+
+#endif // CYGHWR_DEVS_SPI_FREESCALE_DSPI1
+
+// DSPI BUS 2 ================================================================
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI2
+
+#define CYGBLD_DSPI2_TCD_SECTION \
+ CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI2_TCD_SECTION)
+
+#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI2_PCSS
+#define CYGHWR_FREESCALE_DSPI2_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M
+#else
+#define CYGHWR_FREESCALE_DSPI2_MCR_PCSSE 0
+#endif
+
+// SPI chip select pins.
+static const cyg_uint32 spi2_cs_pins[] = {
+#ifdef CYGHWR_FREESCALE_DSPI2_CS0
+ CYGHWR_IO_FREESCALE_SPI2_PIN_CS0,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI2_CS1
+ CYGHWR_IO_FREESCALE_SPI2_PIN_CS1,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI2_CS2
+ CYGHWR_IO_FREESCALE_SPI2_PIN_CS2,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI2_CS3
+ CYGHWR_IO_FREESCALE_SPI2_PIN_CS3,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI2_CS4
+ CYGHWR_IO_FREESCALE_SPI2_PIN_CS4,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI2_CS5
+ CYGHWR_IO_FREESCALE_SPI2_PIN_CS5
+#endif
+};
+
+#ifdef CYGINT_DEVS_SPI_DSPI2_USES_DMA
+ DSPI_EDMA_CHAN_SET(2);
+# define DSPI2_EDMA_SET_P DSPI_EDMA_SET_P_YES(2)
+# define DSPI2_EDMA_TCD DSPI_EDMA_TCD_YES(2)
+#else
+# define DSPI2_EDMA_SET_P DSPI_EDMA_SET_P_NULL(2)
+# define DSPI2_EDMA_TCD DSPI_EDMA_TCD_NULL(2)
+#endif // CYGINT_DEVS_SPI_DSPI2_USES_DMA
+
+DSPI_BUS_PINS(2);
+DSPI_BUS_SETUP(2);
+DSPI_BUS(2);
+
+#endif // CYGHWR_DEVS_SPI_FREESCALE_DSPI2
+
+// DSPI BUS 3 ================================================================
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI3
+
+#define CYGBLD_DSPI3_TCD_SECTION \
+ CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI3_TCD_SECTION)
+
+#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI3_PCSS
+#define CYGHWR_FREESCALE_DSPI3_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M
+#else
+#define CYGHWR_FREESCALE_DSPI3_MCR_PCSSE 0
+#endif
+
+// SPI chip select pins.
+static const cyg_uint32 spi3_cs_pins[] = {
+#ifdef CYGHWR_FREESCALE_DSPI3_CS0
+ CYGHWR_IO_FREESCALE_SPI3_PIN_CS0,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI3_CS1
+ CYGHWR_IO_FREESCALE_SPI3_PIN_CS1,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI3_CS2
+ CYGHWR_IO_FREESCALE_SPI3_PIN_CS2,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI3_CS3
+ CYGHWR_IO_FREESCALE_SPI3_PIN_CS3,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI3_CS4
+ CYGHWR_IO_FREESCALE_SPI3_PIN_CS4,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI3_CS5
+ CYGHWR_IO_FREESCALE_SPI3_PIN_CS5
+#endif
+};
+
+#ifdef CYGINT_DEVS_SPI_DSPI3_USES_DMA
+ DSPI_EDMA_CHAN_SET(3);
+# define DSPI3_EDMA_SET_P DSPI_EDMA_SET_P_YES(3)
+# define DSPI3_EDMA_TCD DSPI_EDMA_TCD_YES(3)
+#else
+# define DSPI3_EDMA_SET_P DSPI_EDMA_SET_P_NULL(3)
+# define DSPI3_EDMA_TCD DSPI_EDMA_TCD_NULL(3)
+#endif // CYGINT_DEVS_SPI_DSPI3_USES_DMA
+
+DSPI_BUS_PINS(3);
+DSPI_BUS_SETUP(3);
+DSPI_BUS(3);
+
+#endif // CYGHWR_DEVS_SPI_FREESCALE_DSPI3
+
+// DSPI BUS 4 ================================================================
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI4
+
+#define CYGBLD_DSPI4_TCD_SECTION \
+ CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI4_TCD_SECTION)
+
+#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI4_PCSS
+#define CYGHWR_FREESCALE_DSPI4_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M
+#else
+#define CYGHWR_FREESCALE_DSPI4_MCR_PCSSE 0
+#endif
+
+// SPI chip select pins.
+static const cyg_uint32 spi4_cs_pins[] = {
+#ifdef CYGHWR_FREESCALE_DSPI4_CS0
+ CYGHWR_IO_FREESCALE_SPI4_PIN_CS0,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI4_CS1
+ CYGHWR_IO_FREESCALE_SPI4_PIN_CS1,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI4_CS2
+ CYGHWR_IO_FREESCALE_SPI4_PIN_CS2,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI4_CS3
+ CYGHWR_IO_FREESCALE_SPI4_PIN_CS3,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI4_CS4
+ CYGHWR_IO_FREESCALE_SPI4_PIN_CS4,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI4_CS5
+ CYGHWR_IO_FREESCALE_SPI4_PIN_CS5
+#endif
+};
+
+#ifdef CYGINT_DEVS_SPI_DSPI4_USES_DMA
+ DSPI_EDMA_CHAN_SET(4);
+# define DSPI4_EDMA_SET_P DSPI_EDMA_SET_P_YES(4)
+# define DSPI4_EDMA_TCD DSPI_EDMA_TCD_YES(4)
+#else
+# define DSPI4_EDMA_SET_P DSPI_EDMA_SET_P_NULL(4)
+# define DSPI4_EDMA_TCD DSPI_EDMA_TCD_NULL(4)
+#endif // CYGINT_DEVS_SPI_DSPI4_USES_DMA
+
+DSPI_BUS_PINS(4);
+DSPI_BUS_SETUP(4);
+DSPI_BUS(4);
+
+#endif // CYGHWR_DEVS_SPI_FREESCALE_DSPI4
+
+// DSPI BUS 5 ================================================================
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI5
+
+#define CYGBLD_DSPI5_TCD_SECTION \
+ CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI5_TCD_SECTION)
+
+#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI5_PCSS
+#define CYGHWR_FREESCALE_DSPI5_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M
+#else
+#define CYGHWR_FREESCALE_DSPI5_MCR_PCSSE 0
+#endif
+
+// SPI chip select pins.
+static const cyg_uint32 spi5_cs_pins[] = {
+#ifdef CYGHWR_FREESCALE_DSPI5_CS0
+ CYGHWR_IO_FREESCALE_SPI5_PIN_CS0,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI5_CS1
+ CYGHWR_IO_FREESCALE_SPI5_PIN_CS1,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI5_CS2
+ CYGHWR_IO_FREESCALE_SPI5_PIN_CS2,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI5_CS3
+ CYGHWR_IO_FREESCALE_SPI5_PIN_CS3,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI5_CS4
+ CYGHWR_IO_FREESCALE_SPI5_PIN_CS4,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI5_CS5
+ CYGHWR_IO_FREESCALE_SPI5_PIN_CS5
+#endif
+};
+
+#ifdef CYGINT_DEVS_SPI_DSPI5_USES_DMA
+ DSPI_EDMA_CHAN_SET(5);
+# define DSPI5_EDMA_SET_P DSPI_EDMA_SET_P_YES(5)
+# define DSPI5_EDMA_TCD DSPI_EDMA_TCD_YES(5)
+#else
+# define DSPI5_EDMA_SET_P DSPI_EDMA_SET_P_NULL(5)
+# define DSPI5_EDMA_TCD DSPI_EDMA_TCD_NULL(5)
+#endif // CYGINT_DEVS_SPI_DSPI5_USES_DMA
+
+DSPI_BUS_PINS(5);
+DSPI_BUS_SETUP(5);
+DSPI_BUS(5);
+
+#endif // CYGHWR_DEVS_SPI_FREESCALE_DSPI5
+
+// DSPI BUS 6 ================================================================
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI6
+
+#define CYGBLD_DSPI6_TCD_SECTION \
+ CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI6_TCD_SECTION)
+
+#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI6_PCSS
+#define CYGHWR_FREESCALE_DSPI6_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M
+#else
+#define CYGHWR_FREESCALE_DSPI6_MCR_PCSSE 0
+#endif
+
+// SPI chip select pins.
+static const cyg_uint32 spi6_cs_pins[] = {
+#ifdef CYGHWR_FREESCALE_DSPI6_CS0
+ CYGHWR_IO_FREESCALE_SPI6_PIN_CS0,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI6_CS1
+ CYGHWR_IO_FREESCALE_SPI6_PIN_CS1,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI6_CS2
+ CYGHWR_IO_FREESCALE_SPI6_PIN_CS2,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI6_CS3
+ CYGHWR_IO_FREESCALE_SPI6_PIN_CS3,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI6_CS4
+ CYGHWR_IO_FREESCALE_SPI6_PIN_CS4,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI6_CS5
+ CYGHWR_IO_FREESCALE_SPI6_PIN_CS5
+#endif
+};
+
+#ifdef CYGINT_DEVS_SPI_DSPI6_USES_DMA
+ DSPI_EDMA_CHAN_SET(6);
+# define DSPI6_EDMA_SET_P DSPI_EDMA_SET_P_YES(6)
+# define DSPI6_EDMA_TCD DSPI_EDMA_TCD_YES(6)
+#else
+# define DSPI6_EDMA_SET_P DSPI_EDMA_SET_P_NULL(6)
+# define DSPI6_EDMA_TCD DSPI_EDMA_TCD_NULL(6)
+#endif // CYGINT_DEVS_SPI_DSPI6_USES_DMA
+
+DSPI_BUS_PINS(6);
+DSPI_BUS_SETUP(6);
+DSPI_BUS(6);
+
+#endif // CYGHWR_DEVS_SPI_FREESCALE_DSPI6
+
+// DSPI BUS 7 ================================================================
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI7
+
+#define CYGBLD_DSPI7_TCD_SECTION \
+ CYGBLD_ATTRIB_SECTION(CYGOPT_DEVS_SPI_FREESCALE_DSPI7_TCD_SECTION)
+
+#ifdef CYHGWR_DEVS_SPI_FREESCALE_DSPI7_PCSS
+#define CYGHWR_FREESCALE_DSPI7_MCR_PCSSE FREESCALE_DSPI_MCR_PCSSE_M
+#else
+#define CYGHWR_FREESCALE_DSPI7_MCR_PCSSE 0
+#endif
+
+// SPI chip select pins.
+static const cyg_uint32 spi7_cs_pins[] = {
+#ifdef CYGHWR_FREESCALE_DSPI7_CS0
+ CYGHWR_IO_FREESCALE_SPI7_PIN_CS0,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI7_CS1
+ CYGHWR_IO_FREESCALE_SPI7_PIN_CS1,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI7_CS2
+ CYGHWR_IO_FREESCALE_SPI7_PIN_CS2,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI7_CS3
+ CYGHWR_IO_FREESCALE_SPI7_PIN_CS3,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI7_CS4
+ CYGHWR_IO_FREESCALE_SPI7_PIN_CS4,
+#endif
+#ifdef CYGHWR_FREESCALE_DSPI7_CS5
+ CYGHWR_IO_FREESCALE_SPI7_PIN_CS5
+#endif
+};
+
+#ifdef CYGINT_DEVS_SPI_DSPI7_USES_DMA
+ DSPI_EDMA_CHAN_SET(7);
+# define DSPI7_EDMA_SET_P DSPI_EDMA_SET_P_YES(7)
+# define DSPI7_EDMA_TCD DSPI_EDMA_TCD_YES(7)
+#else
+# define DSPI7_EDMA_SET_P DSPI_EDMA_SET_P_NULL(7)
+# define DSPI7_EDMA_TCD DSPI_EDMA_TCD_NULL(7)
+#endif // CYGINT_DEVS_SPI_DSPI7_USES_DMA
+
+DSPI_BUS_PINS(7);
+DSPI_BUS_SETUP(7);
+DSPI_BUS(7);
+
+#endif // CYGHWR_DEVS_SPI_FREESCALE_DSPI7
+
+//=============================================================================
+#endif // SPI_FREESCALE_DSPI_BUSES_INL
diff --git a/ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_io.h b/ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_io.h
new file mode 100644
index 0000000..798160e
--- /dev/null
+++ b/ecos/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_io.h
@@ -0,0 +1,292 @@
+#ifndef CYGONCE_DEVS_SPI_FREESCALE_DSPI_IO_H
+#define CYGONCE_DEVS_SPI_FREESCALE_DSPI_IO_H
+//=============================================================================
+//
+// spi_freescale_dspi_io.h
+//
+// IO definitions for Freescale DSPI.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ilijak
+// Date: 2011-11-03
+// Purpose: Freescale DSPI I/O definitions.
+// Description:
+// Usage: #include <cyg/io/spi_freescale_dspi_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+
+// ----------------------------------------------------------------------------
+// DSPI
+
+typedef volatile struct cyghwr_devs_freescale_dspi_s {
+ cyg_uint32 mcr; // Module Configuration Register
+ cyg_uint32 reserved_0;
+ cyg_uint32 tcr; // Transfer Count Register
+ // Clock and Transfer Attributes Register
+ cyg_uint32 ctar[CYGHWR_DEVS_SPI_FREESCALE_DSPI_CTAR_NUM];
+#if CYGHWR_DEVS_SPI_FREESCALE_DSPI_CTAR_NUM < 8
+ cyg_uint32 reserved_1[8-CYGHWR_DEVS_SPI_FREESCALE_DSPI_CTAR_NUM];
+#endif
+ cyg_uint32 sr; // Status Register
+ cyg_uint32 rser; // DMA/IRQ Request Select and Enable Register
+ cyg_uint32 pushr; // TX FIFO PUSH Register
+ cyg_uint32 popr; // RX FIFO POP Register
+ // Transmit FIFO Registers
+ cyg_uint32 txfr[CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE];
+#if CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE < 16
+ cyg_uint32 reserved_2[16-CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE];
+#endif
+ // Receive FIFO Registers
+ cyg_uint32 rxfr[CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE];
+#if CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE < 16
+ cyg_uint32 reserved_3[16-CYGHWR_DEVS_SPI_FREESCALE_DSPI_FIFO_SIZE];
+#endif
+} cyghwr_devs_freescale_dspi_t;
+
+// MCR Bit Fields
+#define FREESCALE_DSPI_MCR_HALT_M 0x1
+#define FREESCALE_DSPI_MCR_HALT_S 0
+#define FREESCALE_DSPI_MCR_SMPL_PT_M 0x300
+#define FREESCALE_DSPI_MCR_SMPL_PT_S 8
+#define FREESCALE_DSPI_MCR_SMPL_PT(__val) \
+ VALUE_(FREESCALE_DSPI_MCR_SMPL_PT_S, __val)
+#define FREESCALE_DSPI_MCR_CLR_RXF_M 0x400
+#define FREESCALE_DSPI_MCR_CLR_RXF_S 10
+#define FREESCALE_DSPI_MCR_CLR_TXF_M 0x800
+#define FREESCALE_DSPI_MCR_CLR_TXF_S 11
+#define FREESCALE_DSPI_MCR_DIS_RXF_M 0x1000
+#define FREESCALE_DSPI_MCR_DIS_RXF_S 12
+#define FREESCALE_DSPI_MCR_DIS_TXF_M 0x2000
+#define FREESCALE_DSPI_MCR_DIS_TXF_S 13
+#define FREESCALE_DSPI_MCR_MDIS_M 0x4000
+#define FREESCALE_DSPI_MCR_MDIS_S 14
+#define FREESCALE_DSPI_MCR_DOZE_M 0x8000
+#define FREESCALE_DSPI_MCR_DOZE_S 15
+#define FREESCALE_DSPI_MCR_PCSIS_M 0x3F0000
+#define FREESCALE_DSPI_MCR_PCSIS_S 16
+#define FREESCALE_DSPI_MCR_PCSIS(__val) \
+ VALUE_(FREESCALE_DSPI_MCR_PCSIS_S, __val)
+#define FREESCALE_DSPI_MCR_ROOE_M 0x1000000
+#define FREESCALE_DSPI_MCR_ROOE_S 24
+#define FREESCALE_DSPI_MCR_PCSSE_M 0x2000000
+#define FREESCALE_DSPI_MCR_PCSSE_S 25
+#define FREESCALE_DSPI_MCR_MTFE_M 0x4000000
+#define FREESCALE_DSPI_MCR_MTFE_S 26
+#define FREESCALE_DSPI_MCR_FRZ_M 0x8000000
+#define FREESCALE_DSPI_MCR_FRZ_S 27
+#define FREESCALE_DSPI_MCR_DCONF_M 0x30000000
+#define FREESCALE_DSPI_MCR_DCONF_S 28
+#define FREESCALE_DSPI_MCR_DCONF(__val) \
+ VALUE_(FREESCALE_DSPI_MCR_DCONF_S, __val)
+#define FREESCALE_DSPI_MCR_CONT_SCKE_M 0x40000000
+#define FREESCALE_DSPI_MCR_CONT_SCKE_S 30
+#define FREESCALE_DSPI_MCR_MSTR_M 0x80000000
+#define FREESCALE_DSPI_MCR_MSTR_S 31
+// TCR Bit Fields
+#define FREESCALE_DSPI_TCR_DSPI_TCNT_M 0xFFFF0000
+#define FREESCALE_DSPI_TCR_DSPI_TCNT_S 16
+#define FREESCALE_DSPI_TCR_DSPI_TCNT(__val) \
+ VALUE_(FREESCALE_DSPI_TCR_DSPI_TCNT_S, __val)
+// CTAR Bit Fields
+#define FREESCALE_DSPI_CTAR_BR_M 0xF
+#define FREESCALE_DSPI_CTAR_BR_S 0
+#define FREESCALE_DSPI_CTAR_BR(__val) \
+ VALUE_(FREESCALE_DSPI_CTAR_BR_S, __val)
+#define FREESCALE_DSPI_CTAR_DT_M 0xF0
+#define FREESCALE_DSPI_CTAR_DT_S 4
+#define FREESCALE_DSPI_CTAR_DT(__val) \
+ VALUE_(FREESCALE_DSPI_CTAR_DT_S, __val)
+#define FREESCALE_DSPI_CTAR_ASC_M 0xF00
+#define FREESCALE_DSPI_CTAR_ASC_S 8
+#define FREESCALE_DSPI_CTAR_ASC(__val) \
+ VALUE_(FREESCALE_DSPI_CTAR_ASC_S, __val)
+#define FREESCALE_DSPI_CTAR_CSSCK_M 0xF000
+#define FREESCALE_DSPI_CTAR_CSSCK_S 12
+#define FREESCALE_DSPI_CTAR_CSSCK(__val) \
+ VALUE_(FREESCALE_DSPI_CTAR_CSSCK_S, __val)
+#define FREESCALE_DSPI_CTAR_PBR_M 0x30000
+#define FREESCALE_DSPI_CTAR_PBR_S 16
+#define FREESCALE_DSPI_CTAR_PBR(__val) \
+ VALUE_(FREESCALE_DSPI_CTAR_PBR_S, __val)
+#define FREESCALE_DSPI_CTAR_PDT_M 0xC0000
+#define FREESCALE_DSPI_CTAR_PDT_S 18
+#define FREESCALE_DSPI_CTAR_PDT(__val) \
+ VALUE_(FREESCALE_DSPI_CTAR_PDT_S, __val)
+#define FREESCALE_DSPI_CTAR_PASC_M 0x300000
+#define FREESCALE_DSPI_CTAR_PASC_S 20
+#define FREESCALE_DSPI_CTAR_PASC(__val) \
+ VALUE_(FREESCALE_DSPI_CTAR_PASC_S, __val)
+#define FREESCALE_DSPI_CTAR_PCSSCK_S 22
+#define FREESCALE_DSPI_CTAR_PCSSCK(__val) \
+ VALUE_(FREESCALE_DSPI_CTAR_PCSSCK_S, __val)
+#define FREESCALE_DSPI_CTAR_LSBFE_S 24
+#define FREESCALE_DSPI_CTAR_LSBFE_M 0x1000000
+
+#define FREESCALE_DSPI_CTAR_FMSZ_M 0x78000000
+#define FREESCALE_DSPI_CTAR_FMSZ_S 27
+#define FREESCALE_DSPI_CTAR_FMSZ(__val) \
+ VALUE_(FREESCALE_DSPI_CTAR_FMSZ_S, __val)
+#define FREESCALE_DSPI_CTAR_DBR_M 0x80000000
+#define FREESCALE_DSPI_CTAR_DBR_S 31
+// CTAR_SLAVE Bit Fields
+#define FREESCALE_DSPI_CTAR_SLAVE_CPHA_M 0x2000000
+#define FREESCALE_DSPI_CTAR_SLAVE_CPHA_S 25
+#define FREESCALE_DSPI_CTAR_SLAVE_CPOL_M 0x4000000
+#define FREESCALE_DSPI_CTAR_SLAVE_CPOL_S 26
+#define FREESCALE_DSPI_CTAR_SLAVE_FMSZ_M 0xF8000000
+#define FREESCALE_DSPI_CTAR_SLAVE_FMSZ_S 27
+#define FREESCALE_DSPI_CTAR_SLAVE_FMSZ(__val) \
+ VALUE_(FREESCALE_DSPI_CTAR_SLAVE_FMSZ_S, __val)
+// SR Bit Fields
+#define FREESCALE_DSPI_SR_POPNXTPTR_M 0xF
+#define FREESCALE_DSPI_SR_POPNXTPTR_S 0
+#define FREESCALE_DSPI_SR_POPNXTPTR(__val) \
+ VALUE_(FREESCALE_DSPI_SR_POPNXTPTR_S, __val)
+#define FREESCALE_DSPI_SR_RXCTR_M 0xF0
+#define FREESCALE_DSPI_SR_RXCTR_S 4
+#define FREESCALE_DSPI_SR_RXCTR(__val) \
+ VALUE_(FREESCALE_DSPI_SR_RXCTR_S, __val)
+#define FREESCALE_DSPI_SR_TXNXTPTR_M 0xF00
+#define FREESCALE_DSPI_SR_TXNXTPTR_S 8
+#define FREESCALE_DSPI_SR_TXNXTPTR(__val) \
+ VALUE_(FREESCALE_DSPI_SR_TXNXTPTR_S, __val)
+#define FREESCALE_DSPI_SR_TXCTR_M 0xF000
+#define FREESCALE_DSPI_SR_TXCTR_S 12
+#define FREESCALE_DSPI_SR_TXCTR(__val) \
+ VALUE_(FREESCALE_DSPI_SR_TXCTR_S, __val)
+#define FREESCALE_DSPI_SR_RFDF_M 0x20000
+#define FREESCALE_DSPI_SR_RFDF_S 17
+#define FREESCALE_DSPI_SR_RFOF_M 0x80000
+#define FREESCALE_DSPI_SR_RFOF_S 19
+#define FREESCALE_DSPI_SR_TFFF_M 0x2000000
+#define FREESCALE_DSPI_SR_TFFF_S 25
+#define FREESCALE_DSPI_SR_TFUF_M 0x8000000
+#define FREESCALE_DSPI_SR_TFUF_S 27
+#define FREESCALE_DSPI_SR_EOQF_M 0x10000000
+#define FREESCALE_DSPI_SR_EOQF_S 28
+#define FREESCALE_DSPI_SR_TXRXS_M 0x40000000
+#define FREESCALE_DSPI_SR_TXRXS_S 30
+#define FREESCALE_DSPI_SR_TCF_M 0x80000000
+#define FREESCALE_DSPI_SR_TCF_S 31
+
+#define FREESCALE_DSPI_CLEAR_FIFOS (FREESCALE_DSPI_SR_TFUF_M |\
+ FREESCALE_DSPI_SR_RFOF_M)
+
+// RSER Bit Fields
+#define FREESCALE_DSPI_RSER_RFDF_DIRS_M 0x10000
+#define FREESCALE_DSPI_RSER_RFDF_DIRS_S 16
+#define FREESCALE_DSPI_RSER_RFDF_RE_M 0x20000
+#define FREESCALE_DSPI_RSER_RFDF_RE_S 17
+#define FREESCALE_DSPI_RSER_RFOF_RE_M 0x80000
+#define FREESCALE_DSPI_RSER_RFOF_RE_S 19
+#define FREESCALE_DSPI_RSER_TFFF_DIRS_M 0x1000000
+#define FREESCALE_DSPI_RSER_TFFF_DIRS_S 24
+#define FREESCALE_DSPI_RSER_TFFF_RE_M 0x2000000
+#define FREESCALE_DSPI_RSER_TFFF_RE_S 25
+#define FREESCALE_DSPI_RSER_TFUF_RE_M 0x8000000
+#define FREESCALE_DSPI_RSER_TFUF_RE_S 27
+#define FREESCALE_DSPI_RSER_EOQF_RE_M 0x10000000
+#define FREESCALE_DSPI_RSER_EOQF_RE_S 28
+#define FREESCALE_DSPI_RSER_TCF_RE_M 0x80000000
+#define FREESCALE_DSPI_RSER_TCF_RE_S 31
+// PUSHR Bit Fields
+#define FREESCALE_DSPI_PUSHR_TXDATA_M 0xFFFF
+#define FREESCALE_DSPI_PUSHR_TXDATA_S 0
+#define FREESCALE_DSPI_PUSHR_TXDATA(__val) \
+ VALUE_(FREESCALE_DSPI_PUSHR_TXDATA_S, __val)
+#define FREESCALE_DSPI_PUSHR_PCS_M 0x3F0000
+#define FREESCALE_DSPI_PUSHR_PCS_S 16
+#define FREESCALE_DSPI_PUSHR_PCS(__val) VALUE_(FREESCALE_DSPI_PUSHR_PCS_S, __val)
+#define FREESCALE_DSPI_PUSHR_CTCNT_M 0x4000000
+#define FREESCALE_DSPI_PUSHR_CTCNT_S 26
+#define FREESCALE_DSPI_PUSHR_EOQ_M 0x8000000
+#define FREESCALE_DSPI_PUSHR_EOQ_S 27
+#define FREESCALE_DSPI_PUSHR_CTAS_M 0x70000000
+#define FREESCALE_DSPI_PUSHR_CTAS_S 28
+#define FREESCALE_DSPI_PUSHR_CTAS(__val) \
+ VALUE_(FREESCALE_DSPI_PUSHR_CTAS_S, __val)
+#define FREESCALE_DSPI_PUSHR_CONT_M 0x80000000
+#define FREESCALE_DSPI_PUSHR_CONT_S 31
+// PUSHR_SLAVE Bit Fields
+#define FREESCALE_DSPI_PUSHR_SLAVE_TXDATA_M 0xFFFFFFFF
+#define FREESCALE_DSPI_PUSHR_SLAVE_TXDATA_S 0
+#define FREESCALE_DSPI_PUSHR_SLAVE_TXDATA(__val) \
+VALUE_(FREESCALE_DSPI_PUSHR_SLAVE_TXDATA_S, __val)
+
+#define FREESCALE_DSPI_PUSHR_PCS_CLEAR(__val)\
+CYG_MACRO_START\
+ __val &= ~FREESCALE_DSPI_PUSHR_PCS_M; \
+CYG_MACRO_END
+
+// POPR Bit Fields
+#define FREESCALE_DSPI_POPR_RXDATA_M 0xFFFFFFFF
+#define FREESCALE_DSPI_POPR_RXDATA_S 0
+#define FREESCALE_DSPI_POPR_RXDATA(__val) \
+ VALUE_(FREESCALE_DSPI_POPR_RXDATA_S, __val)
+// TXFR Bit Fields
+#define FREESCALE_DSPI_TXFR_TXDATA_M 0xFFFF
+#define FREESCALE_DSPI_TXFR_TXDATA_S 0
+#define FREESCALE_DSPI_TXFR_TXCMD_TXDATA_M 0xFFFF0000
+#define FREESCALE_DSPI_TXFR_TXCMD_TXDATA_S 16
+#define FREESCALE_DSPI_TXFR_TXCMD_TXDATA(__fr,__val) \
+ VALUE_(FREESCALE_DSPI_TXFR##__fr##_TXCMD_TXDATA_S, __val)
+// RXFR Bit Fields
+#define FREESCALE_DSPI_RXFR_RXDATA_M 0xFFFFFFFF
+#define FREESCALE_DSPI_RXFR_RXDATA_S 0
+#define FREESCALE_DSPI_RXFR_RXDATA(__fr,__val) \
+ VALUE_(FREESCALE_DSPI_RXFR##_fr##_RXDATA_S, __val)
+
+// Borrow following macros from HAL
+
+// CYGADDR_IO_SPI_FREESCALE_DSPIx_P
+
+// CYGHWR_IO_CLOCK_ENABLE(__clkgate)
+// CYGHWR_IO_FREESCALE_DSPIx_CLK
+
+// CYGHWR_IO_FREESCALE_DSPI_PIN(__pin)
+
+// CYGHWR_IO_FREESCALE_SPIx_PIN_SIN
+// CYGHWR_IO_FREESCALE_SPIx_PIN_SOUT
+// CYGHWR_IO_FREESCALE_SPIx_PIN_SCK
+
+// CYGHWR_IO_FREESCALE_SPIx_PIN_CSn
+
+//=============================================================================
+#endif // CYGONCE_DEVS_SPI_FREESCALE_DSPI_IO_H
diff --git a/ecos/packages/devs/spi/freescale/dspi/current/src/spi_freescale_dspi.c b/ecos/packages/devs/spi/freescale/dspi/current/src/spi_freescale_dspi.c
new file mode 100644
index 0000000..b6842e1
--- /dev/null
+++ b/ecos/packages/devs/spi/freescale/dspi/current/src/spi_freescale_dspi.c
@@ -0,0 +1,1190 @@
+//=============================================================================
+//
+// spi_freescale_dspi.c
+//
+// SPI driver implementation for Freescale DSPI
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): ilijak
+// Date: 2011-11-04
+// Purpose: Freescale DSPI SPI driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <string.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_cache.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/spi.h>
+#include <cyg/hal/hal_endian.h>
+
+#include <pkgconf/devs_spi_freescale_dspi.h>
+#if defined(CYGHWR_DEVS_SPI_FREESCALE_DSPI0) || \
+ defined(CYGHWR_DEVS_SPI_FREESCALE_DSPI1) || \
+ defined(CYGHWR_DEVS_SPI_FREESCALE_DSPI2)
+
+#include <cyg/io/spi_freescale_dspi.h>
+
+
+#define DEBUG_SPI CYGPKG_DEVS_SPI_FREESCALE_DSPI_DEBUG_LEVEL
+
+#if DEBUG_SPI >= 3
+# define DEBUG3_PRINTF(args...) diag_printf(args)
+#else
+# define DEBUG3_PRINTF(args...)
+#endif
+
+#if DEBUG_SPI >= 2
+# define DEBUG2_PRINTF(args...) diag_printf(args)
+#else
+# define DEBUG2_PRINTF(args...)
+#endif
+
+#if DEBUG_SPI >= 1
+# define DEBUG1_PRINTF(args...) diag_printf(args)
+#else
+# define DEBUG1_PRINTF(args...)
+#endif
+
+# define DEBUG0_PRINTF(args...) diag_printf(args)
+
+#define PUSHR_NULL (0xFFFF)
+
+//-----------------------------------------------------------------------------
+// API function call forward references.
+
+static void dspi_transaction_begin (cyg_spi_device*);
+static void dspi_transaction_transfer (cyg_spi_device*, cyg_bool, cyg_uint32,
+ const cyg_uint8*, cyg_uint8*, cyg_bool);
+static void dspi_transaction_tick (cyg_spi_device*, cyg_bool, cyg_uint32);
+static void dspi_transaction_end (cyg_spi_device*);
+static int dspi_get_config (cyg_spi_device*, cyg_uint32,
+ void*, cyg_uint32*);
+static int dspi_set_config (cyg_spi_device*, cyg_uint32,
+ const void*, cyg_uint32*);
+
+//-----------------------------------------------------------------------------
+// Instantiate the bus state data structures.
+
+#include <cyg/io/spi_freescale_dspi_buses.inl>
+
+// Some hardware manipulation inline functions and macros
+
+static inline void dspi_disable(cyghwr_devs_freescale_dspi_t* dspi_p)
+{
+ dspi_p->mcr |= FREESCALE_DSPI_MCR_MDIS_M;
+}
+
+static inline void dspi_enable(cyghwr_devs_freescale_dspi_t* dspi_p)
+{
+ dspi_p->mcr &= ~FREESCALE_DSPI_MCR_MDIS_M;
+}
+
+static inline void dspi_halt(cyghwr_devs_freescale_dspi_t* dspi_p)
+{
+ dspi_p->mcr |= FREESCALE_DSPI_MCR_HALT_M;
+}
+
+static inline void dspi_tlah(cyghwr_devs_freescale_dspi_t* dspi_p)
+{
+ dspi_p->mcr &= ~FREESCALE_DSPI_MCR_HALT_M;
+}
+
+static inline void
+dspi_irq_enable(cyghwr_devs_freescale_dspi_t* dspi_p, cyg_uint32 irq_mask)
+{
+ dspi_p->rser |= irq_mask;
+}
+
+static inline void
+dspi_irq_disable(cyghwr_devs_freescale_dspi_t* dspi_p, cyg_uint32 irq_mask)
+{
+ dspi_p->rser &= ~irq_mask;
+}
+
+static inline void
+dspi_status_clear(cyghwr_devs_freescale_dspi_t* dspi_p, cyg_uint32 sr_mask)
+{
+ dspi_p->sr |= sr_mask;
+}
+
+static inline void
+dspi_fifo_clear(cyghwr_devs_freescale_dspi_t* dspi_p)
+{
+ dspi_p->mcr |= FREESCALE_DSPI_MCR_CLR_RXF_M | FREESCALE_DSPI_MCR_CLR_TXF_M;
+}
+
+static inline void
+dspi_fifo_drain(cyghwr_devs_freescale_dspi_t* dspi_p)
+{
+ dspi_p->sr |= FREESCALE_DSPI_SR_RFDF_M;
+}
+
+
+#define DSPI_IRQ_ENABLE(__dspi_p) \
+ dspi_irq_enable(__dspi_p, FREESCALE_DSPI_RSER_EOQF_RE_M)
+#define DSPI_IRQ_DISABLE(__dspi_p) \
+ dspi_irq_disable(__dspi_p, FREESCALE_DSPI_RSER_EOQF_RE_M)
+#define DSPI_EOQ_CLEAR(__dspi_p) \
+ dspi_status_clear(__dspi_p, FREESCALE_DSPI_SR_EOQF_M | \
+ FREESCALE_DSPI_SR_TCF_M | \
+ FREESCALE_DSPI_SR_RFDF_M)
+#define DSPI_TXRX_ENABLE(__dspi_p) \
+ dspi_status_clear(__dspi_p, FREESCALE_DSPI_SR_TXRXS_M)
+
+// Alternate clocking for spi_transaction_end()
+// Used to initialize CTAR1.
+static const cyg_freescale_dspi_clocking_t aux_clocking =
+{
+ .frame_size = 4,
+ .cl_pol = 0,
+ .cl_pha = 0,
+ .cl_brate = CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_SPEED,
+ .cs_up_udly = CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_CS_DELAY,
+ .cs_dw_udly = CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_CS_DELAY,
+ .tr_bt_udly =CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_CS_DELAY,
+ .dl_unit = CYGNUM_DSPI_DELAY_UNIT(
+ CYGHWR_DEVS_FREESCALE_DSPI_DSPI_CTAR1_AUX_DELAY_UNIT),
+ .cl_dbr = CYGHWR_DEVS_FREESCALEDSPI_DSPI_CTAR1_AUX_USE_DBR
+};
+
+//-----------------------------------------------------------------------------
+// Implement DSPI ISRs.
+
+// ISR for DSPI with DMA
+// Disable DSPI IRQ and Tx DMA channel and schedule DSR.
+static cyg_uint32 dspi_dma_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_spi_freescale_dspi_bus_t* dspi_bus_p =
+ (cyg_spi_freescale_dspi_bus_t*) data;
+ cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus_p->setup_p->dspi_p;
+ cyghwr_hal_freescale_dma_set_t *dma_set_p = dspi_bus_p->setup_p->dma_set_p;
+ cyghwr_hal_freescale_edma_t *edma_p;
+ edma_p = dma_set_p->edma_p;
+
+ cyg_drv_isr_lock();
+
+ // Disable the Tx DMA channel and DSPI IRQ.
+ hal_freescale_edma_erq_disable(edma_p, SPI_DMA_CHAN_I(dma_set_p, TX));
+ DSPI_IRQ_DISABLE(dspi_p);
+
+ cyg_drv_interrupt_acknowledge(vector);
+ cyg_drv_isr_unlock();
+ return (CYG_ISR_CALL_DSR | CYG_ISR_HANDLED);
+}
+
+// ISR for DSPI without DMA
+// Disable DSPI IRQ and schedule DSR.
+static cyg_uint32 dspi_nodma_ISR(cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_spi_freescale_dspi_bus_t* dspi_bus_p =
+ (cyg_spi_freescale_dspi_bus_t*) data;
+ cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus_p->setup_p->dspi_p;
+
+ cyg_drv_isr_lock();
+
+ // Disable the DSPI IRQ.
+ DSPI_IRQ_DISABLE(dspi_p);
+
+ cyg_drv_interrupt_acknowledge(vector);
+ cyg_drv_isr_unlock();
+ return (CYG_ISR_CALL_DSR | CYG_ISR_HANDLED);
+}
+
+// DSPI DSR
+static void dspi_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_spi_freescale_dspi_bus_t* dspi_bus = (cyg_spi_freescale_dspi_bus_t*) data;
+
+ cyg_drv_dsr_lock();
+ cyg_drv_cond_signal(&dspi_bus->transfer_done);
+ cyg_drv_dsr_unlock();
+}
+
+//-----------------------------------------------------------------------------
+// Calculate best fit CTAR baud rate setting (using some brute force).
+// Best fit is considered the highest frequency that is not highe than set point.
+
+static const cyg_uint16 ctar_br[16] = { 2/2, 4/2, 6/2, 8/2, 16/2, 32/2, 64/2,
+ 128/2, 256/2, 512/2, 1024/2, 2048/2, 4096/2, 8192/2, 16384/2, 32768/2 };
+static const cyg_uint8 ctar_pbr[4] = { 2, 3, 5, 7 };
+
+static const cyg_uint16 ctar_cssck[16] = { 2/2, 4/2, 8/2, 16/2, 32/2, 64/2,
+ 128/2, 256/2, 512/2, 1024/2, 2048/2, 4096/2, 8192/2, 16384/2, 32768/2,
+ 65536/2 };
+static const cyg_uint8 ctar_pcssck[4] = { 1, 3, 5, 7 };
+
+typedef struct ctar_br_s {
+ cyg_uint8 valid;
+ cyg_uint8 br;
+ cyg_uint8 dbr;
+ cyg_uint8 pbr;
+} ctar_br_t;
+
+static int dspi_ctar_brbf (const cyg_freescale_dspi_clocking_t* spi_cocking,
+ ctar_br_t* brs_p, const cyg_uint16* br_p,
+ const cyg_uint8* pbr_p, cyg_uint32* alt_brate,
+ cyg_uint32 sys_clk)
+{
+ cyg_uint32 pbr_i;
+ cyg_uint32 br_i;
+ cyg_uint32 dbr;
+ cyg_uint32 clk;
+ cyg_uint32 baud_bf = 0; // Best fit
+ cyg_uint32 baud_tmp;
+ cyg_uint32 baud_sp = alt_brate ? *alt_brate :
+ spi_cocking->cl_brate; // Set point
+
+ // Calculate the maximal viable bus speed.
+ clk = sys_clk;
+ // Desired baud rate very high, use DBR if allowed
+ dbr = (baud_sp > (clk / 4)) && spi_cocking->cl_dbr && (br_p == ctar_br);
+
+ for(pbr_i = 0; pbr_i < 3; pbr_i++) {
+ for(br_i = 0; br_i < 15; br_i++) {
+ if((baud_tmp = (clk * (1+dbr)) / (pbr_p[pbr_i] * (2*br_p[br_i])))
+ <= baud_sp)
+ {
+ if(baud_tmp > baud_bf) {
+ DEBUG3_PRINTF("DSPI Baud:"
+ " SP=%d pbr=0x%x br=0x%x dbr=%d Temp=%d (SysClk=%d)\n",
+ baud_sp, pbr_i, br_i, dbr, baud_tmp, clk);
+ brs_p->br = br_i;
+ brs_p->pbr = pbr_i;
+ brs_p->valid = 1;
+ baud_bf = baud_tmp;
+ if(baud_tmp == baud_sp)
+ goto baud_found;
+ }
+ }
+ }
+ }
+ if(!brs_p->valid) {
+ pbr_i = 3;
+ br_i = 15;
+ DEBUG1_PRINTF("DSPI Baud too low:"
+ " SP=%d pbr=0x%x br=0x%x Actual=%d (SysClk=%d)\n",
+ baud_sp, pbr_i, br_i,
+ (clk * (1+dbr)) / (pbr_p[pbr_i] * (2*br_p[br_i])), clk);
+ brs_p->br = br_i;
+ brs_p->pbr = pbr_i;
+
+ return -1;
+ } else {
+baud_found:
+ brs_p->dbr = dbr;
+ DEBUG1_PRINTF("DSPI Baud found:"
+ " SP=%d pbr=0x%x br=0x%x dbr=%d Actual=%dHz (%dns) (SysClk=%d)\n",
+ baud_sp, brs_p->pbr, brs_p->br, dbr, baud_bf, 1000000000/baud_bf, clk);
+
+ return 0;
+ }
+}
+
+// Set Clock and Transfer Attributes Register
+#define CYG_ASSERT_LOW_FREQ \
+ CYG_ASSERT (false, "Freescale DSPI: Cannot run bus as slowly as requested.")
+cyg_uint32
+dspi_calc_ctar(const cyg_freescale_dspi_clocking_t* spi_clocking, cyg_uint32 sys_clk)
+{
+ cyg_uint32 regval;
+ ctar_br_t brs;
+ cyg_uint32 delay_brate;
+
+ regval = FREESCALE_DSPI_CTAR_FMSZ(spi_clocking->frame_size - 1);
+ if(spi_clocking->cl_pol)
+ regval |= FREESCALE_DSPI_CTAR_SLAVE_CPOL_M;
+ if(spi_clocking->cl_pha)
+ regval |= FREESCALE_DSPI_CTAR_SLAVE_CPHA_M;
+ if(spi_clocking->lsb_first)
+ regval |= FREESCALE_DSPI_CTAR_LSBFE_M;
+
+ // Get divider bits
+ // Baud rate
+ brs.dbr = 0;
+ if (!dspi_ctar_brbf(spi_clocking, &brs, ctar_br, ctar_pbr, NULL, sys_clk))
+ {
+ regval |= FREESCALE_DSPI_CTAR_BR(brs.br) |
+ FREESCALE_DSPI_CTAR_PBR(brs.pbr) |
+ (brs.dbr ? FREESCALE_DSPI_CTAR_DBR_M : 0);
+ } else
+ CYG_ASSERT_LOW_FREQ;
+
+ delay_brate = 100000000 / (spi_clocking->dl_unit * spi_clocking->cs_up_udly);
+ if (!dspi_ctar_brbf(spi_clocking, &brs, ctar_cssck, ctar_pcssck,
+ &delay_brate, sys_clk))
+ {
+ regval |= FREESCALE_DSPI_CTAR_CSSCK(brs.br) |
+ FREESCALE_DSPI_CTAR_PCSSCK(brs.pbr);
+ } else
+ CYG_ASSERT_LOW_FREQ;
+
+ // Delay between clock and CS negation
+ delay_brate = 100000000 / (spi_clocking->dl_unit * spi_clocking->cs_dw_udly);
+ if (!dspi_ctar_brbf(spi_clocking, &brs, ctar_cssck, ctar_pcssck,
+ &delay_brate, sys_clk))
+ {
+ regval |= FREESCALE_DSPI_CTAR_ASC(brs.br) |
+ FREESCALE_DSPI_CTAR_PASC(brs.pbr);
+ } else
+ CYG_ASSERT_LOW_FREQ;
+
+ // Delay between clock and CS negation and assertion
+ delay_brate = 100000000 / (spi_clocking->dl_unit * spi_clocking->tr_bt_udly);
+ if (!dspi_ctar_brbf(spi_clocking, &brs, ctar_cssck, ctar_pcssck,
+ &delay_brate, sys_clk))
+ {
+ regval |= FREESCALE_DSPI_CTAR_DT(brs.br) |
+ FREESCALE_DSPI_CTAR_PDT(brs.pbr);
+ } else
+ CYG_ASSERT_LOW_FREQ;
+ return regval;
+}
+
+//----------------------------------------------------------------------------
+//Set up SPI bus pins
+
+static void dspi_pin_setup(const cyg_uint32* spi_pins_p,
+ const cyg_uint32* cs_pins_p, cyg_uint32 cs_pin_n)
+{
+ const cyg_uint32* pin_p;
+
+ for(pin_p = spi_pins_p;
+ pin_p < spi_pins_p + 3;
+ CYGHWR_IO_FREESCALE_DSPI_PIN(*pin_p++));
+
+ for(pin_p = cs_pins_p;
+ pin_p < cs_pins_p + cs_pin_n;
+ CYGHWR_IO_FREESCALE_DSPI_PIN(*pin_p++));
+}
+
+//-----------------------------------------------------------------------------
+// Set up a new SPI bus on initialisation.
+
+static void dspi_bus_setup(cyg_spi_freescale_dspi_bus_t* spi_bus_p)
+{
+ cyghwr_devs_freescale_dspi_t* dspi_p = spi_bus_p->setup_p->dspi_p;
+ cyghwr_hal_freescale_dma_set_t* dma_set_p;
+ cyghwr_hal_freescale_edma_t* edma_p;
+ cyg_uint32 dma_chan_i;
+
+ // Set up the clocking.
+ CYGHWR_IO_CLOCK_ENABLE(spi_bus_p->setup_p->clk_gate);
+ spi_bus_p->clock_freq = CYGHWR_IO_SPI_FREESCALE_DSPI_CLOCK;
+ DEBUG1_PRINTF("DSPI BUS %p: SysClk=%d\n", spi_bus_p, spi_bus_p->clock_freq);
+
+ // Set up the pins.
+ dspi_pin_setup(spi_bus_p->setup_p->spi_pin_list_p,
+ spi_bus_p->setup_p->cs_pin_list_p,
+ spi_bus_p->setup_p->cs_pin_num);
+
+ // Set up default SPI configuration.
+ dspi_p->mcr = spi_bus_p->setup_p->mcr_opt | FREESCALE_DSPI_MCR_MSTR_M |
+ FREESCALE_DSPI_MCR_CLR_RXF_M | FREESCALE_DSPI_MCR_CLR_TXF_M |
+ FREESCALE_DSPI_MCR_MDIS_M;
+
+ // Enable DSPI controller.
+ dspi_enable(dspi_p);
+
+ if((dma_set_p=spi_bus_p->setup_p->dma_set_p)) {
+ // Initialize DMA channels
+ hal_freescale_edma_init_chanset(dma_set_p);
+#if DEBUG_SPI >= 1
+ hal_freescale_edma_diag(dma_set_p, 0xffff);
+ cyghwr_devs_freescale_dspi_diag(spi_bus_p);
+#endif
+ // Set up DMA transfer control descriptors
+ edma_p = dma_set_p->edma_p;
+ dma_chan_i = dma_set_p->chan_p[SPI_DMA_CHAN_TX_I].dma_chan_i;
+ hal_freescale_edma_transfer_init(edma_p, dma_chan_i,
+ spi_bus_p->tx_dma_tcd_ini_p);
+#if DEBUG_SPI >= 1
+ hal_freescale_edma_transfer_diag(edma_p, dma_chan_i, true);
+#endif
+ dma_chan_i = dma_set_p->chan_p[SPI_DMA_CHAN_RX_I].dma_chan_i;
+ hal_freescale_edma_transfer_init(edma_p, dma_chan_i,
+ spi_bus_p->rx_dma_tcd_ini_p);
+#if DEBUG_SPI >= 1
+ hal_freescale_edma_transfer_diag(edma_p, dma_chan_i, true);
+#endif
+ }
+#if DEBUG_SPI >= 1
+ cyghwr_devs_freescale_dspi_diag(spi_bus_p);
+#endif
+ // Initialise the synchronisation primitivies.
+ cyg_drv_mutex_init (&spi_bus_p->transfer_mutex);
+ cyg_drv_cond_init (&spi_bus_p->transfer_done, &spi_bus_p->transfer_mutex);
+
+ // Hook up the ISR and DSR.
+ cyg_drv_interrupt_create (spi_bus_p->setup_p->intr_num,
+ spi_bus_p->setup_p->intr_prio,
+ (cyg_addrword_t) spi_bus_p,
+ dma_set_p ? dspi_dma_ISR : dspi_nodma_ISR,
+ dspi_DSR, &spi_bus_p->intr_handle,
+ &spi_bus_p->intr_data);
+ cyg_drv_interrupt_attach (spi_bus_p->intr_handle);
+
+ dspi_p->ctar[1] = dspi_calc_ctar(&aux_clocking, spi_bus_p->clock_freq);
+
+ // Call upper layer bus init.
+ CYG_SPI_BUS_COMMON_INIT(&spi_bus_p->spi_bus);
+}
+
+//-----------------------------------------------------------------------------
+// Set up Rx DMA channel
+static void
+rx_dma_channel_setup(cyghwr_hal_freescale_dma_set_t *dma_set_p,
+ cyg_uint8* data_buf, cyg_uint32 bus_16bit,
+ volatile cyghwr_hal_freescale_edma_tcd_t *tcd_p)
+{
+ cyg_uint32 step, sdsize;
+ static cyg_uint8 popr_sink;
+
+ // Set the correct transfer size.
+ if(bus_16bit) {
+ step = 2;
+ sdsize = FREESCALE_EDMA_ATTR_SIZE_16;
+ } else {
+ step = 1;
+ sdsize = FREESCALE_EDMA_ATTR_SIZE_8;
+ }
+ if(data_buf) {
+ tcd_p->doff = step;
+ tcd_p->daddr = data_buf;
+ } else {
+ tcd_p->doff = 0;
+ tcd_p->daddr = &popr_sink;
+ }
+ tcd_p->nbytes.mlno = step;
+ tcd_p->attr = FREESCALE_EDMA_ATTR_SSIZE(sdsize) |
+ FREESCALE_EDMA_ATTR_DSIZE(sdsize) |
+ FREESCALE_EDMA_ATTR_SMOD(0) |
+ FREESCALE_EDMA_ATTR_DMOD(0);
+#if DEBUG_SPI >= 3
+ hal_freescale_edma_tcd_diag(tcd_p, -1, "[DSPI Rx]");
+#endif
+}
+
+//----------------------------------------------------------------------------
+// Set up Tx FIFO queue
+// Set up Tx FIFO command queue
+// DSPI requires sending command for every transfer.
+// Used for transfers that fit within DSPI FIFO.
+
+#if DEBUG_SPI >= 2
+static const char debug_format[] = "BUFF %dbit %s: %p 0x%08x remain %d:\n";
+static const char debug_format1[] = "PUSHR 0x%08x %s: %p 0x%08x remain %d:\n";
+#endif
+
+static inline volatile cyg_uint32
+fifo_pushque_fill(cyg_spi_freescale_dspi_bus_t* dspi_bus, cyg_uint8*
+ data_p, cyg_uint32 count, cyg_bool bus_16bit, cyg_uint32 pushr,
+ cyg_bool drop_cs)
+{
+ cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus->setup_p->dspi_p;
+ cyg_uint32 txfifo_n = dspi_bus->txfifo_n;
+
+ if(data_p) {
+ if(!bus_16bit) {
+ for(; count > 1; count--) {
+ if(!(--txfifo_n)) {
+ dspi_p->pushr = pushr |= *data_p | FREESCALE_DSPI_PUSHR_EOQ_M;
+ count--;
+ DEBUG2_PRINTF(debug_format, 8, "FBK", data_p,
+ pushr | *data_p, count);
+ return count;
+ }
+ DEBUG3_PRINTF(debug_format, 8, "FAD", data_p,
+ pushr | *data_p, count-1);
+ dspi_p->pushr = pushr | *data_p++;
+ }
+ pushr |= *data_p;
+ } else {
+ cyg_uint16* data16_p = (cyg_uint16 *)data_p;
+ cyg_uint16 data_word;
+
+ for(; count > 2; count-=2) {
+ if(!(--txfifo_n)) {
+ dspi_p->pushr = pushr |= *data16_p | FREESCALE_DSPI_PUSHR_EOQ_M;
+ count-=2;
+ DEBUG2_PRINTF(debug_format, 16, "FBK", data_p,
+ pushr, count);
+ return count;
+ }
+ DEBUG3_PRINTF(debug_format, 16, "FAD", data16_p,
+ pushr | *data16_p, (count-1)*2);
+ data_word = *data16_p++;
+ dspi_p->pushr = pushr | data_word;
+ }
+ data_word = *data16_p;
+ pushr |= data_word;
+ }
+ } else {
+ pushr |= PUSHR_NULL;
+ for(; count > 1; count--) {
+ if(!(--txfifo_n)) {
+ dspi_p->pushr = pushr |= FREESCALE_DSPI_PUSHR_EOQ_M;
+ count--;
+ DEBUG2_PRINTF(debug_format, 0, "FBK", &dspi_p->pushr,
+ pushr, count);
+ return count;
+ }
+ dspi_p->pushr = pushr;
+ DEBUG3_PRINTF(debug_format, 0, "FAD", &dspi_p->pushr, pushr,
+ count-1);
+ }
+ }
+ if(drop_cs)
+ pushr &= ~FREESCALE_DSPI_PUSHR_CONT_M;
+ dspi_p->pushr = pushr |= FREESCALE_DSPI_PUSHR_EOQ_M;
+ DEBUG2_PRINTF(data_p ? debug_format : debug_format1, data_p ? (bus_16bit ? 16 :8) : pushr,
+ (drop_cs ? "FEN" : "FSG"), data_p /*&dspi_p->pushr*/, pushr, 0);
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+// Set up Tx
+// Set up Tx DMA command queue
+// DSPI requires sending command for every transfer.
+// Used for transfers larger than DSPI FIFO
+
+static inline volatile cyg_uint32
+dma_pushque_fill(cyg_spi_freescale_dspi_bus_t* dspi_bus, cyg_uint8* data_p,
+ cyg_uint32 count, cyg_bool bus_16bit, cyg_uint32 pushr,
+ cyg_bool drop_cs)
+{
+ volatile cyg_uint32* pushque_p;
+ volatile cyg_uint32* pushque_end;
+
+ pushque_p = dspi_bus->pushque_p;
+ pushque_end = pushque_p + (dspi_bus->pushque_n - (bus_16bit ? 2 : 1));
+ pushque_p = dspi_bus->pushque_p;
+ if(data_p) {
+ if(!bus_16bit) {
+ do {
+ if(pushque_p == pushque_end) {
+ *pushque_p = pushr | *data_p | FREESCALE_DSPI_PUSHR_EOQ_M;
+ count--;
+
+ DEBUG2_PRINTF(debug_format, 8, "BRK", pushque_p,
+ pushque_p[0], count);
+ return count;
+ }
+ *pushque_p++ = pushr | *data_p++;
+ DEBUG3_PRINTF(debug_format, 8, "ADD", pushque_p-1,
+ pushque_p[-1], count-1);
+ } while(--count > 1);
+ pushr |= *data_p;
+ } else {
+ cyg_uint16* data16_p = (cyg_uint16 *)data_p;
+ cyg_uint16 data_word;
+ do {
+ if(pushque_p == pushque_end) {
+ data_word = *data16_p;
+ *pushque_p = pushr | data_word | FREESCALE_DSPI_PUSHR_EOQ_M;
+ count-=2;
+
+ DEBUG2_PRINTF(debug_format, 16, "BRK", pushque_p,
+ pushque_p[0], count);
+ return count;
+ }
+ data_word = *data16_p++;
+ *pushque_p++ = pushr | data_word;
+ DEBUG3_PRINTF(debug_format, 16, "ADD", pushque_p-1,
+ pushque_p[-1], count-2);
+ } while((count -= 2) > 2);
+ data_word = *data16_p;
+ pushr |= data_word;
+ }
+ } else {
+ pushr |= PUSHR_NULL;
+ do {
+ if(pushque_p == pushque_end) {
+ *pushque_p = pushr | FREESCALE_DSPI_PUSHR_EOQ_M;
+ count--;
+
+ DEBUG2_PRINTF(debug_format, 0, "BRK", pushque_p,
+ pushque_p[0], count);
+ return count;
+ }
+ *pushque_p++ = pushr;
+ DEBUG3_PRINTF(debug_format, 0, "ADD", pushque_p-1, pushque_p[-1],
+ count-1);
+ } while(--count > 1);
+ }
+ if(drop_cs) pushr &= ~FREESCALE_DSPI_PUSHR_CONT_M;
+ *pushque_p = pushr |= FREESCALE_DSPI_PUSHR_EOQ_M;
+ DEBUG2_PRINTF(debug_format, data_p ? (bus_16bit ? 16 :8) : 0,
+ (drop_cs ? "END" : "SGM"), pushque_p, pushque_p[0], 0);
+
+ return 0;
+}
+
+// Set up Tx DMA channel
+// Used for transfers larger than DSPI FIFO
+
+static inline cyg_uint32
+tx_dma_channel_setup(cyg_spi_freescale_dspi_bus_t* dspi_bus,
+ cyg_uint8* data_buf, cyg_uint32 count,
+ cyg_bool bus_16bit,
+ cyg_uint32 pushr, cyg_bool drop_cs)
+{
+ cyghwr_hal_freescale_dma_set_t *dma_set_p = dspi_bus->setup_p->dma_set_p;
+ cyghwr_hal_freescale_edma_t *edma_p = dma_set_p->edma_p;
+ volatile cyghwr_hal_freescale_edma_tcd_t *tcd_p;
+ cyg_uint32 remain=0;
+ cyg_uint32 dma_chan_i;
+
+ remain = dma_pushque_fill(dspi_bus, data_buf, count, bus_16bit, pushr, drop_cs);
+ dma_chan_i = SPI_DMA_CHAN_I(dma_set_p, TX);
+ tcd_p = &edma_p->tcd[dma_chan_i];
+ tcd_p->saddr = dspi_bus->pushque_p;
+ DEBUG2_PRINTF("DSPI: Tx channel setup\n");
+#if DEBUG_SPI >= 3
+ hal_freescale_edma_transfer_diag(edma_p, dma_chan_i, true);
+#endif
+ return remain;
+}
+
+//-----------------------------------------------------------------------------
+// Set SPI peripheral chip select.
+
+static inline cyg_uint32
+dspi_chip_select_set(cyg_int32 cs_i, cyg_bool pccse, cyg_bool assert)
+{
+ cyg_uint32 spi_pushr;
+
+ if(cs_i < 0) {
+ spi_pushr = 0;
+ } else {
+ if(pccse) {
+ spi_pushr = cs_i;
+ } else {
+ if(cs_i < 5) {
+ if(assert) {
+ cs_i = 1 << cs_i;
+ spi_pushr = FREESCALE_DSPI_PUSHR_PCS(cs_i);
+ } else
+ spi_pushr = 0;
+ } else {
+ CYG_ASSERT(1, "DSPI: Peripheral Chip Select out of range.\n");
+ spi_pushr = 1 << 5;
+ }
+ }
+ }
+ return spi_pushr;
+}
+
+//-----------------------------------------------------------------------------
+// Execute SPI transaction.
+
+static void spi_transaction_do (cyg_spi_device* device, cyg_bool tick_only,
+ cyg_bool polled, cyg_uint32 count,
+ const cyg_uint8* tx_data, cyg_uint8* rx_data,
+ cyg_bool drop_cs)
+{
+ cyg_spi_freescale_dspi_bus_t* dspi_bus =
+ (cyg_spi_freescale_dspi_bus_t*) device->spi_bus;
+ cyg_spi_freescale_dspi_device_t* dspi_device =
+ (cyg_spi_freescale_dspi_device_t*) device;
+ cyg_bool bus_16bit = dspi_device->clocking.bus_16bit;
+ cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus->setup_p->dspi_p;
+
+ cyghwr_hal_freescale_dma_set_t* dma_set_p;
+ cyghwr_hal_freescale_edma_t* edma_p = NULL;
+
+ cyg_uint32 count_down;
+ cyg_uint32 txfifo_n = dspi_bus->txfifo_n;
+ cyg_uint32 pushr;
+ cyg_uint32 pushque_n;
+ cyg_uint32 dma_chan_rx_i = 0;
+ cyg_uint32 dma_chan_tx_i = 0;
+ cyg_uint8* rx_data0;
+
+#if DEBUG_SPI >= 2
+ cyg_uint32 first_turn = 1;
+#endif
+
+ DEBUG2_PRINTF("DSPI: transaction: count=%d drop_cs=%d tick_only=%d\n",
+ count, drop_cs, tick_only);
+
+ // Set up peripheral CS field. DSPI automatically asserts and deasserts CS
+ pushr =
+#ifndef CYGOPT_DEVS_SPI_FREESCALE_DSPI_TICK_ONLY_DROPS_CS
+ // Compatibility option
+ // eCos Reference Manual states that CS should drop prior to sending
+ // ticks, but other SPI drivers do not touch the CS.
+ tick_only ? dspi_p->pushr & 0x87FF0000 :
+#endif
+ dspi_chip_select_set(
+#ifdef CYGOPT_DEVS_SPI_FREESCALE_DSPI_TICK_ONLY_DROPS_CS
+ // Compatibility option. See comment above.
+ tick_only ? -1 :
+#endif
+ dspi_device->dev_num,
+ dspi_p->mcr & FREESCALE_DSPI_MCR_PCSSE_M, true);
+ pushr |= FREESCALE_DSPI_PUSHR_CONT_M;
+
+ dspi_fifo_clear(dspi_p);
+
+ pushque_n = dspi_bus->pushque_n;
+ if(bus_16bit)
+ txfifo_n *= 2;
+
+ dma_set_p = dspi_bus->setup_p->dma_set_p;
+ if((count > txfifo_n) && dma_set_p) {
+ rx_data0 = rx_data;
+ edma_p = dma_set_p->edma_p;
+ // Set up the DMA channels.
+ dma_chan_rx_i = SPI_DMA_CHAN_I(dma_set_p, RX);
+ dma_chan_tx_i = SPI_DMA_CHAN_I(dma_set_p, TX);
+ rx_dma_channel_setup(dma_set_p, (cyg_uint8*) rx_data,
+ bus_16bit, &edma_p->tcd[dma_chan_rx_i]);
+ hal_freescale_edma_erq_enable(edma_p, dma_chan_rx_i);
+ dspi_irq_enable(dspi_p,
+ FREESCALE_DSPI_RSER_TFFF_RE_M |
+ FREESCALE_DSPI_RSER_RFDF_RE_M |
+ FREESCALE_DSPI_RSER_TFFF_DIRS_M |
+ FREESCALE_DSPI_RSER_RFDF_DIRS_M);
+ } else {
+ rx_data0 = NULL;
+ // If byte count fits in the FIFO don't bother with DMA.
+ if(dma_set_p) {
+ edma_p = dma_set_p->edma_p;
+ hal_freescale_edma_erq_disable(edma_p, SPI_DMA_CHAN_I(dma_set_p, RX));
+ }
+ dma_set_p = NULL;
+ dspi_irq_disable(dspi_p,
+ FREESCALE_DSPI_RSER_TFFF_RE_M |
+ FREESCALE_DSPI_RSER_RFDF_RE_M |
+ FREESCALE_DSPI_RSER_TFFF_DIRS_M |
+ FREESCALE_DSPI_RSER_RFDF_DIRS_M);
+ }
+
+ if(!polled)
+ cyg_drv_interrupt_unmask(dspi_bus->setup_p->intr_num);
+ count_down = count;
+ while(count_down) {
+#if DEBUG_SPI >= 2
+ if(first_turn) {
+ if(dspi_bus->pushque_p)
+ dspi_bus->pushque_p[0] |= FREESCALE_DSPI_PUSHR_CTCNT_M;
+ first_turn = 0;
+ }
+#endif
+ if(dma_set_p && (count_down > txfifo_n)) {
+ // Transfer size is larger than DSPI FIFO
+ // Use DMA Tx
+ count_down = tx_dma_channel_setup(dspi_bus, (cyg_uint8*) tx_data,
+ count_down, bus_16bit,
+ pushr, drop_cs);
+#if DEBUG_SPI >= 3
+ hal_freescale_edma_transfer_diag(edma_p, dma_chan_rx_i, true);
+#endif
+ // Enable the Tx DMA / SPI controller.
+ hal_freescale_edma_erq_enable(edma_p, dma_chan_tx_i);
+ DSPI_EOQ_CLEAR(dspi_p);
+ } else {
+ // Transfer size fits within DSPI FIFO
+ // No need for DMA Tx
+ DSPI_EOQ_CLEAR(dspi_p);
+ count_down = fifo_pushque_fill(dspi_bus, (cyg_uint8*) tx_data,
+ count_down, bus_16bit,
+ pushr, drop_cs);
+#if DEBUG_SPI >= 3
+ cyghwr_devs_freescale_dspi_diag(dspi_bus);
+#endif
+ }
+
+ if(polled) {
+ DEBUG2_PRINTF("DSPI Polled:\n");
+ // Busy-wait for DSPI/DMA (polling for completion).
+ while(!(dspi_p->sr & FREESCALE_DSPI_SR_EOQF_M));
+
+ if(dma_set_p) {
+ // Disable the Tx DMA channel on completion.
+ hal_freescale_edma_erq_disable(edma_p, dma_chan_tx_i);
+ }
+ } else {
+ // Wait for DSPI/DMA completion. (interrupt driven).
+ cyg_drv_mutex_lock(&dspi_bus->transfer_mutex);
+ cyg_drv_dsr_lock();
+
+ DSPI_IRQ_ENABLE(dspi_p);
+ DEBUG2_PRINTF("DSPI IRQ: Enabled\n");
+
+ // Sit back and wait for the ISR/DSRs to signal completion.
+ cyg_drv_cond_wait (&dspi_bus->transfer_done);
+
+ cyg_drv_dsr_unlock();
+ cyg_drv_mutex_unlock(&dspi_bus->transfer_mutex);
+ }
+
+ if(dma_set_p) {
+ // Make sure that Rx has been drained by DMA.
+ while((dspi_p->sr & FREESCALE_DSPI_SR_RFDF_M));
+ DEBUG2_PRINTF("Fifo Drained by DMA 0x%08x\n", dspi_p->sr);
+ if(count_down <= txfifo_n && count_down > 0) {
+ hal_freescale_edma_erq_disable(edma_p, dma_chan_rx_i);
+ dma_set_p = NULL;
+ }
+ } else {
+ // No DMA - "manually" drain Rx FIFO
+ DEBUG2_PRINTF("DSPI FIFO: 'Manually' drain Rx fifo rx_data=%p bus_16bit=%d\n",
+ rx_data, bus_16bit);
+#if DEBUG_SPI >= 3
+ cyghwr_devs_freescale_dspi_diag(dspi_bus);
+#endif
+ if(rx_data) {
+ if(bus_16bit) {
+ cyg_uint16* rx_data16 = (cyg_uint16*) rx_data;
+ while(dspi_p->sr & FREESCALE_DSPI_SR_RXCTR_M) {
+ DEBUG2_PRINTF(" Fifo Pull16 at %p\n", rx_data16);
+ *rx_data16++ = dspi_p->popr;
+ }
+ rx_data = (cyg_uint8*) rx_data16;
+ } else {
+ while(dspi_p->sr & FREESCALE_DSPI_SR_RXCTR_M) {
+ DEBUG2_PRINTF(" Fifo Pull at %p\n", rx_data);
+ *rx_data++ = dspi_p->popr;
+ }
+ }
+ }
+ dspi_fifo_drain(dspi_p);
+ }
+ dspi_fifo_clear(dspi_p);
+ // Prepare for next iteration
+ if(tx_data) {
+ tx_data += pushque_n;
+ if(bus_16bit)
+ tx_data += pushque_n;
+ }
+ }
+ if(rx_data0) {
+ // Rx buffer may be out of sync with cache.
+ DEBUG2_PRINTF("DSPI DMA: Flush cache %p len=%d\n", rx_data0, count);
+ HAL_DCACHE_INVALIDATE(rx_data0, count);
+ DEBUG2_PRINTF("DSPI DMA: Cache flushed\n");
+ }
+
+ if(!polled)
+ cyg_drv_interrupt_mask(dspi_bus->setup_p->intr_num);
+
+ dspi_device->chip_sel = !drop_cs;
+ DEBUG2_PRINTF("cyg_transaction_do() chip_sel = %d drop_cs = %d\n", dspi_device->chip_sel, drop_cs);
+}
+
+//-----------------------------------------------------------------------------
+// Initialise SPI interfaces on startup.
+
+static void CYGBLD_ATTRIB_C_INIT_PRI(CYG_INIT_BUS_SPI)
+dspi_spi_init(void)
+{
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI0
+ dspi_bus_setup (&cyg_spi_dspi_bus0);
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI1
+ dspi_bus_setup (&cyg_spi_dspi_bus1);
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_FREESCALE_DSPI2
+ dspi_bus_setup (&cyg_spi_dspi_bus2);
+#endif
+}
+
+
+//-----------------------------------------------------------------------------
+// Start a SPI transaction.
+
+static void dspi_transaction_begin(cyg_spi_device* device)
+{
+ cyg_spi_freescale_dspi_bus_t* dspi_bus =
+ (cyg_spi_freescale_dspi_bus_t*) device->spi_bus;
+ cyg_spi_freescale_dspi_device_t* dspi_device =
+ (cyg_spi_freescale_dspi_device_t*) device;
+
+ // On the first transaction, generate the values to be programmed into the
+ // SPI configuration registers for this device and cache them. This avoids
+ // having to recalculate the prescaler for every transaction.
+ if(!(dspi_device->clocking.dspi_ctar))
+ dspi_device->clocking.dspi_ctar = dspi_calc_ctar(&dspi_device->clocking,
+ dspi_bus->clock_freq);
+ // Set up the SPI controller.
+ dspi_bus->setup_p->dspi_p->ctar[0] = dspi_device->clocking.dspi_ctar;
+#if DEBUG_SPI >= 2
+ cyghwr_devs_freescale_dspi_diag(dspi_bus);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Run a transaction transfer.
+
+static void dspi_transaction_transfer(cyg_spi_device* device, cyg_bool polled,
+ cyg_uint32 count,
+ const cyg_uint8* tx_data,
+ cyg_uint8* rx_data,
+ cyg_bool drop_cs)
+{
+ cyg_spi_freescale_dspi_device_t* dspi_device =
+ (cyg_spi_freescale_dspi_device_t*) device;
+
+ DEBUG2_PRINTF("Transaction rx_data = %p tx_data = %p count=%d\n", rx_data, tx_data, count);
+
+ // Check for unsupported transactions.
+ CYG_ASSERT (count > 0, "DSPI: Null transfer requested.");
+
+ // We check that the buffers are half-word aligned and that count is a
+ // multiple of two in order to carry out the 16-bit transfer.
+ if (dspi_device->clocking.bus_16bit) {
+ CYG_ASSERT (!(count & 1) && !((cyg_uint32) tx_data & 1) &&
+ !((cyg_uint32) rx_data & 1),
+ "DSPI: Misaligned data in 16-bit transfer.");
+ }
+ spi_transaction_do (device, false, polled, count, tx_data, rx_data, drop_cs);
+}
+
+//-----------------------------------------------------------------------------
+// Carry out a bus tick operation - this drops chip select then pushes the
+// required number of NULL frames onto the bus.
+
+static void dspi_transaction_tick(cyg_spi_device* device, cyg_bool polled,
+ cyg_uint32 count)
+{
+ cyg_spi_freescale_dspi_device_t* dspi_device =
+ (cyg_spi_freescale_dspi_device_t*) device;
+
+ // Check for unsupported transactions.
+ CYG_ASSERT (count > 0, "DSPI: Null transfer requested.");
+
+ // We check that count is a multiple of two in order
+ // to carry out the 16-bit transfer.
+ if (dspi_device->clocking.bus_16bit) {
+ CYG_ASSERT (!(count & 1),
+ "DSPI: Misaligned data in 16-bit transfer.");
+ }
+
+ // Perform null transfer
+ DEBUG2_PRINTF("cyg_transaction_tick()\n");
+ spi_transaction_do (device, true, polled, count, NULL, NULL, false);
+}
+
+//-----------------------------------------------------------------------------
+// Terminate a SPI transaction, disabling the SPI controller.
+
+static void dspi_transaction_end(cyg_spi_device* device)
+{
+ cyg_spi_freescale_dspi_bus_t* dspi_bus =
+ (cyg_spi_freescale_dspi_bus_t*) device->spi_bus;
+ cyg_spi_freescale_dspi_device_t* dspi_device =
+ (cyg_spi_freescale_dspi_device_t*) device;
+
+ const cyghwr_hal_freescale_dma_set_t *dma_set_p = dspi_bus->setup_p->dma_set_p;
+ cyghwr_hal_freescale_edma_t *edma_p;
+ cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus->setup_p->dspi_p;
+
+ DEBUG2_PRINTF("cyg_transaction_end() chip_sel = %d\n", dspi_device->chip_sel);
+ if(dma_set_p) {
+ edma_p = dma_set_p->edma_p;
+ hal_freescale_edma_erq_disable(edma_p, SPI_DMA_CHAN_I(dma_set_p, TX));
+ hal_freescale_edma_erq_disable(edma_p, SPI_DMA_CHAN_I(dma_set_p, RX));
+ }
+
+ if(dspi_device->chip_sel){
+ // Clear peripheral CS by executing a dummy 4 bit transfer.
+ dspi_p->pushr = PUSHR_NULL | FREESCALE_DSPI_PUSHR_EOQ_M |
+ FREESCALE_DSPI_PUSHR_CTAS(1);
+ while(!(dspi_p->sr & FREESCALE_DSPI_SR_EOQF_M));
+ DSPI_EOQ_CLEAR(dspi_p);
+ dspi_fifo_drain(dspi_p);
+ dspi_device->chip_sel = 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Get DSPI configuration parameter
+
+static int dspi_get_config (cyg_spi_device* device, cyg_uint32 key,
+ void* buf, cyg_uint32* len)
+{
+ cyg_spi_freescale_dspi_bus_t* dspi_bus =
+ (cyg_spi_freescale_dspi_bus_t*) device->spi_bus;
+ cyg_spi_freescale_dspi_device_t* dspi_device =
+ (cyg_spi_freescale_dspi_device_t*) device;
+ cyg_uint32* data_p = buf;
+
+ switch (key) {
+ case CYG_IO_GET_CONFIG_SPI_CLOCKRATE :
+ // Sanity check
+ if (NULL == len) {
+ CYG_ASSERT (false, "Freescale DSPI:"
+ " Null pointer as len argument for dspi_get_config().");
+ return -1;
+ } else if (sizeof(cyg_uint32) != *len) {
+ CYG_ASSERT (false, "Freescale DSPI:"
+ " Invalid length with dspi_get_config().");
+ return -1;
+ } else if (NULL == buf) {
+ CYG_ASSERT (false, "Freescale DSPI:"
+ " Null poiter as buf argument for dspi_get_config().");
+ return -1;
+ } else {
+ cyg_uint32 ctar, dbr, br, pbr;
+
+ ctar = dspi_device->clocking.dspi_ctar;
+ dbr = (ctar & FREESCALE_DSPI_CTAR_DBR_M) >>
+ FREESCALE_DSPI_CTAR_DBR_S;
+ br = (ctar & FREESCALE_DSPI_CTAR_BR_M) >>
+ FREESCALE_DSPI_CTAR_BR_S;
+ pbr = (ctar & FREESCALE_DSPI_CTAR_PBR_M) >>
+ FREESCALE_DSPI_CTAR_PBR_S;
+ *data_p = (dspi_bus->clock_freq * (1+dbr)) / (pbr * br);
+
+ DEBUG2_PRINTF("DSPI Get Config: baud = %d\n", *data_p);
+
+ return 0;
+ }
+
+ default :
+ break;
+ }
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// Change some SPI device configuration parameters
+
+static int dspi_set_config(cyg_spi_device* device, cyg_uint32 key,
+ const void* buf, cyg_uint32* len)
+{
+ cyg_spi_freescale_dspi_device_t* dspi_device =
+ (cyg_spi_freescale_dspi_device_t*) device;
+ cyg_spi_freescale_dspi_bus_t* dspi_bus =
+ (cyg_spi_freescale_dspi_bus_t*) device->spi_bus;
+
+ cyg_uint32 regval;
+ ctar_br_t brs;
+
+ switch (key) {
+ case CYG_IO_SET_CONFIG_SPI_CLOCKRATE :
+ // Sanity check
+ if (NULL == len) {
+ CYG_ASSERT (false, "Freescale DSPI:"
+ " Null pointer as len argument for dspi_set_config().");
+ return -1;
+ } else if (sizeof(cyg_uint32) != *len) {
+ CYG_ASSERT (false, "Freescale DSPI:"
+ " Invalid length with dspi_set_config().");
+ return -1;
+ } else if (NULL == buf) {
+ CYG_ASSERT (false, "Freescale DSPI:"
+ " Null pointer as buf argument for dspi_set_config().");
+ return -1;
+ } else {
+ // Get divider bits
+ if (!dspi_ctar_brbf(&dspi_device->clocking, &brs,
+ ctar_br, ctar_pbr, (cyg_uint32 *)buf, dspi_bus->clock_freq))
+ {
+ // Update the cache of the configuration register settings.
+ regval = dspi_device->clocking.dspi_ctar;
+ regval &= ~(FREESCALE_DSPI_CTAR_BR_M |
+ FREESCALE_DSPI_CTAR_PBR_M);
+ regval |= FREESCALE_DSPI_CTAR_BR(brs.br) |
+ FREESCALE_DSPI_CTAR_PBR(brs.pbr);
+ dspi_device->clocking.dspi_ctar = regval;
+
+ return 0;
+
+ } else {
+ CYG_ASSERT (false, "Freescale DSPI:"
+ " Cannot run bus as slowly as requested.");
+ return -1;
+ }
+ }
+ default :
+ break;
+ }
+ return -1;
+}
+
+#if DEBUG_SPI
+//----------------------------------------------------------------------------
+// Print out a DSPI array state
+// Helper for cyghwr_devs_freescale_dspi_diag()
+
+void cyghwr_devs_freescale_dspi_diag_array(char* name_p,
+ volatile cyg_uint32* array_p,
+ cyg_uint32 array_n)
+{
+ diag_printf("%s %p[%u]: ", name_p, array_p, array_n);
+ for(; array_n; array_n--) {
+ diag_printf(" 0x%08x", *array_p++);
+ }
+ diag_printf("\n");
+}
+
+//----------------------------------------------------------------------------
+// Print out DSPI state
+
+void cyghwr_devs_freescale_dspi_diag(cyg_spi_freescale_dspi_bus_t* dspi_bus_p)
+{
+ cyghwr_devs_freescale_dspi_t* dspi_p = dspi_bus_p->setup_p->dspi_p;
+
+ diag_printf("DSPI %p\n", dspi_p);
+ diag_printf(" MCR = 0x%08x TCR = 0x%08x\n", dspi_p->mcr, dspi_p->tcr);
+ cyghwr_devs_freescale_dspi_diag_array(" CTAR", dspi_p->ctar,
+ CYGHWR_DEVS_SPI_FREESCALE_DSPI_CTAR_NUM);
+ diag_printf(" SR = 0x%08x RSER = 0x%08x PUSHR = 0x%08x POPR = 0x%08x\n",
+ dspi_p->sr, dspi_p->rser, dspi_p->pushr, dspi_p->popr);
+ cyghwr_devs_freescale_dspi_diag_array(" TXFR", dspi_p->txfr, dspi_bus_p->txfifo_n);
+ cyghwr_devs_freescale_dspi_diag_array(" RXFR", dspi_p->rxfr, dspi_bus_p->rxfifo_n);
+}
+#endif // DEBUG_SPI
+
+#endif // defined(CYGHWR_DEVS_SPI_FREESCALE_DSPIx)
+
+//=============================================================================
diff --git a/ecos/packages/devs/spi/freescale/dspi/current/tests/spi_loopback.c b/ecos/packages/devs/spi/freescale/dspi/current/tests/spi_loopback.c
new file mode 100644
index 0000000..6e70e0c
--- /dev/null
+++ b/ecos/packages/devs/spi/freescale/dspi/current/tests/spi_loopback.c
@@ -0,0 +1,285 @@
+//=============================================================================
+//
+// spi_loopback.c
+//
+// Standalone SPI loopback test.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Kocho
+// Original: Chris Holgate
+// Date: 2012-12-27
+// Purpose: Freescale DSPI loopback test
+// Description: Standalone SPI loopback test.
+// Usage: Compile as a standalone application.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//=============================================================================
+// This is a quick loopback test for the Freescale DSPI SPI driver. It only checks
+// the data transfer functionality - chip select handling will require
+// testing with external devices. In order to run the test, the MOSI and
+// MISO pins for the test port need to be shorted together to provide an
+// external loopback. Don't do this on a bus which has external devices
+// attached unless you first make sure that none of them are connected to
+// the chip select used by the test harness.
+// The default port and chip select used for this test are SPI bus 1,
+// chip select 0. These can be changed by editing the loopback_device
+// data structure directly.
+// Note that this is intended to be run as a standalone test and not as part
+// of the standard board tests since it requires a hardware modification.
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/testcase.h> // Test macros
+
+#include <cyg/infra/cyg_ass.h> // Assertion macros
+#include <cyg/infra/diag.h> // Diagnostic output
+
+#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/io/spi.h> // Common SPI API
+#include <cyg/io/spi_freescale_dspi.h> // Freescale DSPI data structures
+
+#include <string.h>
+
+//---------------------------------------------------------------------------
+// Thread data structures.
+
+cyg_uint8 stack [CYGNUM_HAL_STACK_SIZE_TYPICAL];
+cyg_thread thread_data;
+cyg_handle_t thread_handle;
+
+externC cyg_spi_freescale_dspi_bus_t cyg_spi_dspi_bus1;
+
+//---------------------------------------------------------------------------
+// SPI loopback device driver data structures.
+
+CYG_DEVS_SPI_FREESCALE_DSPI_DEVICE(
+ loopback_device, // Device name
+ 1, //SPI bus
+ 0, // Dev num
+ 8, // Frame size
+ 0, // Clock pol
+ 0, // Clock phase
+ 6000000, // Clock speed
+ 1, // CS assert delay
+ 1, // CS negate delay
+ 1, // Delay between transfers
+ 1000, // Delay unit [ns]
+ 0 // Double baud rate
+);
+
+//---------------------------------------------------------------------------
+
+static int errors = 0;
+
+const char tx_data0[] = "0123456789a123456789b123456789c123456789d123456789e";
+const char tx_data1[] = "Performing extended API test first transaction..|";
+const char tx_data2[] = "Testing extended API for a second transaction!";
+
+char rx_data [256];
+char rx_data1 [256];
+char rx_data2 [256];
+
+static void memclr(char *dest_p, cyg_uint32 byte_n)
+{
+ while(byte_n--) {
+ *dest_p++ = 0;
+ }
+}
+
+
+//---------------------------------------------------------------------------
+// Run single loopback transaction using simple transfer API call.
+
+void run_test_tick (cyg_bool polled, cyg_uint32 count)
+{
+ diag_printf ("Test 0 : Tick (polled = %d).\n", polled ? 1 : 0);
+ cyg_spi_tick(&loopback_device, polled, count);
+ diag_printf (" Tick end\n");
+}
+
+void run_test_1 (cyg_bool polled, const char* tx_data_p, cyg_uint32 count)
+{
+ diag_printf ("Test 1 : Simple transfer test polled = %d, count=%d\n",
+ polled ? 1 : 0, count);
+ memclr(rx_data1, sizeof(rx_data1));
+ memclr(rx_data2, sizeof(rx_data1));
+ cyg_spi_transfer (&loopback_device, polled, count,
+ (const cyg_uint8*) tx_data_p, (cyg_uint8*) &rx_data[0]);
+ diag_printf (" Tx data : %s\n", tx_data_p);
+ diag_printf (" Rx data : %s 0x%02x\n", rx_data, rx_data[0]);
+
+ if (memcmp (tx_data_p, rx_data, count) != 0) {
+ errors++;
+ diag_printf("Simple transfer loopback failed - mismatched data.\n");
+ }
+}
+
+//---------------------------------------------------------------------------
+// Run two loopback transactions using extended transfer API.
+
+void run_test_2 (cyg_bool polled)
+{
+ diag_printf ("Test 2 : Extended API test (polled = %d).\n", polled ? 1 : 0);
+ memclr(rx_data1, sizeof(rx_data1));
+ memclr(rx_data2, sizeof(rx_data1));
+ cyg_spi_transaction_begin (&loopback_device);
+ cyg_spi_transaction_transfer (&loopback_device, polled, sizeof (tx_data1),
+ (const cyg_uint8*) &tx_data1[0], (cyg_uint8*) &rx_data1[0], false);
+ cyg_spi_transaction_transfer (&loopback_device, polled, sizeof (tx_data2),
+ (const cyg_uint8*) &tx_data2[0], (cyg_uint8*) &rx_data2[0], true);
+ cyg_spi_transaction_end (&loopback_device);
+
+ diag_printf (" Tx data 1 (%u Bytes): %s\n", sizeof(tx_data1), tx_data1);
+ diag_printf (" Rx data 1 : %s\n", rx_data1);
+ diag_printf (" Tx data 2 (%u Bytes): %s\n", sizeof(tx_data2), tx_data2);
+ diag_printf (" Rx data 2 : %s\n", rx_data2);
+ if (memcmp (tx_data1, rx_data1, sizeof (tx_data1)) != 0) {
+ errors++;
+ diag_printf("Simple transfer loopback failed - mismatched data (transfer 1).\n");
+ }
+ if (memcmp (tx_data2, rx_data2, sizeof (tx_data2)) != 0) {
+ errors++;
+ diag_printf("Simple transfer loopback failed - mismatched data (transfer 2).\n");
+ }
+}
+
+void run_test_3 (cyg_bool polled)
+{
+ diag_printf ("Test 3 : Extended API test (polled = %d).\n", polled ? 1 : 0);
+ memclr(rx_data1, sizeof(rx_data1));
+ memclr(rx_data2, sizeof(rx_data1));
+
+ cyg_spi_transaction_begin (&loopback_device);
+ cyg_spi_transaction_transfer (&loopback_device, polled, sizeof (tx_data1),
+ (const cyg_uint8*) &tx_data1[0], (cyg_uint8*) &rx_data1[0], false);
+ cyg_spi_transaction_transfer (&loopback_device, polled, sizeof (tx_data2),
+ (const cyg_uint8*) &tx_data2[0], (cyg_uint8*) &rx_data2[0], true);
+ cyg_spi_transaction_end (&loopback_device);
+ diag_printf (" Tx data 1 (%u Bytes): %s\n", sizeof(tx_data1), tx_data1);
+ diag_printf (" Rx data 31 : %s\n", rx_data1);
+ diag_printf (" Tx data 2 (%u Bytes): %s\n", sizeof(tx_data2), tx_data2);
+ diag_printf (" Rx data 32 : %s\n", rx_data2);
+
+ if (memcmp (tx_data1, rx_data1, sizeof (tx_data1)) != 0) {
+ errors++;
+ diag_printf("Simple transfer loopback failed - mismatched data (transfer 1).\n");
+ }
+ if (memcmp (tx_data2, rx_data2, sizeof (tx_data2)) != 0) {
+ errors++;
+ diag_printf("Simple transfer loopback failed - mismatched data (transfer 2).\n");
+ }
+}
+
+void run_test_4 (cyg_bool polled)
+{
+ diag_printf ("Test 4 : Extended API test NULL transfer (polled = %d).\n", polled ? 1 : 0);
+ memclr(rx_data1, sizeof(rx_data1));
+ memclr(rx_data2, sizeof(rx_data1));
+
+ cyg_spi_transaction_begin (&loopback_device);
+ cyg_spi_transaction_transfer (&loopback_device, polled, sizeof (tx_data1),
+ (const cyg_uint8*) NULL, NULL, true);
+ cyg_spi_transaction_end (&loopback_device);
+ diag_printf (" Tx data 41 (%u Bytes): %s\n", sizeof(tx_data1), tx_data1);
+ diag_printf (" Rx data 1 : %s\n", rx_data1);
+ diag_printf (" Tx data 42 (%u Bytes): %s\n", sizeof(tx_data2), tx_data2);
+ diag_printf (" Rx data 2 : %s\n", rx_data2);
+
+ if (memcmp (rx_data1, rx_data2, sizeof (tx_data1)) != 0) {
+ errors++;
+ diag_printf("Simple transfer loopback failed - mismatched data.\n");
+ errors++;
+ }
+}
+
+
+//---------------------------------------------------------------------------
+// Run all SPI interface loopback tests.
+
+
+void run_tests (void)
+{
+ bool polled = true;
+ diag_printf ("Running Freescale Kinetis/MPC5xxx DSPI driver loopback tests.\n");
+
+ diag_printf ("\nPolled\n");
+ run_test_tick (polled, 1024);
+ run_test_1 (polled, &tx_data0[3], 4);
+ run_test_2 (polled);
+ run_test_3 (polled);
+ run_test_4 (polled);
+
+ polled = false;
+ diag_printf ("\nInterrupt driven.\n");
+ run_test_tick (polled,2048);
+ run_test_1 (polled, &tx_data0[7], 10);
+ run_test_2 (polled);
+ run_test_3 (polled);
+ run_test_4 (polled);
+
+ if(errors)
+ CYG_TEST_FAIL("Errors detected");
+ else
+ CYG_TEST_PASS_FINISH ("Loopback tests ran OK");
+}
+
+//---------------------------------------------------------------------------
+// User startup - tests are run in their own thread.
+
+void cyg_user_start(void)
+{
+ CYG_TEST_INIT();
+ cyg_thread_create(
+ 10, // Arbitrary priority
+ (cyg_thread_entry_t*) run_tests, // Thread entry point
+ 0, //
+ "test_thread", // Thread name
+ &stack[0], // Stack
+ CYGNUM_HAL_STACK_SIZE_TYPICAL, // Stack size
+ &thread_handle, // Thread handle
+ &thread_data // Thread data structure
+ );
+ cyg_thread_resume(thread_handle);
+ cyg_scheduler_start();
+}
+
+//=============================================================================
diff --git a/ecos/packages/devs/touch/arm/aaed2000/current/ChangeLog b/ecos/packages/devs/touch/arm/aaed2000/current/ChangeLog
new file mode 100644
index 0000000..9d945fe
--- /dev/null
+++ b/ecos/packages/devs/touch/arm/aaed2000/current/ChangeLog
@@ -0,0 +1,32 @@
+2002-03-10 Gary Thomas <gthomas@redhat.com>
+
+ * src/aaed2000_ts.c: Update scan frequency to 20Hz.
+
+2002-03-09 Gary Thomas <gthomas@redhat.com>
+
+ * src/aaed2000_ts.c:
+ * touch_aaed2000.cdl: New files(s). Touch screen driver for AAED2000.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/touch/arm/aaed2000/current/src/aaed2000_ts.c b/ecos/packages/devs/touch/arm/aaed2000/current/src/aaed2000_ts.c
new file mode 100644
index 0000000..fd2ad32
--- /dev/null
+++ b/ecos/packages/devs/touch/arm/aaed2000/current/src/aaed2000_ts.c
@@ -0,0 +1,368 @@
+//==========================================================================
+//
+// aaed2000_ts.c
+//
+// Touchscreen driver for the Agilent aaed2000
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2002-03-05
+// Purpose:
+// Description: Touchscreen driver for Agilent AAED2000
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <pkgconf/devs_touch_aaed2000.h>
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/aaed2000.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/fileio/fileio.h> // For select() functionality
+static cyg_selinfo ts_select_info;
+static cyg_bool ts_select_active;
+
+#include <cyg/io/devtab.h>
+
+/* ADS7846 flags */
+#define ADS_START (1 << 7)
+#define ADS_MEASURE_Y (0x01 << 4)
+#define ADS_MEASURE_X (0x05 << 4)
+#define ADS_MODE_12_BIT 0
+#define ADS_PD0 0
+
+// Misc constants
+#define TS_INT (1<<0)
+#define X_THRESHOLD 0x80
+#define Y_THRESHOLD 0x80
+
+// Functions in this module
+
+static Cyg_ErrNo ts_read(cyg_io_handle_t handle,
+ void *buffer,
+ cyg_uint32 *len);
+static cyg_bool ts_select(cyg_io_handle_t handle,
+ cyg_uint32 which,
+ cyg_addrword_t info);
+static Cyg_ErrNo ts_set_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ const void *buffer,
+ cyg_uint32 *len);
+static Cyg_ErrNo ts_get_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ void *buffer,
+ cyg_uint32 *len);
+static bool ts_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo ts_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *st,
+ const char *name);
+
+CHAR_DEVIO_TABLE(aaed2000_ts_handlers,
+ NULL, // Unsupported write() function
+ ts_read,
+ ts_select,
+ ts_get_config,
+ ts_set_config);
+
+CHAR_DEVTAB_ENTRY(aaed2000_ts_device,
+ CYGDAT_DEVS_TOUCH_AAED2000_NAME,
+ NULL, // Base device name
+ &aaed2000_ts_handlers,
+ ts_init,
+ ts_lookup,
+ NULL); // Private data pointer
+
+struct _event {
+ short button_state;
+ short xPos, yPos;
+ short _unused;
+};
+#define MAX_EVENTS CYGNUM_DEVS_TOUCH_AAED2000_EVENT_BUFFER_SIZE
+static int num_events;
+static int _event_put, _event_get;
+static struct _event _events[MAX_EVENTS];
+
+static bool _is_open = false;
+#ifdef DEBUG_RAW_EVENTS
+static unsigned char _ts_buf[512];
+static int _ts_buf_ptr = 0;
+#endif
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+static char ts_scan_stack[STACK_SIZE];
+static cyg_thread ts_scan_thread_data;
+static cyg_handle_t ts_scan_thread_handle;
+#define SCAN_FREQ 20 // Hz
+//#define SCAN_FREQ 5 // Hz
+#define SCAN_DELAY ((1000/SCAN_FREQ)/10)
+
+
+typedef struct {
+ short min;
+ short max;
+ short span;
+} bounds;
+
+static bounds xBounds = {1024, 0, 1024};
+static bounds yBounds = {1024, 0, 1024};
+
+static Cyg_ErrNo
+ts_read(cyg_io_handle_t handle,
+ void *buffer,
+ cyg_uint32 *len)
+{
+ struct _event *ev;
+ int tot = *len;
+ unsigned char *bp = (unsigned char *)buffer;
+
+ cyg_scheduler_lock(); // Prevent interaction with DSR code
+ while (tot >= sizeof(struct _event)) {
+ if (num_events > 0) {
+ ev = &_events[_event_get++];
+ if (_event_get == MAX_EVENTS) {
+ _event_get = 0;
+ }
+ // Self calibrate
+ if (ev->xPos > xBounds.max) xBounds.max = ev->xPos;
+ if (ev->xPos < xBounds.min) xBounds.min = ev->xPos;
+ if (ev->yPos > yBounds.max) yBounds.max = ev->yPos;
+ if (ev->yPos < yBounds.min) yBounds.min = ev->yPos;
+ if ((xBounds.span = xBounds.max - xBounds.min) <= 1) {
+ xBounds.span = 1;
+ }
+ if ((yBounds.span = yBounds.max - yBounds.min) <= 1) {
+ yBounds.span = 1;
+ }
+ // Scale values - done here so these potentially lengthy
+ // operations take place outside of interrupt processing
+#ifdef DEBUG
+ diag_printf("Raw[%d,%d], X[%d,%d,%d], Y[%d,%d,%d]",
+ ev->xPos, ev->yPos,
+ xBounds.max, xBounds.min, xBounds.span,
+ yBounds.max, yBounds.min, yBounds.span);
+#endif
+ ev->xPos = 640 - (((xBounds.max - ev->xPos) * 640) / xBounds.span);
+ ev->yPos = 480 - (((yBounds.max - ev->yPos) * 480) / yBounds.span);
+#ifdef DEBUG
+ diag_printf(", Cooked[%d,%d]\n",
+ ev->xPos, ev->yPos);
+#endif
+ memcpy(bp, ev, sizeof(*ev));
+ bp += sizeof(*ev);
+ tot -= sizeof(*ev);
+ num_events--;
+ } else {
+ break; // No more events
+ }
+ }
+ cyg_scheduler_unlock(); // Allow DSRs again
+ *len -= tot;
+ return ENOERR;
+}
+
+static cyg_bool
+ts_select(cyg_io_handle_t handle,
+ cyg_uint32 which,
+ cyg_addrword_t info)
+{
+ if (which == CYG_FREAD) {
+ cyg_scheduler_lock(); // Prevent interaction with DSR code
+ if (num_events > 0) {
+ cyg_scheduler_unlock(); // Reallow interaction with DSR code
+ return true;
+ }
+ if (!ts_select_active) {
+ ts_select_active = true;
+ cyg_selrecord(info, &ts_select_info);
+ }
+ cyg_scheduler_unlock(); // Reallow interaction with DSR code
+ }
+ return false;
+}
+
+static Cyg_ErrNo
+ts_set_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ const void *buffer,
+ cyg_uint32 *len)
+{
+ return EINVAL;
+}
+
+static Cyg_ErrNo
+ts_get_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ void *buffer,
+ cyg_uint32 *len)
+{
+ return EINVAL;
+}
+
+static bool
+ts_init(struct cyg_devtab_entry *tab)
+{
+ cyg_uint32 _dummy;
+
+ // Initialize SSP interface
+#if 0
+ while (*(volatile cyg_uint32 *)AAEC_SSP_SR & AAEC_SSP_SR_RNE) {
+ _dummy = *(volatile cyg_uint32 *)AAEC_SSP_DR; // Drain FIFO
+ }
+#endif
+ *(volatile cyg_uint32 *)AAEC_SSP_CR0 =
+ (1 << AAEC_SSP_CR0_SSE) | // SSP enable
+ (37 << AAEC_SSP_CR0_SCR) | // Serial clock rate
+ (AAEC_SSP_CR0_FRF_NAT << AAEC_SSP_CR0_FRF) | // MicroWire
+ ((12-1) << AAEC_SSP_CR0_SIZE); // 12 bit words
+ *(volatile cyg_uint32 *)AAEC_SSP_CR1 =
+ (1 << AAEC_SSP_CR1_FEN); // Enable FIFO
+ *(volatile cyg_uint32 *)AAEC_SSP_CPSR = 2; // Clock prescale
+ *(volatile cyg_uint32 *)AAEC_PFDDR &= ~(1<<0); // TS uses port F bit 0
+ cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_TS);
+ cyg_selinit(&ts_select_info);
+ return true;
+}
+
+static cyg_uint32
+read_ts(int axis)
+{
+ cyg_uint32 res;
+
+ *(volatile cyg_uint32 *)AAEC_SSP_DR = (axis | ADS_START | ADS_MODE_12_BIT | ADS_PD0);
+ *(volatile cyg_uint32 *)AAEC_SSP_DR = (axis | ADS_START | ADS_MODE_12_BIT);
+ // Wait for data
+ while ((*(volatile cyg_uint32 *)AAEC_SSP_SR & AAEC_SSP_SR_RNE) == 0);
+ res = *(volatile cyg_uint32 *)AAEC_SSP_DR; // ignore first datum
+ // Wait for data
+ while ((*(volatile cyg_uint32 *)AAEC_SSP_SR & AAEC_SSP_SR_RNE) == 0);
+ res = *(volatile cyg_uint32 *)AAEC_SSP_DR;
+ return res;
+}
+
+static void
+ts_scan(cyg_addrword_t param)
+{
+ short lastX, lastY;
+ short x, y;
+ struct _event *ev;
+ bool pen_down;
+
+ diag_printf("Touch Screen thread started\n");
+ // Discard the first sample - it's always 0
+ x = read_ts(ADS_MEASURE_X);
+ y = read_ts(ADS_MEASURE_Y);
+ lastX = lastY = -1;
+ pen_down = false;
+ while (true) {
+ cyg_thread_delay(SCAN_DELAY);
+ if ((*(volatile cyg_uint32 *)AAEC_PFDR & TS_INT) == 0) {
+ // Pen is down
+ x = read_ts(ADS_MEASURE_X);
+ y = read_ts(ADS_MEASURE_Y);
+// diag_printf("X = %x, Y = %x\n", x, y);
+ if ((x < X_THRESHOLD) || (y < Y_THRESHOLD)) {
+ // Ignore 'bad' samples
+ continue;
+ }
+ lastX = x; lastY = y;
+ pen_down = true;
+ } else {
+ if (pen_down) {
+ // Capture first 'up' event
+ pen_down = false;
+ x = lastX;
+ y = lastY;
+ } else {
+ continue; // Nothing new to report
+ }
+ }
+ if (num_events < MAX_EVENTS) {
+ num_events++;
+ ev = &_events[_event_put++];
+ if (_event_put == MAX_EVENTS) {
+ _event_put = 0;
+ }
+ ev->button_state = pen_down ? 0x04 : 0x00;
+ ev->xPos = x;
+ ev->yPos = y;
+ if (ts_select_active) {
+ ts_select_active = false;
+ cyg_selwakeup(&ts_select_info);
+ }
+ }
+#ifdef DEBUG_RAW_EVENTS
+ memcpy(&_ts_buf[_ts_buf_ptr], pkt->data, 8);
+ _ts_buf_ptr += 8;
+ if (_ts_buf_ptr == 512) {
+ diag_printf("TS handler\n");
+ diag_dump_buf(_ts_buf, 512);
+ _ts_buf_ptr = 0;
+ }
+#endif
+ }
+}
+
+static Cyg_ErrNo
+ts_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *st,
+ const char *name)
+{
+ if (!_is_open) {
+ _is_open = true;
+ cyg_thread_create(1, // Priority
+ ts_scan, // entry
+ 0, // entry parameter
+ "Touch Screen scan", // Name
+ &ts_scan_stack[0], // Stack
+ STACK_SIZE, // Size
+ &ts_scan_thread_handle, // Handle
+ &ts_scan_thread_data // Thread data structure
+ );
+ cyg_thread_resume(ts_scan_thread_handle); // Start it
+ }
+ return ENOERR;
+}
diff --git a/ecos/packages/devs/touch/arm/aaed2000/current/touch_aaed2000.cdl b/ecos/packages/devs/touch/arm/aaed2000/current/touch_aaed2000.cdl
new file mode 100644
index 0000000..312f482
--- /dev/null
+++ b/ecos/packages/devs/touch/arm/aaed2000/current/touch_aaed2000.cdl
@@ -0,0 +1,99 @@
+#==========================================================================
+#
+# touch_aaed2000.cdl
+#
+# eCos configuration data for the Agilent AAED2000 touchscreen
+#
+#==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas
+# Date: 2002-03-03
+# Purpose:
+# Description: Touchscreen drivers for Agilent AAED2000
+#
+#####DESCRIPTIONEND####
+#
+#==========================================================================
+
+cdl_package CYGPKG_DEVS_TOUCH_AAED2000 {
+ display "Touch screen driver for aaed2000"
+ include_dir cyg/io
+
+ active_if CYGPKG_IO_FILEIO
+ requires CYGPKG_IO
+ requires CYGFUN_KERNEL_API_C
+ requires CYGPKG_HAL_ARM_ARM9_AAED2000
+ active_if !CYGSEM_AAED2000_LCD_COMM
+
+ compile -library=libextras.a aaed2000_ts.c
+
+ description "Touch screen driver for the AAED2000"
+
+ cdl_component CYGPKG_DEVS_TOUCH_AAED2000_OPTIONS {
+ display "options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_TOUCH_AAED2000_CFLAGS {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the touchscreen driver package. These flags
+ are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGDAT_DEVS_TOUCH_AAED2000_NAME {
+ display "Device name for the touch screen driver"
+ flavor data
+ default_value {"\"/dev/ts\""}
+ description " This option specifies the name of the touch screen device"
+ }
+
+ cdl_option CYGNUM_DEVS_TOUCH_AAED2000_EVENT_BUFFER_SIZE {
+ display "Number of events the driver can buffer"
+ flavor data
+ default_value { 32 }
+ description "
+ This option defines the size of the touchscreen device internal
+ buffer. The cyg_io_read() function will return as many of these
+ as there is space for in the buffer passed."
+ }
+ }
+}
diff --git a/ecos/packages/devs/touch/arm/ipaq/current/ChangeLog b/ecos/packages/devs/touch/arm/ipaq/current/ChangeLog
new file mode 100644
index 0000000..c2dae76
--- /dev/null
+++ b/ecos/packages/devs/touch/arm/ipaq/current/ChangeLog
@@ -0,0 +1,44 @@
+2001-08-29 Kenichi Nakamura <nakamura@redhat.com>
+
+ * cdl/touch_ipaq.cdl: Modified dependency on file I/O package.
+
+2001-04-24 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/touch_ipaq.cdl: Add dependency on file I/O package.
+
+2001-03-06 Gary Thomas <gthomas@redhat.com>
+
+ * src/ipaq_ts.c: Fully interrupt driven mode, including select()
+ support. Note: scaling for the touch screen is self calibrating.
+
+ * cdl/touch_ipaq.cdl: Remove unused option for repeat interval.
+ Repeat is automatic from the Atmel micro-controller.
+
+2001-03-05 Gary Thomas <gthomas@redhat.com>
+
+ * src/ipaq_ts.c:
+ * cdl/touch_ipaq.cdl: New file(s). iPAQ touch screen driver.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/touch/arm/ipaq/current/cdl/touch_ipaq.cdl b/ecos/packages/devs/touch/arm/ipaq/current/cdl/touch_ipaq.cdl
new file mode 100644
index 0000000..733c9ff
--- /dev/null
+++ b/ecos/packages/devs/touch/arm/ipaq/current/cdl/touch_ipaq.cdl
@@ -0,0 +1,99 @@
+#==========================================================================
+#
+# touch_ipaq.cdl
+#
+# eCos configuration data for the Compaq iPAQ touchscreen
+#
+#==========================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#==========================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): gthomas
+# Contributors: gthomas
+# Date: 2001-03-05
+# Purpose:
+# Description: Touchscreen drivers for Compaq iPAQ
+#
+#####DESCRIPTIONEND####
+#
+#==========================================================================
+
+cdl_package CYGPKG_DEVS_TOUCH_IPAQ {
+ display "Touch screen driver for iPAQ"
+ include_dir cyg/io
+
+ active_if CYGPKG_IO_FILEIO
+ requires CYGPKG_IO
+ requires CYGFUN_KERNEL_API_C
+ requires CYGPKG_HAL_ARM_SA11X0_IPAQ
+ active_if !CYGSEM_IPAQ_LCD_COMM
+
+ compile -library=libextras.a ipaq_ts.c
+
+ description "Touch screen driver for the iPAQ using the Atmel micro-controller"
+
+ cdl_component CYGPKG_DEVS_TOUCH_IPAQ_OPTIONS {
+ display "options"
+ flavor none
+ no_define
+
+ cdl_option CYGPKG_DEVS_TOUCH_IPAQ_CFLAGS {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the touchscreen driver package. These flags
+ are used in addition to the set of global flags."
+ }
+
+ cdl_option CYGDAT_DEVS_TOUCH_IPAQ_NAME {
+ display "Device name for the touch screen driver"
+ flavor data
+ default_value {"\"/dev/ts\""}
+ description " This option specifies the name of the touch screen device"
+ }
+
+ cdl_option CYGNUM_DEVS_TOUCH_IPAQ_EVENT_BUFFER_SIZE {
+ display "Number of events the driver can buffer"
+ flavor data
+ default_value { 32 }
+ description "
+ This option defines the size of the touchscreen device internal
+ buffer. The cyg_io_read() function will return as many of these
+ as there is space for in the buffer passed."
+ }
+ }
+}
diff --git a/ecos/packages/devs/touch/arm/ipaq/current/src/ipaq_ts.c b/ecos/packages/devs/touch/arm/ipaq/current/src/ipaq_ts.c
new file mode 100644
index 0000000..7e268a8
--- /dev/null
+++ b/ecos/packages/devs/touch/arm/ipaq/current/src/ipaq_ts.c
@@ -0,0 +1,282 @@
+//==========================================================================
+//
+// ipaq_ts.c
+//
+// Touchscreen driver for the Compaq iPAQ
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2001-03-05
+// Purpose:
+// Description: Touchscreen driver for Compaq IPAQ
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <pkgconf/devs_touch_ipaq.h>
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_sa11x0.h>
+#include <cyg/hal/ipaq.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <cyg/fileio/fileio.h> // For select() functionality
+static cyg_selinfo ts_select_info;
+static cyg_bool ts_select_active;
+
+#include <cyg/io/devtab.h>
+#include <cyg/hal/atmel_support.h>
+
+// Functions in this module
+
+static Cyg_ErrNo ts_read(cyg_io_handle_t handle,
+ void *buffer,
+ cyg_uint32 *len);
+static cyg_bool ts_select(cyg_io_handle_t handle,
+ cyg_uint32 which,
+ cyg_addrword_t info);
+static Cyg_ErrNo ts_set_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ const void *buffer,
+ cyg_uint32 *len);
+static Cyg_ErrNo ts_get_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ void *buffer,
+ cyg_uint32 *len);
+static bool ts_init(struct cyg_devtab_entry *tab);
+static Cyg_ErrNo ts_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *st,
+ const char *name);
+
+CHAR_DEVIO_TABLE(ipaq_ts_handlers,
+ NULL, // Unsupported write() function
+ ts_read,
+ ts_select,
+ ts_get_config,
+ ts_set_config);
+
+CHAR_DEVTAB_ENTRY(ipaq_ts_device,
+ CYGDAT_DEVS_TOUCH_IPAQ_NAME,
+ NULL, // Base device name
+ &ipaq_ts_handlers,
+ ts_init,
+ ts_lookup,
+ NULL); // Private data pointer
+
+struct _event {
+ short button_state;
+ short xPos, yPos;
+ short _unused;
+};
+#define MAX_EVENTS CYGNUM_DEVS_TOUCH_IPAQ_EVENT_BUFFER_SIZE
+static int num_events;
+static int _event_put, _event_get;
+static bool pen_down = false;
+static struct _event _events[MAX_EVENTS];
+
+static bool _is_open = false;
+#ifdef DEBUG_RAW_EVENTS
+static unsigned char _ts_buf[512];
+static int _ts_buf_ptr = 0;
+#endif
+
+//
+// Note: this routine is called from the Atmel processing DSR
+//
+static void
+ts_handler(atmel_pkt *pkt)
+{
+ unsigned char *dp = pkt->data;
+ static short lastX, lastY;
+ short x, y;
+ struct _event *ev;
+
+#ifdef DEBUG_RAW_EVENTS
+ memcpy(&_ts_buf[_ts_buf_ptr], pkt->data, 8);
+ _ts_buf_ptr += 8;
+ if (_ts_buf_ptr == 512) {
+ diag_printf("TS handler\n");
+ diag_dump_buf(_ts_buf, 512);
+ _ts_buf_ptr = 0;
+ }
+#endif
+ // Try and interpret the mouse data
+ if ((dp[0] & 0x0F) == 0) {
+ // This is a pen up event
+ x = lastX;
+ y = lastY;
+ pen_down = false;
+ } else {
+ // Some sort of event with the pen down
+ x = lastX = (dp[1] << 8) | dp[2];
+ y = lastY = (dp[3] << 8) | dp[4];
+ pen_down = true;
+ }
+ if (num_events < MAX_EVENTS) {
+ num_events++;
+ ev = &_events[_event_put++];
+ if (_event_put == MAX_EVENTS) {
+ _event_put = 0;
+ }
+ ev->button_state = pen_down ? 0x04 : 0x00;
+ ev->xPos = x;
+ ev->yPos = y;
+ if (ts_select_active) {
+ ts_select_active = false;
+ cyg_selwakeup(&ts_select_info);
+ }
+ }
+}
+
+typedef struct {
+ short min;
+ short max;
+ short span;
+} bounds;
+
+static bounds xBounds = {1024, 0, 1024};
+static bounds yBounds = {1024, 0, 1024};
+
+static Cyg_ErrNo
+ts_read(cyg_io_handle_t handle,
+ void *buffer,
+ cyg_uint32 *len)
+{
+ struct _event *ev;
+ int tot = *len;
+ unsigned char *bp = (unsigned char *)buffer;
+
+ cyg_scheduler_lock(); // Prevent interaction with DSR code
+ while (tot >= sizeof(struct _event)) {
+ if (num_events > 0) {
+ ev = &_events[_event_get++];
+ if (_event_get == MAX_EVENTS) {
+ _event_get = 0;
+ }
+ // Self calibrate
+ if (ev->xPos > xBounds.max) xBounds.max = ev->xPos;
+ if (ev->xPos < xBounds.min) xBounds.min = ev->xPos;
+ if (ev->yPos > yBounds.max) yBounds.max = ev->yPos;
+ if (ev->yPos < yBounds.min) yBounds.min = ev->yPos;
+ if ((xBounds.span = xBounds.max - xBounds.min) <= 1) {
+ xBounds.span = 1;
+ }
+ if ((yBounds.span = yBounds.max - yBounds.min) <= 1) {
+ yBounds.span = 1;
+ }
+ // Scale values - done here so these potentially lengthy
+ // operations take place outside of interrupt processing
+ ev->xPos = ((xBounds.max - ev->xPos) * 320) / xBounds.span;
+ ev->yPos = ((yBounds.max - ev->yPos) * 240) / yBounds.span;
+ memcpy(bp, ev, sizeof(*ev));
+ bp += sizeof(*ev);
+ tot -= sizeof(*ev);
+ num_events--;
+ } else {
+ break; // No more events
+ }
+ }
+ cyg_scheduler_unlock(); // Allow DSRs again
+ *len -= tot;
+ return ENOERR;
+}
+
+static cyg_bool
+ts_select(cyg_io_handle_t handle,
+ cyg_uint32 which,
+ cyg_addrword_t info)
+{
+ if (which == CYG_FREAD) {
+ cyg_scheduler_lock(); // Prevent interaction with DSR code
+ if (num_events > 0) {
+ cyg_scheduler_unlock(); // Reallow interaction with DSR code
+ return true;
+ }
+ if (!ts_select_active) {
+ ts_select_active = true;
+ cyg_selrecord(info, &ts_select_info);
+ }
+ cyg_scheduler_unlock(); // Reallow interaction with DSR code
+ }
+ return false;
+}
+
+static Cyg_ErrNo
+ts_set_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ const void *buffer,
+ cyg_uint32 *len)
+{
+ return EINVAL;
+}
+
+static Cyg_ErrNo
+ts_get_config(cyg_io_handle_t handle,
+ cyg_uint32 key,
+ void *buffer,
+ cyg_uint32 *len)
+{
+ return EINVAL;
+}
+
+static bool
+ts_init(struct cyg_devtab_entry *tab)
+{
+ cyg_selinit(&ts_select_info);
+ return true;
+}
+
+static Cyg_ErrNo
+ts_lookup(struct cyg_devtab_entry **tab,
+ struct cyg_devtab_entry *st,
+ const char *name)
+{
+ if (!_is_open) {
+ _is_open = true;
+ atmel_register(ATMEL_CMD_TOUCH, ts_handler);
+ atmel_interrupt_mode(true);
+ }
+ return ENOERR;
+}
diff --git a/ecos/packages/devs/usb/at91/current/ChangeLog b/ecos/packages/devs/usb/at91/current/ChangeLog
new file mode 100644
index 0000000..0f38086
--- /dev/null
+++ b/ecos/packages/devs/usb/at91/current/ChangeLog
@@ -0,0 +1,131 @@
+2010-11-12 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * src/usbs_at91.c : Complete support for halting endpoints
+ * cdl/usbs_at91.cdl : Add option
+ CYGSEM_DEVS_USB_AT91_ZERO_LENGTH_PACKET_TERMINATION. When data
+ transfer length is known from both side, sending an empty packet
+ at the end of the transfer is not required.
+ Add devtab entry for endpoints 4 to 7.
+
+2008-11-17 Gabor Toeroek <tgabor84@gmail.com>
+
+ * src/usbs_at91.c (usbs_at91_set_pullup): Fix typo introduced by
+ Andrew Lunn in the last patch.
+
+2008-11-03 Gabor Toeroek <tgabor84@gmail.com>
+
+ * cdl/usbs_at91.cdl:
+ * include/usbs_at91.h:
+ * src/usbs_at91.c:
+ * src/usbs_at91_data.c: Support for SAM7SE which has an internal
+ pullup. Added extra endpoints for those chips that have them.
+
+2007-11-20 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/usbs_at91.cdl: Fixed typos in
+ CYGNUM_DEVS_USB_AT91_GPIO_PULLUP_INVERTED and
+ CYGNUM_DEVS_USB_AT91_GPIO_READ_POWER_INVERTED. Fixing the typo.
+
+ * src/usbs_at91.c (usbs_at91_set_pullup): Change the logic so that
+ CYGNUM_DEVS_USB_AT91_GPIO_PULLUP_INVERTED does actually cause an
+ invert when set true.
+
+2006-09-07 John Eigelaar <jeigelaar@mweb.co.za>
+
+ * cdl/usbs_at91.c: Read actual EP addresses from the EP configuartion
+ rather than relying on the order in the configuration list.
+
+2006-06-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * cdl/usbs_at91.cdl: Allow EP0 to be enabled when there are no
+ slave clients.
+
+2006-05-25 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/usbs_at91_data.cxx: Change the initialization priority. The
+ USB tty driver is initialized at priority CYG_INIT_IO, so the USB
+ device has to be initialized before that.
+
+2006-05-19 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/usbs_at91.c: Rework pullup and power dectect to use the AT91
+ GPIO macros.
+
+2006-05-07 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * Included into eCos anonymous CVS.
+
+ Note: There appears to be a hardware bug with OUT transfers. It
+ appears that after resetting the endpoint, the first OUT transfer
+ does not trigger a receive interrupt. The BK0 bit is not set,
+ however the number of bytes in the receiver FIFO is correct. The
+ second OUT transfer causes both BK0 and BK1 bits to be set and an
+ interrupt generated. Currently no workaround is used to correct
+ this behavoiour.
+
+2006-04-23 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/usbs_at91.c: Endpoint 3 can send upto 64 bytes at a time,
+ not 8.
+
+2006-04-20 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/usbs_at91.c (usbs_at91_control_data_sent): Send a zero byte
+ packet when the transfer is an exact multiple of the endpoint
+ buffer size.
+
+2006-04-16 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/usbs_at91.c (usbs_testing_endpoints): Added support for the
+ USB testcase framework by exporting what endpoint we have.
+ * src/usbs_at91.c (usbs_at91_control_setup): Make requests other
+ than standard requests work, eg CLASS, VENDOR etc.
+ * src/usbs_at91.c (usbs_at91_handle_reset): Configure the endpoint
+ hardware using the configuration information.
+ * src/usbs_at91.c (usbs_at91_control_data_sent): Transaction is
+ complete when the buffer is empty _and_ there is no refill
+ function defined.
+
+2006-03-10 Oliver Munz <oli@snr.ch>
+
+ * CDL-Update for PLL-Freuenzy.
+
+2006-03-06 Oliver Munz <oli@snr.ch>
+
+ * USB device driver work finished - haha.
+
+ What's missing:
+ The set_... and get_freature-host-commands are not implemented yet.
+ The dynamical configuration of the data-endpoints is not reflectet in
+ the "usbs.h" API.
+ Isochronus transfer is not implemented.
+ Polling routines are not implemented.
+ USB-Tests are not done.
+ The PowerDetectPin is not used for the state.
+ AT91SAM7X's are not supported at the moment.
+
+ But it works for me...
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2010 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/usb/at91/current/cdl/usbs_at91.cdl b/ecos/packages/devs/usb/at91/current/cdl/usbs_at91.cdl
new file mode 100644
index 0000000..91c3994
--- /dev/null
+++ b/ecos/packages/devs/usb/at91/current/cdl/usbs_at91.cdl
@@ -0,0 +1,286 @@
+# ====================================================================
+#
+# usbs_at91.cdl
+#
+# USB device driver for the ATMEL AT91 family of processors.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2006, 2010 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Oliver Munz, Andrew Lunn
+# Original data: bartv
+# Contributors: ccoutand
+# Date: 2006-02-25
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_USB_AT91 {
+ display "Atmel AT91 USB Device Driver"
+ include_dir "cyg/io/usb"
+ parent CYGPKG_IO_USB
+ implements CYGHWR_IO_USB_SLAVE
+
+ cdl_interface CYGINT_DEVS_USB_AT91_HAS_USB {
+ description "
+ This interface is implemented by HALs for devices which have
+ the USB hardware."
+ }
+
+ description "
+ This package provides a suitable eCos device driver
+ for AT91 USB.
+ In this version the driver will support the AT91SAM7S.
+ Other AT92 devices may work, but have not been tested.
+ The Driver needs 48, 96 or 192MHz plus minus 0.25%.
+ Buffers are allocated only in the higher level. There
+ is no need to configure the endpoints in this CDL, because
+ they will be configured dynamical at the set_configuration
+ call from the host...
+ The endpoints 1..3 can be configured as bulk or interrupt
+ IN or OUT endpoint. Isochronous transfer is not supported."
+
+ cdl_component CYGFUN_DEVS_USB_AT91_EP0 {
+ display "Support the control endpoint 0"
+ flavor bool
+ default_value CYGINT_IO_USB_SLAVE_CLIENTS
+ requires CYGPKG_IO_USB CYGPKG_IO_USB_SLAVE
+ requires {
+ ((CYGNUM_HAL_ARM_AT91_CLOCK_SPEED < 48120000 &&
+ CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 47880000) ||
+ (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED < 96240000 &&
+ CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 95760000))
+ }
+
+ active_if CYGINT_DEVS_USB_AT91_HAS_USB
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+
+ compile usbs_at91.c
+ compile -library=libextras.a usbs_at91_data.cxx
+ description "
+ Enable support for endpoint 0. If this support is disabled
+ then the entire USB port is unusable."
+
+ cdl_option CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_INTERNAL {
+ display "The chip has internal pullup"
+ flavor bool
+ calculated { CYGHWR_HAL_ARM_AT91SAM7SE }
+ requires { CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN == "NONE" }
+ description "
+ The chip has an internal pullup resistor;
+ the use of this pullup is mandatory (?), so there
+ should be no external pullup resistor."
+ }
+
+ cdl_option CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN {
+ display "PIO-Pin who controls the pullup resistor"
+ flavor data
+ default_value { "AT91_GPIO_PA16" }
+ description "
+ Every GPIO pin is able to do it. If you don't need
+ a pin because your HW has the pullup fixed wired
+ then select NONE"
+ }
+
+ cdl_option CYGNUM_DEVS_USB_AT91_GPIO_SET_PULLUP_INVERTED {
+ display "Has the signal to be inverted?"
+ active_if {CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN != "NONE"}
+ flavor bool
+ default_value 1
+ description "
+ This option indicates that the pullup pin should
+ be inverted. ie VDD is active, VCC is inactive. For the
+ AT91SAM7SEK it needs to be inverted, hence this default."
+ }
+
+ cdl_option CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN {
+ display "PIO-Pin who see the USB-Power"
+ flavor data
+ default_value { "AT91_GPIO_PA13"}
+ description "
+ Every GPIO pin is able to do it. If you don't need
+ a pin then select NONE"
+ }
+
+ cdl_option CYGNUM_DEVS_USB_AT91_GPIO_READ_POWER_INVERTED {
+ display "Has the signal to be inverted?"
+ flavor bool
+ default_value 0
+ description "
+ This option indicates that the power detect pin should
+ be inverted. ie VDD is active, VCC is inactive."
+ }
+
+ cdl_option CYGSEM_DEVS_USB_AT91_ZERO_LENGTH_PACKET_TERMINATION {
+ display "Allow USB driver to end data transfer with an empty data packet."
+ flavor bool
+ default_value 1
+ description "
+ This option allows the USB driver to automatically signal the
+ end of a data transmission with an empty packet, if the last packet
+ fragment is equal to the endpoint buffer size."
+ }
+
+ }
+
+ cdl_component CYGPKG_DEVS_USB_AT91_DEVTAB_ENTRIES {
+ display "Provide a devtab entry for endpoints"
+ active_if CYGFUN_DEVS_USB_AT91_EP0
+ default_value 0
+ description "
+ This component controls if /dev/usb entries will be created."
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP0_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 0"
+ flavor bool
+ default_value 0
+ requires CYGPKG_IO
+ description "
+ If endpoint 0 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and ioctl calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP1_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 1"
+ flavor bool
+ default_value 1
+ requires CYGPKG_IO
+ description "
+ If this endpoint will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP2_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 2"
+ flavor bool
+ default_value 1
+ requires CYGPKG_IO
+ description "
+ If this endpoint will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP3_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 3"
+ flavor bool
+ default_value 1
+ requires CYGPKG_IO
+ description "
+ If this endpoint will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP4_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 4"
+ flavor bool
+ default_value 0
+ requires CYGPKG_IO
+ description "
+ If this endpoint will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP5_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 5"
+ flavor bool
+ default_value 0
+ requires CYGPKG_IO
+ description "
+ If this endpoint will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP6_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 6"
+ flavor bool
+ default_value 0
+ requires CYGPKG_IO
+ description "
+ If this endpoint will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_AT91_EP7_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 7"
+ flavor bool
+ default_value 0
+ requires CYGPKG_IO
+ description "
+ If this endpoint will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed."
+ }
+
+ cdl_option CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME {
+ display "Base name for devtab entries"
+ flavor data
+ default_value { "\"/dev/usbs\"" }
+ description "
+ If the uAT91 USB device driver package provides devtab
+ entries for any of the endpoints then this option gives
+ control over the names of these entries. By default the
+ endpoints will be called \"/dev/usbs0c\", \"/dev/usbs3w\"
+ and \"/dev/usbs4r\" (assuming all three endpoints are
+ enabled. The common part \"/dev/usbs\" is determined
+ by this configuration option. It may be necessary to
+ change this if there are multiple USB slave-side
+ devices on the target hardware to prevent a name clash."
+ }
+ }
+}
diff --git a/ecos/packages/devs/usb/at91/current/include/usbs_at91.h b/ecos/packages/devs/usb/at91/current/include/usbs_at91.h
new file mode 100644
index 0000000..f3316ce
--- /dev/null
+++ b/ecos/packages/devs/usb/at91/current/include/usbs_at91.h
@@ -0,0 +1,82 @@
+#ifndef CYGONCE_USBS_AT91_H
+#define CYGONCE_USBS_AT91_H
+//==========================================================================
+//
+// include/usbs_at91.h
+//
+// The interface exported by the AT91 USB device driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Oliver Munz
+// Contributors: bartv
+// Date: 2006-02-25
+// Purpose:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/io/usb/usbs.h>
+#include <pkgconf/devs_usb_at91.h>
+#include <pkgconf/system.h>
+#ifdef CYGPKG_HAL_ARM_AT91SAM7
+#include <pkgconf/hal_arm_at91sam7.h>
+#endif
+
+#if defined(CYGHWR_HAL_ARM_AT91SAM7SE)
+#define AT91_USB_ENDPOINTS 8
+#elif defined(CYGHWR_HAL_ARM_AT91SAM7X)
+#define AT91_USB_ENDPOINTS 6
+#else
+#define AT91_USB_ENDPOINTS 4
+#endif
+
+extern usbs_control_endpoint usbs_at91_ep0;
+extern usbs_rx_endpoint usbs_at91_ep1;
+extern usbs_rx_endpoint usbs_at91_ep2;
+extern usbs_rx_endpoint usbs_at91_ep3;
+#if (AT91_USB_ENDPOINTS > 4)
+extern usbs_rx_endpoint usbs_at91_ep4;
+extern usbs_rx_endpoint usbs_at91_ep5;
+#if (AT91_USB_ENDPOINTS > 6)
+extern usbs_rx_endpoint usbs_at91_ep6;
+extern usbs_rx_endpoint usbs_at91_ep7;
+#endif
+#endif
+
+extern void usbs_at91_endpoint_init(usbs_rx_endpoint * pep,
+ cyg_uint8 endpoint_type, cyg_bool enable);
+#endif /* CYGONCE_USBS_AT91_H */
diff --git a/ecos/packages/devs/usb/at91/current/src/bitops.h b/ecos/packages/devs/usb/at91/current/src/bitops.h
new file mode 100644
index 0000000..78ed1eb
--- /dev/null
+++ b/ecos/packages/devs/usb/at91/current/src/bitops.h
@@ -0,0 +1,98 @@
+#ifndef CYGONCE_USBS_AT91_BITOPS_H
+#define CYGONCE_USBS_AT91_BITOPS_H
+
+//==========================================================================
+//
+// bitops.h
+//
+// Hardware Bit manipulation macros for the AT91 USB device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Oliver Munz
+// Contributors: bartv
+// Date: 2006-02-22
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+// Set the given bits in a device register
+#define SET_BITS(_register_, _bits_) \
+ CYG_MACRO_START \
+ cyg_uint32 _value_; \
+ HAL_READ_UINT32(_register_, _value_); \
+ _value_ |= _bits_; \
+ HAL_WRITE_UINT32(_register_, _value_); \
+ CYG_MACRO_END
+
+// Clear the given bits in a device register
+#define CLEAR_BITS(_register_, _bits_) \
+ CYG_MACRO_START \
+ cyg_uint32 _value_; \
+ HAL_READ_UINT32(_register_, _value_); \
+ _value_ &= ~_bits_; \
+ HAL_WRITE_UINT32(_register_, _value_); \
+ CYG_MACRO_END
+
+#define BITS_ARE_SET(_register_, _bits) \
+ bits_are_set(_register_, _bits)
+
+#define BITS_ARE_CLEARED(_register_, _bits) \
+ bits_are_cleared(_register_, _bits)
+
+static inline cyg_bool
+bits_are_set (cyg_addrword_t addr, cyg_uint32 bits)
+{
+ cyg_uint32 read;
+
+ HAL_READ_UINT32 (addr, read);
+
+ return (read & bits) == bits;
+}
+
+static inline cyg_bool
+bits_are_cleared (cyg_addrword_t addr, cyg_uint32 bits)
+{
+ cyg_uint32 read;
+
+ HAL_READ_UINT32 (addr, read);
+
+ return (read | ~bits) == ~bits;
+}
+
+
+#endif // CYGONCE_USBS_AT91_BITOPS_H
+
diff --git a/ecos/packages/devs/usb/at91/current/src/usbs_at91.c b/ecos/packages/devs/usb/at91/current/src/usbs_at91.c
new file mode 100644
index 0000000..03db043
--- /dev/null
+++ b/ecos/packages/devs/usb/at91/current/src/usbs_at91.c
@@ -0,0 +1,1633 @@
+//==========================================================================
+//
+// usbs_at91.c
+//
+// Driver for the AT91 USB device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006, 2010 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Oliver Munz,
+// Contributors: Andrew Lunn, bartv, ccoutand
+// Date: 2006-02-22
+//
+// This code implements support for the on-chip USB port on the AT91
+// family of processors. The code has been developed on the AT91SAM7S
+// and may or may not work on other members of the AT91 family.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_usb_at91.h>
+#include <cyg/io/usb/usb.h>
+#include <cyg/io/usb/usbs.h>
+#include <cyg/io/usb/usbs_at91.h>
+
+#include CYGBLD_HAL_PLATFORM_H
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_platform_ints.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+
+#include "bitops.h"
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define AT91_UDP_CSR0 (AT91_UDP_CSR)
+#define AT91_UDP_FDR0 (AT91_UDP_FDR)
+
+#define pIER (AT91_UDP + AT91_UDP_IER)
+#define pIDR (AT91_UDP + AT91_UDP_IDR)
+#define pISR (AT91_UDP + AT91_UDP_ISR)
+#define pIMR (AT91_UDP + AT91_UDP_IMR)
+#define pICR (AT91_UDP + AT91_UDP_ICR)
+
+#define pCSR0 (AT91_UDP + AT91_UDP_CSR0)
+#define pFDR0 (AT91_UDP + AT91_UDP_FDR0)
+
+#define pCSRn(N) (pCSR0 + (N * 4))
+#define pFDRn(N) (pFDR0 + (N * 4))
+
+#if (AT91_USB_ENDPOINTS == 8)
+#define AT91_UDP_ALLOWED_IRQs \
+ (AT91_UDP_WAKEUP | AT91_UDP_ENDBUSRES | AT91_UDP_EXTRSM | \
+ AT91_UDP_RXRSM | AT91_UDP_RXSUSP | AT91_UDP_EPINT0 | \
+ AT91_UDP_EPINT1 | AT91_UDP_EPINT2 | AT91_UDP_EPINT3 | \
+ AT91_UDP_EPINT4 | AT91_UDP_EPINT5 | \
+ AT91_UDP_EPINT6 | AT91_UDP_EPINT7 )
+#elif (AT91_USB_ENDPOINTS == 6)
+#define AT91_UDP_ALLOWED_IRQs \
+ (AT91_UDP_WAKEUP | AT91_UDP_ENDBUSRES | AT91_UDP_EXTRSM | \
+ AT91_UDP_RXRSM | AT91_UDP_RXSUSP | AT91_UDP_EPINT0 | \
+ AT91_UDP_EPINT1 | AT91_UDP_EPINT2 | AT91_UDP_EPINT3 | \
+ AT91_UDP_EPINT4 | AT91_UDP_EPINT5 )
+#elif (AT91_USB_ENDPOINTS == 4)
+#define AT91_UDP_ALLOWED_IRQs \
+ (AT91_UDP_WAKEUP | AT91_UDP_ENDBUSRES | AT91_UDP_EXTRSM | \
+ AT91_UDP_RXRSM | AT91_UDP_RXSUSP | AT91_UDP_EPINT0 | \
+ AT91_UDP_EPINT1 | AT91_UDP_EPINT2 | AT91_UDP_EPINT3)
+#endif
+
+#define THERE_IS_A_NEW_PACKET_IN_THE_UDP 0xffff
+
+// Fifo size for each end point.
+#if defined(CYGHWR_HAL_ARM_AT91SAM7SE)
+static const cyg_uint16 usbs_at91_endpoint_fifo_size[AT91_USB_ENDPOINTS] = {
+ 8,
+ 64,
+ 64,
+ 64,
+ 512,
+ 512,
+ 64,
+ 64
+};
+#elif defined(CYGHWR_HAL_ARM_AT91SAM7X)
+static const cyg_uint16 usbs_at91_endpoint_fifo_size[AT91_USB_ENDPOINTS] = {
+ 8,
+ 64,
+ 64,
+ 64,
+ 256,
+ 256
+};
+#else
+static const cyg_uint16 usbs_at91_endpoint_fifo_size[AT91_USB_ENDPOINTS] = {
+ 8,
+ 64,
+ 64,
+ 64,
+};
+#endif
+
+// Does an endpoint support ping pong buffering?
+#if defined(CYGHWR_HAL_ARM_AT91SAM7SE)
+static const bool usbs_at91_endpoint_pingpong[AT91_USB_ENDPOINTS] = {
+ false,
+ true,
+ true,
+ false,
+ true,
+ true,
+ true,
+ true
+};
+#elif defined(CYGHWR_HAL_ARM_AT91SAM7X)
+static const bool usbs_at91_endpoint_pingpong[AT91_USB_ENDPOINTS] = {
+ false,
+ true,
+ true,
+ false,
+ true,
+ true
+};
+#else
+static const bool usbs_at91_endpoint_pingpong[AT91_USB_ENDPOINTS] = {
+ false,
+ true,
+ true,
+ false
+};
+#endif
+
+static cyg_uint8 *usbs_at91_endpoint_pbegin[AT91_USB_ENDPOINTS] =
+#if (AT91_USB_ENDPOINTS == 8)
+ { 0, 0, 0, 0, 0, 0, 0, 0 };
+#elif (AT91_USB_ENDPOINTS == 6)
+ { 0, 0, 0, 0, 0, 0 };
+#else
+ { 0, 0, 0, 0 };
+#endif
+
+static cyg_uint8 *usbs_at91_endpoint_pend[AT91_USB_ENDPOINTS] =
+#if (AT91_USB_ENDPOINTS == 8)
+ { 0, 0, 0, 0, 0, 0, 0, 0 };
+#elif (AT91_USB_ENDPOINTS == 6)
+ { 0, 0, 0, 0, 0, 0 };
+#else
+ { 0, 0 ,0, 0 };
+#endif
+
+static bool usbs_at91_endpoint_bank1[AT91_USB_ENDPOINTS] =
+#if (AT91_USB_ENDPOINTS == 8)
+ { false, false, false, false, false, false, false, false };
+#elif (AT91_USB_ENDPOINTS == 6)
+ { false, false, false, false, false, false };
+#else
+ { false, false, false, false };
+#endif
+
+static cyg_uint16 usbs_at91_endpoint_bytes_in_fifo[AT91_USB_ENDPOINTS] =
+#if (AT91_USB_ENDPOINTS == 8)
+ { 0, 0, 0, 0, 0, 0, 0, 0 };
+#elif (AT91_USB_ENDPOINTS == 6)
+ { 0, 0, 0, 0, 0, 0 };
+#else
+ { 0, 0, 0, 0 };
+#endif
+
+static cyg_uint16 usbs_at91_endpoint_bytes_received[AT91_USB_ENDPOINTS] =
+ { THERE_IS_A_NEW_PACKET_IN_THE_UDP, THERE_IS_A_NEW_PACKET_IN_THE_UDP,
+#if (AT91_USB_ENDPOINTS > 4)
+ THERE_IS_A_NEW_PACKET_IN_THE_UDP, THERE_IS_A_NEW_PACKET_IN_THE_UDP,
+#if (AT91_USB_ENDPOINTS > 6)
+ THERE_IS_A_NEW_PACKET_IN_THE_UDP, THERE_IS_A_NEW_PACKET_IN_THE_UDP,
+#endif
+#endif
+ THERE_IS_A_NEW_PACKET_IN_THE_UDP, THERE_IS_A_NEW_PACKET_IN_THE_UDP};
+
+static cyg_interrupt usbs_at91_intr_data;
+static cyg_handle_t usbs_at91_intr_handle;
+
+static void usbs_at91_ep0_start(usbs_control_endpoint *);
+static void usbs_at91_poll(usbs_control_endpoint *);
+
+static void usbs_at91_endpoint_start(usbs_rx_endpoint * pep);
+static void usbs_at91_endpoint_set_halted(usbs_rx_endpoint * pep,
+ cyg_bool new_value);
+void usbs_at91_endpoint_init(usbs_rx_endpoint * pep,
+ cyg_uint8 endpoint_type,
+ cyg_bool enable);
+
+// Endpoint 0, the control endpoint, structure.
+usbs_control_endpoint usbs_at91_ep0 = {
+ // The hardware does not distinguish between detached, attached and powered.
+ state: USBS_STATE_POWERED,
+ enumeration_data: (usbs_enumeration_data *) 0,
+ start_fn: usbs_at91_ep0_start,
+ poll_fn: usbs_at91_poll,
+ interrupt_vector: CYGNUM_HAL_INTERRUPT_UDP,
+ control_buffer: {0, 0, 0, 0, 0, 0, 0, 0},
+ state_change_fn: (void (*) (usbs_control_endpoint *,
+ void *, usbs_state_change, int)) 0,
+ state_change_data: (void *) 0,
+ standard_control_fn: (usbs_control_return (*)
+ (usbs_control_endpoint *, void *)) 0,
+ standard_control_data: (void *) 0,
+ class_control_fn: (usbs_control_return (*)
+ (usbs_control_endpoint *, void *)) 0,
+ class_control_data: (void *) 0,
+ vendor_control_fn: (usbs_control_return (*)
+ (usbs_control_endpoint *, void *)) 0,
+ vendor_control_data: (void *) 0,
+ reserved_control_fn: (usbs_control_return (*)
+ (usbs_control_endpoint *, void *)) 0,
+ reserved_control_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ fill_buffer_fn: (void (*)(usbs_control_endpoint *)) 0,
+ fill_data: (void *) 0,
+ fill_index: 0,
+ complete_fn: (usbs_control_return (*)(usbs_control_endpoint *,
+ int)) 0
+};
+
+// Endpoint 1 receive control structure
+usbs_rx_endpoint usbs_at91_ep1 = {
+ start_rx_fn: usbs_at91_endpoint_start,
+ set_halted_fn: usbs_at91_endpoint_set_halted,
+ complete_fn: (void (*)(void *, int)) 0,
+ complete_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ halted: 0,
+};
+
+// Endpoint 2 Receive control structure
+usbs_rx_endpoint usbs_at91_ep2 = {
+ start_rx_fn: usbs_at91_endpoint_start,
+ set_halted_fn: usbs_at91_endpoint_set_halted,
+ complete_fn: (void (*)(void *, int)) 0,
+ complete_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ halted: 0,
+};
+
+// Endpoint 3 Receive control structure
+usbs_rx_endpoint usbs_at91_ep3 = {
+ start_rx_fn: usbs_at91_endpoint_start,
+ set_halted_fn: usbs_at91_endpoint_set_halted,
+ complete_fn: (void (*)(void *, int)) 0,
+ complete_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ halted: 0,
+};
+
+#if (AT91_USB_ENDPOINTS > 4)
+// Endpoint 4 Receive control structure
+usbs_rx_endpoint usbs_at91_ep4 = {
+ start_rx_fn: usbs_at91_endpoint_start,
+ set_halted_fn: usbs_at91_endpoint_set_halted,
+ complete_fn: (void (*)(void *, int)) 0,
+ complete_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ halted: 0,
+};
+#endif
+
+#if (AT91_USB_ENDPOINTS > 5)
+// Endpoint 5 Receive control structure
+usbs_rx_endpoint usbs_at91_ep5 = {
+ start_rx_fn: usbs_at91_endpoint_start,
+ set_halted_fn: usbs_at91_endpoint_set_halted,
+ complete_fn: (void (*)(void *, int)) 0,
+ complete_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ halted: 0,
+};
+#endif
+
+#if (AT91_USB_ENDPOINTS > 6)
+// Endpoint 6 Receive control structure
+usbs_rx_endpoint usbs_at91_ep6 = {
+ start_rx_fn: usbs_at91_endpoint_start,
+ set_halted_fn: usbs_at91_endpoint_set_halted,
+ complete_fn: (void (*)(void *, int)) 0,
+ complete_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ halted: 0,
+};
+#endif
+
+#if (AT91_USB_ENDPOINTS > 7)
+// Endpoint 7 Receive control structure
+usbs_rx_endpoint usbs_at91_ep7 = {
+ start_rx_fn: usbs_at91_endpoint_start,
+ set_halted_fn: usbs_at91_endpoint_set_halted,
+ complete_fn: (void (*)(void *, int)) 0,
+ complete_data: (void *) 0,
+ buffer: (unsigned char *) 0,
+ buffer_size: 0,
+ halted: 0,
+};
+#endif
+
+// Array of end points. Used for translating end point pointer to an
+// end point number
+static const void *usbs_at91_endpoints[AT91_USB_ENDPOINTS] = {
+ (void *) &usbs_at91_ep0,
+ (void *) &usbs_at91_ep1,
+ (void *) &usbs_at91_ep2,
+ (void *) &usbs_at91_ep3
+#if (AT91_USB_ENDPOINTS > 4)
+ ,(void *) &usbs_at91_ep4, (void *) &usbs_at91_ep5
+#if (AT91_USB_ENDPOINTS > 6)
+ ,(void *) &usbs_at91_ep6, (void *) &usbs_at91_ep7
+#endif
+#endif
+};
+
+// Convert an endpoint pointer to an endpoint number, using the array
+// of endpoint structures
+static int
+usbs_at91_pep_to_number(const usbs_rx_endpoint * pep)
+{
+ int epn;
+
+ for(epn=0; epn < AT91_USB_ENDPOINTS; epn++) {
+ if (pep == usbs_at91_endpoints[epn])
+ return epn;
+ }
+ CYG_FAIL("Unknown endpoint");
+ return 0;
+}
+
+typedef enum ep0_low_level_status_t {
+ EP0_LL_IDLE = 0,
+ EP0_LL_REQUEST,
+ EP0_LL_SEND_READY,
+ EP0_LL_ACK,
+ EP0_LL_RECEIVE_READY,
+ EP0_LL_ISOERROR,
+ EP0_LL_STALL,
+ EP0_LL_SET_ADDRESS,
+} ep0_low_level_status_t;
+
+// Enable/Disable interrupts for a specific endpoint.
+static void
+usbs_at91_endpoint_interrupt_enable (cyg_uint8 epn, bool enable)
+{
+ CYG_ASSERT (epn < AT91_USB_ENDPOINTS, "Invalid endpoint");
+
+ if (enable) {
+ HAL_WRITE_UINT32 (pIER, 1 << epn);
+ } else {
+ HAL_WRITE_UINT32 (pIDR, 1 << epn);
+ }
+}
+
+static cyg_uint8 *
+read_fifo_uint8 (cyg_uint8 * pdest, cyg_addrword_t psource, cyg_uint32 size)
+{
+ cyg_uint8 *preqbyte = pdest;
+ cyg_uint8 reqbyte;
+
+ while (size--) {
+ HAL_READ_UINT8 (psource, reqbyte);
+ *preqbyte = reqbyte;
+ preqbyte++;
+ }
+
+ return preqbyte;
+}
+
+static cyg_uint8 *
+write_fifo_uint8 (cyg_addrword_t pdest, cyg_uint8 * psource,
+ cyg_uint8 * psource_end)
+{
+ cyg_uint8 *preqbyte;
+
+ for (preqbyte = psource; preqbyte < psource_end; preqbyte++) {
+ HAL_WRITE_UINT8 (pdest, (*preqbyte));
+ }
+
+ return preqbyte;
+}
+
+/* Tell the host that the device is ready to start communication */
+static void
+usbs_at91_set_pullup (bool set)
+{
+#ifdef CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_INTERNAL
+ cyg_uint32 txvc;
+ HAL_READ_UINT32(AT91_UDP + AT91_UDP_TXVC, txvc);
+ if (set) {
+ txvc |= AT91_UDP_TXVC_PUON;
+ } else {
+ txvc &= ~AT91_UDP_TXVC_PUON;
+ }
+ HAL_WRITE_UINT32(AT91_UDP + AT91_UDP_TXVC, txvc);
+#endif // CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_INTERNAL
+
+#ifndef CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN_NONE
+ if (
+#ifdef CYGNUM_DEVS_USB_AT91_GPIO_SET_PULLUP_INVERTED
+ !set
+#else
+ set
+#endif
+ ) {
+ HAL_ARM_AT91_GPIO_SET(CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN);
+ } else {
+ HAL_ARM_AT91_GPIO_RESET(CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN);
+ }
+#endif
+}
+
+/* Is the USB powered? */
+bool
+usbs_at91_read_power (void)
+{
+#ifndef CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN_NONE
+ cyg_bool state;
+
+ HAL_ARM_AT91_GPIO_GET(CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN, state);
+#ifdef CYGNUM_DEVS_USB_AT91_GPIO_READ_POWER_INVERTED
+ return !state;
+#else
+ return state;
+#endif
+#endif
+ return true;
+}
+
+// Stop all transfers that are currently active.
+static void
+usbs_end_all_transfers (usbs_control_return returncode)
+{
+ cyg_uint32 epn;
+ usbs_rx_endpoint *pep;
+
+ for (epn = 1; epn < AT91_USB_ENDPOINTS; epn++) {
+ if (BITS_ARE_SET (pIMR, 1 << epn)) {
+ // If the end point is transmitting, call the complete function
+ // to terminate to transfer
+ pep = (usbs_rx_endpoint *) usbs_at91_endpoints[epn];
+
+ if (pep->complete_fn) {
+ (*pep->complete_fn) (pep->complete_data, returncode);
+ }
+ // Disable interrupts from the endpoint
+ usbs_at91_endpoint_interrupt_enable (epn, false);
+ }
+ }
+}
+
+// There has been a change in state. Update the end point.
+static void
+usbs_state_notify (usbs_control_endpoint * pcep)
+{
+ static int old_state = USBS_STATE_CHANGE_POWERED;
+ int state = pcep->state & USBS_STATE_MASK;
+
+ if (pcep->state != old_state) {
+ usbs_end_all_transfers (-EPIPE);
+ switch (state) {
+ case USBS_STATE_DETACHED:
+ case USBS_STATE_ATTACHED:
+ case USBS_STATE_POWERED:
+ // Nothing to do
+ break;
+ case USBS_STATE_DEFAULT:
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_GLB_STATE, 0);
+ break;
+ case USBS_STATE_ADDRESSED:
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_GLB_STATE, AT91_UDP_GLB_FADDEN);
+ break;
+ case USBS_STATE_CONFIGURED:
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_GLB_STATE, AT91_UDP_GLB_CONFG);
+ break;
+ default:
+ CYG_FAIL("Unknown endpoint state");
+ }
+
+ if (pcep->state_change_fn) {
+ (*pcep->state_change_fn) (pcep, pcep->state_change_data, pcep->state, old_state);
+ }
+
+ old_state = pcep->state;
+ }
+}
+
+static usbs_control_return
+usbs_parse_host_get_command (usbs_control_endpoint * pcep)
+{
+ usbs_control_return retcode;
+ cyg_uint8 dev_req_type =
+ (((usb_devreq *) pcep->control_buffer)->type) & USB_DEVREQ_TYPE_MASK;
+
+ switch (dev_req_type) {
+ case USB_DEVREQ_TYPE_STANDARD:
+ if (!pcep->standard_control_fn) {
+ return usbs_handle_standard_control (pcep);
+ }
+
+ retcode =
+ (*pcep->standard_control_fn) (pcep, pcep->standard_control_data);
+
+ if (retcode == USBS_CONTROL_RETURN_UNKNOWN) {
+ return usbs_handle_standard_control (pcep);
+ }
+ return retcode;
+
+ case USB_DEVREQ_TYPE_CLASS:
+ if (!pcep->class_control_fn) {
+ return USBS_CONTROL_RETURN_STALL;
+ }
+ return (*pcep->class_control_fn) (pcep, pcep->class_control_data);
+
+ case USB_DEVREQ_TYPE_VENDOR:
+ if (!pcep->class_control_fn) {
+ return USBS_CONTROL_RETURN_STALL;
+ }
+ return (*pcep->class_control_fn) (pcep, pcep->vendor_control_data);
+
+ case USB_DEVREQ_TYPE_RESERVED:
+ if (!pcep->reserved_control_fn) {
+ return USBS_CONTROL_RETURN_STALL;
+ }
+ return (*pcep->reserved_control_fn) (pcep, pcep->reserved_control_data);
+ default:
+ return USBS_CONTROL_RETURN_STALL;
+ }
+}
+
+static void
+usbs_at91_endpoint_set_halted (usbs_rx_endpoint * pep, cyg_bool new_value)
+{
+ int epn = usbs_at91_pep_to_number(pep);
+ cyg_addrword_t pCSR = pCSRn(epn);
+ cyg_uint32 reg;
+
+ cyg_drv_dsr_lock ();
+
+ if (pep->halted != new_value) {
+ /* There is something is to do */
+ pep->halted = new_value;
+
+ if ( new_value ) {
+
+ /* Halt endpoint */
+ SET_BITS (pCSR, AT91_UDP_CSR_FORCESTALL);
+
+ } else {
+ /* Restart endpoint */
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_FORCESTALL);
+
+ // Reset Fifo
+ HAL_READ_UINT32 (AT91_UDP + AT91_UDP_RST_EP, reg);
+ reg |= (1 << epn);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_RST_EP, reg);
+ reg &= ~(1 << epn);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_RST_EP, reg);
+
+ // Ready to use
+ if (pep->complete_fn) {
+ (*pep->complete_fn) (pep->complete_data, ENOERR);
+ }
+
+ }
+ }
+ cyg_drv_dsr_unlock ();
+}
+
+void
+usbs_at91_endpoint_init (usbs_rx_endpoint * pep, cyg_uint8 endpoint_type,
+ cyg_bool enable)
+{
+ int epn = usbs_at91_pep_to_number(pep);
+ cyg_addrword_t pCSR = pCSRn(epn);
+
+ CYG_ASSERT (AT91_USB_ENDPOINTS > epn, "Invalid end point");
+
+ usbs_at91_endpoint_interrupt_enable (epn, false);
+ /* Reset endpoint */
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_RST_EP, 1 << epn);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_RST_EP, 0);
+
+ pep->halted = false;
+
+ /* Type | In */
+ HAL_WRITE_UINT32 (pCSR, (((((cyg_uint32) endpoint_type) & 0x03) << 8) |
+ ((((cyg_uint32) endpoint_type) & 0x80) << 3)));
+
+ usbs_at91_endpoint_bytes_in_fifo[epn] = 0;
+ usbs_at91_endpoint_bytes_received[epn] = THERE_IS_A_NEW_PACKET_IN_THE_UDP;
+ usbs_at91_endpoint_bank1[epn] = false;
+
+ if (enable) {
+ SET_BITS (pCSR, AT91_UDP_CSR_EPEDS);
+ }
+}
+
+static void
+usbs_at91_reset_device (void)
+{
+ int epn;
+
+ usbs_end_all_transfers (-EPIPE);
+
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_IDR, 0xffffffff);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_ICR, 0xffffffff);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_RST_EP, 0xffffffff);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_RST_EP, 0x00000000);
+
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_FADDR, AT91_UDP_FADDR_FEN);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_CSR0,
+ AT91_UDP_CSR_EPEDS | AT91_UDP_CSR_EPTYPE_CTRL);
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_IER, AT91_UDP_ALLOWED_IRQs);
+
+ for (epn=1; epn < AT91_USB_ENDPOINTS; epn++) {
+ usbs_at91_endpoint_init ((usbs_rx_endpoint *)usbs_at91_endpoints[epn],
+ 0, false);
+ }
+}
+
+static void
+usbs_at91_handle_reset (void)
+{
+ int epn;
+ const usb_endpoint_descriptor *usb_endpoints;
+ cyg_uint8 endpoint_type;
+
+ cyg_uint8 endpoint_number;
+
+ usbs_at91_reset_device ();
+
+ // Now walk the endpoints configuring them correctly. This only
+ // works if there is one interface.
+ usb_endpoints = usbs_at91_ep0.enumeration_data->endpoints;
+
+ for (epn = 1;
+ epn <= usbs_at91_ep0.enumeration_data->total_number_endpoints;
+ epn++) {
+
+ endpoint_type = (usb_endpoints[epn-1].attributes |
+ (usb_endpoints[epn-1].endpoint &
+ USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN ?
+ USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN :
+ USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT));
+ endpoint_number = usb_endpoints[epn-1].endpoint & ~(USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN);
+
+ if ( endpoint_number < AT91_USB_ENDPOINTS ) {
+ usbs_at91_endpoint_init((usbs_rx_endpoint *)usbs_at91_endpoints[endpoint_number],
+ endpoint_type,
+ true);
+ }
+ }
+}
+
+static void
+usbs_at91_ep0_start (usbs_control_endpoint * endpoint)
+{
+ usbs_at91_handle_reset ();
+
+ // If there is additional platform-specific initialization to
+ // perform, do it now. This macro can come from the platform HAL,
+ // but may not be available on all platforms.
+#ifdef AT91_USB_PLATFORM_INIT
+ AT91_USB_PLATFORM_INIT ();
+#endif
+
+ usbs_at91_set_pullup (true);
+ CLEAR_BITS(AT91_UDP + AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
+}
+
+static void
+usbs_at91_endpoint_start (usbs_rx_endpoint * pep)
+{
+ int epn = usbs_at91_pep_to_number(pep);
+ cyg_addrword_t pCSR = pCSRn(epn);
+ cyg_addrword_t pFDR = pFDRn(epn);
+ cyg_uint16 space = 0;
+ cyg_uint16 endpoint_size = usbs_at91_endpoint_fifo_size[epn];
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[epn];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[epn];
+
+ CYG_ASSERT (pep->complete_fn, "No complete_fn()");
+
+ cyg_drv_dsr_lock ();
+ if (usbs_at91_ep0.state != USBS_STATE_CONFIGURED) {
+ /* If not configured it means there is nothing to do */
+ cyg_drv_dsr_unlock ();
+
+ if (pep->complete_fn) {
+ (*pep->complete_fn) (pep->complete_data, -EPIPE);
+ }
+ return;
+ }
+
+ // Is this endpoint currently stalled? If so then a size of 0 can
+ // be used to block until the stall condition is clear, anything
+ // else should result in an immediate callback.
+ if (pep->halted) {
+ /* Halted means nothing to do */
+ cyg_drv_dsr_unlock ();
+
+ if (pep->complete_fn && pep->buffer_size != 0) {
+ (*pep->complete_fn) (pep->complete_data, -EAGAIN);
+ }
+ return;
+ }
+
+ if (BITS_ARE_SET (pIMR, 1 << epn)) {
+ cyg_drv_dsr_unlock ();
+
+ if (pep->complete_fn) {
+ (*pep->complete_fn) (pep->complete_data, -EIO);
+ }
+
+ return;
+ }
+
+ CYG_ASSERT (BITS_ARE_SET (pCSR, 1 << 9), "Wrong endpoint type");
+
+ *ppbegin = pep->buffer; /* Set the working pointers */
+ *ppend = (cyg_uint8 *) ((cyg_uint32) pep->buffer + pep->buffer_size);
+
+ if (BITS_ARE_SET (pCSR, 0x400)) { /* IN: tx_endpoint */
+ space = (cyg_uint32) * ppend - (cyg_uint32) * ppbegin;
+
+#ifdef CYGSEM_DEVS_USB_AT91_ZERO_LENGTH_PACKET_TERMINATION
+ if (space == endpoint_size) {
+ *ppend = *ppbegin; /* Send zero-packet */
+ }
+#endif
+
+ *ppbegin =
+ write_fifo_uint8 (pFDR, *ppbegin,
+ (cyg_uint8 *) ((cyg_uint32) * ppbegin +
+ MIN (space, endpoint_size)));
+ SET_BITS (pCSR, AT91_UDP_CSR_TXPKTRDY);
+
+ if (*ppend == *ppbegin) { /* Last packet ? */
+ *ppend = *ppbegin - 1; /* The packet hasn't been sent yet */
+ }
+ }
+
+ usbs_at91_endpoint_interrupt_enable (epn, true);
+
+ cyg_drv_dsr_unlock ();
+}
+
+// Perform transmit handling on an endpoint
+static bool
+usbs_at91_endpoint_isr_tx(cyg_uint8 epn)
+{
+ cyg_addrword_t pCSR = pCSRn(epn);
+ cyg_addrword_t pFDR = pFDRn(epn);
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[epn];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[epn];
+ cyg_uint32 space = 0;
+ cyg_uint16 endpoint_size = usbs_at91_endpoint_fifo_size[epn];
+
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_TXCOMP);
+
+ if (BITS_ARE_CLEARED (pCSR, AT91_UDP_CSR_TXPKTRDY)) {
+ /* Ready to transmit ? */
+ if (*ppend > *ppbegin) {
+ /* Something to send */
+
+ space = (cyg_uint32) * ppend - (cyg_uint32) * ppbegin;
+
+#ifdef CYGSEM_DEVS_USB_AT91_ZERO_LENGTH_PACKET_TERMINATION
+ if (space == endpoint_size) {
+ *ppend = *ppbegin; /* Send zero-packet */
+ }
+#endif
+
+ *ppbegin =
+ write_fifo_uint8 (pFDR, *ppbegin,
+ (cyg_uint8 *) ((cyg_uint32) * ppbegin +
+ MIN (space, endpoint_size)));
+ SET_BITS (pCSR, AT91_UDP_CSR_TXPKTRDY);
+
+ if (*ppend == *ppbegin) { /* Last packet ? */
+ *ppend = *ppbegin - 1; /* The packet isn't sent yet */
+ }
+
+ } else {
+
+#ifdef CYGSEM_DEVS_USB_AT91_ZERO_LENGTH_PACKET_TERMINATION
+ if (*ppend + 1 == *ppbegin) {
+ *ppend = *ppbegin; /* Flag for DSR */
+ return true;
+ } else {
+ *ppend = *ppbegin - 1; /* Flag for zero-packet */
+ SET_BITS (pCSR, AT91_UDP_CSR_TXPKTRDY); /* Send no data */
+ }
+#else
+ *ppend = *ppbegin; /* Flag for DSR */
+ return true;
+#endif
+
+ }
+ }
+
+ CLEAR_BITS (pCSR,
+ AT91_UDP_CSR_RX_DATA_BK0 | AT91_UDP_CSR_RX_DATA_BK1 |
+ AT91_UDP_CSR_RXSETUP | AT91_UDP_CSR_ISOERROR);
+ return false;
+}
+
+static bool
+usbs_at91_endpoint_isr_rx(cyg_uint8 epn)
+{
+ cyg_addrword_t pCSR = pCSRn(epn);
+ cyg_addrword_t pFDR = pFDRn(epn);
+ cyg_uint16 *pinfifo = &usbs_at91_endpoint_bytes_in_fifo[epn];
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[epn];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[epn];
+ cyg_uint16 *preceived = &usbs_at91_endpoint_bytes_received[epn];
+ cyg_uint16 endpoint_size = usbs_at91_endpoint_fifo_size[epn];
+
+ if (*preceived == THERE_IS_A_NEW_PACKET_IN_THE_UDP) {
+ /* There is a new packet */
+ *preceived = ((*(cyg_uint32 *)pCSR) >> 16) & 0x7ff;
+ *pinfifo = *preceived;
+ }
+
+ while ((*ppbegin < *ppend) && *pinfifo) {
+ /* If we have buffer-space AND data in the FIFO */
+ HAL_READ_UINT8(pFDR, **ppbegin);
+ (*ppbegin)++;
+ (*pinfifo)--;
+ }
+
+ if (*ppbegin == *ppend) {
+ /* The buffer is full... call the DSR */
+ return true;
+ }
+
+ if (*pinfifo == 0) {
+ /* If the FIFO is empty, then we can release it */
+ if (usbs_at91_endpoint_pingpong[epn]) {
+ /* Time to clear the interrupt flag */
+
+ if (usbs_at91_endpoint_bank1[epn]) {
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_RX_DATA_BK1);
+ } else {
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_RX_DATA_BK0);
+ }
+ usbs_at91_endpoint_bank1[epn] = !usbs_at91_endpoint_bank1[epn];
+ } else {
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_RX_DATA_BK0);
+ }
+
+ if (*preceived < endpoint_size) {
+ /* If the last packet was smaller then the endpoint-size... */
+ *ppend = *ppbegin;
+ *preceived = THERE_IS_A_NEW_PACKET_IN_THE_UDP; /* Set flag */
+
+ return true; /* We can call the completion-function in the DSR */
+ }
+
+ *preceived = THERE_IS_A_NEW_PACKET_IN_THE_UDP; /* Set flag */
+ }
+ return false;
+}
+
+// ISR for an endpoint. Handle receive and transmit interrupts.
+static bool
+usbs_at91_endpoint_isr (cyg_uint8 epn)
+{
+ cyg_addrword_t pCSR = pCSRn(epn);
+
+ CYG_ASSERT (AT91_USB_ENDPOINTS > epn && epn, "Invalid end point");
+
+ // Host has acknowledged the endpoint being stall
+ if (BITS_ARE_SET (pCSR, AT91_UDP_CSR_ISOERROR)) {
+ CLEAR_BITS (pCSR, AT91_UDP_CSR_ISOERROR);
+ }
+
+ if (BITS_ARE_SET (pCSR, 0x400)) { /* IN: tx_endpoint */
+ if (usbs_at91_endpoint_isr_tx(epn))
+ return true; // Call the DSR
+ } else { /* OUT: rx_endpoint */
+ if (!BITS_ARE_CLEARED (pCSR, AT91_UDP_CSR_RX_DATA_BK0) ||
+ !BITS_ARE_CLEARED (pCSR, AT91_UDP_CSR_RX_DATA_BK1)) {
+ /* Sometime something received ? */
+ if(usbs_at91_endpoint_isr_rx(epn))
+ return true; // Call the DSR;
+ }
+
+ CLEAR_BITS (pCSR,
+ AT91_UDP_CSR_TXCOMP | AT91_UDP_CSR_RXSETUP |
+ AT91_UDP_CSR_ISOERROR);
+ }
+
+ return false;
+}
+
+// Handle a DSR for an endpoint
+static void
+usbs_at91_endpoint_dsr (cyg_uint8 epn)
+{
+ usbs_rx_endpoint *pep = (usbs_rx_endpoint *) usbs_at91_endpoints[epn];
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[epn];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[epn];
+
+ CYG_ASSERT (AT91_USB_ENDPOINTS > epn && epn, "Invalid end point");
+ CYG_ASSERT (pep->complete_fn, "No complete_fn()");
+
+ if (*ppend == *ppbegin) { /* Transmitted/Received ? */
+
+ pep->buffer_size = (cyg_uint32) * ppbegin - (cyg_uint32) pep->buffer;
+ if (pep->complete_fn)
+ {
+ /* Do not check on pep->buffer_size != 0, user should
+ * be allowed to send empty packet */
+ if (!pep->halted) {
+ (*pep->complete_fn) (pep->complete_data, pep->buffer_size);
+ } else {
+ (*pep->complete_fn) (pep->complete_data, -EAGAIN);
+ }
+ }
+ usbs_at91_endpoint_interrupt_enable (epn, false);
+ }
+}
+
+// Handle an error condition on the control endpoint
+static ep0_low_level_status_t
+usbs_at91_control_error(ep0_low_level_status_t status)
+{
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+
+ usbs_at91_ep0.buffer_size = 0;
+ usbs_at91_ep0.fill_buffer_fn = 0;
+ usbs_at91_ep0.complete_fn = 0;
+
+ *ppbegin = usbs_at91_ep0.buffer;
+ *ppend = *ppbegin;
+
+ if (status == EP0_LL_IDLE) {
+ if (usbs_at91_ep0.complete_fn) {
+ (*usbs_at91_ep0.complete_fn) (&usbs_at91_ep0,
+ USBS_CONTROL_RETURN_STALL);
+ }
+ }
+
+ status = EP0_LL_IDLE;
+
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_ISOERROR | AT91_UDP_CSR_FORCESTALL);
+
+ return status;
+}
+
+// Handle a get status setup message on the control end point
+static ep0_low_level_status_t
+usbs_at91_control_setup_get_status(void)
+{
+ ep0_low_level_status_t status;
+ usb_devreq *req = (usb_devreq *)usbs_at91_ep0.control_buffer;
+ cyg_uint8 recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+ cyg_uint16 word = 0;
+
+ status = EP0_LL_SEND_READY;
+
+ switch (recipient) {
+ case USB_DEVREQ_RECIPIENT_DEVICE:
+ case USB_DEVREQ_RECIPIENT_INTERFACE:
+ // Nothing to do
+ break;
+ case USB_DEVREQ_RECIPIENT_ENDPOINT:
+ if ((usbs_at91_ep0.state == USBS_STATE_CONFIGURED) &&
+ (req->index_lo > 0) &&
+ (req->index_lo < AT91_USB_ENDPOINTS)) {
+ cyg_uint32 CSR;
+
+ HAL_READ_UINT32(pCSRn(req->index_lo), CSR);
+ if (CSR & AT91_UDP_CSR_EPEDS) {
+ word = 1;
+ }
+ } else {
+ status = EP0_LL_STALL;
+ }
+ break;
+ default:
+ status = EP0_LL_STALL;
+ }
+
+ *ppbegin = (cyg_uint8 *)&word;
+ *ppend = *ppbegin + sizeof (word);
+ return status;
+}
+
+// Setup the begin and end pointers such that an ACK is sent
+static void
+usbs_at91_control_setup_send_ack(void)
+{
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+
+ *ppbegin = usbs_at91_ep0.buffer;
+ *ppend = *ppbegin;
+}
+
+// Handle a get status set feature message on the control endpoint
+static ep0_low_level_status_t
+usbs_at91_control_setup_set_feature(void)
+{
+ ep0_low_level_status_t status;
+ usb_devreq *req = (usb_devreq *)usbs_at91_ep0.control_buffer;
+ cyg_uint8 recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+ usbs_rx_endpoint * pep;
+ cyg_uint8 ep_num = req->index_lo & 0x0F;
+
+ usbs_at91_control_setup_send_ack();
+ status = EP0_LL_SEND_READY;
+
+ switch(recipient) {
+ case USB_DEVREQ_RECIPIENT_DEVICE:
+ status = EP0_LL_STALL;
+ break;
+ case USB_DEVREQ_RECIPIENT_INTERFACE:
+ // Nothing to do
+ break;
+ case USB_DEVREQ_RECIPIENT_ENDPOINT:
+ if ((usbs_at91_ep0.state == USBS_STATE_CONFIGURED) &&
+ (ep_num > 0) &&
+ (ep_num < AT91_USB_ENDPOINTS)) {
+ cyg_uint32 CSR;
+
+ HAL_READ_UINT32(pCSRn(ep_num), CSR);
+ pep = (usbs_rx_endpoint *) usbs_at91_endpoints[ep_num];
+ if ( (CSR & AT91_UDP_CSR_EPEDS) ) {
+ usbs_at91_endpoint_set_halted ( pep , true );
+ }
+ else
+ status = EP0_LL_STALL;
+
+ }
+ else {
+ status = EP0_LL_STALL;
+ }
+ break;
+ default:
+ status = EP0_LL_STALL;
+ }
+ return status;
+}
+
+// Handle a get status clear feature message on the control endpoint
+static ep0_low_level_status_t
+usbs_at91_control_setup_clear_feature(void)
+{
+ ep0_low_level_status_t status;
+ usb_devreq *req = (usb_devreq *)usbs_at91_ep0.control_buffer;
+ cyg_uint8 recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+ usbs_rx_endpoint * pep;
+ cyg_uint8 ep_num = req->index_lo & 0x0F;
+
+ usbs_at91_control_setup_send_ack();
+ status = EP0_LL_SEND_READY;
+
+ switch (recipient) {
+ case USB_DEVREQ_RECIPIENT_DEVICE:
+ status = EP0_LL_STALL;
+ break;
+ case USB_DEVREQ_RECIPIENT_INTERFACE:
+ // Nothing to do
+ break;
+ case USB_DEVREQ_RECIPIENT_ENDPOINT:
+ if ((usbs_at91_ep0.state == USBS_STATE_CONFIGURED) &&
+ (ep_num > 0) &&
+ (ep_num < AT91_USB_ENDPOINTS)) {
+ cyg_uint32 CSR;
+
+ HAL_READ_UINT32(pCSRn(ep_num), CSR);
+ pep = (usbs_rx_endpoint *) usbs_at91_endpoints[ep_num];
+ if ( (CSR & AT91_UDP_CSR_EPEDS) && pep->halted ) {
+ usbs_at91_endpoint_set_halted ( pep , false );
+ }
+ else
+ status = EP0_LL_STALL;
+
+ }
+ else {
+ status = EP0_LL_STALL;
+ }
+ break;
+ default:
+ status = EP0_LL_STALL;
+ }
+ return status;
+}
+
+// Handle a setup message from the host
+static ep0_low_level_status_t
+usbs_at91_control_setup(ep0_low_level_status_t status)
+{
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+ usb_devreq *req = (usb_devreq *) usbs_at91_ep0.control_buffer;
+ cyg_uint8 protocol;
+ cyg_uint16 length;
+ bool dev_to_host;
+ usbs_control_return usbcode;
+ bool handled = false;
+
+ usbs_at91_ep0.buffer_size = 0;
+ usbs_at91_ep0.fill_buffer_fn = 0;
+ usbs_at91_ep0.complete_fn = 0;
+
+ read_fifo_uint8 ((cyg_uint8 *)req, pFDR0, sizeof (usb_devreq));
+
+ length = (req->length_hi << 8) | req->length_lo;;
+ dev_to_host = req->type & USB_DEVREQ_DIRECTION_IN;
+
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_DTGLE);
+
+ status = EP0_LL_REQUEST;
+
+ protocol = req->type & (USB_DEVREQ_TYPE_MASK);
+
+ // Set the next transfer direction
+ if (dev_to_host) {
+ SET_BITS (pCSR0, AT91_UDP_CSR_DIR); /* Set IN direction */
+ } else {
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_DIR); /* Set OUT direction */
+ }
+
+ if (protocol == USB_DEVREQ_TYPE_STANDARD) {
+ handled = true;
+ switch (req->request) {
+ case USB_DEVREQ_GET_STATUS:
+ status = usbs_at91_control_setup_get_status();
+ break;
+ case USB_DEVREQ_SET_ADDRESS:
+ // Most of the hard work is done by the hardware. We just need
+ // to send an ACK.
+ usbs_at91_control_setup_send_ack();
+ status = EP0_LL_SEND_READY;
+ break;
+ case USB_DEVREQ_SET_FEATURE:
+ status = usbs_at91_control_setup_set_feature();
+ break;
+ case USB_DEVREQ_CLEAR_FEATURE:
+ status = usbs_at91_control_setup_clear_feature();
+ break;
+ default:
+ handled = false;
+ }
+ }
+ if ((protocol != USB_DEVREQ_TYPE_STANDARD) || !handled) {
+ // Ask the layer above to process the message
+ usbcode = usbs_parse_host_get_command (&usbs_at91_ep0);
+ usbs_at91_ep0.buffer_size = MIN (usbs_at91_ep0.buffer_size, length);
+
+ *ppbegin = usbs_at91_ep0.buffer;
+ *ppend = *ppbegin + usbs_at91_ep0.buffer_size; /* Ready to send... */
+
+ if (usbcode == USBS_CONTROL_RETURN_HANDLED) { /* OK */
+ if (dev_to_host) {
+ status = EP0_LL_SEND_READY;
+ } else {
+ status = EP0_LL_RECEIVE_READY;
+ }
+ } else {
+ status = EP0_LL_STALL;
+ }
+ }
+ // Clear the setup bit so indicating we have processed the message
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_RXSETUP);
+
+ return status;
+}
+
+static ep0_low_level_status_t
+usbs_at91_control_data_recv(ep0_low_level_status_t status)
+{
+ cyg_uint32 received = 0;
+ cyg_uint32 length;
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+ usbs_control_return usbcode;
+
+ if (status == EP0_LL_RECEIVE_READY) {
+ received = ((*(cyg_uint32 *) pCSR0) >> 16) & 0x7ff;
+ length = MIN (received, (cyg_uint32) *ppend - (cyg_uint32) *ppbegin);
+ *ppbegin = read_fifo_uint8 (*ppbegin, pFDR0, length);
+
+ if (received < usbs_at91_endpoint_fifo_size[0]) { /* Last packet ? */
+ *ppend = *ppbegin;
+ }
+
+ if (*ppbegin == *ppend) { /* All received ? */
+ usbs_at91_ep0.buffer_size =
+ (cyg_uint32) *ppend - (cyg_uint32) usbs_at91_ep0.buffer;
+ usbcode = USBS_CONTROL_RETURN_STALL;
+
+ if (usbs_at91_ep0.complete_fn) {
+ usbcode = (*usbs_at91_ep0.complete_fn) (&usbs_at91_ep0, 0);
+ }
+
+ if (usbcode == USBS_CONTROL_RETURN_HANDLED) {
+ status = EP0_LL_SEND_READY;
+ } else {
+ status = EP0_LL_STALL;
+ }
+ }
+ }
+
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_RX_DATA_BK0);
+
+ return status;
+}
+
+static ep0_low_level_status_t
+usbs_at91_control_data_sent(ep0_low_level_status_t status)
+{
+ cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[0];
+ cyg_uint8 **ppend = &usbs_at91_endpoint_pend[0];
+ cyg_uint32 bytes_to_write = 0;
+ usb_devreq *req = (usb_devreq *)usbs_at91_ep0.control_buffer;
+ cyg_uint16 value;
+
+ switch (status) {
+ case EP0_LL_SEND_READY:
+ if (*ppbegin == *ppend &&
+ usbs_at91_ep0.fill_buffer_fn == NULL) {
+ // All bytes are sent, send ACK
+ status = EP0_LL_ACK;
+ SET_BITS (pCSR0, AT91_UDP_CSR_TXPKTRDY); // Signal FIFO loaded
+ } else {
+ // We have more bytes to send
+ bytes_to_write =
+ MIN (*ppend - *ppbegin, usbs_at91_endpoint_fifo_size[0]);
+ *ppbegin = write_fifo_uint8 (pFDR0, *ppbegin, (cyg_uint8 *)
+ ((cyg_uint32) *ppbegin + bytes_to_write));
+ // Send next few bytes
+ if (*ppbegin == *ppend) { /* Control-Endoints don't need ACK's */
+ if (usbs_at91_ep0.fill_buffer_fn) { // More Records ?
+ (*usbs_at91_ep0.fill_buffer_fn) (&usbs_at91_ep0);
+
+ *ppbegin = usbs_at91_ep0.buffer;
+ *ppend = *ppbegin + usbs_at91_ep0.buffer_size;
+
+ /* Ready to send... */
+ bytes_to_write =
+ MIN (*ppend - *ppbegin,
+ usbs_at91_endpoint_fifo_size[0] - bytes_to_write);
+
+ *ppbegin = write_fifo_uint8 (pFDR0, *ppbegin, (cyg_uint8 *)
+ ((cyg_uint32) *ppbegin + bytes_to_write));
+ // Send next few bytes
+ } else {
+ if (bytes_to_write == usbs_at91_endpoint_fifo_size[0]) {
+ // Last packet is full, so we need to send a zero bytes
+ // packet next time
+ status = EP0_LL_SEND_READY;
+ } else {
+ status = EP0_LL_IDLE;
+ }
+
+ }
+ }
+ SET_BITS (pCSR0, AT91_UDP_CSR_TXPKTRDY); // Signal FIFO loaded
+ }
+ break;
+ case EP0_LL_RECEIVE_READY:
+ /* Maybe we have to send an ACK */
+ if (*ppbegin == *ppend) { // All bytes are received, send ACK
+ status = EP0_LL_ACK;
+ SET_BITS (pCSR0, AT91_UDP_CSR_TXPKTRDY); // Signal FIFO loaded
+ }
+ break;
+ case EP0_LL_ACK:
+ if (req->request == USB_DEVREQ_SET_ADDRESS) { // Special-processing
+ HAL_WRITE_UINT32 (AT91_UDP + AT91_UDP_FADDR,
+ req->value_lo | AT91_UDP_FADDR_FEN);
+ value = (req->value_hi << 8) | req->value_lo;
+ if (value) {
+ usbs_at91_ep0.state = USBS_STATE_ADDRESSED;
+ }
+ }
+
+ if (usbs_at91_ep0.complete_fn) {
+ (*usbs_at91_ep0.complete_fn) (&usbs_at91_ep0,
+ USBS_CONTROL_RETURN_HANDLED);
+ }
+ status = EP0_LL_IDLE;
+ usbs_state_notify (&usbs_at91_ep0);
+ break;
+ default:
+ break;
+ }
+ return status;
+}
+
+static void
+usbs_at91_control_dsr (void)
+{
+ static ep0_low_level_status_t status = EP0_LL_IDLE;
+
+ while (!BITS_ARE_CLEARED(pCSR0,
+ AT91_UDP_CSR_TXCOMP | AT91_UDP_CSR_RX_DATA_BK0 |
+ AT91_UDP_CSR_RXSETUP | AT91_UDP_CSR_ISOERROR |
+ AT91_UDP_CSR_RX_DATA_BK1)) {
+
+ // Check and handle any error conditions
+ if (BITS_ARE_SET (pCSR0, AT91_UDP_CSR_ISOERROR)) {
+ status = usbs_at91_control_error(status);
+ }
+
+ // Check for a setup message and handle it
+ if (BITS_ARE_SET (pCSR0, AT91_UDP_CSR_RXSETUP)) {
+ status = usbs_at91_control_setup(status);
+ }
+
+ // Check for received data on the control endpoint
+ if (BITS_ARE_SET (pCSR0, AT91_UDP_CSR_RX_DATA_BK0)) {
+ status = usbs_at91_control_data_recv(status);
+ }
+
+ // Check if the last packet has been sent
+ if (BITS_ARE_CLEARED (pCSR0, AT91_UDP_CSR_TXPKTRDY)) {
+ status = usbs_at91_control_data_sent(status);
+ }
+
+ // Received an ACK packet
+ if (BITS_ARE_SET (pCSR0, AT91_UDP_CSR_TXCOMP)) {
+ CLEAR_BITS (pCSR0, AT91_UDP_CSR_TXCOMP);
+ }
+
+ if (status == EP0_LL_STALL) {
+ CLEAR_BITS (pCSR0, 0x7f);
+ SET_BITS (pCSR0, AT91_UDP_CSR_FORCESTALL);
+ }
+ }
+}
+
+static void
+usbs_at91_dsr (cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_uint8 n;
+
+ CYG_ASSERT (CYGNUM_HAL_INTERRUPT_UDP == vector, "Wrong interrupts");
+ CYG_ASSERT (0 == data, "DSR needs no data");
+
+ CLEAR_BITS (AT91_UDP + AT91_UDP_GLB_STATE, 0x10);
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_WAKEUP)) {
+ usbs_at91_ep0.state = USBS_STATE_DEFAULT;
+ usbs_state_notify (&usbs_at91_ep0);
+
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_WAKEUP);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_ENDBUSRES)) { // RESET UDP
+ usbs_at91_ep0.state = USBS_STATE_POWERED;
+ usbs_state_notify (&usbs_at91_ep0);
+ usbs_at91_handle_reset ();
+
+ HAL_WRITE_UINT32 (pCSR0, AT91_UDP_CSR_EPEDS | AT91_UDP_CSR_EPTYPE_CTRL);
+ HAL_WRITE_UINT32 (pIER, AT91_UDP_EPINT0);
+
+ usbs_at91_ep0.state = USBS_STATE_DEFAULT;
+ usbs_state_notify (&usbs_at91_ep0);
+
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_ENDBUSRES);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_SOFINT)) {
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_SOFINT);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_EXTRSM)) {
+ usbs_at91_ep0.state = usbs_at91_ep0.state & ~USBS_STATE_SUSPENDED;
+ usbs_state_notify (&usbs_at91_ep0);
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_EXTRSM);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_RXRSM)) {
+ usbs_at91_ep0.state = usbs_at91_ep0.state & ~USBS_STATE_SUSPENDED;
+ usbs_state_notify (&usbs_at91_ep0);
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_RXRSM);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_RXSUSP)) {
+ usbs_at91_ep0.state = usbs_at91_ep0.state | USBS_STATE_SUSPENDED;
+ usbs_state_notify (&usbs_at91_ep0);
+ HAL_WRITE_UINT32 (pICR, AT91_UDP_RXSUSP);
+ }
+
+ if (BITS_ARE_SET (pISR, AT91_UDP_EPINT0)) {
+ usbs_at91_control_dsr ();
+ }
+
+ for (n = 1; n < AT91_USB_ENDPOINTS; n++) {
+ if (*(cyg_uint32 *) pIMR & (1 << n)) {
+ usbs_at91_endpoint_dsr (n);
+ }
+ }
+
+ cyg_drv_interrupt_unmask (vector);
+}
+
+static cyg_uint32
+usbs_at91_isr (cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_uint8 n;
+ bool need_dsr = false;
+ cyg_uint32 IMR;
+ cyg_uint32 ISR;
+
+ CYG_ASSERT (CYGNUM_HAL_INTERRUPT_UDP == vector, "Wrong interrupts");
+ CYG_ASSERT (0 == data, "ISR needs no data");
+
+ HAL_READ_UINT32(pIMR, IMR);
+ HAL_READ_UINT32(pISR, ISR);
+
+ for (n = 1; n < AT91_USB_ENDPOINTS; n++) {
+ /* Do any data endpoint need a data transfer ? */
+ if (IMR & ISR & (1 << n)) {
+ need_dsr = usbs_at91_endpoint_isr (n) || need_dsr;
+ }
+ }
+ /* If we don't need any DSR re-enable interrupts and finish */
+ if (BITS_ARE_CLEARED (pISR, AT91_UDP_ALLOWED_IRQs & 0xffffff01)
+ && !need_dsr) {
+ cyg_drv_interrupt_acknowledge (vector);
+ return CYG_ISR_HANDLED;
+ }
+
+ /* Call the DSR */
+ cyg_drv_interrupt_mask (vector);
+ cyg_drv_interrupt_acknowledge (vector);
+
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+
+
+
+// ----------------------------------------------------------------------------
+// Polling support. It is not clear that this is going to work particularly
+// well since according to the documentation the hardware does not generate
+// NAKs automatically - instead the ISR has to set the appropriate bits
+// sufficiently quickly to avoid confusing the host.
+//
+// Calling the isr directly avoids duplicating code, but means that
+// cyg_drv_interrupt_acknowledge() will get called when not inside a
+// real interrupt handler. This should be harmless.
+
+static void
+usbs_at91_poll (usbs_control_endpoint * endpoint)
+{
+ CYG_ASSERT (endpoint == &usbs_at91_ep0, "Wrong endpoint");
+ if (CYG_ISR_CALL_DSR == usbs_at91_isr (CYGNUM_HAL_INTERRUPT_UDP, 0)) {
+ usbs_at91_dsr (CYGNUM_HAL_INTERRUPT_UDP, 0, 0);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Initialization
+//
+// This routine gets called from a prioritized static constructor during
+// eCos startup.
+
+void
+usbs_at91_init (void)
+{
+
+ cyg_uint32 reg;
+
+ HAL_READ_UINT32 (AT91_PMC + AT91_PMC_PLLR, reg);
+
+ /* Set USB divider so we have a 48MHz clock */
+#if ((CYGNUM_HAL_ARM_AT91_CLOCK_SPEED < 48120000) && \
+ (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 47880000))
+
+ // 48MHz clock, divider set to 1
+ HAL_WRITE_UINT32 (AT91_PMC + AT91_PMC_PLLR,
+ (reg & 0x0fffffff) | AT91_PMC_PLLR_USBDIV_1);
+
+#elif ((CYGNUM_HAL_ARM_AT91_CLOCK_SPEED < 96240000) && \
+ (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 95760000))
+
+ // 96MHz clock, divider set to 2
+ HAL_WRITE_UINT32 (AT91_PMC + AT91_PMC_PLLR,
+ (reg & 0x0fffffff) | AT91_PMC_PLLR_USBDIV_2);
+#else
+#error CYGNUM_HAL_ARM_AT91_CLOCK_SPEED is not 48, 96 or 192MHz plusminus 0.25% ...
+#endif
+
+ /* Enable USB clock */
+ HAL_WRITE_UINT32 (AT91_PMC + AT91_PMC_SCER, AT91_PMC_SCER_UDP);
+ HAL_WRITE_UINT32 (AT91_PMC + AT91_PMC_PCER, AT91_PMC_PCER_UDP);
+
+ usbs_at91_set_pullup (false);
+#ifndef CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN_NONE
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(CYGDAT_DEVS_USB_AT91_GPIO_SET_PULLUP_PIN,
+ AT91_PIN_OUT);
+#endif
+#ifndef CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN_NONE
+ HAL_ARM_AT91_GPIO_CFG_DIRECTION(CYGDAT_DEVS_USB_AT91_GPIO_READ_POWER_PIN,
+ AT91_PIN_IN);
+#endif
+ usbs_at91_reset_device ();
+
+ cyg_drv_interrupt_create (CYGNUM_HAL_INTERRUPT_UDP,
+ 6, // priority
+ 0, // data
+ &usbs_at91_isr,
+ &usbs_at91_dsr,
+ &usbs_at91_intr_handle, &usbs_at91_intr_data);
+
+ cyg_drv_interrupt_attach (usbs_at91_intr_handle);
+ cyg_drv_interrupt_unmask (CYGNUM_HAL_INTERRUPT_UDP);
+
+ usbs_at91_ep0.state = USBS_STATE_POWERED;
+ usbs_state_notify (&usbs_at91_ep0);
+}
+
+// ----------------------------------------------------------------------------
+// Testing support.
+usbs_testing_endpoint usbs_testing_endpoints[] = {
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL,
+ endpoint_number : 0,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &usbs_at91_ep0,
+#ifdef CYGVAR_DEVS_USB_AT91_EP0_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "0c",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1, // zero-byte control transfers are meaningless
+ max_size : 0x0FFFF, // limit imposed by protocol
+ max_in_padding : 0,
+ alignment : 0
+ },
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 1,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
+ endpoint : (void*) &usbs_at91_ep1,
+#ifdef CYGVAR_DEVS_USB_AT91_EP1_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "1r",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1,
+ max_size : -1, // No hardware or driver limitation
+ max_in_padding : 0,
+ alignment : 0
+ },
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 2,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &usbs_at91_ep2,
+#ifdef CYGVAR_DEVS_USB_AT91_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "2w",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1,
+ max_size : -1, // No hardware or driver limitation
+ max_in_padding : 1, // hardware limitation
+ alignment : 0
+ },
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 3,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &usbs_at91_ep3,
+#ifdef CYGVAR_DEVS_USB_AT91_EP3_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "3w",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1,
+ max_size : -1, // No hardware or driver limitation
+ max_in_padding : 1, // hardware limitation
+ alignment : 0
+ },
+ USBS_TESTING_ENDPOINTS_TERMINATOR
+};
diff --git a/ecos/packages/devs/usb/at91/current/src/usbs_at91_data.cxx b/ecos/packages/devs/usb/at91/current/src/usbs_at91_data.cxx
new file mode 100644
index 0000000..c9d0665
--- /dev/null
+++ b/ecos/packages/devs/usb/at91/current/src/usbs_at91_data.cxx
@@ -0,0 +1,256 @@
+//==========================================================================
+//
+// usbs_at91_data.cxx
+//
+// Static data for the ATMEL AT91 USB device driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Oliver Munz
+// Contributors: bartv
+// Date: 2006-02-22
+//
+// This file contains various objects that should go into extras.o
+// rather than libtarget.a, e.g. devtab entries that would normally
+// be eliminated by the selective linking.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/diag.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/usb/usbs_at91.h>
+#include <pkgconf/devs_usb_at91.h>
+
+// ----------------------------------------------------------------------------
+// Initialization. The goal here is to call usbs_at91_init()
+// early on during system startup, to take care of things like
+// registering interrupt handlers etc. which are best done
+// during system init.
+//
+// If the endpoint 0 devtab entry is available then its init()
+// function can be used to take care of this. However the devtab
+// entries are optional so an alternative mechanism must be
+// provided. Unfortunately although it is possible to give
+// a C function the constructor attribute, it cannot be given
+// an initpri attribute. Instead it is necessary to define a
+// dummy C++ class.
+
+extern "C" void usbs_at91_init(void);
+
+#ifndef CYGVAR_DEVS_USB_AT91_EP0_DEVTAB_ENTRY
+
+class usbs_at91_initialization {
+public:
+ usbs_at91_initialization() {
+ usbs_at91_init();
+ }
+};
+
+static usbs_at91_initialization CYGBLD_ATTRIB_INIT_BEFORE(CYG_INIT_IO)
+ usbs_at91_init_object;
+#endif
+
+// ----------------------------------------------------------------------------
+// The devtab entries. Each of these is optional, many applications
+// will want to use the lower-level API rather than go via
+// open/read/write/ioctl.
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP0_DEVTAB_ENTRY
+// For endpoint 0 the only legal operations are get_config() and
+// set_config(), and these are provided by the common package.
+
+static bool usbs_at91_devtab_ep0_init(struct cyg_devtab_entry* tab){
+
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+
+ usbs_at91_init();
+
+ return true;
+}
+
+CHAR_DEVIO_TABLE(usbs_at91_ep0_devtab_functions,
+ &cyg_devio_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep0_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "0",
+ 0,
+ &usbs_at91_ep0_devtab_functions,
+ &usbs_at91_devtab_ep0_init,
+ 0,
+ (void*) &usbs_at91_ep0);
+#endif
+
+// ----------------------------------------------------------------------------
+// Common routines for ep1..3
+
+#if defined(CYGVAR_DEVS_USB_AT91_EP1_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_AT91_EP2_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_AT91_EP3_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_AT91_EP4_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_AT91_EP5_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_AT91_EP6_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_AT91_EP7_DEVTAB_ENTRY)
+
+static bool usbs_at91_devtab_dummy_init(struct cyg_devtab_entry* tab){
+
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+ return true;
+}
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP1_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep1_devtab_functions,
+ &usbs_devtab_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep1_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "1",
+ 0,
+ &usbs_at91_ep1_devtab_functions,
+ &usbs_at91_devtab_dummy_init,
+ 0,
+ (void*) &usbs_at91_ep1);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP2_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep2_devtab_functions,
+ &usbs_devtab_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep2_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "2",
+ 0,
+ &usbs_at91_ep2_devtab_functions,
+ &usbs_at91_devtab_dummy_init,
+ 0,
+ (void*) &usbs_at91_ep2);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP3_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep3_devtab_functions,
+ &usbs_devtab_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep3_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "3",
+ 0,
+ &usbs_at91_ep3_devtab_functions,
+ &usbs_at91_devtab_dummy_init,
+ 0,
+ (void*) &usbs_at91_ep3);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP4_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep4_devtab_functions,
+ &usbs_devtab_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep4_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "4",
+ 0,
+ &usbs_at91_ep4_devtab_functions,
+ &usbs_at91_devtab_dummy_init,
+ 0,
+ (void*) &usbs_at91_ep4);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP5_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep5_devtab_functions,
+ &usbs_devtab_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep5_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "5",
+ 0,
+ &usbs_at91_ep5_devtab_functions,
+ &usbs_at91_devtab_dummy_init,
+ 0,
+ (void*) &usbs_at91_ep5);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP6_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep6_devtab_functions,
+ &usbs_devtab_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep6_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "6",
+ 0,
+ &usbs_at91_ep6_devtab_functions,
+ &usbs_at91_devtab_dummy_init,
+ 0,
+ (void*) &usbs_at91_ep6);
+#endif
+
+#ifdef CYGVAR_DEVS_USB_AT91_EP7_DEVTAB_ENTRY
+CHAR_DEVIO_TABLE(usbs_at91_ep7_devtab_functions,
+ &usbs_devtab_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+CHAR_DEVTAB_ENTRY(usbs_at91_ep7_devtab_entry,
+ CYGDAT_DEVS_USB_AT91_DEVTAB_BASENAME "7",
+ 0,
+ &usbs_at91_ep7_devtab_functions,
+ &usbs_at91_devtab_dummy_init,
+ 0,
+ (void*) &usbs_at91_ep7);
+#endif
diff --git a/ecos/packages/devs/usb/cortexm/stm32/current/ChangeLog b/ecos/packages/devs/usb/cortexm/stm32/current/ChangeLog
new file mode 100644
index 0000000..f7f2434
--- /dev/null
+++ b/ecos/packages/devs/usb/cortexm/stm32/current/ChangeLog
@@ -0,0 +1,41 @@
+2012-04-13 Christophe Coutand <ecos@hotmail.co.uk>
+
+ * src/usb_stm32.c (cyg_usbs_cortexm_stm32_init):
+ Peripheral clocks are enable / disable using new
+ CYGHWR_HAL_STM32_CLOCK_DISABLE / CYGHWR_HAL_STM32_CLOCK_ENABLE
+ macro supplied from the variant HAL
+
+2012-04-03 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/usb_stm32.c (cyg_usbs_cortexm_stm32_init):
+ CYGHWR_HAL_STM32_RCC_APB1ENR_CAN was renamed to
+ CYGHWR_HAL_STM32_RCC_APB1ENR_CAN1 in variant HAL.
+
+2010-10-27 Chris Holgate <chris@zynaptic.com>
+
+ * src/usb_stm32.c, include/usb_stm32.h, cdl/usb_stm32.cdl: New
+ STM32 USB slave driver. [ Bugzilla 1001024 ]
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/usb/cortexm/stm32/current/cdl/usb_stm32.cdl b/ecos/packages/devs/usb/cortexm/stm32/current/cdl/usb_stm32.cdl
new file mode 100644
index 0000000..d2f35af
--- /dev/null
+++ b/ecos/packages/devs/usb/cortexm/stm32/current/cdl/usb_stm32.cdl
@@ -0,0 +1,325 @@
+##=============================================================================
+##
+## usb_stm32.cdl
+##
+## STM32 USB driver configuration options.
+##
+##=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): Chris Holgate
+## Date: 2009-05-19
+## Purpose: Configure STM32 USB driver.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+#
+# TODO: Needs to check that the PLL is running off the HSE clock source and
+# is set up to run at 48MHz or 72MHz.
+#
+
+cdl_package CYGPKG_DEVS_USB_CORTEXM_STM32 {
+ display "ST STM32 USB driver"
+ description "
+ This package provides USB device side driver support for the ST
+ STM32 series of microcontrollers.
+ "
+ parent CYGPKG_IO_USB
+ active_if CYGPKG_IO_USB
+ hardware
+ include_dir "cyg/io/usb"
+
+ # Make sure that we are running on the right hardware.
+ requires CYGPKG_HAL_CORTEXM_STM32
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_EP0 {
+ display "Enable the control endpoint 0"
+ default_value CYGINT_IO_USB_SLAVE_CLIENTS
+ requires CYGPKG_IO_USB_SLAVE
+ requires !CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ compile usb_stm32.c
+ description "
+ Enable support for endpoint 0. If this support is disabled
+ then the entire USB port is unusable. Note that this driver does
+ not support slave side devtab entries."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM {
+ display "Max IN endpoints"
+ description "
+ Specify the maximum number of IN (transmit) endpoints supported by the device.
+ The total number of standard IN and OUT endpoints should not exceed 7.
+ "
+ flavor data
+ default_value { 2 }
+ legal_values { 0 to (7 - CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ }
+
+ cdl_option CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM {
+ display "Max OUT endpoints"
+ description "
+ Specify the maximum number of OUT (receive) endpoints supported by the device.
+ The total number of standard IN and OUT endpoints should not exceed 7.
+ "
+ flavor data
+ default_value { 2 }
+ legal_values { 0 to (7 - CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ }
+
+ cdl_option CYGNUM_DEVS_USB_CORTEXM_STM32_EPO_MAX_MSG_SIZE {
+ display "Control endpoint buffer size"
+ description "
+ Selects the size of the control endpoint data buffer, which sets the maximum size
+ of the control endpoint data phase transactions.
+ "
+ flavor data
+ default_value { 128 }
+ legal_values { 8 to 256 }
+ }
+
+ cdl_option CYGHWR_DEVS_USB_CORTEXM_STM32_SELF_POWERED {
+ display "Self powered"
+ description "
+ If set, the USB device will report itself to the host as being self-powered.
+ There is no support for dynamically detecting the power state for dual powered
+ devices.
+ "
+ flavor bool
+ default_value false
+ }
+
+ cdl_option CYGHWR_DEVS_USB_CORTEXM_STM32_BULK_TERM_ZLP {
+ display "Variable length bulk transfers"
+ description "
+ Some USB device classes (eg. CDC ATM) require support for variable length bulk
+ messages. This is implemented by terminating bulk transfers using a short or
+ zero length packet. Selecting this option enables this form of variable length
+ bulk message transfer for all bulk endpoints. Note that this option is incompatible
+ with the standard eCos USB test framework.
+ "
+ flavor bool
+ default_value false
+ }
+
+ cdl_option CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN {
+ display "USB disconnect pin"
+ description "
+ This is the GPIO which is used to control the USB bus D+ pullup resistor, which
+ allows the USB bus connection status to be changed under software control.
+ For the purposes of specifying which GPIO to use, pins are numbered consecutively
+ from 0 (A0) through 16 (B0) to 111 (G15).
+ "
+ flavor data
+ default_value { 30 }
+ }
+
+ cdl_option CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN_ACT_LOW {
+ display "Active low USB disconnect"
+ description "
+ The USB disconnect pin is normally treated as active high - so that when set high
+ the device will be disconnected from the bus. Select this option for boards where
+ the USB disconnect pin is wired as active low.
+ "
+ flavor bool
+ default_value false
+ }
+
+ cdl_option CYGNUM_DEVS_USB_CORTEXM_STM32_ISR_PRIORITY {
+ display "ISR priority"
+ description "
+ Sets the ISR priority level used by the USB driver.
+ "
+ flavor data
+ default_value { 4 }
+ }
+
+ cdl_option CYGBLD_DEVS_USB_CORTEXM_STM32_DEBUG_TRACE {
+ display "Debug trace enable"
+ description "
+ Enables debug tracing for the USB driver.
+ "
+ flavor bool
+ default_value false
+ }
+
+ cdl_component CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_CONFIG {
+ display "Physical endpoint configuration."
+ description "
+ This is the automatically generated physical endpoint configuration for the
+ STM32 USB device. Note that the physical endpoint numbering is only used
+ internally to the driver and has no bearing on the logical endpoint numbers
+ which may be specified in a given device configuration.
+ "
+ flavor none
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_CTRLEP0 {
+ display "Physical endpoint 0 CTRL"
+ flavor bool
+ active_if { (CYGFUN_DEVS_USB_CORTEXM_STM32_EP0) }
+ calculated { (CYGFUN_DEVS_USB_CORTEXM_STM32_EP0) }
+ implements CYGHWR_IO_USB_SLAVE
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_TXEP1 {
+ display "Physical endpoint 1 IN"
+ flavor bool
+ active_if { (1 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ calculated { (1 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_TXEP2 {
+ display "Physical endpoint 2 IN"
+ flavor bool
+ active_if { (2 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ calculated { (2 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_TXEP3 {
+ display "Physical endpoint 3 IN"
+ flavor bool
+ active_if { (3 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ calculated { (3 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_TXEP4 {
+ display "Physical endpoint 4 IN"
+ flavor bool
+ active_if { (4 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ calculated { (4 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_TXEP5 {
+ display "Physical endpoint 5 IN"
+ flavor bool
+ active_if { (5 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ calculated { (5 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_TXEP6 {
+ display "Physical endpoint 6 IN"
+ flavor bool
+ active_if { (6 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ calculated { (6 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_TXEP7 {
+ display "Physical endpoint 7 IN"
+ flavor bool
+ active_if { (7 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ calculated { (7 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_RXEP1 {
+ display "Physical endpoint 1 OUT"
+ flavor bool
+ active_if { (1 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (1 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ calculated { (1 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (1 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_RXEP2 {
+ display "Physical endpoint 2 OUT"
+ flavor bool
+ active_if { (2 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (2 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ calculated { (2 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (2 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_RXEP3 {
+ display "Physical endpoint 3 OUT"
+ flavor bool
+ active_if { (3 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (3 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ calculated { (3 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (3 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_RXEP4 {
+ display "Physical endpoint 4 OUT"
+ flavor bool
+ active_if { (4 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (4 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ calculated { (4 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (4 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_RXEP5 {
+ display "Physical endpoint 5 OUT"
+ flavor bool
+ active_if { (5 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (5 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ calculated { (5 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (5 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_RXEP6 {
+ display "Physical endpoint 6 OUT"
+ flavor bool
+ active_if { (6 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (6 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ calculated { (6 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (6 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ }
+
+ cdl_option CYGFUN_DEVS_USB_CORTEXM_STM32_PHY_RXEP7 {
+ display "Physical endpoint 7 OUT"
+ flavor bool
+ active_if { (7 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (7 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ calculated { (7 > CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) &&
+ (7 <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) }
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ }
+ }
+}
+
+# EOF usb_stm32.cdl
diff --git a/ecos/packages/devs/usb/cortexm/stm32/current/include/usb_stm32.h b/ecos/packages/devs/usb/cortexm/stm32/current/include/usb_stm32.h
new file mode 100644
index 0000000..60a3905
--- /dev/null
+++ b/ecos/packages/devs/usb/cortexm/stm32/current/include/usb_stm32.h
@@ -0,0 +1,56 @@
+#ifndef CYGONCE_DEVS_USB_CORTEXM_STM32_H
+#define CYGONCE_DEVS_USB_CORTEXM_STM32_H
+
+//=============================================================================
+//
+// usb_stm32.h
+//
+// USB slave driver for STM32
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Chris Holgate
+// Date: 2009-05-19
+// Purpose: STM32 USB slave driver
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// Provide external access to the common endpoint 0 data structure.
+extern usbs_control_endpoint cyg_usbs_cortexm_stm32_ep0c;
+
+#endif // CYGONCE_DEVS_USB_CORTEXM_STM32_H
diff --git a/ecos/packages/devs/usb/cortexm/stm32/current/src/usb_stm32.c b/ecos/packages/devs/usb/cortexm/stm32/current/src/usb_stm32.c
new file mode 100644
index 0000000..dcb0ea2
--- /dev/null
+++ b/ecos/packages/devs/usb/cortexm/stm32/current/src/usb_stm32.c
@@ -0,0 +1,2456 @@
+//=============================================================================
+//
+// usb_stm32.c
+//
+// USB slave driver implementation for STM32
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Chris Holgate
+// Date: 2009-05-19
+// Purpose: STM32 USB slave driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+
+#include <cyg/io/usb/usb.h>
+#include <cyg/io/usb/usbs.h>
+
+#include <string.h>
+
+#include <pkgconf/io_usb_slave.h>
+#include <pkgconf/devs_usb_cortexm_stm32.h>
+
+//-----------------------------------------------------------------------------
+// Maintenance and debug macros.
+
+#define TODO_USB(_msg_) CYG_ASSERT(false, "TODO (USB) : " _msg_)
+#define FAIL_USB(_msg_) CYG_ASSERT(false, "FAIL (USB) : " _msg_)
+#define ASSERT_USB(_test_, _msg_) CYG_ASSERT(_test_, "FAIL (USB) : " _msg_)
+
+#if defined(CYGBLD_DEVS_USB_CORTEXM_STM32_DEBUG_TRACE)
+#define TRACE_USB(_msg_, _args_...) diag_printf ("STM32 USB : " _msg_, ##_args_)
+#else
+#define TRACE_USB(_msg_, _args_...) while(0){}
+#endif
+
+//-----------------------------------------------------------------------------
+// Shorthand for some of the configuration options.
+
+#define USB_BASE CYGHWR_HAL_STM32_USB
+#define USB_RAM_BASE CYGHWR_HAL_STM32_USB_CAN_SRAM
+#define USB_RAM_SIZE 512
+#define USB_EPNUM (1 + CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM)
+
+//-----------------------------------------------------------------------------
+// Work out the bus clock frequencies and external timing constraints.
+// NOTE: These require that the clock source is set to HSE, which should be
+// forced by the CDL.
+
+#define PLL_FREQ (CYGARC_HAL_CORTEXM_STM32_INPUT_CLOCK * CYGHWR_HAL_CORTEXM_STM32_CLOCK_PLL_MUL)
+
+#define APB1_FREQ ((CYGARC_HAL_CORTEXM_STM32_INPUT_CLOCK * CYGHWR_HAL_CORTEXM_STM32_CLOCK_PLL_MUL) / \
+ (CYGHWR_HAL_CORTEXM_STM32_CLOCK_HCLK_DIV * CYGHWR_HAL_CORTEXM_STM32_CLOCK_PCLK1_DIV))
+
+#define USB_TSTARTUP 1
+
+//-----------------------------------------------------------------------------
+// Provide macros for accessing the buffer layout pseudo-registers.
+
+// Pseudo-registers for single buffer configurations.
+#define USB_RAM_SB_TXADDR(__ep) ((__ep)*16)
+#define USB_RAM_SB_TXCOUNT(__ep) ((__ep)*16+4)
+#define USB_RAM_SB_RXADDR(__ep) ((__ep)*16+8)
+#define USB_RAM_SB_RXCOUNT(__ep) ((__ep)*16+12)
+
+// Pseudo-registers for double buffer configurations.
+#define USB_RAM_DB_TXADDR(__ep,__buf) ((__ep)*16+(__buf)*8)
+#define USB_RAM_DB_TXCOUNT(__ep,__buf) ((__ep)*16+(__buf)*8+4)
+#define USB_RAM_DB_RXADDR(__ep,__buf) ((__ep)*16+(__buf)*8)
+#define USB_RAM_DB_RXCOUNT(__ep,__buf) ((__ep)*16+(__buf)*8+4)
+
+#define USB_RAM_XX_RXCOUNT_BLOCKS(__x) VALUE_(10,__x)
+#define USB_RAM_XX_RXCOUNT_COUNT_MASK VALUE_(0, 0x03FF)
+
+//-----------------------------------------------------------------------------
+// Set up USB I/O pin configurations.
+
+#if (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN < 0x10)
+#define USB_DISC_PIN CYGHWR_HAL_STM32_GPIO \
+ (A, (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN & 0x0F), OUT_2MHZ, OUT_PUSHPULL)
+
+#elif (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN < 0x20)
+#define USB_DISC_PIN CYGHWR_HAL_STM32_GPIO \
+ (B, (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN & 0x0F), OUT_2MHZ, OUT_PUSHPULL)
+
+#elif (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN < 0x30)
+#define USB_DISC_PIN CYGHWR_HAL_STM32_GPIO \
+ (C, (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN & 0x0F), OUT_2MHZ, OUT_PUSHPULL)
+
+#elif (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN < 0x40)
+#define USB_DISC_PIN CYGHWR_HAL_STM32_GPIO \
+ (D, (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN & 0x0F), OUT_2MHZ, OUT_PUSHPULL)
+
+#elif (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN < 0x50)
+#define USB_DISC_PIN CYGHWR_HAL_STM32_GPIO \
+ (E, (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN & 0x0F), OUT_2MHZ, OUT_PUSHPULL)
+
+#elif (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN < 0x60)
+#define USB_DISC_PIN CYGHWR_HAL_STM32_GPIO \
+ (F, (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN & 0x0F), OUT_2MHZ, OUT_PUSHPULL)
+
+#elif (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN < 0x70)
+#define USB_DISC_PIN CYGHWR_HAL_STM32_GPIO \
+ (G, (CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN & 0x0F), OUT_2MHZ, OUT_PUSHPULL)
+#endif
+
+#define USB_DP_PIN CYGHWR_HAL_STM32_GPIO (A, 12, IN, AIN)
+#define USB_DM_PIN CYGHWR_HAL_STM32_GPIO (A, 11, IN, AIN)
+
+//=============================================================================
+// Define USB transmit endpoint data structures.
+//=============================================================================
+
+typedef enum {
+ TXTR_FLAGS_NONE = 0x00, // No flags set.
+ TXTR_FLAGS_ZLPKT = 0x01, // Set to enable zero length packet termination.
+ TXTR_FLAGS_DBUF = 0x02, // Set to enable doubtle buffered operation.
+} txtr_flags;
+
+typedef enum {
+ TXTR_STATE_RESET, // TX transaction reset state.
+ TXTR_STATE_IDLE, // TX transaction idle (between transactions).
+ TXTR_STATE_SB_NEXT_PKT, // TX transaction send next packet (single buffer).
+ TXTR_STATE_SB_ZERO_PKT, // TX transaction send zero length packet (single buffer).
+ TXTR_STATE_SB_DONE, // TX transaction complete (single buffer).
+ TXTR_STATE_DB_FIRST_PKT, // TX transaction queue first packet (double buffer).
+ TXTR_STATE_DB_NEXT_PKT, // TX transaction queue next packet (double buffer).
+ TXTR_STATE_DB_ZERO_PKT, // TX transaction queue zero length packet (double buffer).
+ TXTR_STATE_DB_LAST_PKT, // TX transaction send last queued packet (double buffer).
+ TXTR_STATE_DB_DONE, // TX transaction complete (double buffer).
+} txtr_state;
+
+typedef struct txtr_impl {
+ txtr_state state; // Current transaction state.
+ txtr_flags flags; // Transaction flags.
+ cyg_uint16 status; // Return status.
+ cyg_uint8 ep_num; // Endpoint number.
+ const cyg_uint8* buf_ptr; // Pointer to next user buffer location.
+ cyg_uint32 buf_size; // Size of user transmit buffer.
+ cyg_uint32 bytes_sent; // Track number of bytes sent.
+} txtr_impl;
+
+typedef struct txep_impl {
+ usbs_tx_endpoint common; // High level driver data.
+ txtr_impl txtr; // Transaction data.
+} txep_impl;
+
+//=============================================================================
+// Define USB receive endpoint data structures.
+//=============================================================================
+
+typedef enum {
+ RXTR_FLAGS_NONE = 0x00, // No flags set.
+ RXTR_FLAGS_ZLPKT = 0x01, // Set to enable zero length packet termination.
+ RXTR_FLAGS_DBUF = 0x02, // Set to enable doubtle buffered operation.
+} rxtr_flags;
+
+typedef enum {
+ RXTR_STATE_RESET, // RX transaction reset state.
+ RXTR_STATE_IDLE, // RX transaction idle (between transactions).
+ RXTR_STATE_SB_NEXT_PKT, // RX transaction get next packet (single buffer).
+ RXTR_STATE_DB_NEXT_PKT, // RX transaction get next packet (double buffer).
+} rxtr_state;
+
+typedef struct rxtr_impl {
+ rxtr_state state; // Current transaction state.
+ rxtr_flags flags; // Transaction flags.
+ cyg_uint16 status; // Return status.
+ cyg_uint8 ep_num; // Endpoint number.
+ cyg_uint8* buf_ptr; // Pointer to next user buffer location.
+ cyg_uint32 buf_size; // Size of receive buffer.
+ cyg_uint32 bytes_rcvd; // Track number of bytes received.
+} rxtr_impl;
+
+typedef struct rxep_impl {
+ usbs_rx_endpoint common; // High level driver data.
+ rxtr_impl rxtr; // Transaction data.
+} rxep_impl;
+
+//=============================================================================
+// Instantiate USB control endpoint data structure.
+//=============================================================================
+
+static void stm32_usb_start (usbs_control_endpoint*);
+static void stm32_usb_poll (usbs_control_endpoint*);
+static usbs_rx_endpoint* stm32_usb_get_rxep (usbs_control_endpoint*, cyg_uint8);
+static usbs_tx_endpoint* stm32_usb_get_txep (usbs_control_endpoint*, cyg_uint8);
+
+// Track the control endpoint state.
+typedef enum {
+ CTRLEP_MSG_STATE_IDLE,
+ CTRLEP_MSG_STATE_IN_DATA,
+ CTRLEP_MSG_STATE_IN_STATUS,
+ CTRLEP_MSG_STATE_OUT_DATA,
+ CTRLEP_MSG_STATE_OUT_STATUS,
+ CTRLEP_MSG_STATE_CTRL_ACK,
+} ctrlep_msg_states;
+
+// Provide the control message buffer.
+static cyg_uint8 ctrlep_msg_buffer [CYGNUM_DEVS_USB_CORTEXM_STM32_EPO_MAX_MSG_SIZE];
+
+// Provide STM32 control endpoint implementation.
+typedef struct ctrlep_impl {
+ usbs_control_endpoint common; // High level driver data.
+ txtr_impl txtr; // Transmit transaction data.
+ rxtr_impl rxtr; // Receive transaction data.
+ ctrlep_msg_states msg_state; // Control endpoint messaging state.
+} ctrlep_impl;
+
+// Instantiate control endpoint data structure.
+static ctrlep_impl ctrlep = {
+ { // Set up data for common high level driver.
+ state : USBS_STATE_POWERED,
+ enumeration_data : (usbs_enumeration_data*) 0,
+ start_fn : &stm32_usb_start,
+ poll_fn : &stm32_usb_poll,
+ interrupt_vector : CYGNUM_HAL_INTERRUPT_USB_LP,
+ control_buffer : { 0, 0, 0, 0, 0, 0, 0, 0 },
+ state_change_fn : 0,
+ state_change_data : 0,
+ standard_control_fn : 0,
+ standard_control_data : 0,
+ class_control_fn : 0,
+ class_control_data : 0,
+ vendor_control_fn : 0,
+ vendor_control_data : 0,
+ reserved_control_fn : 0,
+ reserved_control_data : 0,
+ buffer : 0,
+ buffer_size : 0,
+ fill_buffer_fn : 0,
+ fill_data : 0,
+ fill_index : 0,
+ complete_fn : 0,
+ get_rxep_fn : &stm32_usb_get_rxep,
+ get_txep_fn : &stm32_usb_get_txep,
+ },
+ { // Initialise transmit transaction data.
+ state : TXTR_STATE_RESET,
+ flags : TXTR_FLAGS_ZLPKT,
+ status : ENOERR,
+ ep_num : 0,
+ },
+ { // Initialise receive transaction data.
+ state : RXTR_STATE_RESET,
+ flags : RXTR_FLAGS_ZLPKT,
+ status : ENOERR,
+ ep_num : 0,
+ },
+ msg_state : CTRLEP_MSG_STATE_IDLE,
+};
+
+extern usbs_control_endpoint cyg_usbs_cortexm_stm32_ep0c __attribute__((alias ("ctrlep")));
+
+//=============================================================================
+// ISR/DSR shared data structure. All data which is shared between ISR and
+// DSR contexts is wrapped up in this data structure to make synchronisation
+// between the two more manageable.
+//=============================================================================
+
+typedef enum {
+ ISR_FLAGS_CLEARED = 0x00, // No flags set.
+ ISR_FLAGS_SETUP_READY = 0x01, // Setup packet ready in staging buffer.
+ ISR_FLAGS_DEVICE_RESET = 0x02, // Device reset detected.
+} isr_flags;
+
+typedef struct isr_shared_data {
+ isr_flags flags; // Flags indicating events pending.
+ cyg_uint8 txtr_done; // Flags for indicating TX complete.
+ cyg_uint8 rxtr_done; // Flags for indicating RX complete.
+} isr_shared_data;
+
+static isr_shared_data isr_shared = {
+ flags : ISR_FLAGS_CLEARED,
+ txtr_done : 0,
+ rxtr_done : 0,
+};
+
+//=============================================================================
+// USB driver internal state variables.
+//=============================================================================
+
+// Buffer management.
+static cyg_uint16 stm32_usb_buf_offset;
+static cyg_uint16 stm32_usb_buf_sizes [USB_EPNUM];
+
+// Endpoint descriptors.
+static txep_impl txep_list [CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM];
+static rxep_impl rxep_list [CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM];
+static txep_impl* txep_map [15];
+static rxep_impl* rxep_map [15];
+
+// Interrupts and synchronisation primitives.
+static cyg_interrupt interrupt_data;
+static cyg_handle_t interrupt_handle;
+static cyg_uint32 interrupt_mask_count;
+
+//=============================================================================
+// Provide inlineable functions for implementing counted interrupt masking.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Mask interrupts if not already masked.
+
+static inline void stm32_usb_request_intr_mask
+ (void)
+{
+ cyg_scheduler_lock();
+ if (interrupt_mask_count++ == 0) {
+ cyg_drv_interrupt_mask (CYGNUM_HAL_INTERRUPT_USB_LP);
+ }
+ cyg_scheduler_unlock();
+}
+
+//-----------------------------------------------------------------------------
+// Release interrupt mask. Interrupts will be unmasked once all mask requests
+// have been released.
+
+static inline void stm32_usb_release_intr_mask
+ (void)
+{
+ cyg_scheduler_lock();
+ if (interrupt_mask_count == 0) {
+ FAIL_USB ("Interrupt mask counter decremented through 0.");
+ }
+ else if (--interrupt_mask_count == 0) {
+ cyg_drv_interrupt_unmask (CYGNUM_HAL_INTERRUPT_USB_LP);
+ }
+ cyg_scheduler_unlock();
+}
+
+//=============================================================================
+// Provide inlineable functions for setting the 'flip bit' register values.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Set the transmit status bits to the desired value.
+
+static inline void stm32_usb_set_txep_status
+ (cyg_uint32 ep, cyg_uint32 txep_status)
+{
+ cyg_uint32 reg_val;
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+ reg_val &= ~((cyg_uint32) (CYGHWR_HAL_STM32_USB_EPXR_STATRX_MASK |
+ CYGHWR_HAL_STM32_USB_EPXR_DTOGTX | CYGHWR_HAL_STM32_USB_EPXR_DTOGRX));
+ reg_val ^= txep_status & CYGHWR_HAL_STM32_USB_EPXR_STATTX_MASK;
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+}
+
+//-----------------------------------------------------------------------------
+// Set the receive status bits to the desired value.
+
+static inline void stm32_usb_set_rxep_status
+ (cyg_uint32 ep, cyg_uint32 rxep_status)
+{
+ cyg_uint32 reg_val;
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+ reg_val &= ~((cyg_uint32) (CYGHWR_HAL_STM32_USB_EPXR_STATTX_MASK |
+ CYGHWR_HAL_STM32_USB_EPXR_DTOGTX | CYGHWR_HAL_STM32_USB_EPXR_DTOGRX));
+ reg_val ^= rxep_status & CYGHWR_HAL_STM32_USB_EPXR_STATRX_MASK;
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+}
+
+//-----------------------------------------------------------------------------
+// Assign conventional bits in the endpoint status registers without touching
+// the flip-bit values.
+
+static inline void stm32_usb_assign_epxr
+ (cyg_uint32 ep, cyg_uint32 epxr_val)
+{
+ epxr_val &= ~((cyg_uint32) (CYGHWR_HAL_STM32_USB_EPXR_STATTX_MASK |
+ CYGHWR_HAL_STM32_USB_EPXR_STATRX_MASK | CYGHWR_HAL_STM32_USB_EPXR_DTOGTX |
+ CYGHWR_HAL_STM32_USB_EPXR_DTOGRX));
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), epxr_val);
+}
+
+//-----------------------------------------------------------------------------
+// Set specified conventional bits in the endpoint status registers.
+
+static inline void stm32_usb_set_epxr_bits
+ (cyg_uint32 ep, cyg_uint32 epxr_mask)
+{
+ cyg_uint32 reg_val;
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+ reg_val |= epxr_mask;
+ stm32_usb_assign_epxr (ep, reg_val);
+}
+
+//-----------------------------------------------------------------------------
+// Clear specified conventional bits in the endpoint status registers.
+
+static inline void stm32_usb_clear_epxr_bits
+ (cyg_uint32 ep, cyg_uint32 epxr_mask)
+{
+ cyg_uint32 reg_val;
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+ reg_val &= ~epxr_mask;
+ stm32_usb_assign_epxr (ep, reg_val);
+}
+
+//-----------------------------------------------------------------------------
+// Set specified toggle bits in the endpoint status registers.
+
+static inline void stm32_usb_set_epxr_toggle
+ (cyg_uint32 ep, cyg_uint32 epxr_mask)
+{
+ cyg_uint32 reg_val;
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+ reg_val &= epxr_mask | ~((cyg_uint32) (CYGHWR_HAL_STM32_USB_EPXR_STATTX_MASK |
+ CYGHWR_HAL_STM32_USB_EPXR_STATRX_MASK | CYGHWR_HAL_STM32_USB_EPXR_DTOGTX |
+ CYGHWR_HAL_STM32_USB_EPXR_DTOGRX));
+ reg_val ^= epxr_mask;
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+}
+
+//-----------------------------------------------------------------------------
+// Clear specified toggle bits in the endpoint status registers.
+
+static inline void stm32_usb_clear_epxr_toggle
+ (cyg_uint32 ep, cyg_uint32 epxr_mask)
+{
+ cyg_uint32 reg_val;
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+ reg_val &= epxr_mask | ~((cyg_uint32) (CYGHWR_HAL_STM32_USB_EPXR_STATTX_MASK |
+ CYGHWR_HAL_STM32_USB_EPXR_STATRX_MASK | CYGHWR_HAL_STM32_USB_EPXR_DTOGTX |
+ CYGHWR_HAL_STM32_USB_EPXR_DTOGRX));
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+}
+
+//-----------------------------------------------------------------------------
+// Flip specified toggle bits in the endpoint status registers.
+
+static inline void stm32_usb_flip_epxr_toggle
+ (cyg_uint32 ep, cyg_uint32 epxr_mask)
+{
+ cyg_uint32 reg_val;
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+ reg_val &= ~((cyg_uint32) (CYGHWR_HAL_STM32_USB_EPXR_STATTX_MASK |
+ CYGHWR_HAL_STM32_USB_EPXR_STATRX_MASK | CYGHWR_HAL_STM32_USB_EPXR_DTOGTX |
+ CYGHWR_HAL_STM32_USB_EPXR_DTOGRX));
+ reg_val |= epxr_mask;
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (ep), reg_val);
+}
+
+//=============================================================================
+// The following set of functions provide buffer management capabilities for
+// allocating and then accessing USB buffers in the dual-port buffer RAM.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Get the allocated buffer size for a specified endpoint.
+
+static inline cyg_uint32 stm32_usb_buf_get_size
+ (cyg_uint32 ep)
+{
+ return (stm32_usb_buf_sizes[ep]);
+}
+
+//-----------------------------------------------------------------------------
+// Add a new set of endpoint buffers for the specified endpoint.
+
+static cyg_bool stm32_usb_buf_add_ep
+ (cyg_uint32 ep, cyg_uint32 ep_buf_size, cyg_bool is_tx, cyg_bool is_rx, cyg_bool is_db)
+{
+ cyg_uint32 alloc_size;
+ cyg_uint32 rx_blocks;
+
+ // Check for valid configuration.
+ if ((is_db && is_tx && is_rx) || !(is_tx || is_rx)) {
+ FAIL_USB ("Invalid buffer configuration.");
+ goto failed;
+ }
+
+ // Round up the allocation size so that it matches a valid RX block size.
+ alloc_size = (ep_buf_size & 1) ? ep_buf_size + 1 : ep_buf_size;
+ if ((alloc_size > 62) && (alloc_size & 31)) {
+ alloc_size &= ~31;
+ alloc_size += 32;
+ }
+
+ // Check to see if there is enough RAM available.
+ if (is_db || (is_tx && is_rx)) {
+ if (stm32_usb_buf_offset + 2 * alloc_size > USB_RAM_SIZE) {
+ FAIL_USB ("Insufficient endpoint RAM for configuration.");
+ goto failed;
+ }
+ }
+ else {
+ if (stm32_usb_buf_offset + alloc_size > USB_RAM_SIZE) {
+ FAIL_USB ("Insufficient endpoint RAM for configuration.");
+ goto failed;
+ }
+ }
+
+ // Calculate the blocks (size + num) field for the receive count register.
+ rx_blocks = (alloc_size <= 62) ? (alloc_size / 2) : (31 + alloc_size / 32);
+ stm32_usb_buf_sizes[ep] = (cyg_uint16) ep_buf_size;
+
+ // Program up the pseudo-registers for double buffered transmit.
+ if (is_db && is_tx) {
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_DB_TXADDR (ep, 0), stm32_usb_buf_offset);
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_DB_TXCOUNT (ep, 0), 0);
+ stm32_usb_buf_offset += (cyg_uint16) alloc_size;
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_DB_TXADDR (ep, 1), stm32_usb_buf_offset);
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_DB_TXCOUNT (ep, 1), 0);
+ stm32_usb_buf_offset += (cyg_uint16) alloc_size;
+ }
+
+ // Program up the pseudo-registers for double buffered receive.
+ else if (is_db) {
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_DB_RXADDR (ep, 0), stm32_usb_buf_offset);
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_DB_RXCOUNT (ep, 0), USB_RAM_XX_RXCOUNT_BLOCKS (rx_blocks));
+ stm32_usb_buf_offset += (cyg_uint16) alloc_size;
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_DB_RXADDR (ep, 1), stm32_usb_buf_offset);
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_DB_RXCOUNT (ep, 1), USB_RAM_XX_RXCOUNT_BLOCKS (rx_blocks));
+ stm32_usb_buf_offset += (cyg_uint16) alloc_size;
+ }
+
+ // Program up the pseudo-registers for single buffered transmit/receive.
+ else {
+ if (is_tx) {
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_SB_TXADDR (ep), stm32_usb_buf_offset);
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_SB_TXCOUNT (ep), 0);
+ stm32_usb_buf_offset += (cyg_uint16) alloc_size;
+ }
+ if (is_rx) {
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_SB_RXADDR (ep), stm32_usb_buf_offset);
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_SB_RXCOUNT (ep), USB_RAM_XX_RXCOUNT_BLOCKS (rx_blocks));
+ stm32_usb_buf_offset += (cyg_uint16) alloc_size;
+ }
+ }
+
+ // Exit on success or failure.
+ return true;
+failed :
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Clear the buffer RAM layout for non-control endpoints, prior to setting a
+// new configuration.
+
+static inline void stm32_usb_buf_clear_config
+ (void)
+{
+ cyg_uint32 i;
+
+ // Clear buffer size table for non-control endpoints.
+ for (i = 1; i < USB_EPNUM; i++)
+ stm32_usb_buf_sizes[i] = 0;
+
+ // Update the free pointer to point to the end of the control endpoint buffers.
+ stm32_usb_buf_offset = 8 * USB_EPNUM + 2 * stm32_usb_buf_sizes[0];
+}
+
+//-----------------------------------------------------------------------------
+// Reset the buffer RAM layout, preallocating the requested buffer area for
+// control endpoint 0.
+
+static inline cyg_bool stm32_usb_buf_reset_ep0
+ (cyg_uint32 ep0_buf_size)
+{
+ cyg_uint32 i;
+
+ // The buffer descriptor table is placed at the start of the dual-port RAM.
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_BTABLE, 0);
+ stm32_usb_buf_offset = 8 * USB_EPNUM;
+
+ // Clear buffer size table prior to adding endpoint 0. A zero in this table
+ // essentially prevents any host-side access to a given endpoint buffer.
+ for (i = 0; i < USB_EPNUM; i++)
+ stm32_usb_buf_sizes[i] = 0;
+ return stm32_usb_buf_add_ep (0, ep0_buf_size, true, true, false);
+}
+
+//-----------------------------------------------------------------------------
+// Copy data from user memory to a specified USB buffer (double buffered).
+// Returns the number of bytes transferred, which is capped at the buffer
+// size.
+
+static cyg_uint32 __attribute__((hot)) stm32_usb_copy_to_dbuf
+ (const cyg_uint8* src, cyg_uint32 size, cyg_uint32 ep, cyg_uint32 buf)
+{
+ cyg_uint32 data, i;
+ cyg_haladdress waddr;
+
+ // Truncate the size parameter to the buffer length.
+ if (size > stm32_usb_buf_sizes[ep])
+ size = stm32_usb_buf_sizes[ep];
+
+ // Get the offset of the start of the buffer from the buffer tables
+ // and convert it into a host-side address.
+ HAL_READ_UINT32 (USB_RAM_BASE + USB_RAM_DB_TXADDR (ep, buf), data);
+ waddr = USB_RAM_BASE + data * 2;
+
+ // Copy over the data, remembering to skip the half-word gaps. If the size
+ // is not an integer number of half-words, we stick garbage in the last byte.
+ for (i = (size + 1) >> 1; i != 0; i--) {
+ data = *(src++);
+ data |= ((cyg_uint32) *(src++)) << 8;
+ HAL_WRITE_UINT32 (waddr, data);
+ waddr += 4;
+ }
+
+ // Update the buffer count field and return the buffer size.
+ HAL_WRITE_UINT32 (USB_RAM_BASE + USB_RAM_DB_TXCOUNT (ep, buf), size);
+ return size;
+}
+
+//-----------------------------------------------------------------------------
+// Copy data from user memory to transmit buffer (single buffered endpoint).
+// Returns the number of bytes transferred, which is capped at the buffer
+// size.
+
+static inline cyg_uint32 stm32_usb_copy_to_sbuf
+ (const cyg_uint8* src, cyg_uint32 size, cyg_uint32 ep)
+{
+ return stm32_usb_copy_to_dbuf (src, size, ep, 0);
+}
+
+//-----------------------------------------------------------------------------
+// Copy data from a specified USB buffer to user memory (double buffered).
+// Returns the number of bytes held by the buffer. Will not write beyond the
+// end of the user buffer, but if the user buffer is not large enough to hold
+// the received data (returned value > size) this implies an error condition.
+
+static cyg_uint32 __attribute__((hot)) stm32_usb_copy_from_dbuf
+ (cyg_uint8* dest, cyg_uint32 size, cyg_uint32 ep, cyg_uint32 buf)
+{
+ cyg_uint32 data, bufsize, i;
+ cyg_haladdress raddr;
+
+ // Get the receive buffer size.
+ HAL_READ_UINT32 (USB_RAM_BASE + USB_RAM_DB_RXCOUNT (ep, buf), bufsize);
+ bufsize &= USB_RAM_XX_RXCOUNT_COUNT_MASK;
+
+ // Determine the actual amount of data to transfer.
+ if (bufsize > size)
+ FAIL_USB ("Receive buffer overflow detected.");
+ else
+ size = bufsize;
+
+ // Get the offset of the start of the buffer from the buffer tables
+ // and convert it into a host-side address.
+ HAL_READ_UINT32 (USB_RAM_BASE + USB_RAM_DB_RXADDR (ep, buf), data);
+ raddr = USB_RAM_BASE + data * 2;
+
+ // Copy over the half-word aligned data.
+ for (i = size; i > 1; i -= 2) {
+ HAL_READ_UINT32 (raddr, data);
+ *(dest++) = (cyg_uint8) data;
+ *(dest++) = (cyg_uint8) (data >> 8);
+ raddr += 4;
+ }
+
+ // Copy over the trailing byte if present.
+ if (i) {
+ HAL_READ_UINT32 (raddr, data);
+ *(dest) = (cyg_uint8) data;
+ }
+ return bufsize;
+}
+
+//-----------------------------------------------------------------------------
+// Copy data from a receive buffer to user memory (single buffered endpoint).
+// Returns the number of bytes held by the buffer. Will not write beyond the
+// end of the user buffer, but if the user buffer is not large enough to hold
+// the received data (returned value > size) this implies an error condition.
+
+static inline cyg_uint32 stm32_usb_copy_from_sbuf
+ (cyg_uint8* dest, cyg_uint32 size, cyg_uint32 ep)
+{
+ return stm32_usb_copy_from_dbuf (dest, size, ep, 1);
+}
+
+//=============================================================================
+// The following set of functions provide support for managing multi-packet
+// USB transactions.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Implement transmit transaction state machine. This is called on transaction
+// start and then on all applicable interrupt events in order to progress the
+// transmit transaction.
+
+static cyg_bool stm32_usb_txtr_run
+ (txtr_impl* txtr)
+{
+ cyg_bool completed = false;
+ cyg_uint32 tx_bytes_req, tx_bytes_sent, buf_sel, reg_val;
+
+ switch (txtr->state) {
+
+ // Send next packet (single buffer transfers).
+ case TXTR_STATE_SB_NEXT_PKT:
+ tx_bytes_req = txtr->buf_size - txtr->bytes_sent;
+ tx_bytes_sent = stm32_usb_copy_to_sbuf (txtr->buf_ptr, tx_bytes_req, txtr->ep_num);
+ txtr->buf_ptr += tx_bytes_sent;
+ txtr->bytes_sent += tx_bytes_sent;
+
+ // All bytes sent - see if we need a zero length termination packet.
+ if (txtr->bytes_sent == txtr->buf_size) {
+ if ((tx_bytes_sent == stm32_usb_buf_get_size (txtr->ep_num)) && (txtr->flags & TXTR_FLAGS_ZLPKT))
+ txtr->state = TXTR_STATE_SB_ZERO_PKT;
+ else
+ txtr->state = TXTR_STATE_SB_DONE;
+ }
+
+ // Set buffer valid via the endpoint control register.
+ stm32_usb_set_txep_status (txtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATTX_VALID);
+ break;
+
+ // Send zero length termination packet (single buffer transfers).
+ case TXTR_STATE_SB_ZERO_PKT :
+ txtr->state = TXTR_STATE_SB_DONE;
+ stm32_usb_copy_to_sbuf (txtr->buf_ptr, 0, txtr->ep_num);
+ stm32_usb_set_txep_status (txtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATTX_VALID);
+ break;
+
+ // Complete transaction (single buffer transfers).
+ case TXTR_STATE_SB_DONE :
+ txtr->state = TXTR_STATE_IDLE;
+ completed = true;
+ break;
+
+ // Sets up the first queued packet. Start by clearing the data toggle
+ // bits and leaving the endpoint in valid state.
+ case TXTR_STATE_DB_FIRST_PKT :
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (txtr->ep_num), reg_val);
+ buf_sel = (reg_val & CYGHWR_HAL_STM32_USB_EPXR_DTOGTX) ? 1 : 0;
+ goto queue_packet;
+
+ // Commit the next queued packet for transmission then queue the next
+ // packet in the CPU-side buffer.
+ case TXTR_STATE_DB_NEXT_PKT :
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (txtr->ep_num), reg_val);
+ buf_sel = (reg_val & CYGHWR_HAL_STM32_USB_EPXR_DTOGTX) ? 0 : 1;
+ stm32_usb_flip_epxr_toggle (txtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_SWBUFTX);
+ stm32_usb_set_txep_status (txtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATTX_VALID);
+
+ // This section is common to both DB_NEXT_PKT and DB_FIRST_PKT states.
+ // However, a straight fallthrough won't work and we have to resort to goto.
+ queue_packet:
+ tx_bytes_req = txtr->buf_size - txtr->bytes_sent;
+ tx_bytes_sent = stm32_usb_copy_to_dbuf (txtr->buf_ptr, tx_bytes_req, txtr->ep_num, buf_sel);
+ txtr->buf_ptr += tx_bytes_sent;
+ txtr->bytes_sent += tx_bytes_sent;
+
+ // All bytes queued - see if we need a zero length termination packet.
+ if (txtr->bytes_sent == txtr->buf_size) {
+ if ((tx_bytes_sent == stm32_usb_buf_get_size (txtr->ep_num)) && (txtr->flags & TXTR_FLAGS_ZLPKT))
+ txtr->state = TXTR_STATE_DB_ZERO_PKT;
+ else
+ txtr->state = TXTR_STATE_DB_LAST_PKT;
+ }
+
+ // More data remaining - send next packet.
+ else {
+ txtr->state = TXTR_STATE_DB_NEXT_PKT;
+ }
+ break;
+
+ // Commit the next queued packet for transmission then queue a
+ // zero length packet in the CPU-side buffer.
+ case TXTR_STATE_DB_ZERO_PKT :
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (txtr->ep_num), reg_val);
+ buf_sel = (reg_val & CYGHWR_HAL_STM32_USB_EPXR_DTOGTX) ? 0 : 1;
+ stm32_usb_flip_epxr_toggle (txtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_SWBUFTX);
+ stm32_usb_set_txep_status (txtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATTX_VALID);
+ stm32_usb_copy_to_dbuf (txtr->buf_ptr, 0, txtr->ep_num, buf_sel);
+ txtr->state = TXTR_STATE_DB_LAST_PKT;
+ break;
+
+ // Commit the final queued packet for transmission.
+ case TXTR_STATE_DB_LAST_PKT :
+ stm32_usb_flip_epxr_toggle (txtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_SWBUFTX);
+ stm32_usb_set_txep_status (txtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATTX_VALID);
+ txtr->state = TXTR_STATE_DB_DONE;
+ break;
+
+ // Complete transaction (double buffer transfers).
+ case TXTR_STATE_DB_DONE :
+ stm32_usb_set_txep_status (txtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATTX_NAK);
+ txtr->state = TXTR_STATE_IDLE;
+ completed = true;
+ break;
+
+ // Unknown state - driver error.
+ default :
+ FAIL_USB ("TX transaction in invalid state.");
+ txtr->state = TXTR_STATE_IDLE;
+ txtr->status = EIO;
+ completed = true;
+ break;
+ }
+ return completed;
+}
+
+//-----------------------------------------------------------------------------
+// Initiate a data transmit transaction. This sets up a new transaction,
+// priming the buffers and then kicking the state machine for the first time.
+
+static cyg_bool stm32_usb_txtr_start
+ (txtr_impl* txtr, cyg_bool int_safe)
+{
+ cyg_bool completed;
+
+ // Critical section - avoid races with the ISR.
+ if (!int_safe) stm32_usb_request_intr_mask ();
+
+ // Set up double buffer transactions. We need to prime the buffers which
+ // requires two ticks of the state machine.
+ if (txtr->flags & TXTR_FLAGS_DBUF) {
+ txtr->status = ENOERR;
+ txtr->bytes_sent = 0;
+ txtr->state = TXTR_STATE_DB_FIRST_PKT;
+ stm32_usb_txtr_run (txtr);
+ }
+
+ // Set up single buffer transactions.
+ else {
+ txtr->status = ENOERR;
+ txtr->bytes_sent = 0;
+ txtr->state = TXTR_STATE_SB_NEXT_PKT;
+ }
+
+ // Run the state machine for the first step.
+ completed = stm32_usb_txtr_run (txtr);
+
+ // Exit critical section.
+ if (!int_safe) stm32_usb_release_intr_mask ();
+ return completed;
+}
+
+//-----------------------------------------------------------------------------
+// Halt a transmit endpoint. This places the endpoint in the stall condition
+// and cancels any outstanding transaction, resetting the transaction state
+// machine.
+
+static void stm32_usb_txep_halt
+ (txep_impl* txep, cyg_bool int_safe)
+{
+ cyg_bool call_completion;
+
+ // Critical section - avoid races with the ISR.
+ if (!int_safe) stm32_usb_request_intr_mask ();
+ stm32_usb_set_txep_status (txep->txtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATTX_DIS);
+
+ // Reset the transaction state.
+ call_completion = ((txep->txtr.state != TXTR_STATE_IDLE) &&
+ (txep->txtr.state != TXTR_STATE_RESET)) ? true : false;
+ txep->txtr.state = TXTR_STATE_RESET;
+ txep->common.halted = true;
+ stm32_usb_clear_epxr_bits (txep->txtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_CTRTX);
+
+ // Exit critical section.
+ stm32_usb_set_txep_status (txep->txtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATTX_STALL);
+ if (!int_safe) stm32_usb_release_intr_mask ();
+
+ // Indicate error via the completion callback.
+ if (call_completion) {
+ if (txep->common.complete_fn)
+ (*txep->common.complete_fn) (txep->common.complete_data, -EIO);
+ TRACE_USB ("TX Transaction cancelled on halt.\n");
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Take a transmit endpoint out of halted state. This takes the endpoint out
+// of the halted state and resets the endpoint. Note that according to the
+// spec, the endpoint should also be reset and the toggle bits cleared if
+// 'clear halted' is called while in normal operation.
+
+static void stm32_usb_txep_unhalt
+ (txep_impl* txep, cyg_bool int_safe)
+{
+ cyg_bool call_completion;
+
+ // Critical section - avoid races with the ISR.
+ if (!int_safe) stm32_usb_request_intr_mask ();
+ stm32_usb_set_txep_status (txep->txtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATTX_DIS);
+
+ // Reset the transaction state.
+ call_completion = ((txep->txtr.state != TXTR_STATE_IDLE) &&
+ (txep->txtr.state != TXTR_STATE_RESET)) ? true : false;
+ txep->txtr.state = TXTR_STATE_IDLE;
+ txep->common.halted = false;
+ stm32_usb_clear_epxr_bits (txep->txtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_CTRTX);
+ stm32_usb_clear_epxr_toggle (txep->txtr.ep_num,
+ CYGHWR_HAL_STM32_USB_EPXR_DTOGTX | CYGHWR_HAL_STM32_USB_EPXR_SWBUFTX);
+
+ // Exit critical section.
+ stm32_usb_set_txep_status (txep->txtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATTX_NAK);
+ if (!int_safe) stm32_usb_release_intr_mask ();
+
+ // Indicate error via the completion callback.
+ if (call_completion) {
+ if (txep->common.complete_fn)
+ (*txep->common.complete_fn) (txep->common.complete_data, -EIO);
+ TRACE_USB ("TX Transaction cancelled on resume.\n");
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Implement receive transaction state machine. This is called on all
+// applicable interrupt events in order to progress the transaction.
+
+static cyg_bool stm32_usb_rxtr_run
+ (rxtr_impl* rxtr)
+{
+ cyg_bool completed = false;
+ cyg_uint32 rx_bytes_req, rx_bytes_rcvd, buf_sel, reg_val;
+
+ switch (rxtr->state) {
+
+ // Receive new packet (single buffer transfers).
+ case RXTR_STATE_SB_NEXT_PKT:
+ rx_bytes_req = rxtr->buf_size - rxtr->bytes_rcvd;
+ rx_bytes_rcvd = stm32_usb_copy_from_sbuf (rxtr->buf_ptr, rx_bytes_req, rxtr->ep_num);
+
+ // Check for buffer overflow condition before updating buffer pointer.
+ if (rx_bytes_rcvd > rx_bytes_req) {
+ FAIL_USB ("RX message exceeds allocated buffer size.");
+ rxtr->state = RXTR_STATE_IDLE;
+ rxtr->status = EMSGSIZE;
+ completed = true;
+ break;
+ }
+ rxtr->buf_ptr += rx_bytes_rcvd;
+ rxtr->bytes_rcvd += rx_bytes_rcvd;
+
+ // Short packet received - transaction complete.
+ if (rx_bytes_rcvd < stm32_usb_buf_get_size (rxtr->ep_num)) {
+ rxtr->state = RXTR_STATE_IDLE;
+ completed = true;
+ break;
+ }
+
+ // All bytes received - see if we need a zero length termination packet.
+ // Note that zero length packets can be treated as normal short packets
+ // here, so an additional state transition is not required.
+ if (rxtr->bytes_rcvd == rxtr->buf_size) {
+ if (!((rx_bytes_rcvd == stm32_usb_buf_get_size (rxtr->ep_num)) && (rxtr->flags & RXTR_FLAGS_ZLPKT))) {
+ rxtr->state = RXTR_STATE_IDLE;
+ completed = true;
+ break;
+ }
+ }
+
+ // Set buffer clear via the endpoint control register.
+ stm32_usb_set_rxep_status (rxtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATRX_VALID);
+ break;
+
+ // Receive new packet (double buffer transfers). Start by switching buffers.
+ case RXTR_STATE_DB_NEXT_PKT:
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (rxtr->ep_num), reg_val);
+ buf_sel = (reg_val & CYGHWR_HAL_STM32_USB_EPXR_DTOGRX) ? 0 : 1;
+
+ // Get the receive buffer size.
+ HAL_READ_UINT32 (USB_RAM_BASE + USB_RAM_DB_RXCOUNT (rxtr->ep_num, buf_sel), rx_bytes_rcvd);
+ rx_bytes_req = rxtr->buf_size - rxtr->bytes_rcvd;
+ rx_bytes_rcvd &= USB_RAM_XX_RXCOUNT_COUNT_MASK;
+
+ // Check for buffer overflow condition before updating buffer pointer.
+ if (rx_bytes_rcvd > rx_bytes_req) {
+ FAIL_USB ("RX message exceeds allocated buffer size.");
+ rxtr->state = RXTR_STATE_IDLE;
+ rxtr->status = EMSGSIZE;
+ completed = true;
+ break;
+ }
+
+ // Short packet received - transaction complete.
+ if (rx_bytes_rcvd < stm32_usb_buf_get_size (rxtr->ep_num)) {
+ rxtr->state = RXTR_STATE_IDLE;
+ completed = true;
+ }
+
+ // All bytes received - see if we need a zero length termination packet.
+ // Note that zero length packets can be treated as normal short packets
+ // here, so an additional state transition is not required.
+ if (rxtr->bytes_rcvd + rx_bytes_rcvd == rxtr->buf_size) {
+ if (!((rx_bytes_rcvd == stm32_usb_buf_get_size (rxtr->ep_num)) && (rxtr->flags & RXTR_FLAGS_ZLPKT))) {
+ rxtr->state = RXTR_STATE_IDLE;
+ completed = true;
+ }
+ }
+
+ // Only enable the next receive buffer if this is not the last packet.
+ if (!completed) {
+ stm32_usb_flip_epxr_toggle (rxtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_SWBUFRX);
+ stm32_usb_set_rxep_status (rxtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATRX_VALID);
+ }
+
+ // Set the endpoint to NAK on completion.
+ else {
+ stm32_usb_set_rxep_status (rxtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATRX_NAK);
+ }
+
+ // Copy the received data to our local buffer.
+ rx_bytes_rcvd = stm32_usb_copy_from_dbuf (rxtr->buf_ptr, rx_bytes_req, rxtr->ep_num, buf_sel);
+ rxtr->bytes_rcvd += rx_bytes_rcvd;
+ rxtr->buf_ptr += rx_bytes_rcvd;
+ break;
+
+ // Unknown state - driver error.
+ default :
+ FAIL_USB ("RX transaction in invalid state.");
+ rxtr->state = RXTR_STATE_IDLE;
+ rxtr->status = EIO;
+ completed = true;
+ break;
+
+ }
+ return completed;
+}
+
+//-----------------------------------------------------------------------------
+// Initiate a data receive transaction. This sets up a new transaction,
+// enabling the receive buffers and then waiting for incoming data.
+
+static cyg_bool stm32_usb_rxtr_start
+ (rxtr_impl* rxtr, cyg_bool int_safe)
+{
+ // Critical section - avoid races with the ISR.
+ if (!int_safe) stm32_usb_request_intr_mask ();
+
+ // Set up double buffer transactions.
+ if (rxtr->flags & RXTR_FLAGS_DBUF) {
+ rxtr->state = RXTR_STATE_DB_NEXT_PKT;
+ rxtr->status = ENOERR;
+ rxtr->bytes_rcvd = 0;
+ stm32_usb_flip_epxr_toggle (rxtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_SWBUFRX);
+ stm32_usb_set_rxep_status (rxtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATRX_VALID);
+ }
+
+ // Set up single buffer transactions.
+ else {
+ rxtr->state = RXTR_STATE_SB_NEXT_PKT;
+ rxtr->status = ENOERR;
+ rxtr->bytes_rcvd = 0;
+ stm32_usb_set_rxep_status (rxtr->ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATRX_VALID);
+ }
+
+ // Exit critical section.
+ if (!int_safe) stm32_usb_release_intr_mask ();
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Halt a receive endpoint. This places the endpoint in the stall condition
+// and cancels any outstanding transaction, resetting the transaction state
+// machine.
+
+static void stm32_usb_rxep_halt
+ (rxep_impl* rxep, cyg_bool int_safe)
+{
+ cyg_bool call_completion;
+
+ // Critical section - avoid races with the ISR.
+ if (!int_safe) stm32_usb_request_intr_mask ();
+ stm32_usb_set_rxep_status (rxep->rxtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATRX_DIS);
+
+ // Reset the transaction state.
+ call_completion = ((rxep->rxtr.state != RXTR_STATE_IDLE) &&
+ (rxep->rxtr.state != RXTR_STATE_RESET)) ? true : false;
+ rxep->rxtr.state = RXTR_STATE_RESET;
+ rxep->common.halted = true;
+ stm32_usb_clear_epxr_bits (rxep->rxtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_CTRRX);
+
+ // Exit critical section.
+ stm32_usb_set_rxep_status (rxep->rxtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATRX_STALL);
+ if (!int_safe) stm32_usb_release_intr_mask ();
+
+ // Indicate error via the completion callback.
+ if (call_completion) {
+ if (rxep->common.complete_fn)
+ (*rxep->common.complete_fn) (rxep->common.complete_data, -EIO);
+ TRACE_USB ("RX Transaction cancelled on halt.\n");
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Take a receive endpoint out of halted state. This takes the endpoint out
+// of the halted state and resets the endpoint. Note that according to the
+// spec, the endpoint should also be reset and the toggle bits cleared if
+// 'clear halted' is called while in normal operation.
+
+static void stm32_usb_rxep_unhalt
+ (rxep_impl* rxep, cyg_bool int_safe)
+{
+ cyg_bool call_completion;
+
+ // Critical section - avoid races with the ISR.
+ if (!int_safe) stm32_usb_request_intr_mask ();
+ stm32_usb_set_rxep_status (rxep->rxtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATRX_DIS);
+
+ // Reset the transaction state.
+ call_completion = ((rxep->rxtr.state != RXTR_STATE_IDLE) &&
+ (rxep->rxtr.state != RXTR_STATE_RESET)) ? true : false;
+ rxep->rxtr.state = RXTR_STATE_IDLE;
+ rxep->common.halted = false;
+ stm32_usb_clear_epxr_bits (rxep->rxtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_CTRRX);
+ stm32_usb_clear_epxr_toggle (rxep->rxtr.ep_num,
+ CYGHWR_HAL_STM32_USB_EPXR_DTOGRX | CYGHWR_HAL_STM32_USB_EPXR_SWBUFRX);
+
+ // Exit critical section.
+ stm32_usb_set_rxep_status (rxep->rxtr.ep_num, CYGHWR_HAL_STM32_USB_EPXR_STATRX_NAK);
+ if (!int_safe) stm32_usb_release_intr_mask ();
+
+ // Indicate error via the completion callback.
+ if (call_completion) {
+ if (rxep->common.complete_fn)
+ (*rxep->common.complete_fn) (rxep->common.complete_data, -EIO);
+ TRACE_USB ("RX Transaction cancelled on resume.\n");
+ }
+}
+
+//=============================================================================
+// Implement control endpoint protocol handling.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Forward endpoint 0 state change notifications.
+
+static void stm32_usb_ctrl_update_state
+ (int new_state, usbs_state_change state_change)
+{
+ int old_state = ctrlep.common.state;
+ ctrlep.common.state = new_state;
+ if (ctrlep.common.state_change_fn)
+ (*ctrlep.common.state_change_fn) (&ctrlep.common,
+ ctrlep.common.state_change_data, state_change, old_state);
+}
+
+// --------------------------------------------------------------------------
+// Called on completion of an endpoint 0 control request transaction.
+
+static void stm32_usb_ctrl_completed
+ (int status)
+{
+ ctrlep.msg_state = CTRLEP_MSG_STATE_IDLE;
+ if (ctrlep.common.complete_fn)
+ (*ctrlep.common.complete_fn) (&cyg_usbs_cortexm_stm32_ep0c, -status);
+ if (status != 0)
+ TRACE_USB ("Transaction failed (status %d).\n", status);
+}
+
+//-----------------------------------------------------------------------------
+// Clear endpoint configuration. This disables all non-control endpoints,
+// resetting their state.
+
+static void stm32_usb_ctrl_clear_config
+ (void)
+{
+ cyg_uint32 i;
+ txep_impl* txep = txep_list;
+ rxep_impl* rxep = rxep_list;
+
+ // Disable all non-control endpoints, clearing any outstanding interrupts.
+ // This also ensures that the toggle bits are reset to 0.
+ for (i = 1; i < 8; i++) {
+ stm32_usb_set_txep_status (i, CYGHWR_HAL_STM32_USB_EPXR_STATTX_DIS);
+ stm32_usb_set_rxep_status (i, CYGHWR_HAL_STM32_USB_EPXR_STATRX_DIS);
+ stm32_usb_clear_epxr_toggle (i,
+ CYGHWR_HAL_STM32_USB_EPXR_DTOGTX | CYGHWR_HAL_STM32_USB_EPXR_DTOGRX);
+ stm32_usb_clear_epxr_bits (i, 0xFFFF);
+ }
+
+ // Reset the transaction state for all transmit endpoints.
+ for (i = 0; i < CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM; i++) {
+ txep->common.halted = true;
+ txep->txtr.state = TXTR_STATE_RESET;
+ txep++;
+ }
+
+ // Reset the transaction state for all receive endpoints.
+ for (i = 0; i < CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM; i++) {
+ rxep->common.halted = true;
+ rxep->rxtr.state = RXTR_STATE_RESET;
+ rxep++;
+ }
+
+ // Clear the logical to physical endpoint mappings.
+ for (i = 0; i < 15; i++) {
+ txep_map [i] = NULL;
+ rxep_map [i] = NULL;
+ }
+
+ // Clear buffer RAM for non-control endpoints (preseverves endpoint 0).
+ stm32_usb_buf_clear_config ();
+}
+
+//-----------------------------------------------------------------------------
+// Reset the control endpoint - placing the device in the 'default' state.
+
+static void stm32_usb_ctrl_reset
+ (void)
+{
+ // Re-enable the device on address 0 only.
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_DADDR, CYGHWR_HAL_STM32_USB_DADDR_EF);
+
+ // Reset the buffer RAM layout, allocating only the endpoint 0 buffers.
+ stm32_usb_buf_reset_ep0 (ctrlep.common.enumeration_data->device.max_packet_size);
+
+ // Clear the previous endpoint configuration.
+ stm32_usb_ctrl_clear_config ();
+
+ // Ensure endpoint 0 is assigned the correct endpoint type.
+ stm32_usb_assign_epxr (0, CYGHWR_HAL_STM32_USB_EPXR_EPTYPE_CTRL);
+
+ // Reset endpoint 0, leaving it configured for valid incoming packets.
+ stm32_usb_set_txep_status (0, CYGHWR_HAL_STM32_USB_EPXR_STATTX_NAK);
+ stm32_usb_set_rxep_status (0, CYGHWR_HAL_STM32_USB_EPXR_STATRX_VALID);
+ stm32_usb_clear_epxr_toggle (0,
+ CYGHWR_HAL_STM32_USB_EPXR_DTOGTX | CYGHWR_HAL_STM32_USB_EPXR_DTOGRX);
+ stm32_usb_clear_epxr_bits (0,
+ CYGHWR_HAL_STM32_USB_EPXR_CTRTX | CYGHWR_HAL_STM32_USB_EPXR_CTRRX);
+
+ // Enter default state.
+ stm32_usb_ctrl_update_state (USBS_STATE_DEFAULT, USBS_STATE_CHANGE_RESET);
+}
+
+//-----------------------------------------------------------------------------
+// Fill the transmit control message buffer. This function is used to
+// assemble control response messages for transmission to the host.
+
+static cyg_uint32 stm32_usb_ctrl_fill_msg_buffer
+ (void)
+{
+ cyg_uint32 msg_length = 0;
+
+ // Deal with commands which place their data directly into the staging buffer.
+ if (ctrlep.common.buffer == ctrlep_msg_buffer) {
+ msg_length = ctrlep.common.buffer_size;
+ }
+
+ // Loop until there are no more message segments to append. For buffer
+ // overflows, debug builds will assert and production builds will send a
+ // truncated message.
+ else do {
+ if (ctrlep.common.buffer_size != 0) {
+ if (msg_length + ctrlep.common.buffer_size <= CYGNUM_DEVS_USB_CORTEXM_STM32_EPO_MAX_MSG_SIZE) {
+ memcpy (ctrlep_msg_buffer + msg_length, ctrlep.common.buffer, ctrlep.common.buffer_size);
+ msg_length += ctrlep.common.buffer_size;
+ }
+ else {
+ FAIL_USB ("Endpoint 0 transmit buffer overflow.");
+ break;
+ }
+
+ // Get the next message segment, if available.
+ if (ctrlep.common.fill_buffer_fn)
+ (*ctrlep.common.fill_buffer_fn) (&cyg_usbs_cortexm_stm32_ep0c);
+ }
+ } while (ctrlep.common.fill_buffer_fn);
+
+ return msg_length;
+}
+
+//-----------------------------------------------------------------------------
+// Handle set configuration setup packets. This is implemented in the low
+// level driver because this is the point at which we need to configure the
+// endpoint RAM and realise the endpoints. It 'falls through' to the high
+// level handlers so that they can deal with notifying the application.
+// Note: Only a single (default) interface is supported per configuration.
+
+static usbs_control_return stm32_usb_ctrl_set_config
+ (cyg_uint32 config_id)
+{
+ cyg_uint32 i, j;
+ cyg_uint32 start_interface, start_endpoint, num_endpoints;
+ cyg_uint32 total_interfaces, total_endpoints;
+ cyg_uint32 txep_count = 0;
+ cyg_uint32 rxep_count = 0;
+ cyg_bool alloc_ok;
+ const usb_configuration_descriptor* configurations;
+ const usb_interface_descriptor* interfaces;
+ const usb_endpoint_descriptor* endpoints;
+
+ // Check for valid config.
+ if ((config_id <= 0) ||
+ (config_id > ctrlep.common.enumeration_data->device.number_configurations))
+ return USBS_CONTROL_RETURN_UNKNOWN;
+
+ // Clear the previous endpoint configuration.
+ stm32_usb_ctrl_clear_config ();
+
+ // Get the base pointers for the descriptor tables.
+ configurations = ctrlep.common.enumeration_data->configurations;
+ interfaces = ctrlep.common.enumeration_data->interfaces;
+ endpoints = ctrlep.common.enumeration_data->endpoints;
+
+ start_interface = 0;
+ start_endpoint = 0;
+ num_endpoints = 0;
+ total_interfaces = ctrlep.common.enumeration_data->total_number_interfaces;
+ total_endpoints = ctrlep.common.enumeration_data->total_number_endpoints;
+
+ // Skip over the descriptors until we get to the ones we want.
+ for (i = 0; i < (config_id-1); i++) {
+ ASSERT_USB (start_interface + configurations[i].number_interfaces <= total_interfaces,
+ "Invalid number of interfaces in enumeration data.");
+ for (j = 0; j < configurations[i].number_interfaces; j++) {
+ start_endpoint += interfaces[start_interface+j].number_endpoints;
+ ASSERT_USB (start_endpoint < total_endpoints,
+ "Invalid number of endpoints in enumeration data.");
+ }
+ start_interface += configurations[i].number_interfaces;
+ }
+
+ // Determine the number of endpoint descriptors which need to be included for
+ // all interfaces within the specified configuration.
+ ASSERT_USB (start_interface + configurations[i].number_interfaces <= total_interfaces,
+ "Invalid number of interfaces in enumeration data.");
+ for (j = 0; j < configurations[i].number_interfaces; j++) {
+ num_endpoints += interfaces[start_interface+j].number_endpoints;
+ ASSERT_USB (start_endpoint + num_endpoints <= total_endpoints,
+ "Invalid number of endpoints in enumeration data.");
+ }
+ TRACE_USB ("Found %d interfaces and %d endpoints for configuration %d.\n",
+ configurations[i].number_interfaces, num_endpoints, config_id);
+
+ // Realise the endpoints for the specified interfaces. Set up the buffer
+ // RAM and configure them to NAK the host until the higher layer application
+ // is ready to initiate transfers. Failures to allocate the endpoint buffers
+ // will put the endpoints in the stalled state.
+ for (i = 0; i < num_endpoints; i++) {
+ const usb_endpoint_descriptor* ep_desc = endpoints + start_endpoint + i;
+ cyg_uint32 pkt_size = ep_desc->max_packet_lo + (((cyg_uint32) ep_desc->max_packet_hi) << 8);
+
+ // Deal with transmit (input) endpoints.
+ if (ep_desc->endpoint & USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN) {
+ if ((ep_desc->endpoint & 0x7F) < 1 || (ep_desc->endpoint & 0x7F) > 15) {
+ FAIL_USB ("Invalid endpoint ID in configuration.");
+ goto out;
+ }
+ if (txep_count >= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM) {
+ FAIL_USB ("Too many TX endpoints in configuration.");
+ goto out;
+ }
+
+ // Set up transmit (input) buffers.
+ if (ep_desc->attributes == USB_ENDPOINT_DESCRIPTOR_ATTR_BULK) {
+ alloc_ok = stm32_usb_buf_add_ep (txep_count + 1, pkt_size, true, false, true);
+ stm32_usb_set_epxr_bits (txep_count + 1,
+ CYGHWR_HAL_STM32_USB_EPXR_EPTYPE_BULK | CYGHWR_HAL_STM32_USB_EPXR_EPKIND);
+#ifdef CYGHWR_DEVS_USB_CORTEXM_STM32_BULK_TERM_ZLP
+ (txep_list + txep_count)->txtr.flags = TXTR_FLAGS_ZLPKT | TXTR_FLAGS_DBUF;
+#else
+ (txep_list + txep_count)->txtr.flags = TXTR_FLAGS_DBUF;
+#endif
+ TRACE_USB ("Configured BULK IN endpoint ID %d.\n", ep_desc->endpoint & 0x7F);
+ }
+ else if (ep_desc->attributes == USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT) {
+ alloc_ok = stm32_usb_buf_add_ep (txep_count + 1, pkt_size, true, false, false);
+ (txep_list + txep_count)->txtr.flags = TXTR_FLAGS_NONE;
+ stm32_usb_set_epxr_bits (txep_count + 1, CYGHWR_HAL_STM32_USB_EPXR_EPTYPE_INTR);
+ TRACE_USB ("Configured INTERRUPT IN endpoint ID %d.\n", ep_desc->endpoint & 0x7F);
+ }
+ else {
+ FAIL_USB ("Isochronous endpoints are not currently supported.");
+ goto out;
+ }
+
+ // Enable endpoints if buffer allocation was OK - stall them otherwise.
+ if (alloc_ok) {
+ txep_map [(ep_desc->endpoint & 0x7F) - 1] = txep_list + txep_count;
+ (txep_list + txep_count)->common.halted = false;
+ (txep_list + txep_count)->txtr.state = TXTR_STATE_IDLE;
+ stm32_usb_set_txep_status (txep_count + 1, CYGHWR_HAL_STM32_USB_EPXR_STATTX_NAK);
+ }
+ else {
+ stm32_usb_set_txep_status (txep_count + 1, CYGHWR_HAL_STM32_USB_EPXR_STATTX_STALL);
+ }
+ stm32_usb_set_epxr_bits (txep_count + 1, (ep_desc->endpoint & 0xF));
+ txep_count++;
+ }
+
+ // Deal with receive (output) endpoints.
+ else {
+ if ((ep_desc->endpoint & 0x7F) < 1 || (ep_desc->endpoint & 0x7F) > 15) {
+ FAIL_USB ("Invalid endpoint ID in configuration.");
+ goto out;
+ }
+ if (rxep_count >= CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM) {
+ FAIL_USB ("Too many RX endpoints in configuration.");
+ goto out;
+ }
+
+ // Set up receive (output) buffers.
+ if (ep_desc->attributes == USB_ENDPOINT_DESCRIPTOR_ATTR_BULK) {
+ alloc_ok = stm32_usb_buf_add_ep (rxep_count + CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + 1,
+ pkt_size, false, true, true);
+ stm32_usb_set_epxr_bits (rxep_count + CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + 1,
+ CYGHWR_HAL_STM32_USB_EPXR_EPTYPE_BULK | CYGHWR_HAL_STM32_USB_EPXR_EPKIND);
+#ifdef CYGHWR_DEVS_USB_CORTEXM_STM32_BULK_TERM_ZLP
+ (rxep_list + rxep_count)->rxtr.flags = RXTR_FLAGS_ZLPKT | RXTR_FLAGS_DBUF;
+#else
+ (rxep_list + rxep_count)->rxtr.flags = RXTR_FLAGS_DBUF;
+#endif
+ TRACE_USB ("Configured BULK OUT endpoint ID %d.\n", ep_desc->endpoint & 0x7F);
+ }
+ else if (ep_desc->attributes == USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT) {
+ alloc_ok = stm32_usb_buf_add_ep (rxep_count + CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + 1,
+ pkt_size, false, true, false);
+ (rxep_list + rxep_count)->rxtr.flags = RXTR_FLAGS_NONE;
+ stm32_usb_set_epxr_bits (rxep_count + CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + 1,
+ CYGHWR_HAL_STM32_USB_EPXR_EPTYPE_INTR);
+ TRACE_USB ("Configured INTERRUPT OUT endpoint ID %d.\n", ep_desc->endpoint & 0x7F);
+ }
+ else {
+ FAIL_USB ("Isochronous endpoints are not currently supported.");
+ goto out;
+ }
+
+ // Enable endpoints if buffer allocation was OK - stall them otherwise.
+ if (alloc_ok) {
+ rxep_map [(ep_desc->endpoint & 0x7F) - 1] = rxep_list + rxep_count;
+ (rxep_list + rxep_count)->common.halted = false;
+ (rxep_list + rxep_count)->rxtr.state = RXTR_STATE_IDLE;
+ stm32_usb_set_rxep_status (rxep_count + CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + 1,
+ CYGHWR_HAL_STM32_USB_EPXR_STATRX_NAK);
+ }
+ else {
+ stm32_usb_set_rxep_status (rxep_count + CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + 1,
+ CYGHWR_HAL_STM32_USB_EPXR_STATRX_STALL);
+ }
+ stm32_usb_set_epxr_bits (rxep_count + CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + 1,
+ (ep_desc->endpoint & 0xF));
+ rxep_count++;
+ }
+ }
+
+ // Pass up to higher layers.
+out:
+ return USBS_CONTROL_RETURN_UNKNOWN;
+}
+
+//-----------------------------------------------------------------------------
+// Handle get status setup packets. This function places the status
+// information directly into the staging buffer. We deal with the device
+// and endpoint status responses here. The interface status request is
+// dealt with in the common USB slave layer.
+// TODO - should #define the return fields in usb.h.
+
+static inline usbs_control_return stm32_usb_ctrl_get_status
+ (cyg_uint32 recipient, cyg_uint32 ep_sel)
+{
+ cyg_uint8 dev_state = ctrlep.common.state & USBS_STATE_MASK;
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+
+ // Device status requests are valid in addressed and configured states.
+ // TODO - remote wakeup is not currently supported by this driver.
+ if (recipient == USB_DEVREQ_RECIPIENT_DEVICE) {
+ if (dev_state == USBS_STATE_ADDRESSED || dev_state == USBS_STATE_CONFIGURED) {
+#ifdef CYGHWR_DEVS_USB_CORTEXM_STM32_SELF_POWERED
+ ctrlep_msg_buffer[0] = 0x01;
+#else
+ ctrlep_msg_buffer[0] = 0x00;
+#endif
+ ctrlep_msg_buffer[1] = 0x00;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ }
+
+ // Endpoint 0 status requests are valid in addressed and configured states.
+ // Endpoint 0 cannot be halted. Endpoint number is in the lower 4 bits of the ID.
+ else if (recipient == USB_DEVREQ_RECIPIENT_ENDPOINT && (ep_sel & USB_DEVREQ_INDEX_ENDPOINT_MASK) == 0) {
+ if (dev_state == USBS_STATE_ADDRESSED || dev_state == USBS_STATE_CONFIGURED) {
+ ctrlep_msg_buffer[0] = 0x00;
+ ctrlep_msg_buffer[1] = 0x00;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ }
+
+ // Non-control endpoint status requests are only valid in the configured state.
+ // Returns the halted state of the requested endpoint.
+ else if (recipient == USB_DEVREQ_RECIPIENT_ENDPOINT) {
+ if (dev_state == USBS_STATE_CONFIGURED) {
+
+ // Transmit (IN) endpoint IDs have the top bit set.
+ if ((ep_sel & USB_DEVREQ_INDEX_DIRECTION_MASK) == USB_DEVREQ_INDEX_DIRECTION_IN) {
+ ep_sel = (ep_sel & USB_DEVREQ_INDEX_ENDPOINT_MASK) - 1;
+ if (txep_map[ep_sel] != NULL) {
+ ctrlep_msg_buffer[0] = (txep_map[ep_sel]->common.halted) ? 0x01 : 0x00;
+ ctrlep_msg_buffer[1] = 0x00;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ }
+
+ // Receive (OUT) endpoint IDs have the top bit clear.
+ else {
+ ep_sel = (ep_sel & USB_DEVREQ_INDEX_ENDPOINT_MASK) - 1;
+ if (rxep_map[ep_sel] != NULL) {
+ ctrlep_msg_buffer[0] = (rxep_map[ep_sel]->common.halted) ? 0x01 : 0x00;
+ ctrlep_msg_buffer[1] = 0x00;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ }
+ }
+ }
+
+ // Point the endpoint 0 response buffer at the staging buffer.
+ if (result != USBS_CONTROL_RETURN_UNKNOWN) {
+ ctrlep.common.buffer_size = 2;
+ ctrlep.common.buffer = ctrlep_msg_buffer;
+ }
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// Handle set and clear feature commands. Since remote wakeup support is not
+// implemented and interface features are dealt with at a higher layer we only
+// implement endpoint halting here. This will only ever be called from within
+// the DSR so is interrupt safe.
+
+static usbs_control_return stm32_usb_ctrl_set_feature
+ (cyg_uint32 recipient, cyg_uint32 ep_sel, cyg_uint32 feature, cyg_bool set)
+{
+ cyg_uint8 dev_state = ctrlep.common.state & USBS_STATE_MASK;
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+
+ // Non-control endpoint feature control is valid in the configured state.
+ if (recipient == USB_DEVREQ_RECIPIENT_ENDPOINT &&
+ dev_state == USBS_STATE_CONFIGURED && feature == USB_DEVREQ_FEATURE_ENDPOINT_HALT) {
+
+ // Transmit (IN) endpoint IDs have the top bit set.
+ if ((ep_sel & USB_DEVREQ_INDEX_DIRECTION_MASK) == USB_DEVREQ_INDEX_DIRECTION_IN) {
+ ep_sel = (ep_sel & USB_DEVREQ_INDEX_ENDPOINT_MASK) - 1;
+ if (txep_map[ep_sel] != NULL) {
+ if (set)
+ stm32_usb_txep_halt (txep_map[ep_sel], true);
+ else
+ stm32_usb_txep_unhalt (txep_map[ep_sel], true);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ }
+
+ // Receive (OUT) endpoint IDs have the top bit clear.
+ else {
+ ep_sel = (ep_sel & USB_DEVREQ_INDEX_ENDPOINT_MASK) - 1;
+ if (rxep_map[ep_sel] != NULL) {
+ if (set)
+ stm32_usb_rxep_halt (rxep_map[ep_sel], true);
+ else
+ stm32_usb_rxep_unhalt (rxep_map[ep_sel], true);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ }
+ }
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// Process standard endpoint 0 setup packets.
+
+static usbs_control_return stm32_usb_ctrl_setup_standard
+ (void)
+{
+ usb_devreq* req = (usb_devreq*) &ctrlep.common.control_buffer[0];
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+ cyg_uint32 recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+
+ switch (req->request) {
+
+ // Assign device address. We can't actually update the address register
+ // until after the full bus handshake has completed, otherwise the ACK
+ // packet gets lost.
+ case USB_DEVREQ_SET_ADDRESS :
+ result = USBS_CONTROL_RETURN_HANDLED;
+ break;
+
+ // Set device configuration.
+ case USB_DEVREQ_SET_CONFIGURATION :
+ TRACE_USB ("Setting USB configuration = %d\n", (cyg_uint32) req->value_lo);
+ result = stm32_usb_ctrl_set_config (req->value_lo);
+ break;
+
+ // TODO: Interfaces with multiple settings are not currently supported.
+ // If a device only supports a default setting for a specified interface
+ // the spec says a stall should be sent.
+ case USB_DEVREQ_SET_INTERFACE :
+ TRACE_USB ("Using default interface settings.\n");
+ result = USBS_CONTROL_RETURN_STALL;
+ break;
+
+ // Get device status.
+ case USB_DEVREQ_GET_STATUS :
+ result = stm32_usb_ctrl_get_status (recipient, req->index_lo);
+ break;
+
+ // Control endpoint halting. Halt on 'set feature'.
+ case USB_DEVREQ_SET_FEATURE :
+ result = stm32_usb_ctrl_set_feature (recipient, req->index_lo, req->value_lo, true);
+ break;
+
+ // Control endpoint halting. Resume on 'clear feature'.
+ case USB_DEVREQ_CLEAR_FEATURE :
+ result = stm32_usb_ctrl_set_feature (recipient, req->index_lo, req->value_lo, false);
+ break;
+
+ // Pass up to the user supplied handler, if present.
+ default :
+ if (ctrlep.common.standard_control_fn)
+ result = (*ctrlep.common.standard_control_fn)
+ (&ctrlep.common, ctrlep.common.standard_control_data);
+ break;
+ }
+
+ // If not already handled, pass up to the high level driver.
+ if (result == USBS_CONTROL_RETURN_UNKNOWN)
+ result = usbs_handle_standard_control (&ctrlep.common);
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// Perform initial processing of endpoint 0 setup packets.
+
+static void stm32_usb_ctrl_setup_handler
+ (void)
+{
+ cyg_uint32 req_length, req_type, req_dir;
+ usb_devreq* req = (usb_devreq*) &ctrlep.common.control_buffer[0];
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+
+ // Extract the required fields from the setup packet.
+ req_length = 8 * (cyg_uint32) req->length_hi + req->length_lo;
+ req_type = req->type & USB_DEVREQ_TYPE_MASK;
+ req_dir = req->type & USB_DEVREQ_DIRECTION_MASK;
+
+ // Always fail the transaction if the requested data stage exceeds the
+ // allocated buffer area.
+ if ((req_dir == USB_DEVREQ_DIRECTION_OUT) &&
+ (req_length > CYGNUM_DEVS_USB_CORTEXM_STM32_EPO_MAX_MSG_SIZE)) {
+ FAIL_USB ("Requested control data stage exceeds message buffer size.");
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+
+ // Pass standard requests to the standard handlers.
+ else if (req_type == USB_DEVREQ_TYPE_STANDARD) {
+ result = stm32_usb_ctrl_setup_standard ();
+ }
+
+ // Hand off non-standard requests to their respective handlers.
+ else {
+ usbs_control_return (*callback_fn) (usbs_control_endpoint*, void*);
+ void* callback_arg;
+
+ if (req_type == USB_DEVREQ_TYPE_CLASS) {
+ callback_fn = ctrlep.common.class_control_fn;
+ callback_arg = ctrlep.common.class_control_data;
+ }
+ else if (req_type == USB_DEVREQ_TYPE_VENDOR) {
+ callback_fn = ctrlep.common.vendor_control_fn;
+ callback_arg = ctrlep.common.vendor_control_data;
+ }
+ else {
+ callback_fn = ctrlep.common.reserved_control_fn;
+ callback_arg = ctrlep.common.reserved_control_data;
+ }
+
+ result = (callback_fn) ? (*callback_fn) (&ctrlep.common, callback_arg)
+ : USBS_CONTROL_RETURN_STALL;
+ }
+
+ // If correctly handled, initiate the data transfer phase. This is only
+ // called from within the DSR, so the transaction start is interrupt safe.
+ if (result == USBS_CONTROL_RETURN_HANDLED) {
+
+ // ACK the transfer by sending a zero length packet.
+ if (req_length == 0) {
+ ctrlep.msg_state = CTRLEP_MSG_STATE_CTRL_ACK;
+ ctrlep.txtr.state = TXTR_STATE_IDLE;
+ ctrlep.txtr.buf_ptr = ctrlep_msg_buffer;
+ ctrlep.txtr.buf_size = 0;
+ stm32_usb_txtr_start (&ctrlep.txtr, true);
+ }
+
+ // Send the inbound data.
+ else if (req_dir == USB_DEVREQ_DIRECTION_IN) {
+ ctrlep.msg_state = CTRLEP_MSG_STATE_IN_DATA;
+ ctrlep.txtr.state = TXTR_STATE_IDLE;
+ ctrlep.txtr.buf_ptr = ctrlep_msg_buffer;
+ ctrlep.txtr.buf_size = stm32_usb_ctrl_fill_msg_buffer ();
+ stm32_usb_txtr_start (&ctrlep.txtr, true);
+ }
+
+ // Receive outbound data from the host.
+ else {
+ ctrlep.msg_state = CTRLEP_MSG_STATE_OUT_DATA;
+ ctrlep.rxtr.state = RXTR_STATE_IDLE;
+ ctrlep.rxtr.buf_ptr = ctrlep_msg_buffer;
+ ctrlep.rxtr.buf_size = CYGNUM_DEVS_USB_CORTEXM_STM32_EPO_MAX_MSG_SIZE;
+ stm32_usb_rxtr_start (&ctrlep.rxtr, true);
+ }
+ }
+
+ // Stall endpoint on request.
+ else if (result == USBS_CONTROL_RETURN_STALL) {
+ stm32_usb_set_txep_status (0, CYGHWR_HAL_STM32_USB_EPXR_STATTX_STALL);
+ stm32_usb_set_rxep_status (0, CYGHWR_HAL_STM32_USB_EPXR_STATRX_STALL);
+ }
+
+ // Unsupported setup commands also stall the control endpoint.
+ else {
+ TRACE_USB ("Stall EP0 on UNKNOWN control message : %02X %02X %02X %02X %02X %02X %02X %02X\n",
+ ctrlep.common.control_buffer[0], ctrlep.common.control_buffer[1],
+ ctrlep.common.control_buffer[2], ctrlep.common.control_buffer[3],
+ ctrlep.common.control_buffer[4], ctrlep.common.control_buffer[5],
+ ctrlep.common.control_buffer[6], ctrlep.common.control_buffer[7]);
+ stm32_usb_set_txep_status (0, CYGHWR_HAL_STM32_USB_EPXR_STATTX_STALL);
+ stm32_usb_set_rxep_status (0, CYGHWR_HAL_STM32_USB_EPXR_STATRX_STALL);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Completion of control endpoint data transmit phase.
+
+static inline void stm32_usb_ctrl_txtr_done
+ (void)
+{
+ cyg_uint32 reg_val;
+ usb_devreq* req = (usb_devreq*) &ctrlep.common.control_buffer[0];
+
+ // If this is confirmation that an ACK packet has been sent, complete the
+ // transaction. We also take the opportunity to update the device address
+ // here if required.
+ if (ctrlep.msg_state == CTRLEP_MSG_STATE_CTRL_ACK) {
+ if (req->request == USB_DEVREQ_SET_ADDRESS) {
+ TRACE_USB ("Setting USB device address = %d\n", (cyg_uint32) req->value_lo);
+ reg_val = CYGHWR_HAL_STM32_USB_DADDR_EF;
+ reg_val |= CYGHWR_HAL_STM32_USB_DADDR_ADD ((cyg_uint32) req->value_lo);
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_DADDR, reg_val);
+ stm32_usb_ctrl_update_state (USBS_STATE_ADDRESSED, USBS_STATE_CHANGE_ADDRESSED);
+ }
+ stm32_usb_ctrl_completed (ctrlep.txtr.status);
+ }
+
+ // Complete after transmitting the output status handshake.
+ else if (ctrlep.msg_state == CTRLEP_MSG_STATE_OUT_STATUS) {
+ stm32_usb_ctrl_completed (ctrlep.txtr.status);
+ }
+
+ // If all packets in an inbound transaction have been sent, wait for status
+ // response from the host. Called from DSR so is interrupt safe.
+ else if (ctrlep.msg_state == CTRLEP_MSG_STATE_IN_DATA) {
+ if (ctrlep.txtr.status == ENOERR) {
+ ctrlep.msg_state = CTRLEP_MSG_STATE_IN_STATUS;
+ ctrlep.rxtr.state = RXTR_STATE_IDLE;
+ ctrlep.rxtr.buf_ptr = ctrlep_msg_buffer;
+ ctrlep.rxtr.buf_size = 0;
+ stm32_usb_rxtr_start (&ctrlep.rxtr, true);
+ }
+ else {
+ stm32_usb_ctrl_completed (ctrlep.txtr.status);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Completion of control endpoint data receive phase.
+
+static inline void stm32_usb_ctrl_rxtr_done
+ (void)
+{
+ // If waiting for a status response, we should get a zero length packet.
+ if (ctrlep.msg_state == CTRLEP_MSG_STATE_IN_STATUS) {
+ stm32_usb_ctrl_completed (ctrlep.rxtr.status);
+ }
+
+ // Handle conventional data packets. Incoming packets on endpoint 0 can
+ // be overwritten by setup packets. Called from DSR so is interrupt safe.
+ else if (ctrlep.msg_state == CTRLEP_MSG_STATE_OUT_DATA) {
+ if (ctrlep.rxtr.status == ENOERR) {
+ ctrlep.msg_state = CTRLEP_MSG_STATE_OUT_STATUS;
+ ctrlep.txtr.state = TXTR_STATE_IDLE;
+ ctrlep.txtr.buf_ptr = ctrlep_msg_buffer;
+ ctrlep.txtr.buf_size = 0;
+ stm32_usb_txtr_start (&ctrlep.txtr, true);
+ }
+ else {
+ stm32_usb_ctrl_completed (ctrlep.rxtr.status);
+ }
+ }
+}
+
+//=============================================================================
+// Implement ISRs for low level data transfer.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// ISR for handling control endpoint interrupts.
+
+static inline cyg_bool stm32_usb_ctrlep_ISR
+ (void)
+{
+ cyg_bool completed;
+ cyg_bool call_dsr = false;
+ cyg_uint32 usb_epxr;
+
+ // Process packet transmit events.
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EP0R, usb_epxr);
+ if (usb_epxr & CYGHWR_HAL_STM32_USB_EPXR_CTRTX) {
+ stm32_usb_clear_epxr_bits (0, CYGHWR_HAL_STM32_USB_EPXR_CTRTX);
+
+ completed = stm32_usb_txtr_run (&ctrlep.txtr);
+ if (completed) {
+ isr_shared.txtr_done |= (1 << 0);
+ call_dsr = true;
+ }
+ }
+
+ // Deal with incoming setup packets. These are copied directly to the
+ // staging buffer in the ISR/DSR shared area for subsequent handling in
+ // DSR context.
+ if (usb_epxr & CYGHWR_HAL_STM32_USB_EPXR_CTRRX) {
+ stm32_usb_clear_epxr_bits (0, CYGHWR_HAL_STM32_USB_EPXR_CTRRX);
+
+ if (usb_epxr & CYGHWR_HAL_STM32_USB_EPXR_SETUP) {
+ stm32_usb_copy_from_sbuf (ctrlep.common.control_buffer, 8, 0);
+ isr_shared.flags |= ISR_FLAGS_SETUP_READY;
+ call_dsr = true;
+ }
+
+ // Handle conventional incoming packets.
+ else {
+ completed = stm32_usb_rxtr_run (&ctrlep.rxtr);
+ if (completed) {
+ isr_shared.rxtr_done |= (1 << 0);
+ call_dsr = true;
+ }
+ }
+ }
+ return call_dsr;
+}
+
+//-----------------------------------------------------------------------------
+// ISR for handling transmit endpoint interrupts.
+
+static inline cyg_bool stm32_usb_txep_ISR
+ (cyg_uint32 txep_id)
+{
+ cyg_bool completed;
+ cyg_bool call_dsr = false;
+ cyg_uint32 usb_epxr;
+ txep_impl* txep = txep_list + txep_id - 1;
+
+ // Receive events for a transmit endpoint are an error - discard them.
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (txep_id), usb_epxr);
+ if (usb_epxr & CYGHWR_HAL_STM32_USB_EPXR_CTRRX) {
+ FAIL_USB ("Received RX interrupt for TX endpoint.");
+ stm32_usb_clear_epxr_bits (txep_id, CYGHWR_HAL_STM32_USB_EPXR_CTRRX);
+ }
+
+ // Handle transmit interrupt events.
+ if (usb_epxr & CYGHWR_HAL_STM32_USB_EPXR_CTRTX) {
+ stm32_usb_clear_epxr_bits (txep_id, CYGHWR_HAL_STM32_USB_EPXR_CTRTX);
+ completed = stm32_usb_txtr_run (&txep->txtr);
+ if (completed) {
+ isr_shared.txtr_done |= (1 << txep_id);
+ call_dsr = true;
+ }
+ }
+ return call_dsr;
+}
+
+//-----------------------------------------------------------------------------
+// ISR for handling receive endpoint interrupts.
+
+static inline cyg_bool stm32_usb_rxep_ISR
+ (cyg_uint32 rxep_id)
+{
+ cyg_bool completed;
+ cyg_bool call_dsr = false;
+ cyg_uint32 usb_epxr;
+ rxep_impl* rxep = rxep_list + rxep_id - CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM - 1;
+
+ // Transmit events for a receive endpoint are an error - discard them.
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_EPXR (rxep_id), usb_epxr);
+ if (usb_epxr & CYGHWR_HAL_STM32_USB_EPXR_CTRTX) {
+ FAIL_USB ("Received TX interrupt for RX endpoint.");
+ stm32_usb_clear_epxr_bits (rxep_id, CYGHWR_HAL_STM32_USB_EPXR_CTRTX);
+ }
+
+ // Handle receive interrupt events.
+ if (usb_epxr & CYGHWR_HAL_STM32_USB_EPXR_CTRRX) {
+ stm32_usb_clear_epxr_bits (rxep_id, CYGHWR_HAL_STM32_USB_EPXR_CTRRX);
+ completed = stm32_usb_rxtr_run (&rxep->rxtr);
+ if (completed) {
+ isr_shared.rxtr_done |= (1 << rxep_id);
+ call_dsr = true;
+ }
+ }
+ return call_dsr;
+}
+
+//-----------------------------------------------------------------------------
+// Main ISR for handling interrupt events. The interrupt generation for the
+// USB endpoints is a little strange, with endpoint interrupts effectively being
+// queued through the same interrupt status register. Clearing the interrupt
+// condition has the effect of popping an endpoint interrupt from the queue so
+// that the next endpoint can be serviced. This means that serialising the
+// interrupt processing between ISR and DSR would carry an unacceptable latency
+// penalty - which is why we have to do the buffer copies within the ISR.
+
+static cyg_uint32 stm32_usb_ISR
+ (cyg_vector_t vector, cyg_addrword_t data)
+{
+ cyg_bool call_dsr = false;
+ cyg_uint32 usb_istr, ep_id;
+ cyg_uint32 ret_val = CYG_ISR_HANDLED;
+
+ // Check for device interrupts first.
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_ISTR, usb_istr);
+
+ // Detect reset event and hand it up to the DSR. Note that these will not
+ // be merged with other events for DSR processing.
+ if (usb_istr & CYGHWR_HAL_STM32_USB_ISTR_RESET) {
+ usb_istr &= ~((cyg_uint32) CYGHWR_HAL_STM32_USB_ISTR_RESET);
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_ISTR, usb_istr);
+ isr_shared.flags |= ISR_FLAGS_DEVICE_RESET;
+ call_dsr = true;
+ }
+
+ // TODO: Support for suspend and wake events can be added here if required.
+
+ // Check for endpoint interrupts. These are indicated by the CTR flag.
+ // The endpoint direction is inferred from the endpoint number, since
+ // transmit endpoints are enumerated before receive endpoints.
+ else while (usb_istr & CYGHWR_HAL_STM32_USB_ISTR_CTR) {
+ ep_id = usb_istr & CYGHWR_HAL_STM32_USB_ISTR_EPID_MASK;
+
+ // Service the control endpoint.
+ if (ep_id == 0)
+ call_dsr |= stm32_usb_ctrlep_ISR ();
+
+ // Service transmit endpoints.
+ else if (ep_id <= CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM)
+ call_dsr |= stm32_usb_txep_ISR (ep_id);
+
+ // Service receive endpoints.
+ else if (ep_id < USB_EPNUM)
+ call_dsr |= stm32_usb_rxep_ISR (ep_id);
+
+ // Invalid endpoint. Fail in debug, clear down in production builds.
+ else {
+ FAIL_USB ("Interrupt for invalid endpoint detected.");
+ stm32_usb_clear_epxr_bits (ep_id,
+ CYGHWR_HAL_STM32_USB_EPXR_CTRTX | CYGHWR_HAL_STM32_USB_EPXR_CTRRX);
+ }
+
+ // Check for all endpoints having been serviced.
+ HAL_READ_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_ISTR, usb_istr);
+ }
+
+ // If interrupt has been handled, acknowledge it and return. Leave the
+ // interrupt unmasked until the DSR is called, since intervening ISR calls
+ // will safely post their events to the event masks.
+ cyg_drv_interrupt_acknowledge (vector);
+ if (call_dsr) {
+ ret_val |= CYG_ISR_CALL_DSR;
+ }
+ return ret_val;
+}
+
+//=============================================================================
+// Implement DSRs for handling high-level interrupt responses.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Main DSR for high-level interrupt processing. Information about the
+// interrupt conditions is passed up via the ISR shared data area.
+
+static void stm32_usb_DSR
+ (cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ cyg_uint32 i;
+
+ // Disable interrupts on entry to the DSR to avoid further events getting
+ // added to the event masks.
+ stm32_usb_request_intr_mask ();
+
+ // Process device reset notifications.
+ if (isr_shared.flags & ISR_FLAGS_DEVICE_RESET) {
+ stm32_usb_ctrl_reset ();
+ }
+
+ // Process control endpoint message transmit completions.
+ if (isr_shared.txtr_done & 1) {
+ stm32_usb_ctrl_txtr_done ();
+ }
+
+ // Process control endpoint message receive completions.
+ if (isr_shared.rxtr_done & 1) {
+ stm32_usb_ctrl_rxtr_done ();
+ }
+
+ // Process non-control endpoint message transmit completions.
+ if (isr_shared.txtr_done) {
+ for (i = 1; i < 8; i++) {
+ if (isr_shared.txtr_done & (1 << i)) {
+ txep_impl* txep = txep_list + i - 1;
+ int retval = (txep->txtr.status != ENOERR) ? -txep->txtr.status : txep->txtr.bytes_sent;
+ if (txep->common.complete_fn)
+ (*txep->common.complete_fn) (txep->common.complete_data, retval);
+ if (retval < 0)
+ TRACE_USB ("TX transaction failed (endpoint %d, status %d).\n", txep->txtr.ep_num, retval);
+ }
+ }
+ }
+
+ // Process non-control endpoint message received completions.
+ if (isr_shared.rxtr_done) {
+ for (i = 1; i < 8; i++) {
+ if (isr_shared.rxtr_done & (1 << i)) {
+ rxep_impl* rxep = rxep_list + i - CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM - 1;
+ int retval = (rxep->rxtr.status != ENOERR) ? -rxep->rxtr.status : rxep->rxtr.bytes_rcvd;
+ if (rxep->common.complete_fn)
+ (*rxep->common.complete_fn) (rxep->common.complete_data, retval);
+ if (retval < 0)
+ TRACE_USB ("RX transaction failed (endpoint %d, status %d).\n", rxep->rxtr.ep_num, retval);
+ }
+ }
+ }
+
+ // Process setup packets after ensuring that all outstanding EP0 completions
+ // associated with a previous setup transaction have been dealt with.
+ if (isr_shared.flags & ISR_FLAGS_SETUP_READY) {
+ stm32_usb_ctrl_setup_handler ();
+ }
+
+ // Clear the ISR shared flags before unmasking the interrupt - they should
+ // all have been dealt with.
+ isr_shared.flags = ISR_FLAGS_CLEARED;
+ isr_shared.txtr_done = 0;
+ isr_shared.rxtr_done = 0;
+
+ // Release the interrupt mask if possible.
+ stm32_usb_release_intr_mask ();
+}
+
+//=============================================================================
+// Provide standard USB driver API entry points.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// API entry point for endpoint transmit requests.
+
+static void stm32_usb_tx_start
+ (usbs_tx_endpoint* usbs_txep)
+{
+ txep_impl* txep = (txep_impl*) usbs_txep;
+ txtr_impl* txtr = &txep->txtr;
+ cyg_int32 status = -EIO;
+
+ // Check to see whether a transaction is in progress.
+ if (txtr->state != TXTR_STATE_IDLE) {
+ FAIL_USB ("Endpoint TX request when endpoint already busy.");
+ status = -EBUSY;
+ goto out;
+ }
+
+ // Do a sanity check on the descriptor.
+ if (!txep->common.complete_fn) {
+ FAIL_USB ("Endpoint TX requires a completion function.");
+ goto out;
+ }
+ if (!txep->common.buffer) {
+ FAIL_USB ("Endpoint TX requires a valid transmit buffer.");
+ goto out;
+ }
+ if (stm32_usb_buf_get_size (txtr->ep_num) == 0) {
+ FAIL_USB ("TX request when endpoint buffers not allocated.");
+ goto out;
+ }
+
+ // Attempt to start a transmit transaction and extract error status if it
+ // completes too early. This is not an interrupt safe call.
+ txtr->buf_ptr = txep->common.buffer;
+ txtr->buf_size = (cyg_uint32) txep->common.buffer_size;
+ if (stm32_usb_txtr_start (txtr, false))
+ status = -txtr->status;
+ else
+ status = -ENOERR;
+
+ // If the transaction failed to start, fire the completion handler.
+out:
+ if ((status < 0) && (txep->common.complete_fn)) {
+ txep->common.complete_fn (txep->common.complete_data, status);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// API entry point for endpoint receive requests.
+
+static void stm32_usb_rx_start
+ (usbs_rx_endpoint* usbs_rxep)
+{
+ rxep_impl* rxep = (rxep_impl*) usbs_rxep;
+ rxtr_impl* rxtr = &rxep->rxtr;
+ cyg_int32 status = -EIO;
+
+ // Check to see whether a transaction is in progress.
+ if (rxtr->state != RXTR_STATE_IDLE) {
+ FAIL_USB ("Endpoint RX request when endpoint already busy.");
+ status = -EBUSY;
+ goto out;
+ }
+
+ // Do a sanity check on the descriptor.
+ if (!rxep->common.complete_fn) {
+ FAIL_USB ("Endpoint RX requires a completion function.");
+ goto out;
+ }
+ if (!rxep->common.buffer) {
+ FAIL_USB ("Endpoint RX requires a valid receive buffer.");
+ goto out;
+ }
+ if (stm32_usb_buf_get_size (rxtr->ep_num) == 0) {
+ FAIL_USB ("RX request when endpoint buffers not allocated.");
+ goto out;
+ }
+
+ // Attempt to start a receive transaction and extract error status if it
+ // completes too early. This is not an interrupt safe call.
+ rxtr->buf_ptr = rxep->common.buffer;
+ rxtr->buf_size = (cyg_uint32) rxep->common.buffer_size;
+ if (stm32_usb_rxtr_start (rxtr, false))
+ status = -rxtr->status;
+ else
+ status = -ENOERR;
+
+ // If the transaction failed to start, fire the completion handler.
+out:
+ if ((status < 0) && (rxep->common.complete_fn)) {
+ rxep->common.complete_fn (rxep->common.complete_data, status);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// API entry point for setting transmit endpoint halted state.
+
+static void stm32_usb_set_txep_halted
+ (usbs_tx_endpoint* txep, cyg_bool halted)
+{
+ if (halted)
+ stm32_usb_txep_halt ((txep_impl*) txep, false);
+ else
+ stm32_usb_txep_unhalt ((txep_impl*) txep, false);
+}
+
+//-----------------------------------------------------------------------------
+// API entry point for setting receive endpoint halted state.
+
+static void stm32_usb_set_rxep_halted
+ (usbs_rx_endpoint* rxep, cyg_bool halted)
+{
+ if (halted)
+ stm32_usb_rxep_halt ((rxep_impl*) rxep, false);
+ else
+ stm32_usb_rxep_unhalt ((rxep_impl*) rxep, false);
+}
+
+//=============================================================================
+// Initialise and reset the USB device.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// One-time initialisation. This function is called during device startup
+// in order to bring up the USB peripheral ready for operation.
+
+static void CYGBLD_ATTRIB_C_INIT_PRI(CYG_INIT_DEV_CHAR) cyg_usbs_cortexm_stm32_init
+ (void)
+{
+ cyg_uint32 reg_data;
+
+ // First ensure that the APB bus is being clocked fast enough.
+ ASSERT_USB (APB1_FREQ > 8000000, "APB1 must be clocked faster than 8MHz.");
+
+ // Check that the endpoint configuration is sane.
+ ASSERT_USB (CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM < 8,
+ "Too many hardware endpoints allocated in configuration.");
+
+ // Make sure that the CAN controller is disabled and held in reset.
+ // TODO: If a CAN driver is to be added to the standard distribution, this
+ // should check for USB/CAN configuration clashes.
+ CYGHWR_HAL_STM32_CLOCK_DISABLE( CYGHWR_HAL_STM32_CAN1_CLOCK );
+
+ // Configure the IO pins for USB operation.
+ CYGHWR_HAL_STM32_GPIO_SET (USB_DISC_PIN);
+ CYGHWR_HAL_STM32_GPIO_SET (USB_DP_PIN);
+ CYGHWR_HAL_STM32_GPIO_SET (USB_DM_PIN);
+#ifdef CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN_ACT_LOW
+ CYGHWR_HAL_STM32_GPIO_OUT (USB_DISC_PIN, 0);
+#else
+ CYGHWR_HAL_STM32_GPIO_OUT (USB_DISC_PIN, 1);
+#endif
+
+ // Ensure that the USB clock is disabled prior to setting prescaler.
+ CYGHWR_HAL_STM32_CLOCK_DISABLE( CYGHWR_HAL_STM32_USB_CLOCK );
+
+ // Set up the USB 48MHz serial clock. There are only 2 valid prescaler
+ // settings which correspond to 72MHz and 48MHz PLL clock outputs.
+ HAL_READ_UINT32 (CYGHWR_HAL_STM32_RCC + CYGHWR_HAL_STM32_RCC_CFGR, reg_data);
+#if (PLL_FREQ == 72000000)
+ reg_data &= ~((cyg_uint32) CYGHWR_HAL_STM32_RCC_CFGR_USBPRE);
+#elif (PLL_FREQ == 48000000)
+ reg_data |= CYGHWR_HAL_STM32_RCC_CFGR_USBPRE;
+#else
+#error "SMT32 PLL clock must be set to 48MHz or 72MHz for correct USB operation."
+#endif
+ HAL_WRITE_UINT32 (CYGHWR_HAL_STM32_RCC + CYGHWR_HAL_STM32_RCC_CFGR, reg_data);
+
+ // Activate the USB clock after setting prescaler.
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( CYGHWR_HAL_STM32_USB_CLOCK );
+
+ // Take USB transceiver out of powerdown state, but leave it in reset until we
+ // are ready to start. Leave interrupts disabled at source.
+ reg_data = CYGHWR_HAL_STM32_USB_CNTR_FRES;
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_CNTR, reg_data);
+ CYGACC_CALL_IF_DELAY_US (USB_TSTARTUP);
+
+ // Initialise interrupt mask request counter.
+ interrupt_mask_count = 0;
+
+ // Attach USB interrupts. Everything is done via the standard interrupt - the
+ // high priority interrupt is not used.
+ cyg_drv_interrupt_mask (CYGNUM_HAL_INTERRUPT_USB_HP);
+ cyg_drv_interrupt_create (CYGNUM_HAL_INTERRUPT_USB_LP, CYGNUM_DEVS_USB_CORTEXM_STM32_ISR_PRIORITY,
+ 0, stm32_usb_ISR, stm32_usb_DSR, &interrupt_handle, &interrupt_data);
+ cyg_drv_interrupt_attach (interrupt_handle);
+}
+
+//-----------------------------------------------------------------------------
+// Device endpoint 0 startup. This function is called once the application
+// code has set up the desired USB control endpoint configuration.
+
+static void stm32_usb_start
+ (usbs_control_endpoint* endpoint)
+{
+ cyg_uint32 i;
+ txep_impl* txep = txep_list;
+ rxep_impl* rxep = rxep_list;
+
+ // Fill in the generic endpoint data structures.
+ for (i = 0; i < CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM; i++) {
+ txep->common.start_tx_fn = stm32_usb_tx_start;
+ txep->common.set_halted_fn = stm32_usb_set_txep_halted;
+ txep->common.halted = true;
+ txep->txtr.state = TXTR_STATE_RESET;
+ txep->txtr.ep_num = i + 1;
+ txep++;
+ }
+ for (i = 0; i < CYGNUM_DEVS_USB_CORTEXM_STM32_RXEP_NUM; i++) {
+ rxep->common.start_rx_fn = stm32_usb_rx_start;
+ rxep->common.set_halted_fn = stm32_usb_set_rxep_halted;
+ rxep->common.halted = true;
+ rxep->rxtr.state = RXTR_STATE_RESET;
+ rxep->rxtr.ep_num = i + CYGNUM_DEVS_USB_CORTEXM_STM32_TXEP_NUM + 1;
+ rxep++;
+ }
+
+ // Take the USB driver out of reset and cancel any spurious interrupts.
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_CNTR, 0);
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_ISTR, 0);
+
+ // Enable interrupts at source.
+ HAL_WRITE_UINT32 (USB_BASE + CYGHWR_HAL_STM32_USB_CNTR,
+ CYGHWR_HAL_STM32_USB_CNTR_CTRM | CYGHWR_HAL_STM32_USB_CNTR_RESETM);
+
+ // Reconnect the device to the USB bus if required.
+#ifdef CYGHWR_DEVS_USB_CORTEXM_STM32_DISC_PIN_ACT_LOW
+ CYGHWR_HAL_STM32_GPIO_OUT (USB_DISC_PIN, 1);
+#else
+ CYGHWR_HAL_STM32_GPIO_OUT (USB_DISC_PIN, 0);
+#endif
+ stm32_usb_ctrl_update_state (USBS_STATE_POWERED, USBS_STATE_CHANGE_POWERED);
+
+ // Allow interrupts to run - the bus reset must be driven by the host.
+ cyg_drv_interrupt_unmask (CYGNUM_HAL_INTERRUPT_USB_LP);
+}
+
+//-----------------------------------------------------------------------------
+// Device endpoint 0 poll. Polled operation just calls the ISR followed by
+// the DSR. TODO: Polled operation needs further testing.
+
+static void stm32_usb_poll
+ (usbs_control_endpoint* endpoint)
+{
+ cyg_uint32 isr_retval;
+ isr_retval = stm32_usb_ISR (CYGNUM_HAL_INTERRUPT_USB_LP, 0);
+ if (isr_retval & CYG_ISR_CALL_DSR)
+ stm32_usb_DSR (CYGNUM_HAL_INTERRUPT_USB_LP, 1, 0);
+}
+
+//-----------------------------------------------------------------------------
+// Get a handle on the specified transmit (in) endpoint.
+
+static usbs_tx_endpoint* stm32_usb_get_txep
+ (usbs_control_endpoint* control_endpoint, cyg_uint8 ep_id)
+{
+ txep_impl* txep = NULL;
+
+ // Map from endpoint ID to physical endpoint.
+ if (ep_id > 0 && ep_id < 16)
+ txep = txep_map [ep_id - 1];
+
+ // Return endpoint handle or null pointer for invalid endpoint.
+ if (txep == NULL) {
+ FAIL_USB ("Invalid endpoint ID when accessing transmit (in) endpoint.");
+ return NULL;
+ }
+ return (usbs_tx_endpoint*) txep;
+}
+
+//-----------------------------------------------------------------------------
+// Get a handle on the specified receive (out) endpoint.
+
+static usbs_rx_endpoint* stm32_usb_get_rxep
+ (usbs_control_endpoint* control_endpoint, cyg_uint8 ep_id)
+{
+ rxep_impl* rxep = NULL;
+
+ // Map from endpoint ID to physical endpoint.
+ if (ep_id > 0 && ep_id < 16)
+ rxep = rxep_map [ep_id - 1];
+
+ // Return endpoint handle or null pointer for invalid endpoint.
+ if (rxep == NULL) {
+ FAIL_USB ("Invalid endpoint ID when accessing receive (out) endpoint.");
+ return NULL;
+ }
+ return (usbs_rx_endpoint*) rxep;
+}
+
+//=============================================================================
+// Instantiate the test endpoint data structures if required. This creates a
+// single endpoint of each supported type - bulk transmit, bulk receive,
+// interrupt transmit and interrupt receive.
+//=============================================================================
+
+#ifdef CYGBLD_IO_USB_SLAVE_USBTEST
+
+usbs_testing_endpoint usbs_testing_endpoints[] = {
+
+ { // Control endpoint.
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL,
+ endpoint_number : 0,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &ctrlep,
+ devtab_entry : 0,
+ min_size : 1,
+ max_size : CYGNUM_DEVS_USB_CORTEXM_STM32_EPO_MAX_MSG_SIZE,
+ max_in_padding : 0,
+ alignment : 0
+ },
+
+ { // Bulk transmit (input) endpoint.
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 1,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &txep_list[0],
+ devtab_entry : 0,
+ min_size : 0,
+ max_size : 0x1000, // 4k max for testing.
+ max_in_padding : 0,
+ alignment : 0
+ },
+
+ { // Bulk receive (output) endpoint.
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 2,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
+ endpoint : (void*) &rxep_list[0],
+ devtab_entry : 0,
+ min_size : 0,
+ max_size : 0x1000, // 4k max for testing.
+ max_in_padding : 0,
+ alignment : 0
+ },
+
+ { // Interrupt transmit (input) endpoint
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
+ endpoint_number : 3,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &txep_list[1],
+ devtab_entry : 0,
+ min_size : 0,
+ max_size : 8, // Maximum for low speed devices.
+ max_in_padding : 0,
+ alignment : 0
+ },
+
+ { // Interrupt receive (output) endpoint.
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
+ endpoint_number : 4,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
+ endpoint : (void*) &rxep_list[1],
+ devtab_entry : 0,
+ min_size : 0,
+ max_size : 8, // Maximum for low speed devices.
+ max_in_padding : 0,
+ alignment : 0
+ },
+
+ USBS_TESTING_ENDPOINTS_TERMINATOR
+};
+
+#endif
+
+//=============================================================================
diff --git a/ecos/packages/devs/usb/d12/current/ChangeLog b/ecos/packages/devs/usb/d12/current/ChangeLog
new file mode 100644
index 0000000..aeeca78
--- /dev/null
+++ b/ecos/packages/devs/usb/d12/current/ChangeLog
@@ -0,0 +1,27 @@
+2006-06-06 Frank Pagliughi <fpagliughi@mindspring.com>
+
+ * First version of the USB device driver for the philips D12
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/usb/d12/current/cdl/usbs_d12.cdl b/ecos/packages/devs/usb/d12/current/cdl/usbs_d12.cdl
new file mode 100644
index 0000000..2065b12
--- /dev/null
+++ b/ecos/packages/devs/usb/d12/current/cdl/usbs_d12.cdl
@@ -0,0 +1,318 @@
+# ====================================================================
+#
+# usbs_d12.cdl
+#
+# USB device driver for the Philips PDIUSBD12 Full Speed USB
+# peripheral chip.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Frank M. Pagliughi (fmp), SoRo Systems, Inc.
+# Contributors:
+# Date: 2004-05-24
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_USB_D12 {
+ display "Philips D12 USB Device Driver"
+ include_dir "cyg/io/usb"
+ parent CYGPKG_USB
+ implements CYGHWR_IO_USB_SLAVE
+ doc ref/devs-usb-philips-pdiusbd12.html
+
+ description "
+ The Philips PDIUSBD12 is a USB peripheral controller (slave)
+ chip that can connect to a microcontroller or microprocessor
+ through an 8-bit parallel bus. The SoRo Systems USB-D12-104 is
+ a slave board for the PC's ISA or PC/104 bus that contains a
+ D12 chip placed in the PC's I/O space with jumpered selections
+ for IRQ and DMA settings. This package provides an eCos device
+ driver."
+
+ requires CYGIMP_DEVS_USB_D12_HW_ACCESS_HEADER
+
+ cdl_option CYGIMP_DEVS_USB_D12_HW_ACCESS_HEADER {
+ display "Inline file implementing hardware access"
+ flavor booldata
+ default_value false
+ description "
+ This option should contain the header file which
+ implements basic access to the D12 registers"
+ }
+
+ cdl_component CYGFUN_DEVS_USB_D12_EP0 {
+ display "Support the Control Endpoint 0"
+ default_value CYGINT_IO_USB_SLAVE_CLIENTS
+ requires CYGPKG_IO_USB CYGPKG_IO_USB_SLAVE
+ compile usbs_d12.c
+ compile -library=libextras.a usbs_d12_data.cxx
+ description "
+ Enable support for endpoint 0. If this support is disabled
+ then the entire USB port is unusable."
+
+ cdl_option CYGVAR_DEVS_USB_D12_EP0_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 0"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If endpoint 0 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and ioctl calls then a devtab entry is needed.
+ "
+ }
+ cdl_option CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE {
+ display "Size of statically-allocated endpoint 0 transmit buffer"
+ flavor data
+ default_value 256
+ requires { CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE >=
+ CYGNUM_DEVS_USB_D12_EP0_PKTSIZE }
+ description "
+ The implementation of the support for endpoint 0 uses
+ a single static buffer to hold the response to the
+ current control message. Typically this buffer can be
+ fairly small since replies to control messages tend to
+ be small: typically some tens of bytes for the enumeration
+ data, perhaps a bit more for unicode-encoded string
+ descriptors. However if some application-specific protocol
+ depends on larger control messages then this buffer
+ size may need to be increased."
+ }
+ }
+
+ cdl_option CYGNUM_DEVS_USB_D12_BASEADDR {
+ display "Base Address of D12 chip"
+ flavor data
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ description "
+ The base memory or I/O address where the USB chip resides.
+ The value is set by the hardware specific driver's CDL."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_D12_IRQ {
+ display "IRQ for the D12 chip"
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ flavor data
+ description "
+ The IRQ assigned to the D12 chip. The value
+ is set by the hardware specific drivers's CDL."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_D12_INT {
+ display "INT for the D12 chip"
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ flavor data
+ default_value { CYGNUM_DEVS_USB_D12_IRQ + 32 }
+ description "
+ The interrupt vector assigned to the D12 chip."
+ }
+
+ cdl_component CYGPKG_DEVS_USB_D12_THREAD {
+ display "Use a thread to service D12 chip"
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ default_value 0
+ description "
+ Services the D12 USB chip with a thread, rather than at
+ the DSR level. This allows for increased debug support,
+ like TRACE output from the driver at the expense of some
+ throughput & reaction time. The service thread MUST be at
+ a higher priority than any application thread that uses
+ the USB port. "
+
+ cdl_option CYGNUM_DEVS_USB_D12_THREAD_PRIORITY {
+ display "Thread Priority"
+ flavor data
+ legal_values 1 to 30
+ default_value 4
+ description "
+ The priority of the D12 device driver thread."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_D12_THREAD_STACK_SIZE {
+ display "USB Thread Stack Size"
+ flavor data
+ default_value 4096
+ description "
+ The stack size for the D12 device driver thread."
+ }
+ }
+
+ cdl_component CYGFUN_DEVS_USB_D12_DEBUG {
+ display "Debug output from the D12 Device Driver"
+ requires CYGPKG_DEVS_USB_D12_THREAD
+ default_value 0
+ description "
+ Provide debugging output from the D12 Device Driver"
+
+ cdl_option CYGSEM_DEVS_USB_D12_DEBUG_DUMP_EP0_BUFS {
+ display "Dump the contents of EP0 buffers"
+ flavor bool
+ default_value 0
+ description "
+
+ Dump the contents of the packages going through
+ EP0. This allows you to see things like device
+ requests and responses."
+ }
+
+ cdl_option CYGSEM_DEVS_USB_D12_DEBUG_DUMP_BUFS {
+ display "Dump the contents of data buffers"
+ flavor bool
+ default_value 0
+ description "
+ Dump the contents of the packages going through the generic
+ endpoints. This allow you to see all of the data going through
+ the device."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_D12_TX_EP1 {
+ display "Endpoint 1 Interrupt IN, (tx_ep1)"
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ requires CYGFUN_DEVS_USB_D12_EP0
+ default_value CYGFUN_DEVS_USB_D12_EP0
+ description "
+ On the D12, Endpoint 1 IN can be used for Interrupt,
+ Bulk, or Control packages. This driver currently only supports
+ Interrupt packages on Endpoint 1 (slave -> host) transfers."
+
+ cdl_option CYGVAR_DEVS_USB_D12_TX_EP1_DEVTAB_ENTRY {
+ display "Provide a devtab entry for Endpoint 1 IN"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If Endpoint 1 IN will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_D12_RX_EP1 {
+ display "Endpoint 1 Interrupt OUT, (rx_ep1)"
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ requires CYGFUN_DEVS_USB_D12_EP0
+ default_value CYGFUN_DEVS_USB_D12_EP0
+ description "
+ In the D12, Endpoint 1 OUT can be used for Interrupt,
+ Bulk, or Control packages. This driver currently only supports
+ Interrupt packages on Endpoint 1 for (host -> slave) transfers"
+
+ cdl_option CYGVAR_DEVS_USB_D12_RX_EP1_DEVTAB_ENTRY {
+ display "Provide a devtab entry for Endpoint 1 OUT"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If Endpoint 1 OUT will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_D12_TX_EP2 {
+ display "Endpoint 2 Bulk IN, (tx_ep2)"
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ requires CYGFUN_DEVS_USB_D12_EP0
+ default_value CYGFUN_DEVS_USB_D12_EP0
+ description "
+ In the D12, Endpoint 2 IN can be used for Bulk, Interrupt,
+ or Control packages. This driver currently only supports
+ Bulk packages on Endpoint 2 for (slave -> host) transfers."
+
+ cdl_option CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY {
+ display "Provide a devtab entry for Endpoint 2 IN"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If Endpoint 2 IN will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_D12_RX_EP2 {
+ display "Endpoint 2 Bulk OUT, (rx_ep2)"
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ requires CYGFUN_DEVS_USB_D12_EP0
+ default_value CYGFUN_DEVS_USB_D12_EP0
+ description "
+ In the D12, Endpoint 2 OUT can be used for Bulk, Interrupt,
+ Control packages. This driver currently only supports
+ Bulk packages on Endpoint 2 for (host -> slave) transfers."
+
+ cdl_option CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY {
+ display "Provide a devtab entry for Endpoint 2 OUT"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If Endpoint 2 OUT will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed."
+ }
+ }
+
+ cdl_option CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME {
+ display "Base name for devtab entries"
+ flavor data
+ active_if { CYGVAR_DEVS_USB_D12_EP0_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_D12_TX_EP1_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_D12_RX_EP1_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY }
+ default_value { "\"/dev/usbs\"" }
+ description "
+ If the D12 USB device driver package provides devtab entries
+ for any of the endpoints then this option gives
+ control over the names of these entries. By default the
+ endpoints will be called \"/dev/usbs0c\", \"/dev/usbs1r\"
+ \"/dev/usbs1w\", \"/dev/usbs2r\", \"/dev/usbs2w\"
+ (assuming those endpoints are all enabled. The common
+ part \"/dev/usbs\" is determined by this configuration
+ option. It may be necessary to change this if there are
+ multiple USB slave-side devices on the target hardware to
+ prevent a name clash."
+ }
+}
+
diff --git a/ecos/packages/devs/usb/d12/current/include/usbs_d12.h b/ecos/packages/devs/usb/d12/current/include/usbs_d12.h
new file mode 100644
index 0000000..3758450
--- /dev/null
+++ b/ecos/packages/devs/usb/d12/current/include/usbs_d12.h
@@ -0,0 +1,74 @@
+#ifndef CYGONCE_USBS_D12_H
+#define CYGONCE_USBS_D12_H
+//==========================================================================
+//
+// include/usbs_d12.h
+//
+// The interface exported by the D12 USB device driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Frank Pagliughi (fmp)
+// Contributors: fmp
+// Date: 2004-05-24
+// Purpose:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/io/usb/usbs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The Philips D12 is a full speed (12Mbps) USB peripheral controller
+ * chip, with a parallel interface allowing it to be connected to nearly
+ * any microcontroller or microprocessor.
+ */
+extern usbs_control_endpoint usbs_d12_ep0;
+
+extern usbs_rx_endpoint usbs_d12_rx_ep1;
+extern usbs_tx_endpoint usbs_d12_tx_ep1;
+extern usbs_rx_endpoint usbs_d12_rx_ep2;
+extern usbs_tx_endpoint usbs_d12_tx_ep2;
+
+#ifdef __cplusplus
+} /* extern "C" { */
+#endif
+
+#endif /* CYGONCE_USBS_D12_H */
diff --git a/ecos/packages/devs/usb/d12/current/src/usbs_d12.c b/ecos/packages/devs/usb/d12/current/src/usbs_d12.c
new file mode 100644
index 0000000..f353cd9
--- /dev/null
+++ b/ecos/packages/devs/usb/d12/current/src/usbs_d12.c
@@ -0,0 +1,2323 @@
+//==========================================================================
+//
+// usbs_d12.c
+//
+// Driver for the D12 USB Slave Board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Frank M. Pagliughi (fmp)
+// Date: 2004-05-22
+//
+// This code is a device driver for the SoRo Systems USB-D12-104, a PC/104
+// (ISA) Full-Speed USB slave board, which turns a PC/104 stack into a USB
+// slave device. The board contains a Philips PDIUSBD12 Peripheral Controller
+// Chip mapped into the PC's I/O space, with jumper-selectable I/O base
+// address, IRQ, and DMA settings. The eCos config tool is used to adjust
+// settings for this driver to match the physical jumper settings. The chip
+// could run in polled mode without an IRQ, but this wouldn't be a great idea
+// other than maybe a debug environment.
+//
+// The board supports DMA transfers over the Main endpoint, but I temporarily
+// removed that code to make the driver portable to other platforms.
+//
+// *** This driver should also work with the Philips ISA Eval Board
+// for the D12, but I couldn't get one of them from Philips, so
+// I couldn't test it.
+//
+// The D12 uses an indexed register set, which it describes as "commands."
+// You first write a command (index) to the command register then you can
+// read or write data to that register. Each multi-byte command read or write
+// must be dione atomically, so all access to the chip must be serialized.
+//
+// The D12 requests service through a single interrupt. The driver can
+// be configured to service the chip through a DSR or a thread. In either
+// case, the "service" code assumes it has unfettered access to the chip.
+// The interrupt, therefore never touches the chip. It just schedules the
+// DSR or service thread.
+// Currently, the code gets exclusive access to the chip by locking the
+// scheduler. This is suboptimal (locking the whole OS to touch one I/O
+// chip), and better method should be explored.
+//
+// This version of the driver does not support Isocronous transfers.
+//
+// Additional notes on the D12:
+//
+// - The D12 has 4 endpoints (2 IN, and 2 OUT) in addition to the main
+// control endpoint:
+// - Endp 0 (Control In & Out, 16 byte buffer)
+// - Endp 1 (IN & OUT, Bulk or Interrupt, 16 byte ea)
+// - Endp 2 (IN and/or OUT, Bulk, Interrupt, or Isoc, 64 bytes ea)
+//
+// - The "main" endpoint (as Philips calls it) is Endp 2. It's double
+// buffered and has a DMA interface, and thus, is suited for high
+// throughput. For applications that perform either Isoc In or Out,
+// the buffers for Endp 2 can be combined for a 128 byte space.
+// This driver, however, currently does not support this.
+//
+// - There may be a flaw in the double buffering of the rx main endpoint.
+// According to the documentation it should be invisible to the software,
+// but if both buffers fill (on an rx/OUT), they must both be read
+// together, otherwise it appears that the buffers/packets are returned
+// in reverse order. ReadMainEndpointBuf() returns the data properly.
+//
+// - All the interrupt sources on the chip - individual endpoints, bus reset,
+// suspend, and DMA - are OR'ed together and can be checked via the
+// interrupt status register. When using edge-sensitive interrupts, as
+// we do here, the ISR/DSR must be sure all interrupts are cleared before
+// returning otherwise no new interrupts will be latched.
+//
+// - If the DMA controller is not used for the Main Endpoint, you MUST enable
+// the main endpoint interrupts in the DMA register (bits 6 & 7).
+// Personally, I think this should be the default at reset, to make it
+// compatible with the other endpoints, but Philips didn't see it that
+// way.
+//
+// - When a Setup (Device Request) packet arrives in the control endpoint, a
+// bit is set in the endpoint's status register indicating the packet is
+// setup and not data. By the USB standard, a setup packet can not be
+// NAK'ed or STALL'ed, so when the chip receives a setup packet, it
+// flushes the Ctrl (EP0) IN buffer and disables the Validate and Clear
+// Buffer commands. We must send an "acknowledge setup" to both
+// EP0 IN and OUT before a Validate or Clear Buffer command is effective.
+// See ReadSetupPacket().
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/diag.h>
+
+#include <pkgconf/devs_usb_d12.h>
+
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/error/codes.h>
+
+#include <cyg/io/usb/usb.h>
+#include <cyg/io/usb/usbs.h>
+
+#include <string.h>
+
+// --------------------------------------------------------------------------
+// Common Types
+// --------------------------------------------------------------------------
+
+typedef cyg_uint8 byte;
+typedef cyg_uint8 uint8;
+typedef cyg_int16 int16;
+typedef cyg_uint16 uint16;
+typedef cyg_int32 int32;
+typedef cyg_uint32 uint32;
+
+// --------------------------------------------------------------------------
+// Tracing & Debug
+// --------------------------------------------------------------------------
+// If the driver is configured to use a thread to service the chip, then it
+// can also be configured to dump a lot of debug output.
+// Care must be taken that USB timing requirements are not violated by
+// dumping debug info. If the data is sent to a serial port, it should use
+// a hardware driver and have a large output buffer (115200 baud & 2kB
+// buffer works for me).
+
+#if defined(CYGFUN_DEVS_USB_D12_DEBUG) && CYGFUN_DEVS_USB_D12_DEBUG
+#define TRACE_D12 diag_printf
+#else
+#define TRACE_D12 (1) ? (void)0 : diag_printf
+#endif
+
+#if defined(CYGSEM_DEVS_USB_D12_DEBUG_DUMP_EP0_BUFS) && CYGSEM_DEVS_USB_D12_DEBUG_DUMP_EP0_BUFS
+#define TRACE_EP0 1
+#endif
+
+#if defined(CYGSEM_DEVS_USB_D12_DEBUG_DUMP_BUFS) && CYGSEM_DEVS_USB_D12_DEBUG_DUMP_BUFS
+#define TRACE_EP 1
+#endif
+
+#if defined(TRACE_EP0) || defined(TRACE_EP)
+static void _trace_buf(const char *hdr, const byte* buf, unsigned n)
+{
+ unsigned i;
+
+ if (buf != 0 && n != 0) {
+ if (hdr && hdr[0])
+ TRACE_D12("%s ", hdr);
+
+ TRACE_D12("[");
+ for (i=0; i<n; i++)
+ TRACE_D12(" x%02X", buf[i]);
+ TRACE_D12("]\n");
+ }
+}
+#endif
+
+#if defined(TRACE_EP0)
+#define TRACE_BUF0 _trace_buf
+#else
+#define TRACE_BUF0(hdr, buf, n)
+#endif
+
+#if defined(TRACE_EP)
+#define TRACE_BUF _trace_buf
+#else
+#define TRACE_BUF(hdr, buf, n)
+#endif
+
+// ==========================================================================
+// Chip Wrapper
+// ==========================================================================
+
+// This section contains functions that wrapper the low-level access to the
+// chip. There's a function around each register access on the chip, and then
+// some.
+
+#if defined(CYGSEM_DEVS_USB_D12_IO_MAPPED)
+typedef void* d12_addr_type;
+#else
+typedef byte* d12_addr_type;
+#endif
+
+#define D12_BASE_ADDR ((d12_addr_type) CYGNUM_DEVS_USB_D12_BASEADDR)
+
+#define D12_ENDP0_SIZE 16 // Size of Ctrl Endp
+#define D12_MAIN_ENDP 2 // The D12's "Main" Endp is special, double buffered
+#define D12_MAIN_ENDP_SIZE 64 // Size of each main endp buffer
+#define D12_MAX_PACKET_SIZE 128 // Max packet is actually double main endp
+
+#define D12_CHIP_ID 0x1012 // Value that's returned by a read of
+ //the D12's Chip ID register
+
+// ----- Endpoint Indices -----
+
+enum {
+ D12_ENDP_INVALID = 0xFF,
+ D12_ENDP_MIN = 0,
+
+ D12_RX_CTRL_ENDP = D12_ENDP_MIN, // Rx/Tx Nomenclature
+ D12_TX_CTRL_ENDP,
+
+ D12_RX_ENDP0 = D12_ENDP_MIN,
+ D12_TX_ENDP0,
+ D12_RX_ENDP1,
+ D12_TX_ENDP1,
+ D12_RX_ENDP2,
+ D12_TX_ENDP2,
+ D12_RX_MAIN_ENDP = D12_RX_ENDP2,
+ D12_TX_MAIN_ENDP = D12_TX_ENDP2,
+
+
+ D12_CTRL_ENDP_OUT = D12_ENDP_MIN, // IN/OUT Nomenclature
+ D12_CTRL_ENDP_IN,
+
+ D12_ENDP0_OUT = D12_ENDP_MIN,
+ D12_ENDP0_IN,
+ D12_ENDP1_OUT,
+ D12_ENDP1_IN,
+ D12_ENDP2_OUT,
+ D12_ENDP2_IN,
+ D12_MAIN_ENDP_OUT = D12_ENDP2_OUT,
+ D12_MAIN_ENDP_IN = D12_ENDP2_IN,
+
+ D12_ENDP_INSERT_BEFORE,
+ D12_ENDP_MAX = D12_ENDP_INSERT_BEFORE-1
+};
+
+// ----- Set Mode Reg configuration byte -----
+
+enum {
+ D12_MODE_CFG_NO_LAZYCLOCK = 0x02,
+ D12_MODE_CFG_CLOCK_RUNNING = 0x04,
+ D12_MODE_CFG_INTERRUPT = 0x08,
+ D12_MODE_CFG_SOFT_CONNECT = 0x10,
+
+ D12_MODE_CFG_NON_ISO = 0x00,
+ D12_MODE_CFG_ISO_OUT = 0x40,
+ D12_MODE_CFG_ISO_IN = 0x80,
+ D12_MODE_CFG_ISO_IO = 0xC0,
+
+ D12_MODE_CFG_DFLT = (D12_MODE_CFG_NO_LAZYCLOCK |
+ D12_MODE_CFG_CLOCK_RUNNING |
+ D12_MODE_CFG_NON_ISO)
+};
+
+// ----- Set Mode Reg clock div factor -----
+
+enum {
+ D12_MODE_CLK_24_MHZ = 1,
+ D12_MODE_CLK_16_MHZ = 2,
+ D12_MODE_CLK_12_MHZ = 3,
+ D12_MODE_CLK_8_MHZ = 5,
+ D12_MODE_CLK_6_MHZ = 7,
+ D12_MODE_CLK_4_MHZ = 11,
+
+ D12_MODE_CLK_DIV_MASK = 0x0F,
+
+ D12_MODE_CLK_SET_TO_ONE = 0x40,
+ D12_MODE_CLK_SOF_ONLY_INTR = 0x80,
+
+ D12_MODE_CLK_DFLT = (D12_MODE_CLK_4_MHZ |
+ D12_MODE_CLK_SET_TO_ONE)
+};
+
+// ----- Set DMA Register -----
+
+enum {
+ D12_DMA_SINGLE_CYCLE,
+ D12_DMA_BURST_4_CYCLE,
+ D12_DMA_BURST_8_CYCLE,
+ D12_DMA_BURST_16_CYCLE,
+
+ D12_DMA_ENABLE = 0x04,
+ D12_DMA_DIR_WRITE = 0x08,
+ D12_DMA_DIR_READ = 0x00,
+ D12_DMA_AUTO_RELOAD = 0x10,
+ D12_DMA_INTR_PIN_MODE = 0x20,
+
+ D12_DMA_MAIN_ENDP_OUT_INTR_ENABLE = 0x40,
+ D12_DMA_MAIN_RX_ENDP_INTR_ENABLE = 0x40,
+
+ D12_DMA_MAIN_ENDP_IN_INTR_ENABLE = 0x80,
+ D12_DMA_MAIN_TX_ENDP_INTR_ENABLE = 0x80,
+
+ D12_DMA_MAIN_ENDP_INTR_ENABLE = 0xC0 // Enables IN & OUT Intr
+};
+
+// ----- Interrupt Register Bits -----
+
+enum {
+ D12_INTR_RX_CTRL_ENDP = 0x0001,
+ D12_INTR_TX_CTRL_ENDP = 0x0002,
+
+ D12_INTR_RX_ENDP0 = D12_INTR_RX_CTRL_ENDP,
+ D12_INTR_TX_ENDP0 = D12_INTR_TX_CTRL_ENDP,
+ D12_INTR_RX_ENDP1 = 0x0004,
+ D12_INTR_TX_ENDP1 = 0x0008,
+ D12_INTR_RX_ENDP2 = 0x0010,
+ D12_INTR_TX_ENDP2 = 0x0020,
+
+ D12_INTR_BUS_RESET = 0x0040,
+ D12_INTR_SUSPEND_CHANGE = 0x0080,
+ D12_INTR_DMA_EOT = 0x0100
+};
+
+// ----- Read Endpoint Status -----
+
+enum {
+ D12_ENDP_STAT_SETUP_PACKET = 0x04,
+ D12_ENDP_STAT_BUF0_FULL = 0x20,
+ D12_ENDP_STAT_BUF1_FULL = 0x40,
+ D12_ENDP_STAT_ANY_BUF_FULL = 0x60,
+ D12_ENDP_STAT_BOTH_BUF_FULL = 0x60,
+ D12_ENDP_STAT_STALL = 0x80,
+};
+
+// ----- Last Transaction Status Bits -----
+
+enum {
+ D12_LAST_TRANS_DATA_SUCCESS = 0x01,
+ D12_LAST_TRANS_ERR_CODE_MASK = 0x1E,
+ D12_LAST_TRANS_SETUP_PACKET = 0x20,
+ D12_LAST_TRANS_DATA1_PACKET = 0x40,
+ D12_LAST_TRANS_PREV_STAT_NOT_READ = 0x80
+};
+
+static const byte RX_ENDP_INDEX[] =
+ { D12_RX_ENDP0, D12_RX_ENDP1, D12_RX_ENDP2 };
+static const byte TX_ENDP_INDEX[] =
+ { D12_TX_ENDP0, D12_TX_ENDP1, D12_TX_ENDP2 };
+
+static const int RX_ENDP_SIZE[] = { 16, 16, 64 };
+static const int TX_ENDP_SIZE[] = { 16, 16, 64 };
+
+typedef void (*completion_fn)(void*, int);
+
+#ifndef USB_SETUP_PACKET_LEN
+#define USB_SETUP_PACKET_LEN 8
+#endif
+
+// ----- Command Definitions -----
+
+enum {
+ CMD_SET_ADDR_EN = 0xD0, // Write 1 byte
+ CMD_SET_ENDP_EN = 0xD8, // Write 1 byte
+ CMD_SET_MODE = 0xF3, // Write 2 bytes
+ CMD_SET_DMA = 0xFB, // Write/Read 1 byte
+ CMD_READ_INTR_REG = 0xF4, // Read 2 bytes
+ CMD_SEL_ENDP = 0x00, // (+ Endp Index) Read 1 byte (opt)
+ CMD_READ_LAST_TRANS_STAT = 0x40, // (+ Endp Index) Read 1 byte (opt)
+ CMD_READ_ENDP_STAT = 0x80, // (+ Endp Index) Read 1 byte
+ CMD_READ_BUF = 0xF0, // Read n bytes
+ CMD_WRITE_BUF = 0xF0, // Write n bytes
+ CMD_SET_ENDP_STAT = 0x40, // (+ Endp Index) Write 1 byte
+ CMD_ACK_SETUP = 0xF1, // None
+ CMD_CLEAR_BUF = 0xF2, // None
+ CMD_VALIDATE_BUF = 0xFA, // None
+ CMD_SEND_RESUME = 0xF6, // None
+ CMD_READ_CURR_FRAME_NUM = 0xF5, // Read 1 or 2 bytes
+ CMD_READ_CHIP_ID = 0xFD // Read 2 bytes
+};
+
+// ----- Set Endpoint Enable Register -----
+
+enum {
+ ENDP_DISABLE,
+ ENDP_ENABLE
+};
+
+// ----- Select Endpoint Results -----
+
+enum {
+ SEL_ENDP_FULL = 0x01,
+ SEL_ENDP_STALL = 0x02
+};
+
+// ----- Error Codes from ReadLastTrans (need to be bit shifter) -----
+
+enum {
+ ERROR_NO_ERROR,
+ ERROR_PID_ENCODING,
+ ERROR_PID_UNKNOWN,
+ ERROR_UNEXPECTED_PACKET,
+ ERROR_TOKEN_CRC,
+ ERROR_DATA_CRC,
+ ERROR_TIMEOUT,
+ ERROR_BABBLE,
+ ERROR_UNEXPECTED_EOP,
+ ERROR_NAK,
+ ERROR_PACKET_ON_STALL,
+ ERROR_OVERFLOW,
+ ERROR_BITSTUFF,
+ ERROR_WRONG_DATA_PID
+};
+
+// ------------------------------------------------------------------------
+// Routines to access the D12 registers. The hardware specific driver
+// provides 8bit access functions and block access functions.
+
+#include CYGIMP_DEVS_USB_D12_HW_ACCESS_HEADER
+
+
+static inline uint16
+make_word(byte hi, byte lo)
+{
+ return ((uint16) hi << 8) | lo;
+}
+
+// These routines read or write 16 bit values to the data area.
+
+static inline uint16
+d12_read_data_word(d12_addr_type base_addr)
+{
+ uint16 val = d12_read_data_byte(base_addr);
+ val |= ((uint16) d12_read_data_byte(base_addr)) << 8;
+ return val;
+}
+
+static inline void
+d12_write_data_word(d12_addr_type base_addr, uint16 val)
+{
+ d12_write_data_byte(base_addr, (byte) val);
+ d12_write_data_byte(base_addr, (byte) (val >> 8));
+}
+
+// ------------------------------------------------------------------------
+// Command & Data I/O
+// ------------------------------------------------------------------------
+//
+// These routines read & write the registers in the D12. The procedure is
+// to write a register/command value to the command address (A0=1) then
+// read or write any required data a byte at a time to the data address
+// (A0=0). The data can be one byte or two. If two, the low byte is read/
+// written first.
+
+// NOTE: These MUST be atomic operations. It's up to the caller
+// to insure this.
+
+// The hardware specific driver provides the basic access function.
+//
+
+static inline void
+d12_write_byte(d12_addr_type base_addr, byte cmd, byte val)
+{
+ d12_write_cmd(base_addr, cmd);
+ d12_write_data_byte(base_addr, val);
+}
+
+static inline void
+d12_write_word(d12_addr_type base_addr, byte cmd, uint16 val)
+{
+ d12_write_cmd(base_addr, cmd);
+ d12_write_data_word(base_addr, val);
+}
+
+static inline byte
+d12_read_byte(d12_addr_type base_addr, byte cmd)
+{
+ d12_write_cmd(base_addr, cmd);
+ return d12_read_data_byte(base_addr);
+}
+
+static inline uint16
+d12_read_word(d12_addr_type base_addr, byte cmd)
+{
+ d12_write_cmd(base_addr, cmd);
+ return d12_read_data_word(base_addr);
+}
+
+// ------------------------------------------------------------------------
+// Higher Level Commands
+// ------------------------------------------------------------------------
+
+// Stalls or Unstalls the endpoint. Bit0=1 for stall, =0 to unstall.
+
+static inline void
+d12_set_endp_status(d12_addr_type base_addr, byte endp_idx, byte stat)
+{
+ d12_write_byte(base_addr, CMD_SET_ENDP_STAT + endp_idx, stat);
+}
+
+// ------------------------------------------------------------------------
+// Stalls the control endpoint (both in & out).
+
+static void
+d12_stall_ctrl_endp(d12_addr_type base_addr, bool stall)
+{
+ d12_set_endp_status(base_addr, D12_TX_CTRL_ENDP, stall ? 1 : 0);
+ d12_set_endp_status(base_addr, D12_RX_CTRL_ENDP, stall ? 1 : 0);
+}
+
+// ------------------------------------------------------------------------
+// Stalls/unstalls the specified endpoint.
+
+void inline
+d12_stall_endp(d12_addr_type base_addr, byte endp_idx, bool stall)
+{
+ d12_set_endp_status(base_addr, endp_idx, stall ? 1 : 0);
+}
+
+// ------------------------------------------------------------------------ */
+// Tells the chip that the selected endpoint buffer has been completely
+// read. This should be called after the application reads all the data
+// from an endpoint. While there's data in the buffer the chip will
+// automatically NAK any additional OUT packets from the host.
+
+static inline void
+d12_clear_buffer(d12_addr_type base_addr)
+{
+ d12_write_cmd(base_addr, CMD_CLEAR_BUF);
+}
+
+// ------------------------------------------------------------------------
+// Tells the chip that the data in the selected endpoint buffer is complete
+// and ready to be sent to the host.
+
+static inline void
+d12_validate_buffer(d12_addr_type base_addr)
+{
+ d12_write_cmd(base_addr, CMD_VALIDATE_BUF);
+}
+
+// ------------------------------------------------------------------------
+// Sends an upstream resume signal for 10ms. This command is normally
+// issued when the device is in suspend.
+
+static inline void
+d12_send_resume(d12_addr_type base_addr)
+{
+ d12_write_cmd(base_addr, CMD_SEND_RESUME);
+}
+
+// ------------------------------------------------------------------------
+// Gets the frame number of the last successfully received
+// start-of-frame (SOF).
+
+static inline uint16
+d12_read_curr_frame_num(d12_addr_type base_addr)
+{
+ return d12_read_word(base_addr, CMD_READ_CURR_FRAME_NUM);
+}
+
+// ------------------------------------------------------------------------
+// This routine acknowledges a setup packet by writing an Ack Setup command
+// to the currently selected Endpoint. This must be done for both EP0 out
+// and EP0 IN whenever a setup packet is received.
+
+static inline void
+d12_ack_setup(d12_addr_type base_addr)
+{
+ d12_write_cmd(base_addr, CMD_ACK_SETUP);
+}
+
+// ------------------------------------------------------------------------
+// Gets the value of the 16-bit interrupt register, which indicates the
+// source of an interrupt (if interrupts are not used, this reg can be
+// polled to find when service is required).
+
+static inline uint16
+d12_read_intr_reg(d12_addr_type base_addr)
+{
+ return d12_read_word(base_addr, CMD_READ_INTR_REG) & 0x01FF;
+}
+
+// ------------------------------------------------------------------------
+// Gets/Sets the contents of the DMA register.
+
+static inline byte
+d12_get_dma(d12_addr_type base_addr)
+{
+ return d12_read_byte(base_addr, CMD_SET_DMA);
+}
+
+static inline void
+d12_set_dma(d12_addr_type base_addr, byte mode)
+{
+ d12_write_byte(base_addr, CMD_SET_DMA, mode);
+}
+
+// ------------------------------------------------------------------------
+// Sends the "Select Endpoint" command (0x00 - 0x0D) to the chip.
+// This command initializes an internal pointer to the start of the
+// selected buffer.
+//
+// Returns: Bitfield containing status of the endpoint
+
+static byte
+d12_select_endp(d12_addr_type base_addr, byte endp_idx)
+{
+ return d12_read_byte(base_addr, CMD_SEL_ENDP + endp_idx);
+}
+
+// ------------------------------------------------------------------------
+// Gets the status of the last transaction of the endpoint. It also resets
+// the corresponding interrupt flag in the interrupt register, and clears
+// the status, indicating that it was read.
+//
+// Returns: Bitfield containing the last transaction status.
+
+static inline byte
+d12_read_last_trans_status(d12_addr_type base_addr, byte endp_idx)
+{
+ return d12_read_byte(base_addr, CMD_READ_LAST_TRANS_STAT + endp_idx);
+}
+
+// ------------------------------------------------------------------------
+// Reads the status of the requested endpoint.
+// Just for the heck of it, we mask off the reserved bits.
+//
+// Returns: Bitfield containing the endpoint status.
+
+static inline byte
+d12_read_endp_status(d12_addr_type base_addr, byte endp_idx)
+{
+ return d12_read_byte(base_addr, CMD_READ_ENDP_STAT + endp_idx) & 0xE4;
+}
+
+// ------------------------------------------------------------------------
+// Returns true if there is data available in the specified endpoint's
+// ram buffer. This is determined by the buf full flags in the endp status
+// register.
+
+static inline bool
+d12_data_available(d12_addr_type base_addr, byte endp_idx)
+{
+ byte by = d12_read_endp_status(base_addr, endp_idx);
+ return (bool) (by & D12_ENDP_STAT_ANY_BUF_FULL);
+}
+
+// ------------------------------------------------------------------------
+// Clears the transaction status for each of the endpoints by calling the
+// d12_read_last_trans_status() function for each.
+
+static void
+d12_clear_all_intr(d12_addr_type base_addr)
+{
+ uint8 endp;
+
+ d12_read_intr_reg(base_addr);
+
+ for (endp=D12_ENDP_MIN; endp<=D12_ENDP_MAX; ++endp)
+ d12_read_last_trans_status(base_addr, endp);
+}
+
+// ------------------------------------------------------------------------
+// Loads a value into the Set Address / Enable register. This sets the
+// device's USB address (lower 7 bits) and enables/disables the function
+// (msb).
+
+static void
+d12_set_addr_enable(d12_addr_type base_addr, byte usb_addr, bool enable)
+{
+ if (enable)
+ usb_addr |= 0x80;
+
+ d12_write_byte(base_addr, CMD_SET_ADDR_EN, usb_addr);
+}
+
+// ------------------------------------------------------------------------
+// Enables/disables the generic endpoints.
+
+static inline void
+d12_set_endp_enable(d12_addr_type base_addr, bool enable)
+{
+ d12_write_byte(base_addr, CMD_SET_ENDP_EN,
+ (enable) ? ENDP_ENABLE : ENDP_DISABLE);
+}
+
+// ------------------------------------------------------------------------
+// Sets the device's configuration and CLKOUT frequency.
+
+static void
+d12_set_mode(d12_addr_type base_addr, byte config, byte clk_div)
+{
+ uint16 w = make_word(clk_div, config);
+ d12_write_word(base_addr, CMD_SET_MODE, w);
+}
+
+// ------------------------------------------------------------------------
+// Reads a setup packet from the control endpoint. This procedure is
+// somewhat different than reading a data packet. By the USB standard, a
+// setup packet can not be NAK'ed or STALL'ed, so when the chip receives a
+// setup packet, it flushes the Ctrl (EP0) IN buffer and disables the
+// Validate and Clear Buffer commands. The processor must send an
+// acknowledge setup to both EP0 IN and OUT before a Validate or Clear
+// Buffer command is effective.
+//
+// Parameters:
+// buf buffer to receive the contents of the setup packet. Must
+// be at least 8 bytes.
+// Returns:
+// true if there are 8 bytes waiting in the EP0 OUT RAM buffer
+// on the D12 (i.e., true if successful)
+// false otherwise
+
+static bool
+d12_read_setup_packet(d12_addr_type base_addr, byte *buf)
+{
+ uint8 n;
+
+ d12_select_endp(base_addr, D12_RX_CTRL_ENDP);
+
+ d12_read_byte(base_addr, CMD_READ_BUF); // Read & discard reserved byte
+ n = d12_read_data_byte(base_addr); // # bytes available
+
+ if (n > USB_SETUP_PACKET_LEN) {
+ //TRACE("* Warning: Setup Packet too large: %u *\n", (unsigned) n);
+ n = USB_SETUP_PACKET_LEN;
+ }
+
+ n = d12_read_data(base_addr, buf, n);
+
+ d12_ack_setup(base_addr);
+ d12_clear_buffer(base_addr);
+
+ // ----- Ack Setup to EP0 IN ------
+
+ d12_select_endp(base_addr, D12_TX_CTRL_ENDP);
+ d12_ack_setup(base_addr);
+
+ return n == USB_SETUP_PACKET_LEN;
+}
+
+// ------------------------------------------------------------------------
+// Reads the contents of the currently selected endpoint's RAM buffer into
+// the buf[] array.
+//
+// The D12's buffer comes in as follows:
+// [0] junk ("reserved" - can be anything). Just disregard
+// [1] # data bytes to follow
+// [2] data byte 0, ...
+// up to
+// [N+2] data byte N-1
+//
+// Parameters:
+// buf byte array to receive data. This MUST be at least the size
+// of the chip's RAM buffer for the currently selected endpoint.
+// If buf is NULL, the data is read & discarded.
+//
+// Returns: the actual number of bytes read (could be <= n)
+
+static uint8
+d12_read_selected_endp_buf(d12_addr_type base_addr, byte *buf)
+{
+ uint8 n;
+
+ d12_read_byte(base_addr, CMD_READ_BUF); // Read & discard reserved byte
+ n = d12_read_data_byte(base_addr); // # bytes in chip's buf
+ d12_read_data(base_addr, buf, n);
+ d12_clear_buffer(base_addr);
+
+ return n;
+}
+
+// ------------------------------------------------------------------------
+// Selects the specified endpoint and reads the contents of it's RAM buffer
+// into the buf[] array. For the Main OUT endpoint, it will check whether
+// both buffers are full, and if so, read them both.
+//
+// Side Effects:
+// - Leaves endp_idx as the currently selected endpoint.
+//
+// Parameters:
+// endp_idx the endpoint from which to read
+// buf buffer to receive the data. This MUST be at least the size
+// of the chip's RAM buffer for the specified endpoint.
+// For the Main endp, it must be 2x the buffer size (128 total)
+//
+// Returns: the # of bytes read.
+
+static uint8
+d12_read_endp_buf(d12_addr_type base_addr, byte endp_idx, byte *buf)
+{
+ return (d12_select_endp(base_addr, endp_idx) & SEL_ENDP_FULL)
+ ? d12_read_selected_endp_buf(base_addr, buf) : 0;
+}
+
+// ------------------------------------------------------------------------
+// Does a read of the "main" endpoint (#2). Since it's double buffered,
+// this will check if both buffers are full, and if so it will read them
+// both. Thus the caller's buffer, buf, must be large enough to hold all
+// the data - 128 bytes total.
+//
+// If either buffer contains less than the full amount, the done flag
+// is set indicating that a Bulk OUT transfer is complete.
+//
+// This determines if a bulk transfer is done, since the caller can't
+// necessarily determine this from the size of the return buffer.
+// If either buffer is less than full, '*done' is set to a non-zero value.
+
+static uint8
+d12_read_main_endp_buf(d12_addr_type base_addr, byte *buf, int *done)
+{
+ int nBuf = 1;
+ uint8 n = 0;
+ byte stat = d12_read_endp_status(base_addr, D12_RX_MAIN_ENDP) &
+ D12_ENDP_STAT_ANY_BUF_FULL;
+
+ if (stat == 0)
+ return 0;
+
+ if (stat == D12_ENDP_STAT_BOTH_BUF_FULL)
+ nBuf++;
+
+ *done = false;
+
+ while (nBuf--) {
+ if (d12_select_endp(base_addr, D12_RX_MAIN_ENDP) & SEL_ENDP_FULL) {
+ uint8 n1 = d12_read_selected_endp_buf(base_addr, buf+n);
+ n += n1;
+ if (n1 < D12_MAIN_ENDP_SIZE) {
+ *done = true;
+ break;
+ }
+ }
+ else
+ *done = true;
+ }
+ return n;
+}
+
+// ------------------------------------------------------------------------
+// Writes the contents of the buf[] array to the currently selected
+// endpoint's RAM buffer. The host will get the data on the on the next IN
+// packet from the endpoint.
+//
+// Note:
+// - The length of the buffer, n, must be no more than the size of the
+// endpoint's RAM space, though, currently, this is not checked.
+// - It's feasible that the application needs to send an empty (NULL)
+// packet. It's valid for 'n' to be zero, and/or buf NULL.
+
+static uint8
+d12_write_selected_endp_buf(d12_addr_type base_addr, const byte *buf, uint8 n)
+{
+ d12_write_byte(base_addr, CMD_WRITE_BUF, 0);
+ d12_write_data_byte(base_addr, n);
+ d12_write_data(base_addr, buf, n);
+ d12_validate_buffer(base_addr);
+
+ return n;
+}
+
+// ------------------------------------------------------------------------
+// Writes the contents of the buf[] array to the specified endoint's RAM
+// buffer. The host will get this data on the next IN packet from the
+// endpoint.
+//
+// Side Effects:
+// - Leaves endp_idx as the currently selected endpoint.
+
+static uint8
+d12_write_endp_buf(d12_addr_type base_addr, byte endp_idx,
+ const byte *buf, uint8 n)
+{
+ d12_select_endp(base_addr, endp_idx);
+ return d12_write_selected_endp_buf(base_addr, buf, n);
+}
+
+// ------------------------------------------------------------------------
+// Reads & returns the contents of the Chip ID register.
+
+static inline uint16
+d12_read_chip_id(d12_addr_type base_addr)
+{
+ return d12_read_word(base_addr, CMD_READ_CHIP_ID);
+}
+
+
+// ==========================================================================
+// eCos-Specific Device Driver Code
+// ==========================================================================
+
+static void usbs_d12_reset(void);
+
+// Make some abbreviations for the configuration options.
+
+#if defined(CYGPKG_DEVS_USB_D12_RX_EP1)
+#define _RX_EP1
+#endif
+
+#if defined(CYGPKG_DEVS_USB_D12_TX_EP1)
+#define _TX_EP1
+#endif
+
+#if defined(CYGPKG_DEVS_USB_D12_RX_EP2)
+#define _RX_EP2
+#endif
+
+#if defined(CYGPKG_DEVS_USB_D12_TX_EP2)
+#define _TX_EP2
+#endif
+
+// --------------------------------------------------------------------------
+// Endpoint 0 Data
+// --------------------------------------------------------------------------
+
+static cyg_interrupt usbs_d12_intr_data;
+static cyg_handle_t usbs_d12_intr_handle;
+
+static byte ep0_tx_buffer[CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE];
+
+static void usbs_d12_start(usbs_control_endpoint*);
+static void usbs_d12_poll(usbs_control_endpoint*);
+
+typedef enum endp_state {
+ ENDP_STATE_IDLE,
+ ENDP_STATE_IN,
+ ENDP_STATE_OUT
+} endp_state;
+
+typedef struct ep0_impl {
+ usbs_control_endpoint common;
+ endp_state ep_state;
+ int length;
+ int transmitted;
+ bool tx_empty;
+} ep0_impl;
+
+static ep0_impl ep0 = {
+ common:
+ {
+ state: USBS_STATE_POWERED,
+ enumeration_data: (usbs_enumeration_data*) 0,
+ start_fn: &usbs_d12_start,
+ poll_fn: &usbs_d12_poll,
+ interrupt_vector: CYGNUM_DEVS_USB_D12_IRQ,
+ control_buffer: { 0, 0, 0, 0, 0, 0, 0, 0 },
+ state_change_fn: 0,
+ state_change_data: 0,
+ standard_control_fn: 0,
+ standard_control_data: 0,
+ class_control_fn: 0,
+ class_control_data: 0,
+ vendor_control_fn: 0,
+ vendor_control_data: 0,
+ reserved_control_fn: 0,
+ reserved_control_data: 0,
+ buffer: 0,
+ buffer_size: 0,
+ fill_buffer_fn: 0,
+ fill_data: 0,
+ fill_index: 0,
+ complete_fn: 0
+ },
+ ep_state: ENDP_STATE_IDLE,
+ length: 0,
+ transmitted: 0,
+ tx_empty: 0
+};
+
+extern usbs_control_endpoint usbs_d12_ep0 __attribute__((alias ("ep0")));
+
+// --------------------------------------------------------------------------
+// Rx Endpoints 1 & 2 Data
+// --------------------------------------------------------------------------
+
+#if defined(_RX_EP1) || defined(_RX_EP2)
+
+typedef struct rx_endpoint {
+ usbs_rx_endpoint common;
+ int endp, received;
+} rx_endpoint;
+
+static void usbs_d12_api_start_rx_ep(usbs_rx_endpoint*);
+static void usbs_d12_api_stall_rx_ep(usbs_rx_endpoint*, cyg_bool);
+
+static void usbs_d12_ep_rx_complete(rx_endpoint *ep, int result);
+static void usbs_d12_stall_rx_ep(rx_endpoint*, cyg_bool);
+
+#endif
+
+
+#if defined(_RX_EP1)
+
+static rx_endpoint rx_ep1 = {
+ common: {
+ start_rx_fn: &usbs_d12_api_start_rx_ep,
+ set_halted_fn: &usbs_d12_api_stall_rx_ep,
+ halted: 0
+ },
+ endp: 1
+};
+
+extern usbs_rx_endpoint usbs_d12_rx_ep1 __attribute__((alias ("rx_ep1")));
+
+#endif
+
+
+#if defined(_RX_EP2)
+
+static rx_endpoint rx_ep2 = {
+ common: {
+ start_rx_fn: &usbs_d12_api_start_rx_ep,
+ set_halted_fn: &usbs_d12_api_stall_rx_ep,
+ halted: 0
+ },
+ endp: 2
+};
+
+extern usbs_rx_endpoint usbs_d12_rx_ep2 __attribute__((alias ("rx_ep2")));
+
+#endif
+
+// --------------------------------------------------------------------------
+// Tx Endpoints 1 & 2 Data
+// --------------------------------------------------------------------------
+
+#if defined(_TX_EP1) || defined(_TX_EP2)
+
+typedef struct tx_endpoint {
+ usbs_tx_endpoint common;
+ int endp, transmitted;
+ bool tx_empty;
+} tx_endpoint;
+
+static void usbs_d12_api_start_tx_ep(usbs_tx_endpoint*);
+static void usbs_d12_api_stall_tx_ep(usbs_tx_endpoint*, cyg_bool);
+
+static void usbs_d12_ep_tx_complete(tx_endpoint *ep, int result);
+static void usbs_d12_stall_tx_ep(tx_endpoint*, cyg_bool);
+#endif
+
+#if defined(_TX_EP1)
+
+static tx_endpoint tx_ep1 = {
+ common: {
+ start_tx_fn: &usbs_d12_api_start_tx_ep,
+ set_halted_fn: &usbs_d12_api_stall_tx_ep,
+ halted: 0
+ },
+ endp: 1
+};
+
+extern usbs_tx_endpoint usbs_d12_tx_ep1 __attribute__((alias ("tx_ep1")));
+#endif
+
+#if defined(_TX_EP2)
+
+static tx_endpoint tx_ep2 = {
+ common: {
+ start_tx_fn: &usbs_d12_api_start_tx_ep,
+ set_halted_fn: &usbs_d12_api_stall_tx_ep,
+ halted: 0
+ },
+ endp: 2
+};
+
+extern usbs_tx_endpoint usbs_d12_tx_ep2 __attribute__((alias ("tx_ep2")));
+
+#endif
+
+// --------------------------------------------------------------------------
+// Synchronization
+
+static inline void usbs_d12_lock(void) { cyg_scheduler_lock(); }
+static inline void usbs_d12_unlock(void) { cyg_scheduler_unlock(); }
+
+// --------------------------------------------------------------------------
+// Control Endpoint
+// --------------------------------------------------------------------------
+
+// Fills the EP0 transmit buffer with a packet. Partial data packets are
+// retrieved by repeatedly calling the fill function.
+
+static int
+ep0_fill_tx_buffer(void)
+{
+ int nFilled = 0;
+
+ while (nFilled < CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE) {
+ if (ep0.common.buffer_size != 0) {
+ if ((nFilled + ep0.common.buffer_size) <
+ CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE) {
+ memcpy(&ep0_tx_buffer[nFilled], ep0.common.buffer,
+ ep0.common.buffer_size);
+ nFilled += ep0.common.buffer_size;
+ ep0.common.buffer_size = 0;
+ }
+ else {
+ break;
+ }
+ }
+ else if (ep0.common.fill_buffer_fn) {
+ (*ep0.common.fill_buffer_fn)(&ep0.common);
+ }
+ else {
+ break;
+ }
+ }
+ CYG_ASSERT((ep0.common.buffer_size == 0) && (!ep0.common.fill_buffer_fn),
+ "EP0 transmit buffer overflow");
+ TRACE_D12("EP0: Filled Tx Buf with %d bytes\n", nFilled);
+
+ ep0.length = nFilled;
+
+ ep0.common.fill_buffer_fn = 0;
+ ep0.common.fill_data = 0;
+ ep0.common.fill_index = 0;
+
+ return nFilled;
+}
+
+// --------------------------------------------------------------------------
+// Called when a transfer is complete on the control endpoint EP0.
+// It resets the endpoint's data structure and calls the completion function,
+// if any.
+//
+// PARAMETERS:
+// result 0, on success
+// -EPIPE or -EIO to indicate a cancellation
+
+static usbs_control_return
+usbs_d12_ep0_complete(int result)
+{
+ usbs_control_return ret = USBS_CONTROL_RETURN_UNKNOWN;
+
+ ep0.ep_state = ENDP_STATE_IDLE;
+
+ if (ep0.common.complete_fn)
+ ret = (*ep0.common.complete_fn)(&ep0.common, result);
+
+ ep0.common.buffer = 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.complete_fn = 0;
+ //ep0.common.fill_buffer_fn = 0;
+
+ return ret;
+}
+
+// --------------------------------------------------------------------------
+// This routine is called when we want to send the next packet to the tx ep0
+// on the chip. It is used to start a new transfer, and is also called when
+// the chip interrupts to indicate that the ep0 tx buffer is empty and ready
+// to receive a new packet.
+//
+// NOTE:
+// On the D12, when you send a zero-length packet to a tx endpoint, the
+// chip transmits the empty packet to the host, but doesn't interrupt
+// indicating that it is complete. So immediately after sending the
+// empty packet we complete the transfer.
+
+static void
+usbs_d12_ep0_tx(void)
+{
+ int nRemaining = ep0.length - ep0.transmitted;
+ uint8 n;
+
+ // ----- Intermittent interrupt? Get out -----
+
+ if (!ep0.common.buffer) {
+ TRACE_D12("EP0: Tx no buffer (%d)\n", nRemaining);
+ return;
+ }
+
+ // ----- If prev packet was last, signal that we're done -----
+
+ if (nRemaining == 0 && !ep0.tx_empty) {
+ TRACE_D12("\tEP0: Tx Complete (%d) %p\n", ep0.transmitted,
+ ep0.common.complete_fn);
+ usbs_d12_ep0_complete(0);
+ return;
+ }
+
+ // ----- Load the next tx packet onto the chip -----
+
+ if (nRemaining < D12_ENDP0_SIZE) {
+ n = (uint8) nRemaining;
+ ep0.tx_empty = false;
+ }
+ else
+ n = D12_ENDP0_SIZE;
+
+ d12_write_endp_buf(D12_BASE_ADDR, D12_TX_ENDP0,
+ &ep0_tx_buffer[ep0.transmitted], n);
+
+ TRACE_D12("EP0: Wrote %u bytes\n", (unsigned) n);
+ TRACE_BUF0("\t", &ep0_tx_buffer[ep0.transmitted], n);
+
+ ep0.transmitted += n;
+
+ // ----- If empty packet, D12 won't interrupt, so end now ----- */
+
+ if (n == 0) {
+ TRACE_D12("\tEP0: Tx Complete (%d) %p\n", ep0.transmitted,
+ ep0.common.complete_fn);
+ usbs_d12_ep0_complete(0);
+ }
+}
+
+// --------------------------------------------------------------------------
+// This function is called when a packet has been successfully sent on the
+// primary control endpoint (ep0). It indicates that the chip is ready for
+// another packet. We read the LastTransStatus for the endpoint to clear
+// the interrupt bit, then call ep0_tx() to continue the transfer.
+
+static void
+usbs_d12_ep0_tx_intr(void)
+{
+ d12_read_last_trans_status(D12_BASE_ADDR, D12_TX_ENDP0);
+ usbs_d12_ep0_tx();
+}
+
+// --------------------------------------------------------------------------
+// Try to handle standard requests. This is a three step process:
+// 1. If it's something we should handle internally we take care of it.
+// Currently we can handle SET_ADDRESS requests, and a few others.
+// 2. If the upper level code has installed a standard control handler
+// we let that function have a crack at it.
+// 3. If neither of those handle the packet we let
+// usbs_handle_standard_control() have a last try at it.
+//
+// Locally:
+// SET_ADDRESS: The host is demanding that we change our USB address.
+// This is done by updating the Address/Enable register on the D12.
+// Note, however that the USB protocol requires us to ack at the old
+// address, change address, and then accept the next control message
+// at the new address. The D12 address reg is buffered to do this
+// automatically for us. The updated address on the chip won't take
+// affect until after the empty ack is sent. Nice.
+//
+
+static usbs_control_return
+usbs_d12_handle_std_req(usb_devreq *req)
+{
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+ int recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+
+ if (req->request == USB_DEVREQ_SET_ADDRESS) {
+ TRACE_D12("Setting Addr: %u\n", (unsigned) req->value_lo);
+ d12_set_addr_enable(D12_BASE_ADDR, req->value_lo, true);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ else if (req->request == USB_DEVREQ_GET_STATUS) {
+ if (recipient == USB_DEVREQ_RECIPIENT_DEVICE) {
+ const usbs_enumeration_data *enum_data = ep0.common.enumeration_data;
+ if (enum_data && enum_data->device.number_configurations == 1 &&
+ enum_data->configurations) {
+ ep0.common.control_buffer[0] =
+ (enum_data->configurations[0].attributes
+ & USB_CONFIGURATION_DESCRIPTOR_ATTR_SELF_POWERED) ? 1 : 0;
+ ep0.common.control_buffer[0] |=
+ (enum_data->configurations[0].attributes
+ & USB_CONFIGURATION_DESCRIPTOR_ATTR_REMOTE_WAKEUP) ? 2 : 0;
+ ep0.common.control_buffer[1] = 0;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ }
+ else if (recipient == USB_DEVREQ_RECIPIENT_ENDPOINT) {
+ bool halted = false;
+ result = USBS_CONTROL_RETURN_HANDLED;
+
+ switch (req->index_lo) {
+#if defined(_RX_EP1)
+ case 0x01 : halted = rx_ep1.common.halted; break;
+#endif
+#if defined(_TX_EP1)
+ case 0x81 : halted = tx_ep1.common.halted; break;
+#endif
+#if defined(_RX_EP2)
+ case 0x02 : halted = rx_ep2.common.halted; break;
+#endif
+#if defined(_TX_EP2)
+ case 0x82 : halted = tx_ep2.common.halted; break;
+#endif
+
+ default:
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+
+ TRACE_D12("Get Status: Endp [0x%02X] %s\n", (unsigned) req->index_lo,
+ halted ? "Halt" : "Unhalt");
+ if (result == USBS_CONTROL_RETURN_HANDLED) {
+ ep0.common.control_buffer[0] = (halted) ? 1 : 0;
+ ep0.common.control_buffer[1] = 0;
+ }
+ }
+
+ if (result == USBS_CONTROL_RETURN_HANDLED) {
+ ep0.common.buffer = ep0.common.control_buffer;
+ ep0.common.buffer_size = 2;
+ ep0.common.fill_buffer_fn = 0;
+ ep0.common.complete_fn = 0;
+ }
+ }
+ else if ((req->request == USB_DEVREQ_SET_FEATURE ||
+ req->request == USB_DEVREQ_CLEAR_FEATURE) &&
+ recipient == USB_DEVREQ_RECIPIENT_ENDPOINT) {
+
+ bool halt = (req->request == USB_DEVREQ_SET_FEATURE);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ TRACE_D12("Endpoint [0x%02X] %s\n", (unsigned) req->index_lo,
+ halt ? "Halt" : "Unhalt");
+
+ switch (req->index_lo) {
+#if defined(_RX_EP1)
+ case 0x01 : usbs_d12_stall_rx_ep(&rx_ep1, halt); break;
+#endif
+#if defined(_TX_EP1)
+ case 0x81 : usbs_d12_stall_tx_ep(&tx_ep1, halt); break;
+#endif
+#if defined(_RX_EP2)
+ case 0x02 : usbs_d12_stall_rx_ep(&rx_ep2, halt); break;
+#endif
+#if defined(_TX_EP2)
+ case 0x82 : usbs_d12_stall_tx_ep(&tx_ep2, halt); break;
+#endif
+
+ default:
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+ }
+ else if (ep0.common.standard_control_fn != 0) {
+ result = (*ep0.common.standard_control_fn)
+ (&ep0.common,
+ ep0.common.standard_control_data);
+ }
+
+ if (result == USBS_CONTROL_RETURN_UNKNOWN)
+ result = usbs_handle_standard_control(&ep0.common);
+
+ return result;
+}
+
+// --------------------------------------------------------------------------
+// Handler for the receipt of a setup (dev request) packet from the host.
+// We examine the packet to determine what function(s) should get a crack
+// at trying to handle it, then pass control to the proper function. If
+// the function handles the message we either ACK (len==0) or prepare for
+// an IN or OUT data phase. If no one handled the message, we stall the
+// control endpoint.
+
+static void
+usbs_d12_ep0_setup_packet(usb_devreq* req)
+{
+ int len, dir, protocol, recipient;
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+
+ // ----- See who should take the request -----
+
+ len = make_word(req->length_hi, req->length_lo);
+
+ dir = req->type & USB_DEVREQ_DIRECTION_MASK;
+ protocol = req->type & USB_DEVREQ_TYPE_MASK;
+ recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+
+ TRACE_BUF0("DevReq: ", ep0.common.control_buffer, sizeof(usb_devreq));
+
+ if (protocol == USB_DEVREQ_TYPE_STANDARD)
+ result = usbs_d12_handle_std_req(req);
+ else {
+ // Pass on non-standard requests to registered handlers
+
+ usbs_control_return (*callback_fn)(usbs_control_endpoint*, void*);
+ void *callback_arg;
+
+ if (protocol == USB_DEVREQ_TYPE_CLASS) {
+ callback_fn = ep0.common.class_control_fn;
+ callback_arg = ep0.common.class_control_data;
+ }
+ else if (protocol == USB_DEVREQ_TYPE_VENDOR) {
+ callback_fn = ep0.common.vendor_control_fn;
+ callback_arg = ep0.common.vendor_control_data;
+ }
+ else {
+ callback_fn = ep0.common.reserved_control_fn;
+ callback_arg = ep0.common.reserved_control_data;
+ }
+
+ result = (callback_fn) ? (*callback_fn)(&ep0.common, callback_arg)
+ : USBS_CONTROL_RETURN_STALL;
+ }
+
+ // ----- If handled prep/handle data phase, otherwise stall -----
+
+ if (result == USBS_CONTROL_RETURN_HANDLED) {
+ if (len == 0) {
+ TRACE_D12("\tCtrl ACK\n");
+ d12_write_endp_buf(D12_BASE_ADDR, D12_TX_ENDP0, 0, 0);
+ }
+ else {
+ // Set EP0 state to IN or OUT mode for data phase
+ ep0.transmitted = 0;
+ ep0.length = len;
+
+ if (dir == USB_DEVREQ_DIRECTION_OUT) {
+ // Wait for the next packet from the host.
+ ep0.ep_state = ENDP_STATE_OUT;
+ CYG_ASSERT(ep0.common.buffer != 0,
+ "A rx buffer should have been provided for EP0");
+ CYG_ASSERT(ep0.common.complete_fn != 0,
+ "A completion function should be provided for EP0 OUT control messages");
+ }
+ else {
+ ep0.tx_empty = true;
+ ep0.ep_state = ENDP_STATE_IN;
+ ep0_fill_tx_buffer();
+ usbs_d12_ep0_tx();
+ }
+ }
+ }
+ else {
+ TRACE_D12("\t*** Unhandled Device Request ***\n");
+ // The request wasn't handled, so stall control endpoint
+ d12_stall_ctrl_endp(D12_BASE_ADDR, true);
+ }
+}
+
+// --------------------------------------------------------------------------
+// This is called when the chip indicates that a packet has been received
+// on control endpoint 0. If it's a setup packet, we handle it accordingly,
+// otherwise it's a data packet coming in on ep0.
+//
+
+static void
+usbs_d12_ep0_rx_intr(void)
+{
+ byte byStat = d12_read_last_trans_status(D12_BASE_ADDR, D12_RX_ENDP0);
+ TRACE_D12("\tEP0 Status: 0x%02X\n", (unsigned) byStat);
+
+ if (byStat & D12_LAST_TRANS_SETUP_PACKET) {
+ usb_devreq *req = (usb_devreq *) ep0.common.control_buffer;
+
+ if (!d12_read_setup_packet(D12_BASE_ADDR, (byte*) req)) {
+ TRACE_D12("ep0_rx_dsr: Error reading setup packet\n");
+ d12_stall_ctrl_endp(D12_BASE_ADDR, true);
+ }
+ else
+ usbs_d12_ep0_setup_packet(req);
+ }
+ else {
+ if (ep0.common.buffer) {
+ uint8 n = d12_read_endp_buf(D12_BASE_ADDR, D12_RX_ENDP0,
+ ep0.common.buffer + ep0.transmitted);
+ ep0.transmitted += n;
+
+ TRACE_D12("EP0: Received %d bytes\n", (unsigned) n);
+
+ if (n < D12_ENDP0_SIZE ||
+ ep0.common.buffer_size - ep0.transmitted < D12_ENDP0_SIZE) {
+ TRACE_D12("\tEP0: Rx Complete (%d) %p\n",
+ ep0.transmitted, ep0.common.complete_fn);
+
+ if (usbs_d12_ep0_complete(0) == USBS_CONTROL_RETURN_HANDLED)
+ d12_write_endp_buf(D12_BASE_ADDR, D12_TX_ENDP0, 0, 0);
+ else
+ d12_stall_ctrl_endp(D12_BASE_ADDR, true);
+ }
+ }
+ else {
+ TRACE_D12("EP0: No Rx buffer. Discarding packet\n");
+ d12_read_endp_buf(D12_BASE_ADDR, D12_RX_ENDP0, NULL);
+ }
+ }
+}
+
+// --------------------------------------------------------------------------
+// Handler for when the device is put into or taken out of suspend mode.
+// It updates the state variable in the control endpoint and calls the
+// registered state change function, if any.
+
+// TODO: Put the chip into low power mode??? Stop clocks, etc???
+
+static void
+usbs_d12_suspend(bool suspended)
+{
+ int old_state = ep0.common.state;
+ usbs_state_change state_change;
+
+ if (suspended) {
+ ep0.common.state |= USBS_STATE_SUSPENDED;
+ state_change = USBS_STATE_CHANGE_SUSPENDED;
+ }
+ else {
+ ep0.common.state &= USBS_STATE_MASK;
+ state_change = USBS_STATE_CHANGE_RESUMED;
+ }
+
+ if (ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ state_change, old_state);
+ }
+}
+
+// --------------------------------------------------------------------------
+// Common Rx Endpoint 1 & 2
+// --------------------------------------------------------------------------
+
+#if defined(_RX_EP1) || defined(_RX_EP2)
+
+static void usbs_d12_clear_rx_ep(rx_endpoint *ep)
+{
+ ep->common.buffer = 0;
+ ep->common.buffer_size = 0;
+ ep->common.complete_fn = 0;
+ ep->common.complete_data = 0;
+
+ ep->received = 0;
+}
+
+// --------------------------------------------------------------------------
+// This is called when an rx operation is completed. It resets the endpoint
+// vars and calls the registered completion function.
+//
+
+static void
+usbs_d12_ep_rx_complete(rx_endpoint *ep, int result)
+{
+ completion_fn fn = ep->common.complete_fn;
+ void *data = ep->common.complete_data;
+
+ usbs_d12_clear_rx_ep(ep);
+
+ if (fn)
+ (*fn)(data, result);
+}
+
+// --------------------------------------------------------------------------
+// This routine is called when an rx buffer in the chip is full and ready to
+// be read. If there's an endpoint buffer available and room to hold the data
+// we read it in, otherwise we call the completion function, but leave the
+// data in the chip. The hardware will automatically NAK packages from the
+// host until the app calls another start read to continue receiving data.
+//
+// CONTEXT:
+// Called from either the DSR or application thread, via start rx.
+// In either case, it's assumed that the chip is locked.
+//
+
+static void
+usbs_d12_ep_rx(rx_endpoint *ep)
+{
+ int n, ep_size, buf_remaining, endp = ep->endp;
+ bool done;
+
+ // The main endp is double buffered and we need to be prepared
+ // to read both simultaneously.
+ ep_size = (endp == D12_MAIN_ENDP) ? (2 * D12_MAIN_ENDP_SIZE)
+ : RX_ENDP_SIZE[endp];
+
+ buf_remaining = ep->common.buffer_size - ep->received;
+
+ // ----- If no space left in buffer, call completion fn -----
+
+ if (!ep->common.buffer || buf_remaining < ep_size) {
+ int ret = ep->received;
+
+ // See if caller requested a read smaller than the endp. Read &
+ // throw away extra
+ if (ep->common.buffer_size < ep_size) {
+ byte tmp_buf[D12_MAX_PACKET_SIZE];
+
+ if (endp == D12_MAIN_ENDP)
+ n = d12_read_main_endp_buf(D12_BASE_ADDR, tmp_buf, &done);
+ else
+ n = d12_read_endp_buf(D12_BASE_ADDR, RX_ENDP_INDEX[endp], tmp_buf);
+
+ if (n > ep->common.buffer_size) {
+ n = ep->received = ep->common.buffer_size;
+ ret = -ENOMEM;
+ TRACE_D12("\tEP%d: *** Rx Buffer too small. Data Lost ***\n", endp);
+ }
+ else
+ ret = ep->received = n;
+
+ memcpy(ep->common.buffer, tmp_buf, n);
+ buf_remaining = ep->common.buffer_size - n;
+ }
+
+ TRACE_D12("\tEP%d: Rx Complete. Buffer (nearly) full. [%d]\n",
+ endp, buf_remaining);
+ usbs_d12_ep_rx_complete(ep, ret);
+ return;
+ }
+
+ // ----- Read the data from the chip -----
+
+ if (endp == D12_MAIN_ENDP)
+ n = d12_read_main_endp_buf(D12_BASE_ADDR,
+ ep->common.buffer + ep->received, &done);
+ else {
+ n = d12_read_endp_buf(D12_BASE_ADDR, RX_ENDP_INDEX[endp],
+ ep->common.buffer + ep->received);
+ done = (n < RX_ENDP_SIZE[endp]);
+ }
+
+ ep->received += n;
+ buf_remaining = ep->common.buffer_size - ep->received;
+
+ done = done || (buf_remaining < ep_size);
+
+ TRACE_D12("EP%d: Received %d bytes.\n", endp, n);
+ TRACE_BUF("\t", ep->common.buffer + ep->received-n, n);
+
+ // ----- If we're done, complete the receive -----
+
+ if (done) {
+ TRACE_D12("\tEP%d Rx Complete (%d) %p\n", endp,
+ ep->received, ep->common.complete_fn);
+ usbs_d12_ep_rx_complete(ep, ep->received);
+ }
+}
+
+// --------------------------------------------------------------------------
+// Stalls/unstalls the specified endpoint.
+
+static void
+usbs_d12_stall_rx_ep(rx_endpoint *ep, cyg_bool halt)
+{
+ ep->common.halted = halt;
+ d12_stall_endp(D12_BASE_ADDR, RX_ENDP_INDEX[ep->endp], halt);
+}
+
+// --------------------------------------------------------------------------
+// Handler for an Rx endpoint full interrupt. It clears the interrupt on the
+// D12 by reading the endpoint's status register then calls the routine to
+// read the data into the buffer.
+//
+// Called from the DSR context only.
+//
+
+static void
+usbs_d12_ep_rx_intr(rx_endpoint *ep)
+{
+ d12_read_last_trans_status(D12_BASE_ADDR, RX_ENDP_INDEX[ep->endp]);
+ usbs_d12_ep_rx(ep);
+}
+
+#endif
+
+// --------------------------------------------------------------------------
+// Common Tx Endpoint 1 & 2
+// --------------------------------------------------------------------------
+
+#if defined(_TX_EP1) || defined(_TX_EP2)
+
+// Clears out the endpoint data structure before/after a tx is complete.
+
+static void usbs_d12_clear_tx_ep(tx_endpoint *ep)
+{
+ ep->common.buffer = 0;
+ ep->common.buffer_size = 0;
+ ep->common.complete_fn = 0;
+ ep->common.complete_data = 0;
+
+ ep->transmitted = 0;
+ ep->tx_empty = false;
+}
+
+// --------------------------------------------------------------------------
+// This is called when a transmit is completed. It resets the endpoint vars
+// and calls the registered completion function, if any.
+//
+// CONTEXT:
+// Called from either the DSR or the app thread that started tx.
+
+static void usbs_d12_ep_tx_complete(tx_endpoint *ep, int result)
+{
+ completion_fn fn = ep->common.complete_fn;
+ void *data = ep->common.complete_data;
+
+ usbs_d12_clear_tx_ep(ep);
+
+ if (fn)
+ (*fn)(data, result);
+}
+
+// --------------------------------------------------------------------------
+// The routine writes data to the chip and updates the endpoint's counters.
+// It gets called at the start of a transfer operation to prime the device
+// and then gets called each time the chip finishes sending a packet to the
+// host and is ready for more data. If the amount of data remaining is
+// smaller than can fit in the chip's endpoint buffer, then this is the last
+// packet to send, so we call the completion function.
+//
+// CONTEXT:
+// Called from either the DSR or the app thread that started the tx
+// In either case, it's assumed the chip is locked.
+
+static void
+usbs_d12_ep_tx(tx_endpoint *ep)
+{
+ int n, nRemaining;
+
+ // ----- Already done. Intermittent interrupt, so get out -----
+
+ if (!ep->common.buffer)
+ return;
+
+ // ----- See how many bytes remaining in buffer -----
+
+ nRemaining = ep->common.buffer_size - ep->transmitted;
+
+ TRACE_D12("EP%d: Tx %p, %d Done, %d Remaining\n", ep->endp,
+ ep->common.buffer, ep->transmitted, nRemaining);
+
+ // ----- If prev packet was last, signal that we're done -----
+
+ if (nRemaining == 0 && !ep->tx_empty) {
+ TRACE_D12("\tEP%d: Tx complete (%d) %p\n", ep->endp,
+ ep->transmitted, ep->common.complete_fn);
+ usbs_d12_ep_tx_complete(ep, ep->transmitted);
+ return;
+ }
+
+ // ----- Write the next packet to chip -----
+
+ if (nRemaining < TX_ENDP_SIZE[ep->endp]) {
+ n = nRemaining;
+ ep->tx_empty = false;
+ }
+ else
+ n = TX_ENDP_SIZE[ep->endp];
+
+ TRACE_D12("EP%d: Writing %d bytes. %s\n", ep->endp,
+ n, (n == 0) ? "DONE" : "");
+ TRACE_BUF("\t", ep->common.buffer + ep->transmitted, n);
+
+ d12_write_endp_buf(D12_BASE_ADDR, TX_ENDP_INDEX[ep->endp],
+ ep->common.buffer + ep->transmitted, (uint8) n);
+
+ ep->transmitted += n;
+
+ // ----- If empty packet, complete now -----
+
+ if (n == 0) {
+ TRACE_D12("\tEP%d: Tx complete (%d) %p\n", ep->endp,
+ ep->transmitted, ep->common.complete_fn);
+ usbs_d12_ep_tx_complete(ep, ep->transmitted);
+ return;
+ }
+}
+
+// --------------------------------------------------------------------------
+// Stalls/unstalls the specified tx endpoint.
+
+static void
+usbs_d12_stall_tx_ep(tx_endpoint *ep, cyg_bool halt)
+{
+ ep->common.halted = halt;
+ d12_stall_endp(D12_BASE_ADDR, TX_ENDP_INDEX[ep->endp], halt);
+}
+
+// --------------------------------------------------------------------------
+// Handler for when the chip's tx RAM for an endoint has just been emptied
+// (sent to the host) and the chip is ready for more data.
+// We read the endpoint's last trans status register to clear the interrupt
+// on the D12, then call the tx function to send the next packet or
+// complete the transfer.
+
+static void
+usbs_d12_ep_tx_intr(tx_endpoint *ep)
+{
+ d12_read_last_trans_status(D12_BASE_ADDR, TX_ENDP_INDEX[ep->endp]);
+ usbs_d12_ep_tx(ep);
+}
+
+#endif // defined(_TX_EP1) || defined(_TX_EP2)
+
+// --------------------------------------------------------------------------
+// Application Program Interface (API)
+// --------------------------------------------------------------------------
+
+#if defined(_RX_EP1) || defined(_RX_EP2)
+// Starts a receive operation on the specified endpoint. If the buffer size
+// is zero the completion function is called immediately. The routine checks
+// if tehre is data in the chip's endpoint buffer, and if so it will call
+// ep_rx() to start reading the data out of the chip.
+//
+// If the endpoint is currently stalled, a read size of zero can be used to
+// block the calling thread until the stall is cleared. If the read size is
+// non-zero and the endpoint is stalled the completion function is called
+// immediately with an error result.
+
+static void
+usbs_d12_api_start_rx_ep(usbs_rx_endpoint *ep)
+{
+ rx_endpoint *epx = (rx_endpoint *) ep;
+
+ if (ep->halted) {
+ if (ep->buffer_size != 0)
+ usbs_d12_ep_rx_complete(epx, -EAGAIN);
+ }
+ else if (ep->buffer_size == 0) {
+ usbs_d12_ep_rx_complete(epx, 0);
+ }
+ else {
+ TRACE_D12("EP%d: Starting Rx, %p, %d\n", epx->endp, ep->buffer,
+ ep->buffer_size);
+ usbs_d12_lock();
+
+ epx->received = 0;
+ if (d12_data_available(D12_BASE_ADDR, RX_ENDP_INDEX[epx->endp]))
+ usbs_d12_ep_rx(epx);
+
+ usbs_d12_unlock();
+ }
+}
+
+// --------------------------------------------------------------------------
+// Halts/unhalts one of the generic rx (OUT) endpoints.
+//
+
+static void usbs_d12_api_stall_rx_ep(usbs_rx_endpoint *ep, cyg_bool halt)
+{
+ usbs_d12_lock();
+ usbs_d12_stall_rx_ep((rx_endpoint*) ep, halt);
+ usbs_d12_unlock();
+}
+
+#endif // defined(_RX_EP1) || defined(_RX_EP2)
+
+// --------------------------------------------------------------------------
+// Tx API
+// --------------------------------------------------------------------------
+
+#if defined(_TX_EP1) || defined(_TX_EP2)
+
+// This starts a transmit on one of the data endpoints. If the endpoint is
+// stalled a buffer size of zero can be used to block until the stall is
+// cleared. Any other size on a stalled endpoint will result in an error
+// callback immediately. The first packet is sent to the chip immediately,
+// in the application context. If the chip's buffer can contain the whole
+// transfer, the completion function will be called immediately, again,
+// still in the application context.
+//
+// If an empty packet is requested we send one from here and call the
+// completion function. This should not cause an intr on the D12.
+//
+// CONTEXT:
+// Called from an application thread
+
+static void usbs_d12_api_start_tx_ep(usbs_tx_endpoint *ep)
+{
+ tx_endpoint *epx = (tx_endpoint*) ep;
+
+ if (ep->halted) {
+ if (ep->buffer_size != 0)
+ usbs_d12_ep_tx_complete(epx, -EAGAIN);
+ }
+ else if (ep->buffer_size == 0) {
+ usbs_d12_lock();
+
+ d12_write_endp_buf(D12_BASE_ADDR, TX_ENDP_INDEX[epx->endp], 0, 0);
+ usbs_d12_ep_tx_complete(epx, 0);
+
+ usbs_d12_unlock();
+ }
+ else {
+ TRACE_D12("EP%d: Starting Tx, %p, %d\n", epx->endp, ep->buffer,
+ ep->buffer_size);
+ usbs_d12_lock();
+
+ epx->tx_empty = true;
+ epx->transmitted = 0;
+ usbs_d12_ep_tx(epx);
+
+ usbs_d12_unlock();
+ }
+}
+
+// --------------------------------------------------------------------------
+// Halts/unhalts one of the generic endpoints.
+
+static void
+usbs_d12_api_stall_tx_ep(usbs_tx_endpoint *ep, cyg_bool halt)
+{
+ usbs_d12_lock();
+ usbs_d12_stall_tx_ep((tx_endpoint*) ep, halt);
+ usbs_d12_unlock();
+}
+
+#endif // defined(_TX_ENDP1) || defined(_TX_EP2)
+
+// --------------------------------------------------------------------------
+// DSR
+// --------------------------------------------------------------------------
+
+// The DSR for the D12 chip. This is normally called in the DSR context when
+// the D12 has raised its interrupt flag indicating that it needs to be
+// serviced. The interrupt register contains bit flags that are OR'ed togther
+// indicating what items need to be serviced. There are flags for the
+// following:
+// - The endpoints (one bit for each)
+// - Bus Reset
+// - Suspend Change
+// - DMA (terminal count)
+//
+// Care must be taken in that the D12's interrupt output is level-sensitive
+// (in that the interrupt sources are OR'ed together and not all cleared
+// atomically in a single operation). Platforms (such as the PC) may be
+// expecting edge-triggered interrupts, so we must work around that.
+// So, we loop on the interrupt register. Even though, in each loop, we
+// perform all of the required operations to clear the interrupts, a new
+// one may have arrived before we finished clearing the previous ones.
+// So we read the intr reg again. Once the intr reg gives a zero reading
+// we know that the D12 has dropped its IRQ line.
+//
+// Note, if we're configured to use a thread, this routine is called from
+// within a thread context (not a DSR context).
+//
+
+static void
+usbs_d12_dsr(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data)
+{
+ uint16 status;
+ bool suspended;
+
+ CYG_ASSERT(vector == CYGNUM_DEVS_USB_D12_INT,
+ "DSR should only be invoked for D12 interrupts");
+
+ while ((status = d12_read_intr_reg(D12_BASE_ADDR)) != 0) {
+ TRACE_D12("Intr Status: 0x%04X\n", (unsigned) status);
+
+ if (status & D12_INTR_BUS_RESET) {
+ TRACE_D12("\n>>> Bus Reset <<<\n");
+ usbs_d12_reset();
+ }
+ else {
+
+ // ----- Suspend Change -----
+
+ suspended = (bool) (ep0.common.state & USBS_STATE_SUSPENDED);
+
+ if (status & D12_INTR_SUSPEND_CHANGE) {
+ if (!suspended && (status & ~D12_INTR_SUSPEND_CHANGE) == 0)
+ usbs_d12_suspend(true);
+ }
+ else if (suspended)
+ usbs_d12_suspend(false);
+
+ // ----- Bulk Endpoints -----
+
+#ifdef _TX_EP2
+ if (status & D12_INTR_TX_ENDP2)
+ usbs_d12_ep_tx_intr(&tx_ep2);
+#endif
+
+#ifdef _RX_EP2
+ if (status & D12_INTR_RX_ENDP2)
+ usbs_d12_ep_rx_intr(&rx_ep2);
+#endif
+
+ // ----- Interrupt Endpoints -----
+
+#ifdef _TX_EP1
+ if (status & D12_INTR_TX_ENDP1)
+ usbs_d12_ep_tx_intr(&tx_ep1);
+#endif
+
+#ifdef _RX_EP1
+ if (status & D12_INTR_RX_ENDP1)
+ usbs_d12_ep_rx_intr(&rx_ep1);
+#endif
+
+ // ----- Control Endpoint -----
+
+ if (status & D12_INTR_TX_CTRL_ENDP)
+ usbs_d12_ep0_tx_intr();
+
+ if (status & D12_INTR_RX_CTRL_ENDP)
+ usbs_d12_ep0_rx_intr();
+ }
+ }
+
+ cyg_drv_interrupt_unmask(vector);
+}
+
+// --------------------------------------------------------------------------
+// Interrupt
+// --------------------------------------------------------------------------
+
+// Here, the ISR does nothing but schedule the DSR to run. The ISR's/DSR's
+// are serialized. The CPU won't process another ISR until after the DSR
+// completes.
+
+static uint32
+usbs_d12_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ CYG_ASSERT(CYGNUM_DEVS_USB_D12_INT == vector,
+ "usbs_isr: Incorrect interrupt");
+
+ // Prevent another interrupt until DSR completes
+ cyg_drv_interrupt_mask(vector);
+ cyg_drv_interrupt_acknowledge(vector);
+
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+
+// --------------------------------------------------------------------------
+// Polling
+// --------------------------------------------------------------------------
+
+static void
+usbs_d12_poll(usbs_control_endpoint *endp)
+{
+ CYG_ASSERT(endp == &ep0.common, "usbs_poll: wrong endpoint");
+
+ usbs_d12_lock();
+ usbs_d12_dsr(CYGNUM_DEVS_USB_D12_INT, 0, 0);
+ usbs_d12_unlock();
+}
+
+// --------------------------------------------------------------------------
+// Thread Processing
+// --------------------------------------------------------------------------
+
+// The user can opt to configure the driver to service the D12 using a high
+// priority thread. The thread's priority MUST be greater than the priority
+// of any application thread making calls into the driver.
+// When we use a thread, the DSR simply signals a semaphore tio wake the
+// thread up. The thread, in turn, calls the the routine to service the D12,
+// now in a thread context. This allows for greater debug options, including
+// tracing.
+
+#ifdef CYGPKG_DEVS_USB_D12_THREAD
+
+static byte usbs_d12_thread_stack[CYGNUM_DEVS_USB_D12_THREAD_STACK_SIZE];
+static cyg_thread usbs_d12_thread;
+static cyg_handle_t usbs_d12_thread_handle;
+static cyg_sem_t usbs_d12_sem;
+
+static void
+usbs_d12_thread_dsr(cyg_vector_t vector, cyg_ucount32 count,
+ cyg_addrword_t data)
+{
+ cyg_semaphore_post(&usbs_d12_sem);
+
+ CYG_UNUSED_PARAM(cyg_vector_t, vector);
+ CYG_UNUSED_PARAM(cyg_ucount32, count);
+ CYG_UNUSED_PARAM(cyg_addrword_t, data);
+}
+
+
+static void
+usbs_d12_thread_fn(cyg_addrword_t param)
+{
+ while (1) {
+ cyg_semaphore_wait(&usbs_d12_sem);
+ usbs_d12_poll(&ep0.common);
+ }
+
+ CYG_UNUSED_PARAM(cyg_addrword_t, param);
+}
+
+
+static void
+usbs_d12_thread_init(void)
+{
+ cyg_semaphore_init(&usbs_d12_sem, 0);
+
+ cyg_thread_create(CYGNUM_DEVS_USB_D12_THREAD_PRIORITY,
+ &usbs_d12_thread_fn, 0, "D12 USB Driver Thread",
+ usbs_d12_thread_stack,
+ CYGNUM_DEVS_USB_D12_THREAD_STACK_SIZE,
+ &usbs_d12_thread_handle, &usbs_d12_thread);
+ cyg_thread_resume(usbs_d12_thread_handle);
+}
+
+#endif // CYGPKG_DEVS_USB_D12_THREAD
+
+// --------------------------------------------------------------------------
+// Start/Reset
+// --------------------------------------------------------------------------
+
+// Chip initialization and handler for a USB Bus Reset. This gets called at
+// system startup and after a USB Bus Reset. It puts the chip into the
+// default state, with USB Address 0, connected to the bus (i.e.
+// "SoftConnect" asserted). Interrupts to the main endpoint are turned on
+// via the DMA register.
+
+static void
+usbs_d12_reset(void)
+{
+ int old_state = ep0.common.state;
+ ep0.common.state = USBS_STATE_DEFAULT;
+
+ if (ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ USBS_STATE_CHANGE_RESET, old_state);
+ }
+
+ d12_set_addr_enable(D12_BASE_ADDR, 0, true);
+ d12_set_endp_enable(D12_BASE_ADDR, true);
+ d12_set_dma(D12_BASE_ADDR, D12_DMA_MAIN_ENDP_INTR_ENABLE);
+ d12_set_mode(D12_BASE_ADDR, D12_MODE_CFG_DFLT | D12_MODE_CFG_SOFT_CONNECT,
+ D12_MODE_CLK_DFLT);
+
+ // If any endpoints were going, signal the end of transfers
+
+#if defined(_TX_EP2)
+ usbs_d12_ep_tx_complete(&tx_ep2, -EPIPE);
+#endif
+
+#if defined(_RX_EP2)
+ usbs_d12_ep_rx_complete(&rx_ep2, -EPIPE);
+#endif
+
+#if defined(_TX_EP1)
+ usbs_d12_ep_tx_complete(&tx_ep1, -EPIPE);
+#endif
+
+#if defined(_RX_EP1)
+ usbs_d12_ep_rx_complete(&rx_ep1, -EPIPE);
+#endif
+}
+
+// --------------------------------------------------------------------------
+// The start function is called indirectly by the application when
+// initialization is complete. By this time, the enumeration data has been
+// assigned to the control endpoint and we're ready to connect to the host.
+// Within the reset function the D12's SoftConnect line is asserted which
+// allows the host (hub) to see us on the USB bus. If connected, the host
+// should start the enumeration process.
+//
+
+static void usbs_d12_start(usbs_control_endpoint *endpoint)
+{
+#if defined(_TRACE) && !defined(_TRACE_STDOUT)
+ TRACE_OPEN(TRACE_SINK);
+#endif
+
+ CYG_ASSERT(endpoint == &ep0.common, "ep0 start: wrong endpoint");
+ TRACE_D12("USBS D12: Starting.\n");
+
+ d12_clear_all_intr(D12_BASE_ADDR);
+ usbs_d12_reset();
+}
+
+// --------------------------------------------------------------------------
+// Initialization
+// --------------------------------------------------------------------------
+
+// This routine is called early in the program's startup, possibly before
+// main (from within a C++ object initialization). We want to put this chip
+// and driver in a neutral, but ready, state until the application gets
+// control, initializes itself and calls the usb start function.
+//
+// The D12 has a "Soft Connect" feature to tristate the USB bus, making it
+// appear that the USB device is not connected to the bus. We initially
+// keep seperated from the bus to allow for initialization.
+
+void
+usbs_d12_init(void)
+{
+ cyg_DSR_t *pdsr;
+
+ d12_set_mode(D12_BASE_ADDR, D12_MODE_CFG_DFLT & ~D12_MODE_CFG_SOFT_CONNECT,
+ D12_MODE_CLK_DFLT);
+
+ d12_set_addr_enable(D12_BASE_ADDR, 0, false);
+ d12_set_endp_enable(D12_BASE_ADDR, false);
+
+ // ----- Clear the endpoints -----
+
+#if defined(_TX_EP2)
+ usbs_d12_clear_tx_ep(&tx_ep2);
+#endif
+
+#if defined(_RX_EP2)
+ usbs_d12_clear_rx_ep(&rx_ep2);
+#endif
+
+#if defined(_TX_EP1)
+ usbs_d12_clear_tx_ep(&tx_ep1);
+#endif
+
+#if defined(_RX_EP1)
+ usbs_d12_clear_rx_ep(&rx_ep1);
+#endif
+
+ // ----- Start the thread (if we're using it) -----
+
+#ifdef CYGPKG_DEVS_USB_D12_THREAD
+ usbs_d12_thread_init();
+ pdsr = &usbs_d12_thread_dsr;
+#else
+ pdsr = &usbs_d12_dsr;
+#endif
+
+ // ----- Attach the ISR -----
+
+ cyg_drv_interrupt_create(CYGNUM_DEVS_USB_D12_INT,
+ 0, 0, &usbs_d12_isr, pdsr,
+ &usbs_d12_intr_handle, &usbs_d12_intr_data);
+
+ cyg_drv_interrupt_attach(usbs_d12_intr_handle);
+ cyg_drv_interrupt_unmask(CYGNUM_DEVS_USB_D12_INT);
+}
+
+// ----------------------------------------------------------------------------
+// Testing support.
+
+usbs_testing_endpoint usbs_testing_endpoints[] = {
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL,
+ endpoint_number : 0,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &ep0.common,
+#ifdef CYGVAR_DEVS_USB_D12_EP0_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "0c",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1,
+ max_size : CYGNUM_DEVS_USB_D12_EP0_TXBUFSIZE,
+ max_in_padding : 0,
+ alignment : 0
+ },
+
+ /*
+#ifdef _TX_EP1
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
+ endpoint_number : 1,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &tx_ep1.common,
+# ifdef CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "1w",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 0,
+ max_size : 0x0FFFF, // Driver limitation, only a single
+ // buffer descriptor is used
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+
+#ifdef _RX_EP1
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
+ endpoint_number : 1,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
+ endpoint : (void*) &rx_ep1.common,
+# ifdef CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "1r",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 1,
+ max_size : 0x0FFFF, // Driver limitation
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+ */
+
+#ifdef _TX_EP2
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 2,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &tx_ep2.common,
+# ifdef CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "2w",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 0,
+ max_size : 0x1000, // 4k for testing
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+
+#ifdef _RX_EP2
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 2,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
+ endpoint : (void*) &rx_ep2.common,
+# ifdef CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "2r",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 1,
+ max_size : 0x1000, // 4k for testing
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+
+ USBS_TESTING_ENDPOINTS_TERMINATOR
+};
+
diff --git a/ecos/packages/devs/usb/d12/current/src/usbs_d12_data.cxx b/ecos/packages/devs/usb/d12/current/src/usbs_d12_data.cxx
new file mode 100644
index 0000000..4fef23e
--- /dev/null
+++ b/ecos/packages/devs/usb/d12/current/src/usbs_d12_data.cxx
@@ -0,0 +1,231 @@
+//==========================================================================
+//
+// usbs_d12_data.cxx
+//
+// Static data for the D12 USB device driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): fmp
+// Contributors: fmp
+// Date: 2004-05-27
+//
+// This file contains various objects that should go into extras.o
+// rather than libtarget.a, e.g. devtab entries that would normally
+// be eliminated by the selective linking.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/io/devtab.h>
+#include <cyg/io/usb/usbs_d12.h>
+#include <pkgconf/devs_usb_d12.h>
+
+// ----------------------------------------------------------------------------
+// Initialization. The goal here is to call usbs_d12_init()
+// early on during system startup, to take care of things like
+// registering interrupt handlers etc. which are best done
+// during system init.
+//
+// If the endpoint 0 devtab entry is available then its init()
+// function can be used to take care of this. However the devtab
+// entries are optional so an alternative mechanism must be
+// provided. Unfortunately although it is possible to give
+// a C function the constructor attribute, it cannot be given
+// an initpri attribute. Instead it is necessary to define a
+// dummy C++ class.
+
+extern "C" void usbs_d12_init(void);
+
+#ifndef CYGVAR_DEVS_USB_D12_EP0_DEVTAB_ENTRY
+class usbs_d12_initialization {
+public:
+ usbs_d12_initialization() {
+ usbs_d12_init();
+ }
+};
+
+static usbs_d12_initialization usbs_d12_init_object
+ CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);
+#endif
+
+// ----------------------------------------------------------------------------
+// The devtab entries. Each of these is optional, many applications
+// will want to use the lower-level API rather than go via
+// open/read/write/ioctl.
+
+#ifdef CYGVAR_DEVS_USB_D12_EP0_DEVTAB_ENTRY
+
+// For endpoint 0 the only legal operations are get_config() and
+// set_config(), and these are provided by the common package.
+
+static bool
+usbs_d12_devtab_ep0_init(struct cyg_devtab_entry* tab)
+{
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+ usbs_d12_init();
+ return true;
+}
+
+static
+CHAR_DEVIO_TABLE(usbs_d12_ep0_devtab_functions,
+ &cyg_devio_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static CHAR_DEVTAB_ENTRY(usbs_d12_ep0_devtab_entry,
+ CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "0c",
+ 0,
+ &usbs_d12_ep0_devtab_functions,
+ &usbs_d12_devtab_ep0_init,
+ 0,
+ (void*) &usbs_d12_ep0);
+#endif
+
+// ----------------------------------------------------------------------------
+// Common routines for ep1 and ep2.
+
+#if defined(CYGVAR_DEVS_USB_D12_TX_EP1_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_D12_RX_EP1_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY)
+
+static bool
+usbs_d12_devtab_dummy_init(struct cyg_devtab_entry* tab)
+{
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+ return true;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// tx (in) ep1 devtab entry. This can only be used for slave->host,
+// so only the cwrite() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_D12_TX_EP1_DEVTAB_ENTRY
+
+static
+CHAR_DEVIO_TABLE(usbs_d12_tx_ep1_devtab_functions,
+ &usbs_devtab_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static
+CHAR_DEVTAB_ENTRY(usbs_d12_tx_ep1_devtab_entry,
+ CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "1w",
+ 0,
+ &usbs_d12_tx_ep1_devtab_functions,
+ &usbs_d12_devtab_dummy_init,
+ 0,
+ (void*) &usbs_d12_tx_ep1);
+#endif
+
+// ----------------------------------------------------------------------------
+// rx (out) ep1 devtab entry. This can only be used for host->slave,
+// so only the cread() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_D12_RX_EP1_DEVTAB_ENTRY
+
+static
+CHAR_DEVIO_TABLE(usbs_d12_rx_ep1_devtab_functions,
+ &cyg_devio_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static
+CHAR_DEVTAB_ENTRY(usbs_d12_rx_ep1_devtab_entry,
+ CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "1r",
+ 0,
+ &usbs_d12_rx_ep1_devtab_functions,
+ &usbs_d12_devtab_dummy_init,
+ 0,
+ (void*) &usbs_d12_rx_ep1);
+#endif
+
+
+// ----------------------------------------------------------------------------
+// tx (in) ep2 devtab entry. This can only be used for slave->host, so only the
+// cwrite() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_D12_TX_EP2_DEVTAB_ENTRY
+
+static
+CHAR_DEVIO_TABLE(usbs_d12_tx_ep2_devtab_functions,
+ &usbs_devtab_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static
+CHAR_DEVTAB_ENTRY(usbs_d12_tx_ep2_devtab_entry,
+ CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "2w",
+ 0,
+ &usbs_d12_tx_ep2_devtab_functions,
+ &usbs_d12_devtab_dummy_init,
+ 0,
+ (void*) &usbs_d12_tx_ep2);
+#endif
+
+// ----------------------------------------------------------------------------
+// rx (out) ep2 devtab entry. This can only be used for host->slave,
+// so only the cread() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_D12_RX_EP2_DEVTAB_ENTRY
+
+static
+CHAR_DEVIO_TABLE(usbs_d12_rx_ep2_devtab_functions,
+ &cyg_devio_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static
+CHAR_DEVTAB_ENTRY(usbs_d12_rx_ep2_devtab_entry,
+ CYGDAT_DEVS_USB_D12_DEVTAB_BASENAME "2r",
+ 0,
+ &usbs_d12_rx_ep2_devtab_functions,
+ &usbs_d12_devtab_dummy_init,
+ 0,
+ (void*) &usbs_d12_rx_ep2);
+#endif
diff --git a/ecos/packages/devs/usb/i386/SoRoD12/current/ChangeLog b/ecos/packages/devs/usb/i386/SoRoD12/current/ChangeLog
new file mode 100644
index 0000000..62c4456
--- /dev/null
+++ b/ecos/packages/devs/usb/i386/SoRoD12/current/ChangeLog
@@ -0,0 +1,28 @@
+2006-06-06 Frank Pagliughi <fpagliughi@mindspring.com>
+
+ * First version of the USB device driver using the philips D12
+ for i386 targets.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/usb/i386/SoRoD12/current/cdl/usbs_i386_sorod12.cdl b/ecos/packages/devs/usb/i386/SoRoD12/current/cdl/usbs_i386_sorod12.cdl
new file mode 100644
index 0000000..4e76de2
--- /dev/null
+++ b/ecos/packages/devs/usb/i386/SoRoD12/current/cdl/usbs_i386_sorod12.cdl
@@ -0,0 +1,92 @@
+# ====================================================================
+#
+# usbs_i386_sorod12.cdl
+#
+# Hardware specific parts for the SoRo D12 PC 104 USB card.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Frank M. Pagliughi (fmp), SoRo Systems, Inc., asl
+# Contributors:
+# Date: 2006-04-27
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_USB_I386_SOROD12 {
+ display "Hardware specific part for SoRo D12 USB Device Driver"
+ include_dir "cyg/io/usb"
+ parent CYGPKG_DEVS_USB_D12
+
+ requires { CYGIMP_DEVS_USB_D12_HW_ACCESS_HEADER ==
+ "<cyg/io/usb/usbs_i386_sorod12.inl>" }
+
+ cdl_option CYGSEM_DEVS_USB_I386_SOROD12_IO_MAPPED {
+ display "I/O mapped."
+ flavor bool
+ default_value 1
+ description "
+ The PDIUSBD12 can be mapped into the processor's I/O space or memory
+ space. If this is set the driver accesses the chip through HAL_READ
+ and HAL_WRITE macros, otherwise it uses direct memory access."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_I386_SOROD12_BASEADDR {
+ display "Base Address of D12 chip"
+ flavor data
+ no_define
+ legal_values 1 to 0xFF8
+ default_value 544
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ requires { CYGNUM_DEVS_USB_D12_BASEADDR ==
+ CYGNUM_DEVS_USB_I386_SOROD12_BASEADDR }
+ description "
+ The base memory or I/O address where the USB chip resides."
+ }
+
+ cdl_option CYGNUM_DEVS_USB_I386_SORODD12_IRQ {
+ display "IRQ for the D12 chip"
+ flavor data
+ no_define
+ legal_values { 3 5 7 }
+ default_value 5
+ active_if CYGFUN_DEVS_USB_D12_EP0
+ requires { CYGNUM_DEVS_USB_D12_IRQ ==
+ CYGNUM_DEVS_USB_I386_SORODD12_IRQ }
+ description "
+ The IRQ assigned to the D12 chip."
+ }
+}
diff --git a/ecos/packages/devs/usb/i386/SoRoD12/current/include/usbs_i386_sorod12.inl b/ecos/packages/devs/usb/i386/SoRoD12/current/include/usbs_i386_sorod12.inl
new file mode 100644
index 0000000..d74883b
--- /dev/null
+++ b/ecos/packages/devs/usb/i386/SoRoD12/current/include/usbs_i386_sorod12.inl
@@ -0,0 +1,130 @@
+#ifndef USBS_I386_SORO12_INL
+#define USBS_I386_SORO12_INL
+//==========================================================================
+//
+// usbS_i386_sorod12.inl
+//
+// Hardware specific parts for the SoRo D12 PC 104 USB card.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Frank M. Pagliughi (fmp), ASL
+// Date: 2004-05-22
+//
+// This code is a hardware specific device driver for the SoRo Systems
+// USB-D12-104, a PC/104 (ISA) Full-Speed USB slave board, which turns
+// a PC/104 stack into a USB slave device. The board contains a
+// Philips PDIUSBD12 Peripheral Controller Chip mapped into the PC's
+// I/O space, with jumper-selectable I/O base address, IRQ, and DMA
+// settings. The eCos config tool is used to adjust settings for this
+// driver to match the physical jumper settings. The chip could run in
+// polled mode without an IRQ, but this wouldn't be a great idea other
+// than maybe a debug environment.
+
+// ------------------------------------------------------------------------
+// Data-Only I/O
+// ------------------------------------------------------------------------
+//
+
+#include <pkgconf/devs_usb_i386_sorod12.h>
+
+// These routines read or write 8 bit values to the data area.
+
+static inline byte d12_read_data_byte(d12_addr_type base_addr)
+{
+ #if defined(CYGSEM_DEVS_USB_I386_SOROD12_IO_MAPPED)
+ byte val;
+ HAL_READ_UINT8((unsigned) base_addr, val);
+ return val;
+ #else
+ return *base_addr;
+ #endif
+}
+
+static inline void d12_write_data_byte(d12_addr_type base_addr, byte val)
+{
+ #if defined(CYGSEM_DEVS_USB_I386_SOROD12_IO_MAPPED)
+ HAL_WRITE_UINT8((unsigned) base_addr, val);
+ #else
+ *base_addr = val;
+ #endif
+}
+
+// This routine writes a command to the device.
+
+static inline void d12_write_cmd(d12_addr_type base_addr, byte cmd)
+{
+ #if defined(CYGSEM_DEVS_USB_I386_SOROD12_IO_MAPPED)
+ HAL_WRITE_UINT8((unsigned) base_addr+1, cmd);
+ #else
+ *(base_addr+1) = cmd;
+ #endif
+}
+
+// ------------------------------------------------------------------------
+// Reads 'n' bytes from the data address of the D12 and places them into
+// the buf[] array. Buf can be NULL, in which case the specified number of
+// bytes are read and discarded.
+
+static uint8 d12_read_data(d12_addr_type base_addr, byte *buf, uint8 n)
+{
+ uint8 i;
+
+ if (buf) {
+ for (i=0; i<n; ++i)
+ buf[i] = d12_read_data_byte(base_addr);
+ }
+ else {
+ for (i=0; i<n; ++i)
+ d12_read_data_byte(base_addr);
+ n = 0;
+ }
+
+ return n;
+}
+
+// ------------------------------------------------------------------------
+// Writes 'n' bytes out the data reg of the chip
+
+static void d12_write_data(d12_addr_type base_addr, const byte *buf, uint8 n)
+{
+ uint8 i;
+
+ for (i=0; i<n; ++i)
+ d12_write_data_byte(base_addr, buf[i]);
+}
+
+#endif // USBS_I386_SORO12_INL
diff --git a/ecos/packages/devs/usb/nec_upd985xx/current/ChangeLog b/ecos/packages/devs/usb/nec_upd985xx/current/ChangeLog
new file mode 100644
index 0000000..8235811
--- /dev/null
+++ b/ecos/packages/devs/usb/nec_upd985xx/current/ChangeLog
@@ -0,0 +1,125 @@
+2003-02-25 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * doc/usbs_upd985xx.sgml: Declare as <part> not <reference> to get
+ correct TOC numbering.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/usbs_upd985xx.cdl: Fix doc link.
+
+ * doc/usbs_upd985xx.sgml: Comment out DOCTYPE for now to allow building
+ with standard doc build.
+ Add an enclosing <reference> so it's structured better with standard
+ doc build.
+
+2003-01-22 Anssi Pulkkinen <anssi.pulkkinen@ascom.ch>
+
+ * src/usbs_upd985xx.c (ep0_rx_dsr): After sending a stall response
+ on ep0, start a new receive process for the next control message.
+
+2002-12-01 Bart Veer <bartv@ecoscentric.com>
+
+ * src/usbs_upd985xx.c, cdl/usbs_upd985xx.cdl:
+ Make the control packet size configurable, to work around a
+ problem detected by USB compliance testing. Based on work
+ by Clark Williams and Andrew Lunn.
+
+2002-10-26 Bart Veer <bartv@ecoscentric.com>
+
+ * src/usbs_upd985xx.c (ep0_rx_dsr):
+ Fix typo in expression, reported by Andrew Lunn. The system's
+ behaviour should not be affected.
+
+2001-09-20 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_upd985xx.c (ep0_init):
+ During a reset, also reset the tx_in_progress and
+ tx_pending locks. Otherwise if there are ongoing
+ transmits while the host is issuing a reset no
+ further transmits would be possible.
+
+2001-09-14 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_upd985xx.c:
+ Various changes related to USB testing. Also include
+ potential work-arounds for some unconfirmed hardware
+ problems, but these are disabled for now.
+
+ * src/usbs_upd985xx.c:
+ Change how the reset signal interrupt bit gets masked, to
+ cope with the way Windows initializes a new USB device.
+
+2001-08-09 Bart Veer <bartv@redhat.com>
+
+ * doc/usbs_upd985xx.sgml, doc/*.html:
+ Updated to describe the driver's current behaviour.
+
+ * src/usbs_upd985xx.c, cdl/usbs_upd985xx.cdl:
+ Implement workaround for some hardware problems,
+ by serializing transmit operations.
+
+2001-08-08 Bart Veer <bartv@redhat.com>
+
+ * cdl/usbs_upd985xx.cdl, include/usbs_upd985xx.h,
+ src/usbs_upd985xx.c, src/usbs_upd985xx.cxx:
+ Implement workarounds for some hardware problems.
+ 1) flush the ibus after every write operation.
+ 2) implement support for endpoint 5 transfers, and
+ optionally for emulating bulk transfers over this
+ endpoint (normally this endpoint is used for interrupt
+ transfers).
+ All under the control of suitable configuration options,
+ which by default are set to work around the hardware problems.
+
+2001-08-06 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_upd985xx.c:
+ Add initial support for USB testing.
+
+2001-07-02 Bart Veer <bartv@redhat.com>
+
+ * doc/usbs_upd985xx.sgml:
+ Document alignment restrictions for receive buffers, and
+ the optional platform-specific INIT macro.
+
+ * doc/devs-usb-nec-upd985xx.html
+ Regenerate following above change.
+
+ * src/usbs_upd985xx.c:
+ Remove FIXME related to cacheline alignment, not an issue
+ for MIPS.
+ Remove FIXME related to platform-specific USB startup,
+ now implemented.
+
+2001-06-28 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_upd985xx.c, cdl/usbs_upd985xx.cdl:
+ Device driver now functional.
+
+2001-05-22 Bart Veer <bartv@redhat.com>
+
+ * USB device driver work started.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/usb/nec_upd985xx/current/cdl/usbs_upd985xx.cdl b/ecos/packages/devs/usb/nec_upd985xx/current/cdl/usbs_upd985xx.cdl
new file mode 100644
index 0000000..55ce56f
--- /dev/null
+++ b/ecos/packages/devs/usb/nec_upd985xx/current/cdl/usbs_upd985xx.cdl
@@ -0,0 +1,291 @@
+# ====================================================================
+#
+# usbs_upd985xx.cdl
+#
+# USB device driver for the NEC uPD985xx family of processors.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Original data: bartv
+# Contributors:
+# Date: 2001-05-22
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_USB_UPD985XX {
+ display "NEC uPD985xx USB Device Driver"
+ include_dir "cyg/io/usb"
+ parent CYGPKG_USB
+ implements CYGHWR_IO_USB_SLAVE
+ doc ref/devs-usb-nec-upd985xx.html
+
+ # Make sure that we are running on the right hardware.
+ requires CYGPKG_HAL_MIPS
+ requires CYGPKG_HAL_MIPS_UPD985XX
+
+ description "
+ The NEC uPD985xx family of processors implements an
+ on-chip USB device controller, facilitating the use of this
+ processor in USB peripherals. This package provides a
+ suitable eCos device driver."
+
+ cdl_component CYGFUN_DEVS_USB_UPD985XX_EP0 {
+ display "Support the control endpoint 0"
+ default_value CYGINT_IO_USB_SLAVE_CLIENTS
+ requires CYGPKG_IO_USB CYGPKG_IO_USB_SLAVE
+ compile usbs_upd985xx.c
+ compile -library=libextras.a usbs_upd985xx_data.cxx
+ description "
+ Enable support for endpoint 0. If this support is disabled
+ then the entire USB port is unusable."
+
+ cdl_option CYGVAR_DEVS_USB_UPD985XX_EP0_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 0"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If endpoint 0 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and ioctl calls then a devtab entry is needed.
+ "
+ }
+
+ cdl_option CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE {
+ display "Size of endpoint 0 control packets"
+ flavor data
+ default_value 8
+ legal_values { 8 16 32 64 }
+ description "
+ Control messages on endpoint 0 are split into packets of
+ 8, 16, 32 or 64 bytes - these are the values permitted by the
+ USB specification. The same packet size is used for both
+ receives and transmits. This value must also be used for the
+ max_packet_size field of the device descriptor in the
+ application's USB enumeration data.
+
+ According to section 5.5.5 of the USB specification, if a new
+ control message is received before the previous transaction
+ has completed then the previous transaction must be aborted.
+ If that transaction involved transferring data to the host
+ then there is a problem: that data may still be queued for
+ transmission and the NEC USB device appears to provide no way
+ of aborting that transmit. The problem is unlikely to arise
+ with normal usage, but may be detected by compliance
+ testsuites. Increasing the packet size to its maximum value
+ of 64 reduces the probability of failure.
+ "
+ }
+
+ cdl_option CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE {
+ display "Size of statically-allocated endpoint 0 transmit buffer"
+ flavor data
+ default_value 256
+ requires { CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE >= CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE }
+ description "
+ The implementation of the support for endpoint 0 uses
+ a single static buffer to hold the response to the
+ current control message. Typically this buffer can be
+ fairly small since replies to control messages tend to
+ be small: typically some tens of bytes for the enumeration
+ data, perhaps a bit more for unicode-encoded string
+ descriptors. However if some application-specific protocol
+ depends on larger control messages then this buffer
+ size may need to be increased.
+ "
+ }
+
+ cdl_option CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE {
+ display "Size of statically-allocated endpoint 0 transmit buffer"
+ flavor data
+ default_value 64
+ requires { CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE >= CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE }
+ description "
+ The implementation of the support for endpoint 0 uses
+ a single static buffer to hold incoming control messages.
+ Typically this buffer can be small: standard control messages
+ involve an initial eight-byte header, sometimes followed by
+ a small amount of additional data. However if some
+ application-specific protocol depends on larger control
+ messages then this buffer size may need to be increased.
+ "
+ }
+ }
+ cdl_component CYGPKG_DEVS_USB_UPD985XX_EP3 {
+ display "Support endpoint 3, used for slave->host IN bulk transfers"
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ requires CYGFUN_DEVS_USB_UPD985XX_EP0
+ default_value 0
+ description "
+ In the uPD985xx USB implementation endpoint 3 can only be
+ used for slave->host IN bulk transfers. If the intended application
+ only involves host->slave transfers then this endpoint is
+ not relevant.
+
+ By default this endpoint is disabled: according to NEC erratum
+ U3 there may be problems when doing transfers of 192 bytes or
+ greater. Instead the interrupt endpoint 5 is used, with
+ software emulation of the bulk protocol. If the application
+ involves only transfers of less than 192 bytes then endpoint
+ 3 can be enabled.
+ "
+
+ cdl_option CYGVAR_DEVS_USB_UPD985XX_EP3_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 3"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If endpoint 3 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed.
+ "
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_UPD985XX_EP4 {
+ display "Support endpoint 4, used for slave->host OUT bulk transfers"
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ requires CYGFUN_DEVS_USB_UPD985XX_EP0
+ default_value CYGFUN_DEVS_USB_UPD985XX_EP0
+ description "
+ In the uPD985xx USB implementation endpoint 4 can only be
+ used for host->slave OUT bulk transfers. If the intended application
+ only involves slave->host transfers then the support for
+ endpoint 4 can be disabled. Note that this does not affect
+ control messages which always go via endpoint 0."
+
+ cdl_option CYGVAR_DEVS_USB_UPD985XX_EP4_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 4"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If endpoint 4 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed."
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_UPD985XX_EP5 {
+ display "Support endpoint 5, used for slave->host IN transfers"
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ requires CYGFUN_DEVS_USB_UPD985XX_EP0
+ default_value CYGFUN_DEVS_USB_UPD985XX_EP0
+ description "
+ In the uPD985xx USB implementation endpoint 5 can only be
+ used for slave->host communication. This endpoint is
+ intended primarily for interrupt transfers, but can be
+ used for bulk transfers given a small amount of additional
+ software support."
+
+ cdl_option CYGIMP_DEVS_USB_UPD985XX_EP5_BULK {
+ display "Implement bulk transfers rather than interrupt transfers"
+ default_value 1
+ description "
+ Endpoint 5 is normally used for interrupt transfers, which
+ are limited to 64 bytes. However with a little bit of software
+ support it is possible to implement bulk transfers instead.
+ With some revisions of the silicon this provides a workaround
+ for problems with endpoint 3 - NEC erratum U3 should be consulted
+ for additional information."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_UPD985XX_EP5_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 5"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If endpoint 5 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed.
+ "
+ }
+ }
+
+ cdl_option CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME {
+ display "Base name for devtab entries"
+ flavor data
+ active_if { CYGVAR_DEVS_USB_UPD985XX_EP0_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_UPD985XX_EP3_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_UPD985XX_EP4_DEVTAB_ENTRY
+ }
+ default_value { "\"/dev/usbs\"" }
+ description "
+ If the uPD985xx USB device driver package provides devtab
+ entries for any of the endpoints then this option gives
+ control over the names of these entries. By default the
+ endpoints will be called \"/dev/usbs0c\", \"/dev/usbs3w\"
+ and \"/dev/usbs4r\" (assuming all three endpoints are
+ enabled. The common part \"/dev/usbs\" is determined
+ by this configuration option. It may be necessary to
+ change this if there are multiple USB slave-side
+ devices on the target hardware to prevent a name clash.
+ "
+ }
+
+ cdl_option CYGIMP_DEVS_USB_UPD985XX_IBUS_WRITE_LIMIT {
+ display "Work around potential hardware problem with IBUS writes"
+ default_value 1
+ description "
+ With some revisions of the silicon there may be problems if
+ a device driver performs multiple writes to the IBUS in
+ quick succession. By default this driver avoids such problems,
+ at the cost of some cpu cycles and a small amount of extra code.
+ NEC erratum S1 should be consulted for more details."
+ }
+
+ cdl_option CYGIMP_DEVS_USB_UPD985XX_SERIALIZE_TRANSMITS {
+ display "Work around potential hardware problem with concurrent transmits"
+ default_value 1
+ description "
+ With some revisions of the silicon there may be problems if
+ the device driver is asked to perform concurrent slave->host
+ transmissions on different endpoints, for example sending
+ a reply to a control message while there is a bulk transfer
+ in progress. This option enables a workaround for the
+ problem by ensuring that only one transmit operation is in
+ progress at any one time. NEC errata U3 and U4 should be
+ consulted for more details."
+ }
+}
diff --git a/ecos/packages/devs/usb/nec_upd985xx/current/doc/devs-usb-nec-upd985xx.html b/ecos/packages/devs/usb/nec_upd985xx/current/doc/devs-usb-nec-upd985xx.html
new file mode 100644
index 0000000..6317b66
--- /dev/null
+++ b/ecos/packages/devs/usb/nec_upd985xx/current/doc/devs-usb-nec-upd985xx.html
@@ -0,0 +1,372 @@
+<!-- Copyright (C) 2001 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/). -->
+<!-- Distribution of substantively modified versions of this -->
+<!-- document is prohibited without the explicit permission of the -->
+<!-- copyright holder. -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission is obtained from the copyright holder. -->
+<HTML
+><HEAD
+><TITLE
+>NEC uPD985xx USB Device Driver</TITLE
+><meta name="MSSmartTagsPreventParsing" content="TRUE">
+<META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.64
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="DEVS-USB-NEC-UPD985XX"
+>NEC uPD985xx USB Device Driver</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN4"
+></A
+><H2
+>Name</H2
+>NEC uPD985xx USB Support&nbsp;--&nbsp;Device driver for the on-chip NEC uPD985xx USB device</DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN7"
+></A
+><H2
+>NEC uPD985xx USB Hardware</H2
+><P
+>The NEC uPD985xx family of processors is supplied with an on-chip USB
+slave device, the UDC (USB Device Controller). This supports seven
+endpoints. Endpoint 0 can only be used for control messages. Endpoints
+1 and 2 are for isochronous transmits and receives respectively.
+Endpoints 3 and 4 support bulk transmits and receives. Endpoints 5 and
+6 normally support interrupt transmits and receives,but endpoint 5 can
+also be configured to support bulk transmits. At this time only the
+control endpoint 0, the bulk endpoints 3 and 4, and the interrupt
+endpoint 5 are supported.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN10"
+></A
+><H2
+>Endpoint Data Structures</H2
+><P
+>The uPD985xx USB device driver can provide up to four data structures
+corresponding to the four supported endpoints: a
+<SPAN
+CLASS="STRUCTNAME"
+>usbs_control_endpoint</SPAN
+> structure
+<TT
+CLASS="VARNAME"
+>usbs_upd985xx_ep0</TT
+>;
+<SPAN
+CLASS="STRUCTNAME"
+>usbs_tx_endpoint</SPAN
+> structures
+<TT
+CLASS="VARNAME"
+>usbs_upd985xx_ep3</TT
+> and
+<TT
+CLASS="VARNAME"
+>usbs_upd985xx_ep5</TT
+>; and a
+<SPAN
+CLASS="STRUCTNAME"
+>usbs_rx_endpoint</SPAN
+>
+<TT
+CLASS="VARNAME"
+>usbs_upd985xx_ep4</TT
+>. The header file
+<TT
+CLASS="FILENAME"
+>cyg/io/usb/usbs_nec_upd985xx.h</TT
+>
+provides declarations for these.</P
+><P
+>Not all applications will require support for all the endpoints. For
+example, if the intended use of the UDC only involves peripheral to
+host transfers then <TT
+CLASS="LITERAL"
+>usbs_upd985xx_ep4</TT
+> is redundant.
+The device driver provides configuration options to control the
+presence of each endpoint:</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>Endpoint 0 is controlled by
+<TT
+CLASS="LITERAL"
+>CYGFUN_DEVS_USB_UPD985XX_EP0</TT
+>. This defaults to
+enabled if there are any higher-level packages that require USB
+hardware or if the global preference
+<TT
+CLASS="LITERAL"
+>CYGGLO_IO_USB_SLAVE_APPLICATION</TT
+> is enabled,
+otherwise it is disabled. Usually this has the desired effect. It may
+be necessary to override this in special circumstances, for example if
+the target board uses an external USB chip in preference to the UDC
+and it is that external chip's device driver that should be used
+rather than the on-chip UDC. It is not possible to disable endpoint 0
+and at the same time enable one or both of the other endpoints, since
+a USB device is only usable if it can process the standard control
+messages.</P
+></LI
+><LI
+><P
+>Endpoint 3 is controlled by
+<TT
+CLASS="LITERAL"
+>CYGPKG_DEVS_USB_UPD985XX_EP3</TT
+>. By default this
+endpoint is disabled: according to NEC erratum U3 there may be
+problems when attempting bulk transfers of 192 bytes or greater. As an
+alternative the device driver provides endpoint 5 configured to
+support bulk transfers. Endpoint 3 can be enabled if the application
+only requires bulk transfers of less than 192 bytes, or if this
+erratum is not applicable to the system being developed for other
+reasons.</P
+></LI
+><LI
+><P
+>Similarly endpoint 4 is controlled by
+<TT
+CLASS="LITERAL"
+>CYGPKG_DEVS_USB_UPD985XX_EP4</TT
+>. This is enabled by
+default whenever endpoint 0 is enabled, but it can be disabled
+manually.</P
+></LI
+><LI
+><P
+>Endpoint 5 is controlled by
+<TT
+CLASS="LITERAL"
+>CYGPKG_DEVS_USB_UPD985XX_EP5</TT
+>. This is enabled by
+default whenever endpoint 0 is enabled, but it can be disabled
+manually. There is also a configuration option
+<TT
+CLASS="LITERAL"
+>CYGIMP_DEVS_USB_UPD985XX_EP5_BULK</TT
+>, enabled by
+default. This option allows the endpoint to be used for bulk
+transfers rather than interrupt transfers.</P
+></LI
+></OL
+><P
+>The uPD985xx USB device driver implements the interface specified by the
+common eCos USB Slave Support package. The documentation for that
+package should be consulted for further details. </P
+><P
+>The device driver assumes a bulk packet size of 64 bytes, so this
+value should be used in the endpoint descriptors in the enumeration
+data provided by application code. The device driver also assumes
+a control packet size of eight bytes, and again this should be
+reflected in the enumeration data. If endpoint 5 is configured for
+interrupt rather than bulk transfers then the maximum packet size is
+limited to 64 bytes by the USB standard.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN40"
+></A
+><H2
+>Devtab Entries</H2
+><P
+>In addition to the endpoint data structures the uPD985xx USB device
+driver can also provide devtab entries for each endpoint. This allows
+higher-level code to use traditional I/O operations such as
+<TT
+CLASS="FUNCTION"
+>open</TT
+>/<TT
+CLASS="FUNCTION"
+>read</TT
+>/<TT
+CLASS="FUNCTION"
+>write</TT
+>
+rather than the USB-specific non-blocking functions like
+<TT
+CLASS="FUNCTION"
+>usbs_start_rx_buffer</TT
+>. These devtab entries are
+optional since they are not always required. The relevant
+configuration options are
+<TT
+CLASS="LITERAL"
+>CYGVAR_DEVS_USB_UPD985XX_EP0_DEVTAB_ENTRY</TT
+>,
+<TT
+CLASS="LITERAL"
+>CYGVAR_DEVS_USB_UPD985XX_EP3_DEVTAB_ENTRY</TT
+>,
+<TT
+CLASS="LITERAL"
+>CYGVAR_DEVS_USB_UPD985XX_EP4_DEVTAB_ENTRY</TT
+>, and
+<TT
+CLASS="LITERAL"
+>CYGVAR_DEVS_USB_UPD985XX_EP5_DEVTAB_ENTRY</TT
+>. By
+default these devtab entries are provided if the global preference
+<TT
+CLASS="LITERAL"
+>CYGGLO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES</TT
+> is enabled,
+which is usually the case. Obviously a devtab entry for a given
+endpoint will only be provided if the underlying endpoint is enabled.
+For example, there will not be a devtab entry for endpoint 4 if
+<TT
+CLASS="LITERAL"
+>CYGPKG_DEVS_USB_UPD985XX_EP4</TT
+> is disabled.</P
+><P
+>The names for the devtab entries are determined by using a
+configurable base name and appending <TT
+CLASS="LITERAL"
+>0c</TT
+>,
+<TT
+CLASS="LITERAL"
+>3w</TT
+>, <TT
+CLASS="LITERAL"
+>4r</TT
+> or <TT
+CLASS="LITERAL"
+>5w</TT
+>.
+The base name is determined by the configuration option
+<TT
+CLASS="LITERAL"
+>CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME</TT
+> and has a
+default value of <TT
+CLASS="LITERAL"
+>/dev/usbs</TT
+>, so the devtab entry for
+endpoint 4 would default to <TT
+CLASS="LITERAL"
+>/dev/usbs4r</TT
+>. If the
+target hardware involves multiple USB devices then application
+developers may have to change the base name to prevent a name clash
+with other USB device drivers.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN61"
+></A
+><H2
+>Restrictions</H2
+><P
+>The current device driver imposes a restriction on certain bulk
+receives on endpoint 4. If the protocol being used involves
+variable-length transfers, in other words if the host is allowed to
+send less data than a maximum-sized transfer, then the buffer passed
+to the device driver for receives must be aligned to a 16-byte
+cacheline boundary and it must be a multiple of this 16-byte cacheline
+size. This restriction does not apply if the protocol only involves
+fixed-size transfers.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN64"
+></A
+><H2
+>Optional Hardware Workarounds</H2
+><P
+>The NEC errata list a number of other problems that affect the
+USB device driver. The device driver contains workarounds for these,
+which are enabled by default but can be disabled if the application
+developer knows that the relevant errata are not relevant to the
+system being developed.</P
+><P
+>Erratum S1 lists a possible problem if the device driver attempts
+multiple writes to the USB hardware. This is circumvented by a
+dummy read operation after every write. If this workaround is not
+required then the configuration option
+<TT
+CLASS="LITERAL"
+>CYGIMP_DEVS_USB_UPD985XX_IBUS_WRITE_LIMIT</TT
+> can be disabled.</P
+><P
+>Errata U3 and U4 describe various problems related to concurrent
+transmissions on different endpoints. By default the device driver
+works around this by serializing all transmit operations. For example
+if the device driver needs to send a response to a control message on
+endpoint 0 while there is an ongoing bulk transfer on endpoint 5, the
+response is delayed until the bulk transfer has completed. Under
+typical operating conditions this does not cause any problems:
+endpoint 0 traffic usually happens only during initialization, when
+the target is connected to the host, while endpoint 5 traffic only
+happens after initialization. However if transmit serialization is
+inappropriate for the system being developed then it can be disabled
+using the configuration option
+<TT
+CLASS="LITERAL"
+>CYGIMP_DEVS_USB_UPD985XX_SERIALIZE_TRANSMITS</TT
+>. </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN71"
+></A
+><H2
+>Platform Dependencies</H2
+><P
+>On some platforms it is necessary for the low-level USB device driver
+to perform some additional operations during start-up. For example it
+may be necessary to manipulate one of the processor's GPIO lines
+before the host can detect a new USB peripheral and attempt to
+communicate with it. This avoids problems if the target involves a
+significant amount of work prior to device driver initialization, for
+example a power-on self-test sequence. If the USB host attempted to
+contact the target before the USB device driver had been initialized,
+it would fail to get the expected responses and conclude that the
+target was not a functional USB peripheral.</P
+><P
+>Platform-specific initialization code can be provided via a macro
+<TT
+CLASS="FUNCTION"
+>UPD985XX_USB_PLATFORM_INIT</TT
+>. Typically this macro
+would be defined in the platform HAL's header file
+<TT
+CLASS="FILENAME"
+>cyg/hal/plf_io.h</TT
+>. If the
+current platform defines such a macro, the USB device driver will
+invoke it during the endpoint 0 start-up operation.</P
+></DIV
+></BODY
+></HTML
+>
diff --git a/ecos/packages/devs/usb/nec_upd985xx/current/doc/makefile b/ecos/packages/devs/usb/nec_upd985xx/current/doc/makefile
new file mode 100644
index 0000000..ed36ede
--- /dev/null
+++ b/ecos/packages/devs/usb/nec_upd985xx/current/doc/makefile
@@ -0,0 +1,54 @@
+#=============================================================================
+#
+# makefile
+#
+# For building the NEC uPD985xx USB device driver documentation
+#
+#=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#=============================================================================
+#####DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Date: 2001-01-11
+#####DESCRIPTIONEND####
+#=============================================================================
+
+TOPLEVEL := ../../../../..
+MAIN_SGML := usbs_upd985xx.sgml
+MAIN_HTML := devs-usb-upd985xx.html
+MAIN_PDF := devs-usb-upd985xx.pdf
+OTHER_SGML :=
+PICTURES :=
+
+include $(TOPLEVEL)/pkgconf/rules.doc
diff --git a/ecos/packages/devs/usb/nec_upd985xx/current/doc/usbs_upd985xx.sgml b/ecos/packages/devs/usb/nec_upd985xx/current/doc/usbs_upd985xx.sgml
new file mode 100644
index 0000000..74a4e4c
--- /dev/null
+++ b/ecos/packages/devs/usb/nec_upd985xx/current/doc/usbs_upd985xx.sgml
@@ -0,0 +1,257 @@
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- usbs_nec_upd9850x.sgml -->
+<!-- -->
+<!-- Documentation for the NEC uPD9850x USB Device Driver. -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2001, 2002 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2001/05/22 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-usb-nec-upd985xx-ref">
+<!-- reference id="devs-usb-nec-upd985xx-ref" -->
+ <title>NEC uPD985xx USB Device Driver</title>
+
+<refentry id="devs-usb-nec-upd985xx">
+<refmeta>
+<refentrytitle>NEC uPD985xx USB Device Driver</refentrytitle>
+</refmeta>
+<refnamediv>
+<refname>NEC uPD985xx USB Support</refname>
+<refpurpose>Device driver for the on-chip NEC uPD985xx USB device</refpurpose>
+</refnamediv>
+
+<refsect1><title>NEC uPD985xx USB Hardware</title>
+<para>
+The NEC uPD985xx family of processors is supplied with an on-chip USB
+slave device, the UDC (USB Device Controller). This supports seven
+endpoints. Endpoint 0 can only be used for control messages. Endpoints
+1 and 2 are for isochronous transmits and receives respectively.
+Endpoints 3 and 4 support bulk transmits and receives. Endpoints 5 and
+6 normally support interrupt transmits and receives, but endpoint 5 can
+also be configured to support bulk transmits. At this time only the
+control endpoint 0, the bulk endpoints 3 and 4, and the interrupt
+endpoint 5 are supported.
+</para>
+</refsect1>
+
+<refsect1><title>Endpoint Data Structures</title>
+<para>
+The uPD985xx USB device driver can provide up to four data structures
+corresponding to the four supported endpoints: a
+<structname>usbs_control_endpoint</structname> structure
+<varname>usbs_upd985xx_ep0</varname>;
+<structname>usbs_tx_endpoint</structname> structures
+<varname>usbs_upd985xx_ep3</varname> and
+<varname>usbs_upd985xx_ep5</varname>; and a
+<structname>usbs_rx_endpoint</structname>
+<varname>usbs_upd985xx_ep4</varname>. The header file
+<filename class="headerfile">cyg/io/usb/usbs_nec_upd985xx.h</filename>
+provides declarations for these.
+</para>
+<para>
+Not all applications will require support for all the endpoints. For
+example, if the intended use of the UDC only involves peripheral to
+host transfers then <literal>usbs_upd985xx_ep4</literal> is redundant.
+The device driver provides configuration options to control the
+presence of each endpoint:
+</para>
+<orderedlist>
+<listitem>
+<para>
+Endpoint 0 is controlled by
+<literal>CYGFUN_DEVS_USB_UPD985XX_EP0</literal>. This defaults to
+enabled if there are any higher-level packages that require USB
+hardware or if the global preference
+<literal>CYGGLO_IO_USB_SLAVE_APPLICATION</literal> is enabled,
+otherwise it is disabled. Usually this has the desired effect. It may
+be necessary to override this in special circumstances, for example if
+the target board uses an external USB chip in preference to the UDC
+and it is that external chip's device driver that should be used
+rather than the on-chip UDC. It is not possible to disable endpoint 0
+and at the same time enable one or both of the other endpoints, since
+a USB device is only usable if it can process the standard control
+messages.
+</para>
+</listitem>
+<listitem>
+<para>
+Endpoint 3 is controlled by
+<literal>CYGPKG_DEVS_USB_UPD985XX_EP3</literal>. By default this
+endpoint is disabled: according to NEC erratum U3 there may be
+problems when attempting bulk transfers of 192 bytes or greater. As an
+alternative the device driver provides support for endpoint 5,
+configured to allow bulk transfers. Endpoint 3 can be enabled if the
+application only requires bulk transfers of less than 192 bytes, or if
+this erratum is not applicable to the system being developed for other
+reasons.
+</para>
+</listitem>
+<listitem>
+<para>
+Endpoint 4 is controlled by
+<literal>CYGPKG_DEVS_USB_UPD985XX_EP4</literal>. This is enabled by
+default whenever endpoint 0 is enabled, but it can be disabled
+manually.
+</para>
+</listitem>
+<listitem>
+<para>
+Endpoint 5 is controlled by
+<literal>CYGPKG_DEVS_USB_UPD985XX_EP5</literal>. This is enabled by
+default whenever endpoint 0 is enabled, but it can be disabled
+manually. There is also a configuration option
+<literal>CYGIMP_DEVS_USB_UPD985XX_EP5_BULK</literal>, enabled by
+default. This option allows the endpoint to be used for bulk
+transfers rather than interrupt transfers.
+</para>
+</listitem>
+</orderedlist>
+<para>
+The uPD985xx USB device driver implements the interface specified by the
+common eCos USB Slave Support package. The documentation for that
+package should be consulted for further details.
+</para>
+<para>
+The device driver assumes a bulk packet size of 64 bytes, so this
+value should be used in the endpoint descriptors in the enumeration
+data provided by application code. The device driver also assumes
+a control packet size of eight bytes, and again this should be
+reflected in the enumeration data. If endpoint 5 is configured for
+interrupt rather than bulk transfers then the maximum packet size is
+limited to 64 bytes by the USB standard.
+</para>
+</refsect1>
+
+<refsect1><title>Devtab Entries</title>
+<para>
+In addition to the endpoint data structures the uPD985xx USB device
+driver can also provide devtab entries for each endpoint. This allows
+higher-level code to use traditional I/O operations such as
+<function>open</function>/<function>read</function>/<function>write</function>
+rather than the USB-specific non-blocking functions like
+<function>usbs_start_rx_buffer</function>. These devtab entries are
+optional since they are not always required. The relevant
+configuration options are
+<literal>CYGVAR_DEVS_USB_UPD985XX_EP0_DEVTAB_ENTRY</literal>,
+<literal>CYGVAR_DEVS_USB_UPD985XX_EP3_DEVTAB_ENTRY</literal>,
+<literal>CYGVAR_DEVS_USB_UPD985XX_EP4_DEVTAB_ENTRY</literal>, and
+<literal>CYGVAR_DEVS_USB_UPD985XX_EP5_DEVTAB_ENTRY</literal>. By
+default these devtab entries are provided if the global preference
+<literal>CYGGLO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES</literal> is enabled,
+which is usually the case. Obviously a devtab entry for a given
+endpoint will only be provided if the underlying endpoint is enabled.
+For example, there will not be a devtab entry for endpoint 4 if
+<literal>CYGPKG_DEVS_USB_UPD985XX_EP4</literal> is disabled.
+</para>
+<para>
+The names for the devtab entries are determined by using a
+configurable base name and appending <literal>0c</literal>,
+<literal>3w</literal>, <literal>4r</literal> or <literal>5w</literal>.
+The base name is determined by the configuration option
+<literal>CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME</literal> and has a
+default value of <literal>/dev/usbs</literal>, so the devtab entry for
+endpoint 4 would default to <literal>/dev/usbs4r</literal>. If the
+target hardware involves multiple USB devices then application
+developers may have to change the base name to prevent a name clash
+with other USB device drivers.
+</para>
+</refsect1>
+
+<refsect1><title>Restrictions</title>
+<para>
+The current device driver imposes a restriction on certain bulk
+receives on endpoint 4. If the protocol being used involves
+variable-length transfers, in other words if the host is allowed to
+send less data than a maximum-sized transfer, then the buffer passed
+to the device driver for receives must be aligned to a 16-byte
+cacheline boundary and it must be a multiple of this 16-byte cacheline
+size. This restriction does not apply if the protocol only involves
+fixed-size transfers.
+</para>
+</refsect1>
+
+<refsect1><title>Optional Hardware Workarounds</title>
+<para>
+The NEC errata list a number of other problems that affect the USB
+device driver. The device driver contains workarounds for these, which
+are enabled by default but can be disabled if the application
+developer knows that the errata are not relevant to the system being
+developed.
+</para>
+<para>
+Erratum S1 lists a possible problem if the device driver attempts
+multiple writes to the USB hardware. This is circumvented by a
+dummy read operation after every write. If the workaround is not
+required then the configuration option
+<literal>CYGIMP_DEVS_USB_UPD985XX_IBUS_WRITE_LIMIT</literal> can be disabled.
+</para>
+<para>
+Errata U3 and U4 describe various problems related to concurrent
+transmissions on different endpoints. By default the device driver
+works around this by serializing all transmit operations. For example
+if the device driver needs to send a response to a control message on
+endpoint 0 while there is an ongoing bulk transfer on endpoint 5, the
+response is delayed until the bulk transfer has completed. Under
+typical operating conditions this does not cause any problems:
+endpoint 0 traffic usually happens only during initialization, when
+the target is connected to the host, while endpoint 5 traffic only
+happens after initialization. However if transmit serialization is
+inappropriate for the system being developed then it can be disabled
+using the configuration option
+<literal>CYGIMP_DEVS_USB_UPD985XX_SERIALIZE_TRANSMITS</literal>.
+</para>
+</refsect1>
+
+<refsect1><title>Platform Dependencies</title>
+<para>
+On some platforms it is necessary for the low-level USB device driver
+to perform some additional operations during start-up. For example it
+may be necessary to manipulate one of the processor's GPIO lines
+before the host can detect a new USB peripheral and attempt to
+communicate with it. This avoids problems if the target involves a
+significant amount of work prior to device driver initialization, for
+example a power-on self-test sequence. If the USB host attempted to
+contact the target before the USB device driver had been initialized,
+it would fail to get the expected responses and conclude that the
+target was not a functional USB peripheral.
+</para>
+<para>
+Platform-specific initialization code can be provided via a macro
+<function>UPD985XX_USB_PLATFORM_INIT</function>. Typically this macro
+would be defined in the platform HAL's header file
+<filename class="headerfile">cyg/hal/plf_io.h</filename>. If the
+current platform defines such a macro, the USB device driver will
+invoke it during the endpoint 0 start-up operation.
+</para>
+</refsect1>
+
+</refentry>
+</part>
+<!-- /reference -->
diff --git a/ecos/packages/devs/usb/nec_upd985xx/current/include/usbs_upd985xx.h b/ecos/packages/devs/usb/nec_upd985xx/current/include/usbs_upd985xx.h
new file mode 100644
index 0000000..96b1b9d
--- /dev/null
+++ b/ecos/packages/devs/usb/nec_upd985xx/current/include/usbs_upd985xx.h
@@ -0,0 +1,78 @@
+#ifndef CYGONCE_USBS_UPD985XX_H
+# define CYGONCE_USBS_UPD985XX_H
+//==========================================================================
+//
+// include/usbs_upd985xx.h
+//
+// The interface exported by the NEC uPD985xx USB device driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors: bartv
+// Date: 2000-05-22
+// Purpose:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/io/usb/usbs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The NEC UPD985xx family comes with on-chip USB slave support. This
+ * provides seven endpoints. Endpoint 0 can only be used for control
+ * messages. Endpoints 1 and 2 can only be used for isochronous
+ * transfers, and are not supported at this time. Endpoints 3 and 4
+ * are for bulk transfers, although endpoint 3 is normally disabled
+ * and endpoint 5 is used for bulk transfers instead. Endpoints 5
+ * and 6 are normally used for interrupt transfers, but endpoint 5 can
+ * also be used bulk transfers. Endpoint 6 is not currently supported.
+ */
+extern usbs_control_endpoint usbs_upd985xx_ep0;
+extern usbs_tx_endpoint usbs_upd985xx_ep3;
+extern usbs_rx_endpoint usbs_upd985xx_ep4;
+extern usbs_tx_endpoint usbs_upd985xx_ep5;
+
+#ifdef __cplusplus
+} /* extern "C" { */
+#endif
+
+
+#endif /* CYGONCE_USBS_UPD985XX_H */
diff --git a/ecos/packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx.c b/ecos/packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx.c
new file mode 100644
index 0000000..b104edf
--- /dev/null
+++ b/ecos/packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx.c
@@ -0,0 +1,2687 @@
+//==========================================================================
+//
+// usbs_upd985xx.c
+//
+// Driver for the NEC uPD985xx USB device
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors: bartv
+// Date: 2001-05-22
+//
+// This code implements support for the on-chip USB port on the NEC
+// uPD985xx family of processors. The code has been developed on the
+// uPD98503 and may or may not work on other members of the uPD985xx
+// family.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/diag.h>
+
+#include <pkgconf/hal_mips_upd985xx.h>
+#include <pkgconf/devs_usb_upd985xx.h>
+
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/error/codes.h>
+
+#include <cyg/io/usb/usb.h>
+#include <cyg/io/usb/usbs.h>
+
+// For memcpy()
+#include <string.h>
+
+// ----------------------------------------------------------------------------
+// Toplevel FIXME's.
+//
+// The device supports remote wakeups, but this driver does not. Note that
+// the device GET_STATUS, SET_FEATURE and CLEAR_FEATURE operations are
+// affected by remote wakeup support.
+
+// ----------------------------------------------------------------------------
+// Debugging-related odds and ends.
+#if 0
+# define DBG(a) diag_printf a
+#else
+# define DBG(a)
+#endif
+
+// ----------------------------------------------------------------------------
+// Hardware definitions.
+//
+// The NEC uPD985Xx on-chip USB device provides the following:
+//
+// endpoint 0 - control messages only
+// endpoint 1 - isochronous transmits
+// endpoint 2 - isochronous receives
+// endpoint 3 - bulk transmits
+// endpoint 4 - bulk receives
+// endpoint 5 - interrupt transmits
+// endpoint 6 - interrupt receives
+
+// All acess to the USB controller registers goes via the IBUS, which
+// always runs little-endian. Hence when the CPU is running
+// little-endian no extra work is needed, but when running big-endian
+// all register updates involve swapping.
+#ifdef CYGPKG_HAL_MIPS_LSBFIRST
+# define IBUS_SWAP32(_a_) (_a_)
+# define IBUS_SWAPPTR(_type_, _a_) (_a_)
+#else
+# error IBUS_SWAP32() needs to be defined and tested
+#endif
+
+// Move an address to kseg1. Or'ing in the relevant bits means
+// that this macro will work even if the specified address is
+// already in kseg1
+#define MIPS_TO_UNCACHED(_a_) ((void*)(((cyg_uint32)(_a_)) | MIPS_KSEG1_BASE))
+
+// For now access the various registers directly. A structure might
+// be marginally more inefficient in that if a function accesses
+// several registers this could be handled by a single base plus
+// offsets, rather than by separate addresses.
+#define USBS_REGISTER(_a_) ((volatile cyg_uint32*)(MIPS_IO_BASE + UPD985XX_SYSUSB_OFF + (_a_)))
+#define USBS_ADDRREG(_type_, _a_) ((_type_* volatile*)(MIPS_IO_BASE + UPD985XX_SYSUSB_OFF + (_a_)))
+
+#define USBS_GMR USBS_REGISTER(0x0000)
+#define USBS_VER USBS_REGISTER(0x0004)
+#define USBS_GSR1 USBS_REGISTER(0x0010)
+#define USBS_IMR1 USBS_REGISTER(0x0014)
+#define USBS_GSR2 USBS_REGISTER(0x0018)
+#define USBS_IMR2 USBS_REGISTER(0x001C)
+#define EP0_CR USBS_REGISTER(0x0020)
+#define EP1_CR USBS_REGISTER(0x0024)
+#define EP2_CR USBS_REGISTER(0x0028)
+#define EP3_CR USBS_REGISTER(0x002C)
+#define EP4_CR USBS_REGISTER(0x0030)
+#define EP5_CR USBS_REGISTER(0x0034)
+#define EP6_CR USBS_REGISTER(0x0038)
+#define USBS_CMR USBS_REGISTER(0x0040)
+#define USBS_CA USBS_ADDRREG(void, 0x0044)
+#define USBS_TEPSR USBS_REGISTER(0x0048)
+#define USBS_RP0IR USBS_REGISTER(0x0050)
+#define USBS_RP0AR USBS_ADDRREG(RxBufferDescriptor, 0x0054)
+#define USBS_RP1IR USBS_REGISTER(0x0058)
+#define USBS_RP1AR USBS_ADDRREG(RxBufferDescriptor, 0x005C)
+#define USBS_RP2IR USBS_REGISTER(0x0060)
+#define USBS_RP2AR USBS_ADDRREG(RxBufferDescriptor, 0x0064)
+#define USBS_TMSA USBS_ADDRREG(TxMailbox, 0x0070)
+#define USBS_TMBA USBS_ADDRREG(TxMailbox, 0x0074)
+#define USBS_TMRA USBS_ADDRREG(TxMailbox, 0x0078)
+#define USBS_TMWA USBS_ADDRREG(TxMailbox, 0x007C)
+#define USBS_RMSA USBS_ADDRREG(RxMailbox, 0x0080)
+#define USBS_RMBA USBS_ADDRREG(RxMailbox, 0x0084)
+#define USBS_RMRA USBS_ADDRREG(RxMailbox, 0x0088)
+#define USBS_RMWA USBS_ADDRREG(RxMailbox, 0x008C)
+
+// There are additional counter registers from offset 0x100 onwards.
+// These registers are not used by the driver, and anyway may not be
+// available on all hardware.
+
+// The General Mode register USBS_GMR
+#define USBS_GMR_VT (0x01 << 23)
+#define USBS_GMR_FA_MASK (0x7F << 16)
+#define USBS_GMR_FA_SHIFT 16
+#define USBS_GMR_SOFINTVL_MASK (0x00FF << 8)
+#define USBS_GMR_SOFINTVL_SHIFT 8
+#define USBS_GMR_SOFINTVL_DEFAULT_VALUE (0x18 << 8)
+#define USBS_GMR_AU (0x01 << 2)
+#define USBS_GMR_LE (0x01 << 1)
+#define USBS_GMR_RR (0x01 << 0)
+
+// The Frame Number/Version register
+#define USBS_VER_UVER_MASK (0x0FFFF << 16)
+#define USBS_VER_UVER_SHIFT 16
+#define USBS_VER_UFNR_MASK (0x03FF << 0)
+#define USBS_VER_UFNR_SHIFT 0
+
+// General status register 1
+#define USBS_GSR1_GSR2 (0x01 << 31)
+#define USBS_GSR1_TMF (0x01 << 23)
+#define USBS_GSR1_RMF (0x01 << 22)
+#define USBS_GSR1_RPE2 (0x01 << 21)
+#define USBS_GSR1_RPE1 (0x01 << 20)
+#define USBS_GSR1_RPE0 (0x01 << 19)
+#define USBS_GSR1_RPA2 (0x01 << 18)
+#define USBS_GSR1_RPA1 (0x01 << 17)
+#define USBS_GSR1_RPA0 (0x01 << 16)
+#define USBS_GSR1_DER (0x01 << 10)
+#define USBS_GSR1_EP2FO (0x01 << 9)
+#define USBS_GSR1_EP1FU (0x01 << 8)
+#define USBS_GSR1_EP6RF (0x01 << 7)
+#define USBS_GSR1_EP5TF (0x01 << 6)
+#define USBS_GSR1_EP4RF (0x01 << 5)
+#define USBS_GSR1_EP3TF (0x01 << 4)
+#define USBS_GSR1_EP2RF (0x01 << 3)
+#define USBS_GSR1_EP1TF (0x01 << 2)
+#define USBS_GSR1_EP0RF (0x01 << 1)
+#define USBS_GSR1_EP0TF (0x01 << 0)
+
+// The Interrupt mask 1 bits correspond to the GSR1 bits above
+
+// General status register 2
+#define USBS_GSR2_FW (0x01 << 21)
+#define USBS_GSR2_IFN (0x01 << 20)
+#define USBS_GSR2_IEA (0x01 << 19)
+#define USBS_GSR2_URSM (0x01 << 18)
+#define USBS_GSR2_URST (0x01 << 17)
+#define USBS_GSR2_USPD (0x01 << 16)
+#define USBS_GSR2_EP2OS (0x01 << 7)
+#define USBS_GSR2_EP2ED (0x01 << 6)
+#define USBS_GSR2_EP2ND (0x01 << 5)
+#define USBS_GSR2_EP1NT (0x01 << 4)
+#define USBS_GSR2_EP1ET (0x01 << 3)
+#define USBS_GSR2_EP1ND (0x01 << 2)
+#define USBS_GSR2_ES (0x01 << 1)
+#define USBS_GSR2_SL (0x01 << 0)
+
+// Interrupt mask 2 bits correspond to GSR2
+
+// Endpoint control registers.
+// EP0 - control messages
+#define EP0_CR_EP0EN (0x01 << 31)
+#define EP0_CR_ISS (0x01 << 20)
+#define EP0_CR_INAK (0x01 << 19)
+#define EP0_CR_OSS (0x01 << 18)
+#define EP0_CR_NHSK0 (0x01 << 17)
+#define EP0_CR_ONAK (0x01 << 16)
+#define EP0_CR_MAXP0_MASK (0x7F << 0)
+#define EP0_CR_MAXP0_SHIFT 0
+
+// EP1 - isochronous transmits
+#define EP1_CR_EP1EN (0x01 << 31)
+#define EP1_CR_TM1 (0x01 << 19)
+#define EP1_CR_TM1_MASK (0x01 << 19)
+#define EP1_CR_TM1_SZLP (0x00 << 19)
+#define EP1_CR_TM1_NZLP (0x01 << 19)
+#define EP1_CR_MAXP1_MASK (0x3FF << 0)
+#define EP1_CR_MAXP1_SHIFT 0
+
+// EP2 - isochronous receives
+#define EP2_CR_EP2EN (0x01 << 31)
+#define EP2_CR_RM2_MASK (0x03 << 19)
+#define EP2_CR_RM2_NORMAL (0x00 << 19)
+#define EP2_CR_RM2_ASSEMBLE (0x02 << 19)
+#define EP2_CR_RM2_SEPARATE (0x03 << 19)
+#define EP2_CR_MAXP2_MASK (0x3FF << 0)
+#define EP2_CR_MAXP2_SHIFT 0
+
+// EP3 - bulk transmits
+#define EP3_CR_EP3EN (0x01 << 31)
+#define EP3_CR_TM3 (0x01 << 19)
+#define EP3_CR_TM3_MASK (0x01 << 19)
+#define EP3_CR_TM3_SZLP (0x00 << 19)
+#define EP3_CR_TM3_NZLP (0x01 << 19)
+#define EP3_CR_SS3 (0x01 << 18)
+#define EP3_CR_NAK3 (0x01 << 16)
+#define EP3_CR_MAXP3_MASK (0x7F << 0)
+#define EP3_CR_MAXP3_SHIFT 0
+
+// EP4 - bulk receives
+#define EP4_CR_EP4EN (0x01 << 31)
+#define EP4_CR_RM4_MASK (0x03 << 19)
+#define EP4_CR_RM4_NORMAL (0x00 << 19)
+#define EP4_CR_RM4_ASSEMBLE (0x02 << 19)
+#define EP4_CR_RM4_SEPARATE (0x03 << 19)
+#define EP4_CR_SS4 (0x01 << 18)
+#define EP4_CR_NHSK4 (0x01 << 17)
+#define EP4_CR_NAK4 (0x01 << 16)
+#define EP4_CR_MAXP4_MASK (0x7F << 0)
+#define EP4_CR_MAXP4_SHIFT 0
+
+// EP5 - interrupt transmits
+#define EP5_CR_EP5EN (0x01 << 31)
+#define EP5_CR_FM (0x01 << 19)
+#define EP5_CR_SS5 (0x01 << 18)
+#define EP5_CR_NAK5 (0x01 << 16)
+#define EP5_CR_MAXP5_MASK (0x7F << 0)
+#define EP5_CR_MAXP5_SHIFT 0
+
+// EP6 - interrupt receives
+#define EP6_CR_EP6EN (0x01 << 31)
+#define EP6_CR_SS6 (0x01 << 18)
+#define EP6_CR_NHSK6 (0x01 << 17)
+#define EP6_CR_NAK6 (0x01 << 16)
+#define EP6_CR_MAXP6_MASK (0x7F << 0)
+#define EP6_CR_MAXP6_SHIFT 0
+
+// Some bits which can be applied to multiple transmit or receive
+// endpoint control registers, thus avoiding unnecessary code
+// duplication. These will not work for the isochronous endpoints
+// because those are just too special.
+#define EPtx_CR_EpxEN (0x01 << 31)
+#define EPtx_CR_SSx (0x01 << 18)
+#define EPtx_CR_NAKx (0x01 << 16)
+#define EPtx_CR_MAXPx_MASK (0x7F << 0)
+#define EPtx_CR_MAXPx_SHIFT 0
+
+#define EPrx_CR_EPxEN (0x01 << 31)
+#define EPrx_CR_SSx (0x01 << 18)
+#define EPrx_CR_NHSKx (0x01 << 17)
+#define EPrx_CR_NAKx (0x01 << 16)
+#define EPrx_CR_MAXPx_MASK (0x7F << 0)
+#define EPrx_CR_MAXPx_SHIFT 0
+
+// USB command register
+#define USBS_CMR_BUSY (0x01 << 31)
+#define USBS_CMR_COMMAND_MASK (0x07 << 24)
+#define USBS_CMR_COMMAND_SHIFT 24
+#define USBS_CMR_COMMAND_TX_EP0 (0x00 << 24)
+#define USBS_CMR_COMMAND_TX_EP1 (0x01 << 24)
+#define USBS_CMR_COMMAND_TX_EP3 (0x02 << 24)
+#define USBS_CMR_COMMAND_TX_EP5 (0x03 << 24)
+#define USBS_CMR_COMMAND_ADD_POOL0 (0x04 << 24)
+#define USBS_CMR_COMMAND_ADD_POOL1 (0x05 << 24)
+#define USBS_CMR_COMMAND_ADD_POOL2 (0x06 << 24)
+#define USBS_CMR_SIZE_MASK (0x0FFFF << 0)
+#define USBS_CMR_SIZE_SHIFT 0
+
+// TX Endpoint status
+#define USBS_TEPSR_EP5TS_MASK (0x03 << 24)
+#define USBS_TEPSR_EP5TS_SHIFT 24
+#define USBS_TEPSR_EP5TS_IDLE (0x00 << 24)
+#define USBS_TEPSR_EP5TS_ONE (0x01 << 24)
+#define USBS_TEPSR_EP5TS_TWO (0x02 << 24)
+#define USBS_TEPSR_EP3TS_MASK (0x03 << 16)
+#define USBS_TEPSR_EP3TS_SHIFT 16
+#define USBS_TEPSR_EP3TS_IDLE (0x00 << 16)
+#define USBS_TEPSR_EP3TS_ONE (0x01 << 16)
+#define USBS_TEPSR_EP3TS_TWO (0x02 << 16)
+#define USBS_TEPSR_EP1TS_MASK (0x03 << 8)
+#define USBS_TEPSR_EP1TS_SHIFT 8
+#define USBS_TEPSR_EP1TS_IDLE (0x00 << 8)
+#define USBS_TEPSR_EP1TS_ONE (0x01 << 8)
+#define USBS_TEPSR_EP1TS_TWO (0x02 << 8)
+#define USBS_TEPSR_EP0TS_MASK (0x03 << 0)
+#define USBS_TEPSR_EP0TS_SHIFT 0
+#define USBS_TEPSR_EP0TS_IDLE (0x00 << 0)
+#define USBS_TEPSR_EP0TS_ONE (0x01 << 0)
+#define USBS_TEPSR_EP0TS_TWO (0x02 << 0)
+
+// Receive pools. The RP0IR, RP1IR and RP2IR registers
+// all use the same bits.
+#define USBS_RPxIR_AL_MASK (0x07 << 28)
+#define USBS_RPxIR_AL_SHIFT 28
+#define USBS_RPxIR_AL_NONE (0 << 28)
+#define USBS_RPxIR_RNOD_MASK (0x0FFFF << 0)
+#define USBS_RPxIR_RNOD_SHIFT 0
+
+// The other registers do not have special bits.
+
+// Data transfers involve buffer descriptors and mailboxes. The
+// relevant data structures and fields need to be defined. For now
+// assume 32-bit mode of operation, i.e. there will be no padding
+// between two successive 32-bit entities
+
+// A transmit packet directory consists of up to 255 buffer
+// descriptors. Each buffer descriptor specifies a buffer and a size
+// of up to 64K.
+
+typedef struct TxBufferDescriptor {
+ cyg_uint32 control;
+ void* buffer;
+} TxBufferDescriptor;
+
+#define TXBUFDESC_CTRL_LAST (0x01 << 31)
+#define TXBUFDESC_CTRL_BUFDESC_MASK (0x01 << 30)
+#define TXBUFDESC_CTRL_BUFDESC_SHIFT 30
+#define TXBUFDESC_CTRL_BUFDESC_LINK (0x00 << 30)
+#define TXBUFDESC_CTRL_BUFDESC_BUFDESC (0x01 << 30)
+#define TXBUFDESC_CTRL_SIZE_MASK (0x0FFFF << 0)
+#define TXBUFDESC_CTRL_SIZE_SHIFT 0
+
+// The result of a transmit operation gets written to a mailbox
+// structure in memory.
+typedef struct TxMailbox {
+ cyg_uint32 status;
+} TxMailbox;
+
+#define TXMBOX_STATUS_IBUS_ERROR (0x01 << 10)
+#define TXMBOX_STATUS_UNDERRUN (0x01 << 9)
+#define TXMBOX_STATUS_MODE_MASK (0x01 << 8)
+#define TXMBOX_STATUS_MODE_SHIFT 8
+#define TXMBOX_STATUS_MODE_SZLP (0x00 << 8)
+#define TXMBOX_STATUS_MODE_NZLP (0x01 << 8)
+#define TXMBOX_STATUS_EPN_MASK (0x07 << 0)
+#define TXMBOX_STATUS_EPN_SHIFT 0
+#define TXMBOX_STATUS_EPN_EP0 (0x00 << 0)
+#define TXMBOX_STATUS_EPN_EP1 (0x02 << 0)
+#define TXMBOX_STATUS_EPN_EP3 (0x04 << 0)
+#define TXMBOX_STATUS_EPN_EP5 (0x06 << 0)
+
+// Now for receive operations. This involves adding buffer descriptors
+// to one of three pools. The pools are managed by registers.
+typedef struct RxBufferDescriptor {
+ cyg_uint32 control;
+ void* buffer;
+} RxBufferDescriptor;
+
+#define RXBUFDESC_CTRL_LAST (0x01 << 31)
+#define RXBUFDESC_CTRL_BUFDESC_MASK (0x01 << 30)
+#define RXBUFDESC_CTRL_BUFDESC_SHIFT 30
+#define RXBUFDESC_CTRL_BUFDESC_LINK (0x00 << 30)
+#define RXBUFDESC_CTRL_BUFDESC_BUFDESC (0x01 << 30)
+#define RXBUFDESC_CTRL_SIZE_MASK (0x0FFFF << 0)
+#define RXBUFDESC_CTRL_SIZE_SHIFT 0
+
+typedef struct RxMailbox {
+ cyg_uint32 status;
+ void* address;
+} RxMailbox;
+
+#define RXMBOX_STATUS_EPN_MASK (0x07 << 29)
+#define RXMBOX_STATUS_EPN_SHIFT 29
+#define RXMBOX_STATUS_EPN_EP0 (0x01 << 29)
+#define RXMBOX_STATUS_EPN_EP2 (0x03 << 29)
+#define RXMBOX_STATUS_EPN_EP4 (0x05 << 29)
+#define RXMBOX_STATUS_EPN_EP6 (0x07 << 29)
+#define RXMBOX_STATUS_CORRUPTION (0x01 << 25)
+#define RXMBOX_STATUS_IBUS_ERROR (0x01 << 24)
+#define RXMBOX_STATUS_SETUP_MASK (0x01 << 23)
+#define RXMBOX_STATUS_SETUP_SHIFT 23
+#define RXMBOX_STATUS_SETUP_NORMAL (0x00 << 23)
+#define RXMBOX_STATUS_SETUP_SETUP (0x01 << 23)
+#define RXMBOX_STATUS_OVERRUN (0x01 << 22)
+#define RXMBOX_STATUS_DATA_TOGGLE (0x01 << 21)
+#define RXMBOX_STATUS_CRC (0x01 << 20)
+#define RXMBOX_STATUS_BIT_STUFFING (0x01 << 19)
+#define RXMBOX_STATUS_64K (0x01 << 18)
+#define RXMBOX_STATUS_MODE_MASK (0x03 << 16)
+#define RXMBOX_STATUS_MODE_SHIFT 16
+#define RXMBOX_STATUS_MODE_NORMAL (0x00 << 16)
+#define RXMBOX_STATUS_MODE_NORMAL2 (0x01 << 16)
+#define RXMBOX_STATUS_MODE_ASSEMBLE (0x02 << 16)
+#define RXMBOX_STATUS_MODE_SEPARATE (0x03 << 16)
+#define RXMBOX_STATUS_SIZE_MASK (0x0FFFF << 0)
+#define RXMBOX_STATUS_SIZE_SHIFT 0
+
+
+// ----------------------------------------------------------------------------
+// Hardware work around - see NEC erratum S1, CPU to IBUS write restriction.
+// Reading back from the USB device after every write prevents any problems.
+// Strictly speaking it is only necessary to do this after every three
+// writes, but if there is concurrent ethernet activity then doing it
+// after eveyr write is safer. The frame number/version register seems
+// like a good one to read back from.
+
+#ifdef CYGIMP_DEVS_USB_UPD985XX_IBUS_WRITE_LIMIT
+# define FLUSH_IBUS() \
+ CYG_MACRO_START \
+ (void)*USBS_VER; \
+ CYG_MACRO_END
+
+#else
+# define FLUSH_IBUS() CYG_EMPTY_STATEMENT
+#endif
+
+// ----------------------------------------------------------------------------
+// Static data. There is a data structure for each endpoint. The
+// implementation is essentially a private class that inherits from
+// common classes for control and data endpoints, but device drivers
+// are supposed to be written in C so some ugliness is required.
+//
+// Devtab entries are defined in usbs_upd985xx_data.cxx to make sure
+// that the linker does not garbage-collect them.
+
+// Support for the interrupt handling code.
+static cyg_interrupt usbs_upd985xx_intr_data;
+static cyg_handle_t usbs_upd985xx_intr_handle;
+
+// The various bits in the two interrupt status registers are read-once,
+// i.e. reading the register clears the bits. Since much of the processing
+// is deferred to DSR level, it is necessary to keep track of pending
+// interrupts in separate variables. If another interrupt happens during
+// DSR processing, these variables will be updated. The main DSR loops
+// until there are no interesting bits left. Interrupts have to be
+// disabled briefly when clearing bits.
+static volatile cyg_uint32 usbs_upd985xx_gsr1 = 0;
+static volatile cyg_uint32 usbs_upd985xx_gsr2 = 0;
+
+// Many of the interrupt bits are of no interest and it is convenient
+// to mask them out in the ISR, thus avoiding unnecessary dsr
+// invocations.
+static cyg_uint32 usbs_upd985xx_gsr1_mask = 0;
+static cyg_uint32 usbs_upd985xx_gsr2_mask = 0;
+
+// Sizes for the receive and transmit mboxes.
+// NOTE: it is not clear what the optimal size for these
+// mailboxes is. For receives maybe one per rx endpoint,
+// plus a spare. For transmits maybe just two, since only
+// one transmit at a time is supported. Mailboxes are
+// relatively small, so for now four each should be ok.
+#define RXMBOX_COUNT 4
+#define TXMBOX_COUNT 4
+
+// There is one instance of this data structure. It is allocated
+// in kseg0 cached memory, but during initialization a separate
+// pointer value is set to the kseg1 uncached equivalent. This
+// makes it easier to point the hardware at uncached memory without
+// having to worry about cache line boundaries everywhere.
+
+typedef struct uncached_data {
+ // This partial cacheline does not actually store any data.
+ // However it ensures that the data does not share a cacheline
+ // with some other static, with updates to that other static
+ // causing funny side effects on the uncached data. There is a
+ // memory optimisation of subtracting sizeof(RxMailbox.status),
+ // i.e. exploit knowledge of alignment.
+ unsigned char cacheline_start[HAL_DCACHE_LINE_SIZE - sizeof(cyg_uint32)];
+
+ RxMailbox rx_mboxes[RXMBOX_COUNT];
+ TxMailbox tx_mboxes[TXMBOX_COUNT];
+
+ // For transmits a single buffer descriptor per endpoint suffices.
+ // If transmit locking is enabled then actually a single buffer
+ // descriptor for the whole system would suffice.
+ TxBufferDescriptor ep0_tx_bufdesc;
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+ TxBufferDescriptor ep3_tx_bufdesc;
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+ TxBufferDescriptor ep5_tx_bufdesc;
+#endif
+
+
+ // More buffer descriptors are needed than might be expected, see
+ // the start_rx routines.
+ RxBufferDescriptor ep0_rx_bufdescs[4];
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
+ RxBufferDescriptor ep4_rx_bufdescs[8];
+#endif
+
+
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
+ // Space for the start and end of a transfer, avoiding problems
+ // with invalidating partial cache lines.
+ unsigned char ep4_head[HAL_DCACHE_LINE_SIZE];
+ unsigned char ep4_tail[HAL_DCACHE_LINE_SIZE];
+#endif
+
+ // The "big" buffers come last, reducing the offsets for the previous
+ // structures. It is not clear this really matters for MIPS.
+ //
+ // Endpoint 0 receive and transmit buffers. A transmit buffer is
+ // convenient because the hardware pretty much expects all of the
+ // data to be in contiguous memory, as opposed to the normal eCos
+ // USB driver model with refill buffers etc. An alternative
+ // implementation would keep the data in separate areas but would
+ // require lots of TxBufferDescriptors, so in memory terms the
+ // overheads of a single transmit buffer are not as big as might
+ // seem. It might be possible to get things working eight bytes
+ // at a time since the hardware appears to depend on zero-byte
+ // terminating packets in places, but that has not been attempted.
+ //
+ // A separate receive buffer is useful because it can be placed in
+ // uncached memory, avoiding the need for invalidation and
+ // worrying about other data in the cache lines. Note that this
+ // buffer may also get used for endpoint 6 interrupt receives
+ // because the two endpoints share a single pool.
+ unsigned char ep0_rx_buffer[CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE];
+ unsigned char ep0_tx_buffer[CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE];
+
+ // Another cacheline to prevent overlap with other statics.
+ // This has to be full-sized since the previous field is only byte-aligned.
+ unsigned char cacheline_end[HAL_DCACHE_LINE_SIZE];
+} uncached_data;
+
+// This data structure is quite large so making it all uninitialized
+// means a potentially big saving in ROM-booting systems. This
+// requires additional effort by the endpoint initialization routines.
+static uncached_data cached_copy;
+
+static uncached_data* uncached = (uncached_data*)0;
+
+// Endpoint 0. See the description below.
+
+static void usbs_upd985xx_ep0_start(usbs_control_endpoint*);
+static void usbs_upd985xx_poll(usbs_control_endpoint*);
+
+typedef struct ep0_impl {
+ usbs_control_endpoint common;
+ cyg_bool rx_expecting_data;
+ cyg_bool rx_indicator_valid;
+ RxMailbox rx_indicator;
+ cyg_bool tx_indicator_valid;
+ TxMailbox tx_indicator;
+ cyg_bool tx_needs_zero_transfer;
+ cyg_uint32 tx_size;
+} ep0_impl;
+
+static ep0_impl ep0 = {
+ common:
+ {
+ state: USBS_STATE_POWERED, // The hardware does not distinguish between detached, attached and powered.
+ enumeration_data: (usbs_enumeration_data*) 0,
+ start_fn: &usbs_upd985xx_ep0_start,
+ poll_fn: &usbs_upd985xx_poll,
+ interrupt_vector: CYGNUM_HAL_INTERRUPT_USB,
+ control_buffer: { 0, 0, 0, 0, 0, 0, 0, 0 },
+ state_change_fn: (void (*)(usbs_control_endpoint*, void*, usbs_state_change, int)) 0,
+ state_change_data: (void*) 0,
+ standard_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
+ standard_control_data: (void*) 0,
+ class_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
+ class_control_data: (void*) 0,
+ vendor_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
+ vendor_control_data: (void*) 0,
+ reserved_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
+ reserved_control_data: (void*) 0,
+ buffer: (unsigned char*) 0,
+ buffer_size: 0,
+ fill_buffer_fn: (void (*)(usbs_control_endpoint*)) 0,
+ fill_data: (void*) 0,
+ fill_index: 0,
+ complete_fn: (usbs_control_return (*)(usbs_control_endpoint*, int)) 0
+ },
+ rx_expecting_data: false,
+ rx_indicator_valid: false,
+ rx_indicator: { 0, (void*) 0 },
+ tx_indicator_valid: false,
+ tx_indicator: { 0 },
+ tx_needs_zero_transfer: 0
+};
+
+extern usbs_control_endpoint usbs_upd985xx_ep0 __attribute__((alias ("ep0")));
+
+// Endpoint 1, isochronous transmits. This endpoint is not yet
+// supported. Although the interface for bulk transmits should be
+// mostly re-usable, there are some additional error conditions if
+// either the host or the target fails to achieve the desired
+// throughput.
+
+// Endpoint 2, isochronous receives. Not yet supported for now, just
+// like endpoint 1.
+
+// Endpoints 3 and 5 can share some code.
+#if defined(CYGPKG_DEVS_USB_UPD985XX_EP3) || defined(CYGPKG_DEVS_USB_UPD985XX_EP5)
+// Endpoint 3, bulk transmits, and endpoint 5, either interrupt transmits
+// or emulation of bulk transmits. The hardware does most
+// of the work.
+typedef struct ep35_impl {
+ usbs_tx_endpoint common;
+ cyg_bool tx_indicator_valid;
+ TxMailbox tx_indicator;
+ int send_command;
+ volatile cyg_uint32* cr;
+ TxBufferDescriptor* tx_bufdesc;
+} ep35_impl;
+
+# ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+static void ep3_start_tx(usbs_tx_endpoint*);
+static void ep3_set_halted(usbs_tx_endpoint*, cyg_bool);
+
+static ep35_impl ep3 = {
+ common: {
+ start_tx_fn: &ep3_start_tx,
+ set_halted_fn: &ep3_set_halted,
+ complete_fn: (void (*)(void*, int)) 0,
+ complete_data: (void*) 0,
+ buffer: (const unsigned char*) 0,
+ buffer_size: 0,
+ halted: 0,
+ },
+ tx_indicator_valid: false,
+ tx_indicator: { 0 },
+ send_command: USBS_CMR_COMMAND_TX_EP3,
+ cr: EP3_CR,
+ tx_bufdesc: 0 // Needs run-time initialization
+};
+
+extern usbs_tx_endpoint usbs_upd985xx_ep3 __attribute__ ((alias ("ep3")));
+# endif
+
+# ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+static void ep5_start_tx(usbs_tx_endpoint*);
+static void ep5_set_halted(usbs_tx_endpoint*, cyg_bool);
+
+static ep35_impl ep5 = {
+ common: {
+ start_tx_fn: &ep5_start_tx,
+ set_halted_fn: &ep5_set_halted,
+ complete_fn: (void (*)(void*, int)) 0,
+ complete_data: (void*) 0,
+ buffer: (const unsigned char*) 0,
+ buffer_size: 0,
+ halted: 0,
+ },
+ tx_indicator_valid: false,
+ tx_indicator: { 0 },
+ send_command: USBS_CMR_COMMAND_TX_EP5,
+ cr: EP5_CR,
+ tx_bufdesc: 0 // Needs run-time initialization
+};
+
+extern usbs_tx_endpoint usbs_upd985xx_ep5 __attribute__ ((alias ("ep5")));
+# endif
+#endif
+
+
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
+// Endpoint 4, bulk receives. Again the hardware does the hard work.
+// Receive pool 2 is reserved for this endpoint.
+
+typedef struct ep4_impl {
+ usbs_rx_endpoint common;
+ cyg_uint32 head_size;
+ cyg_uint32 direct_size;
+ cyg_uint32 tail_size;
+ cyg_bool rx_indicator_valid;
+ RxMailbox rx_indicator;
+ cyg_int32 tail_index;
+} ep4_impl;
+
+static void ep4_start_rx(usbs_rx_endpoint*);
+static void ep4_set_halted(usbs_rx_endpoint*, cyg_bool);
+
+static ep4_impl ep4 = {
+ common: {
+ start_rx_fn: &ep4_start_rx,
+ set_halted_fn: &ep4_set_halted,
+ complete_fn: (void (*)(void*, int)) 0,
+ complete_data: (void*) 0,
+ buffer: (unsigned char*) 0,
+ buffer_size: 0,
+ halted: 0,
+ },
+ rx_indicator_valid: false,
+ rx_indicator: { 0, (void*) 0 },
+ tail_index: -1
+};
+
+extern usbs_rx_endpoint usbs_upd985xx_ep4 __attribute__((alias ("ep4")));
+#endif
+
+// Endpoint 6, interrupt receives. Not yet implemented. There may
+// be conflicts because the hardware is shared with endpoint 0.
+
+// ----------------------------------------------------------------------------
+// Mailbox support.
+//
+// The transmit and receive mailboxes are shared between the
+// appropriate endpoints. This causes some complications if e.g.
+// transmits on several endpoints complete at the same time. For
+// example the tx mailbox might contain send indicators for endpoints
+// 3 and 0, but the DSR code will process endpoint 0 before endpoint
+// 3.
+//
+// This device driver works on the basis that there can be only one
+// transmit and/or receive in progress for any given endpoint, so the
+// relevant information can be extracted from the mailbox and put into
+// the per-endpoint structures. The routines below can be used to
+// move data from the mailboxes. They will be called in DSR context
+// so there is no need to worry about locking.
+
+static void
+drain_tx_mailbox(void)
+{
+ TxMailbox* tmra = IBUS_SWAPPTR(TxMailbox, *USBS_TMRA);
+ TxMailbox* tmwa = IBUS_SWAPPTR(TxMailbox, *USBS_TMWA);
+ if (tmra != tmwa) {
+ do {
+ TxMailbox mbox = *tmra;
+ tmra++;
+ if (tmra == &(uncached->tx_mboxes[TXMBOX_COUNT])) {
+ tmra = &(uncached->tx_mboxes[0]);
+ }
+
+ switch(mbox.status & TXMBOX_STATUS_EPN_MASK) {
+ case TXMBOX_STATUS_EPN_EP0:
+ CYG_ASSERT(false == ep0.tx_indicator_valid, "Only one ep0 transmit should be in progress at a time");
+ ep0.tx_indicator = mbox;
+ ep0.tx_indicator_valid = true;
+ break;
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+ case TXMBOX_STATUS_EPN_EP3:
+ CYG_ASSERT(false == ep3.tx_indicator_valid, "Only one ep3 transmit should be in progress at a time");
+ ep3.tx_indicator = mbox;
+ ep3.tx_indicator_valid = true;
+ break;
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+ case TXMBOX_STATUS_EPN_EP5:
+ CYG_ASSERT(false == ep5.tx_indicator_valid, "Only one ep5 transmit should be in progress at a time");
+ ep5.tx_indicator = mbox;
+ ep5.tx_indicator_valid = true;
+ break;
+#endif
+ default:
+ break;
+ }
+ } while (tmra != tmwa);
+ *USBS_TMRA = IBUS_SWAPPTR(TxMailbox, tmra); FLUSH_IBUS();
+ }
+}
+
+static void
+drain_rx_mailbox(void)
+{
+ RxMailbox* rmra = IBUS_SWAPPTR(RxMailbox, *USBS_RMRA);
+ RxMailbox* rmwa = IBUS_SWAPPTR(RxMailbox, *USBS_RMWA);
+
+ if (rmra != rmwa) {
+ do {
+ RxMailbox mbox = *rmra;
+ rmra++;
+ if (rmra == &(uncached->rx_mboxes[RXMBOX_COUNT])) {
+ rmra = &(uncached->rx_mboxes[0]);
+ }
+
+ switch(mbox.status & RXMBOX_STATUS_EPN_MASK) {
+ case RXMBOX_STATUS_EPN_EP0:
+ // Ignore zero-byte transfers. It is not clear why
+ // these happen, but they have been observed.
+ if (0 != (mbox.status & RXMBOX_STATUS_SIZE_MASK)) {
+ CYG_ASSERT(false == ep0.rx_indicator_valid, "Only one ep0 receive should be in progress at a time");
+ ep0.rx_indicator = mbox;
+ ep0.rx_indicator_valid = true;
+ }
+ break;
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
+ case RXMBOX_STATUS_EPN_EP4:
+ // If an error occurs then the hardware may report
+ // multiple rx completions, each with an IBUS error
+ // indicator. For now only the last rx indicator is
+ // taken into account, which means we could lose
+ // a successful receive that happens to be followed
+ // by an error.
+ // NOTE: any possibility of improving on this?
+#if 1
+ CYG_ASSERT(false == ep4.rx_indicator_valid, "Only one ep4 receive should be in progress at a time");
+#endif
+ ep4.rx_indicator = mbox;
+ ep4.rx_indicator_valid = true;
+ break;
+#endif
+ default:
+ break;
+ }
+ } while (rmra != rmwa);
+ *USBS_RMRA = IBUS_SWAPPTR(RxMailbox, rmra); FLUSH_IBUS();
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Transmit locking.
+//
+// According to NEC errata U3 and U4 the hardware may exhibit
+// undesirable behaviour if there are concurrent transmissions. There
+// are various ways of resolving this, but the simplest is to perform
+// locking in software so that at most one transmit endpoint is in use
+// at any one time. This approach works fine if transmissions only
+// involve one tx endpoint plus the control endpoint because the
+// control endpoint generally only gets used during initialization and
+// the other endpoint only gets used after initialization. If multiple
+// transmit endpoints are used then locking in software becomes less
+// acceptable, especially if isochronous transfers are used because
+// timing is important for those.
+//
+// There is a theoretical problem if e.g. there is a very large bulk
+// transfer on a busy bus and it is necessary to respond to a control
+// message. The control reply would be delayed, possibly causing a
+// violation of the USB standard and a timeout on the host.
+
+#ifdef CYGIMP_DEVS_USB_UPD985XX_SERIALIZE_TRANSMITS
+static void ep0_start_tx(void);
+# if defined(CYGPKG_DEVS_USB_UPD985XX_EP3) || defined(CYGPKG_DEVS_USB_UPD985XX_EP5)
+static void ep35_start_tx(ep35_impl*);
+# endif
+
+static cyg_bool tx_in_progress = false;
+static cyg_bool ep0_tx_pending = false;
+# ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+static cyg_bool ep3_tx_pending = false;
+# endif
+# ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+static cyg_bool ep5_tx_pending = false;
+# endif
+
+// Invoked from ep?_start_tx(). Scheduling may or may not be locked.
+static cyg_bool
+tx_try_lock(cyg_bool* which)
+{
+ cyg_bool result;
+ cyg_drv_dsr_lock();
+ if (tx_in_progress) {
+ result = false;
+ *which = true;
+ } else {
+ result = true;
+ tx_in_progress = true;
+ }
+ cyg_drv_dsr_unlock();
+ return result;
+}
+
+// Invoked only from dsr context.
+static void
+tx_unlock(void)
+{
+ tx_in_progress = false;
+ if (ep0_tx_pending) {
+ ep0_tx_pending = false;
+ ep0_start_tx();
+ return;
+ }
+# ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+ if (ep3_tx_pending) {
+ ep3_tx_pending = false;
+ ep35_start_tx(&ep3);
+ return;
+ }
+# endif
+# ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+ if (ep5_tx_pending) {
+ ep5_tx_pending = false;
+ ep35_start_tx(&ep5);
+ return;
+ }
+# endif
+}
+
+# define TX_TRY_LOCK(_x_) tx_try_lock(_x_)
+# define TX_UNLOCK() tx_unlock()
+
+#else
+
+# define TX_TRY_LOCK(_x_) 1
+# define TX_UNLOCK() CYG_EMPTY_STATEMENT
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+// Endpoint 0
+//
+// As usual, control messages are more complicated than the rest.
+//
+// 1) during initialization a receive is initiated into the common
+// eight-byte buffer, used for the standard header of the control
+// packet. Until that header has been received and analysed,
+// there is no way of knowing whether or not the host will be
+// sending any more data.
+//
+// 2) the control packet may indicate that the host will be sending
+// more data. A higher-level handler for the control message should
+// have provided a suitable buffer, so a receive can be started
+// into that buffer. A flag indicates whether we are currently
+// receiving a new control packet or additional data.
+//
+// 3) the host may decide to cancel that extra data and send a new
+// control message instead. There is a flag to indicate that
+// the transfer included a SETUP token.
+//
+// 4) transmits only happen when the control packet involves returning
+// data. Unfortunately there is a problem in that, with eCos, the
+// return data will generally not be in a single contiguous buffer.
+// Discontinuous data could be handled by having a separate buffer
+// descriptor for each bit of data, but it is not known in advance
+// how many buffer descriptors might be needed so allocating
+// those statically presents a problem as well. Instead a single
+// static buffer is used, and data from higher-level code is copied
+// there. This introduces a new problem: how big should that buffer
+// be? A configuration option is used for that.
+//
+// If endpoint 6 is in use as well then things get more complicated
+// because a single receive pool will be shared between endpoints 0
+// and 6, and when adding a buffer to a pool there is no way of
+// specifying the endpoint. Hence it will be necessary to receive
+// into a static buffer and then copy into either an endpoint 0 or
+// and endpoint 6 buffer.
+
+// Fill the transmit buffer by repeatedly invoking the refill function
+// and copying into the ep0 tx buffer. The relevant fields in the
+// ep0 structure are cleared immediately and the completion function
+// is called, even though the data has not actually gone out. That avoids
+// a possible race condition where the host sends a new control packet
+// immediately, before the transmit-complete has been processed
+// (unlikely in practice, not least because ep0_tx_dsr() will get called
+// before ep0_rx_dsr()).
+static int
+ep0_fill_txbuffer(void)
+{
+ int filled = 0;
+ while (filled < CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE) {
+ if (0 != ep0.common.buffer_size) {
+ if ((filled + ep0.common.buffer_size) < CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE) {
+ memcpy(&(uncached->ep0_tx_buffer[filled]), ep0.common.buffer, ep0.common.buffer_size);
+ filled += ep0.common.buffer_size;
+ ep0.common.buffer_size = 0;
+ } else {
+ break;
+ }
+ } else if ((void (*)(usbs_control_endpoint*))0 != ep0.common.fill_buffer_fn) {
+ (*ep0.common.fill_buffer_fn)(&ep0.common);
+ } else {
+ break;
+ }
+ }
+ CYG_ASSERT((0 == ep0.common.buffer_size) && ((void (*)(usbs_control_endpoint*))0 == ep0.common.fill_buffer_fn), \
+ "Endpoint 0 transmit buffer overflow");
+
+ if ((usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn) {
+ (*ep0.common.complete_fn)(&ep0.common, 0);
+ }
+ ep0.common.buffer = (unsigned char*) 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.fill_buffer_fn = 0;
+ ep0.common.complete_fn = 0;
+
+ return filled;
+}
+
+// Start a new receive operation on endpoint 0. This needs to happen
+// from a number of places, including from initialization.
+//
+// IMHO the hardware is somewhat overengineered here. All that is
+// needed is to receive a single eight-byte control packet, or a
+// small amount of additional control data. That could be achieved
+// by using a single buffer descriptor in the uncached structure,
+// plus a suitably-sized static uncached ep0_rx_buffer.
+//
+// But no, buffer descriptors must be linked and new buffers must
+// be added to the end. When a control packet arrives, the
+// receive pool continues to point at the old buffer descriptor.
+// So we need two buffer descriptors plus two links, switching
+// between them as appropriate.
+//
+// It is not at all clear what would happen if another packet
+// started to happen while things were being updated. There is
+// also potential confusion between endpoint 0 and endpoint 6
+// receives.
+
+static void
+ep0_start_rx(cyg_uint32 size)
+{
+ // The buffer descriptor to be added. This will be either
+ // ep0_rxbufdescs[0] or ep0_rxbufdescs[2];
+ RxBufferDescriptor* desc = &(uncached->ep0_rx_bufdescs[0]);
+
+ CYG_ASSERTC(size > 0);
+
+ // Block interrupts for the duration. This does not prevent
+ // problems if the hardware sees another packet and starts
+ // doing things, but should prevent some software race
+ // conditions.
+ cyg_drv_isr_lock();
+
+ // We are about to start a new rx operation, so the
+ // current indicator may get invalidated.
+ ep0.rx_indicator_valid = false;
+
+ // Start by looking at the current pool0 status. There are
+ // three possibilities: during init or after reset, the pool
+ // will be empty; otherwise the pool should point at either
+ // rx_bufdescs[0] or rx_bufdescs[2], corresponding to the
+ // last received packet.
+ if (0 == (*USBS_RP0IR & USBS_RPxIR_RNOD_MASK)) {
+ // Nothing currently in the pool. Use ep0_rx_bufdescs[0],
+ // and no need to update a link.
+ } else if (desc == *USBS_RP0AR) {
+ // The pool already points at bufdescs[0], switch to bufdescs[2],
+ // and link from bufdescs[1].
+ desc = &(uncached->ep0_rx_bufdescs[2]);
+ uncached->ep0_rx_bufdescs[1].buffer = (void*) desc;
+ } else {
+ // The pool should point at bufdescs[2], stick with bufdescs[0]
+ CYG_ASSERT(&(uncached->ep0_rx_bufdescs[2]) == *USBS_RP0AR, "Endpoint 0 rx buffer confusion");
+ uncached->ep0_rx_bufdescs[3].buffer = (void*) desc;
+ }
+
+ // Now fill in the buffer directory being added
+ desc[0].control = RXBUFDESC_CTRL_LAST | RXBUFDESC_CTRL_BUFDESC_BUFDESC | size;
+ desc[0].buffer = (void*) uncached->ep0_rx_buffer;
+ desc[1].control = RXBUFDESC_CTRL_BUFDESC_LINK;
+ desc[1].buffer = 0;
+
+ while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
+ // Do nothing: this situation should be short-lived.
+ }
+ *USBS_CA = IBUS_SWAPPTR(void, desc); FLUSH_IBUS();
+ *USBS_CMR = IBUS_SWAP32(USBS_CMR_COMMAND_ADD_POOL0 | 1); FLUSH_IBUS();
+ cyg_drv_isr_unlock();
+}
+
+// Ditto for transmits. The data is assumed to be in
+// uncached->ep0_tx_buffer already. A size of 0 indicates
+// a need to send a terminating packet explicitly.
+static void
+ep0_start_tx(void)
+{
+ if (!TX_TRY_LOCK(&ep0_tx_pending)) {
+ return;
+ }
+
+ uncached->ep0_tx_bufdesc.buffer = uncached->ep0_tx_buffer;
+ uncached->ep0_tx_bufdesc.control = TXBUFDESC_CTRL_LAST | TXBUFDESC_CTRL_BUFDESC_BUFDESC | ep0.tx_size;
+
+ cyg_drv_isr_lock();
+ while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
+ // Do nothing: this situation should be short-lived.
+ }
+ *USBS_CA = IBUS_SWAPPTR(void, &(uncached->ep0_tx_bufdesc)); FLUSH_IBUS();
+ *USBS_CMR = IBUS_SWAP32(USBS_CMR_COMMAND_TX_EP0 | ep0.tx_size); FLUSH_IBUS();
+ cyg_drv_isr_unlock();
+}
+
+// An endpoint 0 transmission has completed. Usually the only action
+// that is needed is to drain the tx mailbox entry, otherwise it is
+// possible that we could end up with ep0 transmits using up all
+// available slots. The endpoint 0 hardware requires no further
+// attention, and as far as higher-level code is concerned the
+// transmission completed a long time ago when ep0_fill_txbuffer()
+// called the completion function.
+//
+// There is one special case. If the host asked for e.g. a string
+// descriptor and asked for 255 bytes, but the string was only
+// e.g. 32 bytes, then there is a problem. With a default value
+// for CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE, the data will be
+// transferred as four 8-byte packets, but it is necessary to
+// terminate the transfer with a 0-byte packet. Endpoint 0 always
+// operates in NZLP mode so the hardware will never generate
+// this last packet. Instead it is necessary to set up an
+// additional transfer of zero bytes. That could be done at the
+// same time as the main data transfer, but then it would be
+// necessary to poll the hardware and wait until it has finished
+// processing that initial transfer.
+static void
+ep0_tx_dsr(void)
+{
+ if (!ep0.tx_indicator_valid) {
+ drain_tx_mailbox();
+ if (!ep0.tx_indicator_valid) {
+ // A transmit interrupt when there does not appear to be
+ // any data?
+ CYG_FAIL("EP0 tx DSR invoked when there is no valid tx indicator");
+ return;
+ }
+ }
+ // There is not actually anything worth looking at in the status.
+ ep0.tx_indicator_valid = false;
+
+ if (ep0.tx_needs_zero_transfer) {
+ ep0.tx_needs_zero_transfer = false;
+ uncached->ep0_tx_bufdesc.buffer = uncached->ep0_tx_buffer;
+ uncached->ep0_tx_bufdesc.control = TXBUFDESC_CTRL_LAST | TXBUFDESC_CTRL_BUFDESC_BUFDESC | 0;
+
+ cyg_drv_isr_lock();
+ while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
+ // Do nothing: this situation should be short-lived.
+ }
+ *USBS_CA = IBUS_SWAPPTR(void, &(uncached->ep0_tx_bufdesc)); FLUSH_IBUS();
+ *USBS_CMR = IBUS_SWAP32(USBS_CMR_COMMAND_TX_EP0 | 0); FLUSH_IBUS();
+ cyg_drv_isr_unlock();
+
+ } else {
+ TX_UNLOCK();
+ }
+}
+
+// An endpoint 0 receive has completed. This could be a new control
+// message. Or it could be the data for a previous control message. Or
+// it could be a new control message when expecting the data from
+// a previous one. The ep0.rx_expecting_data field indicates
+// whether or not a new control message is expected.
+//
+// At times an interrupt triggers and there is an rx indication for a
+// zero-byte transfer. Such a transfer may be followed immediately by
+// a real transfer. It is not understood why the zero-byte transfer
+// occurs. They are ignored by the drain_rx_mailbox() code, to make
+// sure that there is at most one valid rx indicator at a time.
+static void
+ep0_rx_dsr(void)
+{
+ // Start by checking the rx indicator to make sure that a packet
+ // really has been received.
+ if (!ep0.rx_indicator_valid) {
+ drain_rx_mailbox();
+ if (!ep0.rx_indicator_valid) {
+ // Do not assert, in case of a spurious interrupt for a
+ // zero-byte transfer.
+ return;
+ }
+ }
+
+ // We have a valid receive, with the data held in uncached->ep0_rx_buffer.
+ // Are we expecting the remaining data of a control transfer?
+ if (ep0.rx_expecting_data) {
+ // Was this data interrupted by a new setup packet?
+ if (0 != (ep0.rx_indicator.status & RXMBOX_STATUS_SETUP_SETUP)) {
+ // NOTE: it is not clear from the documentation exactly what
+ // happens here, e.g. is it guaranteed that the new control
+ // packet appears at the start of the buffer rather than
+ // after any data previously received? Given typical
+ // USB host-side implementations this scenario is considered
+ // sufficiently unlikely that no further investigation has
+ // been carried out.
+
+ // Inform higher-level code that the receive has been aborted.
+ if ((usbs_control_return (*)(usbs_control_endpoint*, int)) 0 != ep0.common.complete_fn) {
+ (*ep0.common.complete_fn)(&ep0.common, -EIO);
+ }
+ ep0.rx_expecting_data = false;
+ ep0.common.buffer = (unsigned char*) 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.fill_buffer_fn = 0;
+ ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
+ // Fall through the main control message handling code below.
+ } else {
+ // Data was expected and received. Transfer the data to the
+ // user's buffer, and perform completion.
+ usbs_control_return result;
+ cyg_uint32 size = ep0.rx_indicator.status & RXMBOX_STATUS_SIZE_MASK;
+
+ CYG_ASSERT( (usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn, \
+ "A completion function should be provided for OUT control messages");
+ CYG_ASSERT(size == ep0.common.buffer_size, "Inconsistency between buffer and transfer sizes");
+ memcpy(ep0.common.buffer, uncached->ep0_rx_buffer, size);
+ result = (*ep0.common.complete_fn)(&ep0.common, 0);
+ ep0.common.buffer = (unsigned char*) 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
+ ep0.rx_expecting_data = false;
+
+ // Start another receive for the next control message.
+ // Note that there has been a window where there was no receive
+ // in progress for endpoint 0, even though according to the
+ // USB spec a device must always be able to accept new
+ // control messages.
+ ep0_start_rx(8);
+ return;
+ }
+ }
+
+ // When we get here we should have an eight-byte control message
+ // in uncached->ep0_rx_buffer. This should get moved into
+ // the ep0.common.control_buffer so that higher-level code sees
+ // it in the appropriate location.
+ CYG_ASSERT((ep0.rx_indicator.address == &(uncached->ep0_rx_bufdescs[0])) || \
+ (ep0.rx_indicator.address == &(uncached->ep0_rx_bufdescs[2])), \
+ "Received ep0 data should involve the ep0 rx buffer descriptor");
+
+ CYG_ASSERT(8 == (ep0.rx_indicator.status & RXMBOX_STATUS_SIZE_MASK), "Control messages should be 8 bytes");
+ memcpy(ep0.common.control_buffer, uncached->ep0_rx_buffer, 8);
+
+ // If we have received a control packet then any reset signals really
+ // will have come from the host and must be processed normally.
+ // Make sure that reset interrupts are no longer masked off.
+ if (0 == (*USBS_IMR2 & IBUS_SWAP32(USBS_GSR2_URST))) {
+ *USBS_IMR2 |= IBUS_SWAP32(USBS_GSR2_URST); FLUSH_IBUS();
+ usbs_upd985xx_gsr2_mask |= USBS_GSR2_URST;
+ }
+
+ {
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+ usb_devreq* req = (usb_devreq*) ep0.common.control_buffer;
+ int length, direction, protocol, recipient;
+
+ // Now we need to do some decoding of the data. A non-zero
+ // length field indicates that there will be a subsequent
+ // IN or OUT phase. The direction is controlled by the
+ // top bit of the first byte. The protocol is determined
+ // by other bits of the top byte.
+ length = (req->length_hi << 8) | req->length_lo;
+ direction = req->type & USB_DEVREQ_DIRECTION_MASK;
+ protocol = req->type & USB_DEVREQ_TYPE_MASK;
+ recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+
+ DBG(("ep0, new control request: type %x, code %x\n", req->type, req->request));
+ DBG((" %s, length %d, value hi %x lo %x, index hi %x lo %x\n",
+ (USB_DEVREQ_DIRECTION_OUT == direction) ? "out" : "in",
+ length, req->value_hi, req->value_lo, req->index_hi, req->index_lo));
+
+ if (USB_DEVREQ_TYPE_STANDARD == protocol) {
+
+ // First see if the request can be handled entirely in
+ // this module.
+ if (USB_DEVREQ_SET_ADDRESS == req->request) {
+ // The USB device address should be in value_lo.
+ // No more data is expected.
+ int old_state = ep0.common.state;
+ int address = req->value_lo;
+ if ((0 != length) || (address > 127)) {
+ result = USBS_CONTROL_RETURN_STALL;
+ } else {
+ *USBS_GMR = (*USBS_GMR & ~(USBS_GMR_FA_MASK | USBS_GMR_VT)) | (address << USBS_GMR_FA_SHIFT); FLUSH_IBUS();
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ // Switch to addressed state, informing higher-level
+ // code of this.
+ if (USBS_STATE_ADDRESSED != (old_state & USBS_STATE_MASK)) {
+ ep0.common.state = USBS_STATE_ADDRESSED;
+ if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ USBS_STATE_CHANGE_ADDRESSED, old_state);
+ }
+ }
+ // End of SET_ADDRESS handling
+ } else if (USB_DEVREQ_GET_STATUS == req->request) {
+ // GET_STATUS on the device as a whole is used to
+ // check the remote-wakeup and self-powered bits.
+ // GET_STATUS on an endpoint is used to determine
+ // the halted condition.
+ // GET_STATUS on anything else has to be left to
+ // other code.
+ if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {
+ // The host should expect two bytes back.
+ if ((2 == length) && (USB_DEVREQ_DIRECTION_IN == direction)) {
+ ep0.common.control_buffer[0] = 0; // Not self-powered, no remote wakeup
+ ep0.common.control_buffer[1] = 0;
+ ep0.common.buffer = ep0.common.control_buffer;
+ ep0.common.buffer_size = 2;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ } else {
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+
+ } else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {
+ if ((2 == length) && (USB_DEVREQ_DIRECTION_IN == direction)) {
+ int endpoint = req->index_lo;
+ if (0 == endpoint) {
+ // get-status on endpoint 0 is either undefined or always valid.
+ // endpoint 0 is always up.
+ ep0.common.control_buffer[0] = 0;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+ else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 3) == endpoint) &&
+ (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
+ ep0.common.control_buffer[0] = ep3.common.halted;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
+ else if (((USB_DEVREQ_INDEX_DIRECTION_OUT | 4) == endpoint) &&
+ (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
+ ep0.common.control_buffer[0] = ep4.common.halted;
+ result = USBS_CONTROL_RETURN_HANDLED;
+
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+ else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 5) == endpoint) &&
+ (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
+ ep0.common.control_buffer[0] = ep5.common.halted;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#endif
+ else {
+ // An invalid endpoint has been specified or the
+ // endpoint can only be examined in configured state.
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+ if (USBS_CONTROL_RETURN_HANDLED == result) {
+ ep0.common.control_buffer[1] = 0;
+ ep0.common.buffer = ep0.common.control_buffer;
+ ep0.common.buffer_size = 2;
+ }
+ } else {
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+ } // Endpoint or device get-status
+
+ } else if (USB_DEVREQ_CLEAR_FEATURE == req->request) {
+
+ // CLEAR_FEATURE operates in much the same way as
+ // GET_STATUS
+ if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {
+
+ // No data should be transferred, and only remote-wakeup can be cleared.
+ if ((0 != length) || (USB_DEVREQ_FEATURE_DEVICE_REMOTE_WAKEUP != req->value_lo)) {
+ result = USBS_CONTROL_RETURN_STALL;
+ } else {
+ // Clearing remote-wakeup is a no-op.
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+
+ } else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {
+ // The only feature that can be cleared is endpoint-halt, no data should be transferred.
+ if ((0 != length) || (USB_DEVREQ_FEATURE_ENDPOINT_HALT != req->value_lo)) {
+ result = USBS_CONTROL_RETURN_STALL;
+ } else {
+ int endpoint = req->index_lo;
+ if (0 == endpoint) {
+ // Clearing halt on endpoint 0 is always a no-op since that endpoint cannot be halted
+ }
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+ else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 3) == endpoint) &&
+ (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
+ ep3_set_halted(&ep3.common, false);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
+ else if (((USB_DEVREQ_INDEX_DIRECTION_OUT | 4) == endpoint) &&
+ (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
+ ep4_set_halted(&ep4.common, false);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+ else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 5) == endpoint) &&
+ (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
+ ep5_set_halted(&ep5.common, false);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#endif
+ else {
+ // Invalid endpoint or not in configured state.
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+ }
+ } // Endpoing or device clear-feature
+
+ } else if (USB_DEVREQ_SET_FEATURE == req->request) {
+
+ // SET_FEATURE also operates in much the same way as
+ // GET_STATUS
+ if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {
+ // The only valid feature that can be set is remote-wakeup,
+ // which is not supported by this driver.
+ result = USBS_CONTROL_RETURN_STALL;
+
+ } else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {
+
+ // Only the halt condition can be set, and no data should be transferred.
+ // Halting endpoint 0 should probably be disallowed although the
+ // standard does not explicitly say so.
+ if ((0 != length) ||
+ (USB_DEVREQ_FEATURE_ENDPOINT_HALT != req->value_lo) ||
+ (USBS_STATE_CONFIGURED != (ep0.common.state & USBS_STATE_MASK))) {
+
+ result = USBS_CONTROL_RETURN_STALL;
+
+ } else {
+ int endpoint = req->index_lo;
+ if (0) {
+ }
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+ else if ((USB_DEVREQ_INDEX_DIRECTION_IN | 3) == endpoint) {
+ ep3_set_halted(&ep3.common, true);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
+ else if ((USB_DEVREQ_INDEX_DIRECTION_OUT | 4) == endpoint) {
+ ep4_set_halted(&ep4.common, true);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+ else if ((USB_DEVREQ_INDEX_DIRECTION_IN | 5) == endpoint) {
+ ep5_set_halted(&ep5.common, true);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#endif
+ else {
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+ }
+ } // Endpoint or device set-feature
+ }
+
+ // If the result has not been handled yet, pass it to
+ // the installed callback function (if any).
+ if (USBS_CONTROL_RETURN_UNKNOWN == result) {
+ if ((usbs_control_return (*)(usbs_control_endpoint*, void*))0 != ep0.common.standard_control_fn) {
+ result = (*ep0.common.standard_control_fn)(&ep0.common, ep0.common.standard_control_data);
+ }
+ }
+
+ // If the result has still not been handled, leave it to
+ // the default implementation in the USB slave common place.
+ if (USBS_CONTROL_RETURN_UNKNOWN == result) {
+ result = usbs_handle_standard_control(&ep0.common);
+ }
+ } else {
+ // The other three types of control message can be
+ // handled by similar code.
+ usbs_control_return (*callback_fn)(usbs_control_endpoint*, void*);
+ void* callback_arg;
+
+ if (USB_DEVREQ_TYPE_CLASS == protocol) {
+ callback_fn = ep0.common.class_control_fn;
+ callback_arg = ep0.common.class_control_data;
+ } else if (USB_DEVREQ_TYPE_VENDOR == protocol) {
+ callback_fn = ep0.common.vendor_control_fn;
+ callback_arg = ep0.common.vendor_control_data;
+ } else {
+ callback_fn = ep0.common.reserved_control_fn;
+ callback_arg = ep0.common.reserved_control_data;
+ }
+
+ if ((usbs_control_return (*)(usbs_control_endpoint*, void*)) 0 == callback_fn) {
+ result = USBS_CONTROL_RETURN_STALL;
+ } else {
+ result = (*callback_fn)(&ep0.common, callback_arg);
+ }
+ }
+
+ if (USBS_CONTROL_RETURN_HANDLED != result) {
+ // This control request cannot be handled. Generate a stall.
+ // These stalls will be cleared automaticaly by the next
+ // setup packet.
+ *EP0_CR |= (EP0_CR_ISS | EP0_CR_OSS); FLUSH_IBUS();
+ // Start a receive for the next control message
+ ep0_start_rx(8);
+ } else {
+ // The control request has been handled. Is there any more
+ // data to be transferred?
+ if (0 == length) {
+ // Definitely start a receive for another control message
+ ep0_start_rx(8);
+
+ // This operation is complete so we need to ack. It
+ // appears that the way to achieve this is to send a
+ // zero-byte packet.
+ ep0.tx_size = 0;
+ ep0_start_tx();
+
+ } else {
+ // Time to check the direction.
+
+ if (USB_DEVREQ_DIRECTION_OUT == direction) {
+ // The host expects to send more data. Higher-level code
+ // should have provided an appropriate buffer.
+ CYG_ASSERT( (unsigned char*) 0 != ep0.common.buffer, "A receive buffer should have been provided");
+ CYG_ASSERT( (usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn, \
+ "A completion function should be provided for OUT control messages");
+ CYG_ASSERT(length <= CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE, "Insufficient buffer space configured");
+
+ ep0.rx_expecting_data = true;
+ ep0_start_rx(length);
+ } else {
+ // The host expects to be able to read some data.
+ // This needs to go into a single contiguous
+ // buffer, and then the transfer can be started.
+ // Care has to be taken with various boundary conditions.
+ int actual_length = ep0_fill_txbuffer();
+ if (actual_length > length) {
+ actual_length = length;
+ }
+ if ((length != actual_length) && (0 == (actual_length % CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE))) {
+ ep0.tx_needs_zero_transfer = true;
+ } else {
+ ep0.tx_needs_zero_transfer = false;
+ }
+ ep0.tx_size = actual_length;
+ ep0_start_tx();
+
+ // And make sure that there is another receive in progress
+ // for the next setup packet.
+ ep0_start_rx(8);
+ }
+ }
+ } // Control message handled
+ }
+}
+
+// Endpoint 0 initialization also takes care of initializing generic bits
+// of the USB controller, for example letting through resume and suspend
+// interrupts and setting up the mailboxes. Also, it is necessary to
+// start a receive operation so that the first control message can
+// be processed. This code gets called during device driver initialization
+// and after a reset from the host.
+static void
+ep0_init(void)
+{
+ // Reset the various fields in the ep0 structure.
+ ep0.common.buffer = (unsigned char*) 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
+ ep0.common.fill_data = (void*) 0;
+ ep0.common.fill_index = 0;
+ ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
+ ep0.rx_expecting_data = false;
+ ep0.tx_indicator_valid = false;
+ ep0.rx_indicator_valid = false;
+ ep0.tx_needs_zero_transfer = false;
+
+#ifdef CYGIMP_DEVS_USB_UPD985XX_SERIALIZE_TRANSMITS
+ tx_in_progress = false;
+ ep0_tx_pending = false;
+# ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+ ep3_tx_pending = false;
+# endif
+# ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+ ep5_tx_pending = false;
+# endif
+#endif
+
+ // The general mode register. We do not have an address yet. The
+ // SOFINTVL field needs to be set to its default value. The other
+ // bits should be zero for now.
+ *USBS_GMR = USBS_GMR_SOFINTVL_DEFAULT_VALUE; FLUSH_IBUS();
+
+ // The version register and the status registers are read-only.
+
+ // Interrupt masks. Endpoint 0 transmits and receives both have
+ // to be detected, as do the control operations. There should
+ // be no need to worry about full mailboxes or empty receive
+ // pools. DMA errors might be of interest, but it is not clear
+ // what to do about them since there does not appear to be
+ // a way of figuring out which transfer is affected. Frame number
+ // and addressing problems are ignored, there is nothing obvious
+ // that can be done about these. The other endpoints have their
+ // own initialization routines.
+ //
+ // Care has to be taken with reset interrupts. With some hardware
+ // the usb lines may be left floating during initialization, so
+ // the chip believes it sees continuous reset interrupts. There
+ // also appear to be problems if the host does generate a real
+ // reset signal, with interrupt storms lasting 10 or more
+ // milliseconds and preventing any other activity from taking
+ // place. What is done here is that reset interrupts are enabled
+ // if in the initial POWERED state. When a reset is detected,
+ // either a spurious one or a real reset from the host,
+ // handle_reset() will move the target to DEFAULT state, call
+ // ep0_init() again, and reset interrupts will be masked out.
+ // When a real control request is received from the host we
+ // know we have a good connection and the reset interrupt will
+ // be unmasked in ep0_rx_dsr(), so further resets from the
+ // host will be processed correctly. If the target is disconnected
+ // then we may again get a spurious reset interrupt, so we end
+ // up back in DEFAULT state and the reset interrupt would be
+ // masked again.
+ *USBS_IMR1 = IBUS_SWAP32(USBS_GSR1_GSR2 | USBS_GSR1_EP0TF | USBS_GSR1_EP0RF); FLUSH_IBUS();
+ usbs_upd985xx_gsr1_mask = (USBS_GSR1_EP0TF | USBS_GSR1_EP0RF);
+ if (USBS_STATE_DEFAULT == (ep0.common.state & USBS_STATE_MASK)) {
+ *USBS_IMR2 = IBUS_SWAP32(USBS_GSR2_URSM | USBS_GSR2_USPD); FLUSH_IBUS();
+ usbs_upd985xx_gsr2_mask = (USBS_GSR2_URSM | USBS_GSR2_USPD);
+ } else {
+ *USBS_IMR2 = IBUS_SWAP32(USBS_GSR2_URSM | USBS_GSR2_URST | USBS_GSR2_USPD); FLUSH_IBUS();
+ usbs_upd985xx_gsr2_mask = (USBS_GSR2_URSM | USBS_GSR2_URST | USBS_GSR2_USPD);
+ }
+
+ // Writing to the command register is a bad idea, because even
+ // writing 0 constitutes a command. Similarly there is no point
+ // in writing to the command address register.
+
+ // The endpoint status register is read-only.
+
+ // Set the rx pool information registers to disable alerts.
+ *USBS_RP0IR = IBUS_SWAP32(USBS_RPxIR_AL_NONE); FLUSH_IBUS();
+ *USBS_RP1IR = IBUS_SWAP32(USBS_RPxIR_AL_NONE); FLUSH_IBUS();
+ *USBS_RP2IR = IBUS_SWAP32(USBS_RPxIR_AL_NONE); FLUSH_IBUS();
+
+ // The pool address registers are read-only. The documentation
+ // that describes initialization says that these registers need to
+ // be filled in, but that seems wrong: providing receive buffers
+ // involves the command register. Presumably on early revisions it
+ // was necessary to fill in the address register.
+
+ // Sort out the mailboxes.
+ *USBS_TMSA = IBUS_SWAPPTR(TxMailbox, &(uncached->tx_mboxes[0])); FLUSH_IBUS();
+ *USBS_TMBA = IBUS_SWAPPTR(TxMailbox, &(uncached->tx_mboxes[TXMBOX_COUNT])); FLUSH_IBUS();
+ *USBS_RMSA = IBUS_SWAPPTR(RxMailbox, &(uncached->rx_mboxes[0])); FLUSH_IBUS();
+ *USBS_RMBA = IBUS_SWAPPTR(RxMailbox, &(uncached->rx_mboxes[RXMBOX_COUNT])); FLUSH_IBUS();
+ // It is not clear whether these registers actually need to be initialized.
+ // The documentation suggests that they do, unlike TMWA and RMWA which
+ // are taken care of by the hardware.
+#if 0
+ *USBS_TMRA = IBUS_SWAPPTR(TxMailbox, &(uncached->tx_mboxes[0])); FLUSH_IBUS();
+ *USBS_RMRA = IBUS_SWAPPTR(RxMailbox, &(uncached->rx_mboxes[0])); FLUSH_IBUS();
+#endif
+
+ // Start a receive operation for a control message.
+ ep0_start_rx(8);
+
+ // The endpoint 0 control register. The control packet size is
+ // configurable, with a default value of 8. Setting the
+ // enabled bit here affects the state as seen by the host.
+ *EP0_CR = IBUS_SWAP32(EP0_CR_EP0EN | CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE); FLUSH_IBUS();
+
+ // The other endpoint registers will be initialized by the appropriate
+ // _init() functions. Note that those other _init() functions should
+ // probably be called before the ep0-enabled bit is set.
+}
+
+// ----------------------------------------------------------------------------
+// Endpoint 1 - isochronous transmits.
+#if 0
+// A real implementation
+#else
+static inline void
+ep1_init(void)
+{
+ *EP1_CR = IBUS_SWAP32(0); // Clear EP1EN bit, thus disabling the endpoint
+ FLUSH_IBUS();
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// Endpoint 2 - isochronous receives
+#if 0
+// A real implementation
+#else
+static inline void
+ep2_init(void)
+{
+ *EP2_CR = IBUS_SWAP32(0); // Clear EP2EN bit, thus disabling the endpoint
+ FLUSH_IBUS();
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// Generic transmit support. This is intended for use with both endpoints
+// 3 and 5. For now the endpoint 0 code is too different.
+
+#if defined(CYGPKG_DEVS_USB_UPD985XX_EP3) || defined(CYGPKG_DEVS_USB_UPD985XX_EP5)
+
+// A utility routine for completing a transfer. This takes care of the
+// callback as well as resetting the buffer.
+static void
+ep35_tx_complete(ep35_impl* ep, int result)
+{
+ void (*complete_fn)(void*, int) = ep->common.complete_fn;
+ void* complete_data = ep->common.complete_data;
+
+ ep->common.buffer = (unsigned char*) 0;
+ ep->common.buffer_size = 0;
+ ep->common.complete_fn = (void (*)(void*, int)) 0;
+ ep->common.complete_data = (void*) 0;
+
+ if ((void (*)(void*, int))0 != complete_fn) {
+ (*complete_fn)(complete_data, result);
+ }
+}
+
+static void
+ep35_start_tx(ep35_impl* ep)
+{
+ // Is this endpoint currently stalled? If so then a size of 0 can
+ // be used to block until the stall condition is clear, anything
+ // else should result in an immediate callback.
+ if (ep->common.halted) {
+ if (0 != ep->common.buffer_size) {
+ ep35_tx_complete(ep, -EAGAIN);
+ }
+ } else if (0 == ep->common.buffer_size) {
+ // A check to see if the endpoint is halted. It isn't.
+ ep35_tx_complete(ep, 0);
+ } else {
+ cyg_uint32 send_command;
+#if 0
+ diag_printf("Tx: %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep->common.buffer[0], ep->common.buffer[1], ep->common.buffer[2], ep->common.buffer[3],
+ ep->common.buffer[4], ep->common.buffer[5], ep->common.buffer[6], ep->common.buffer[7]);
+ diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep->common.buffer[8], ep->common.buffer[9], ep->common.buffer[10], ep->common.buffer[11],
+ ep->common.buffer[12], ep->common.buffer[13], ep->common.buffer[14], ep->common.buffer[15]);
+ diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep->common.buffer[16], ep->common.buffer[17], ep->common.buffer[18], ep->common.buffer[19],
+ ep->common.buffer[20], ep->common.buffer[21], ep->common.buffer[22], ep->common.buffer[23]);
+ diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep->common.buffer[24], ep->common.buffer[25], ep->common.buffer[26], ep->common.buffer[27],
+ ep->common.buffer[28], ep->common.buffer[29], ep->common.buffer[30], ep->common.buffer[31]);
+ diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep->common.buffer[32], ep->common.buffer[33], ep->common.buffer[34], ep->common.buffer[35],
+ ep->common.buffer[36], ep->common.buffer[37], ep->common.buffer[38], ep->common.buffer[39]);
+ diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep->common.buffer[40], ep->common.buffer[41], ep->common.buffer[42], ep->common.buffer[43],
+ ep->common.buffer[44], ep->common.buffer[45], ep->common.buffer[46], ep->common.buffer[47]);
+#endif
+
+ // Update the static buffer descriptor.
+ ep->tx_bufdesc->buffer = MIPS_TO_UNCACHED(ep->common.buffer);
+ ep->tx_bufdesc->control = ep->common.buffer_size | TXBUFDESC_CTRL_LAST | TXBUFDESC_CTRL_BUFDESC_BUFDESC;
+
+ // Make sure that the entire transmit buffer is flushed to
+ // memory.
+ HAL_DCACHE_STORE(ep->common.buffer, ep->common.buffer_size);
+
+ // Issue the send command. It is known that no transmits are
+ // in progress for this endpoint so the upper bound of 2
+ // pending transmits can be ignored. The send command involves
+ // writing to two registers in succession, so interrupts had
+ // better be disabled while doing this.
+ send_command = ep->send_command | ep->common.buffer_size;
+ cyg_drv_isr_lock();
+ while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
+ // Do nothing: this situation should be short-lived.
+ }
+ *USBS_CA = IBUS_SWAPPTR(void, (void*)ep->tx_bufdesc); FLUSH_IBUS();
+ *USBS_CMR = IBUS_SWAP32(send_command); FLUSH_IBUS();
+ cyg_drv_isr_unlock();
+ }
+}
+
+// The stalled state is controlled by a single bit in the appropriate
+// control register. However there is a problem in that it is not
+// possible to abort a transmission that is already going out.
+// Furthermore there is no way of detecting whether or not any
+// packets have already gone out for this transfer: setting the halt
+// bit before any data has gone out is reasonably ok, doing so
+// in the middle of a transfer could be confusing.
+//
+// The approach taken here is to check whether or not there is a
+// current tx buffer. If not then the stall bit can be set immediately.
+// Otherwise the halted flag is set here, and it is left to the dsr
+// to set the stall bit when the transfer completes. This may not
+// be totally standards-compliant, but is probably the best solution
+// for now.
+static void
+ep35_set_halted(ep35_impl* ep, cyg_bool new_value)
+{
+ if (ep->common.halted == new_value) {
+ return;
+ }
+
+ // Avoid race conditions with the DSR updating the buffer fields.
+ cyg_drv_dsr_lock();
+
+ if (new_value ){
+ // Set the halted flag to prevent further transmits, and if
+ // there is no transmission currently in progress then set
+ // the stalled bit immediately.
+ ep->common.halted = true;
+ if ((void*)0 == ep->common.buffer) {
+ *(ep->cr) |= IBUS_SWAP32(EPtx_CR_SSx); FLUSH_IBUS();
+ }
+ } else {
+ // Update the hardware (that may be a no-op if the stalled bit
+ // never got set by the DSR), and clear the halted flag.
+ *(ep->cr) &= IBUS_SWAP32(~EPtx_CR_SSx); FLUSH_IBUS();
+ ep->common.halted = false;
+
+ // If there is a pending request to wait until the endpoint stall
+ // condition is clear, inform higher-level code. This test may
+ // give false positives but those would be harmless.
+ if (0 == ep->common.buffer_size) {
+ ep35_tx_complete(ep, 0);
+ }
+ }
+
+ cyg_drv_dsr_unlock();
+}
+
+// An interrupt has occured related to endpoint 3 or 5 - i.e. the EP3TF
+// or EP5TF interrupts, nothing else seems especially relevant. It is
+// necessary to extract the appropriate send indicator from the tx
+// mailbox to determine whether or not the transmission was successful
+// and report status to higher-level code.
+static void
+ep35_dsr(ep35_impl* ep)
+{
+ TxMailbox mbox;
+
+ // Extract the transmit indicator if that has not happened
+ // already courtesy of another DSR.
+ if (!ep->tx_indicator_valid) {
+ drain_tx_mailbox();
+ if (!ep->tx_indicator_valid) {
+ // A transmit interrupt when there does not appear to be
+ // any data?
+ CYG_FAIL("ep35_dsr invoked when there is no valid tx indicator");
+ return;
+ }
+ }
+ mbox = ep->tx_indicator;
+ ep->tx_indicator_valid = false;
+
+#ifdef CYGIMP_DEVS_USB_UPD985XX_EP5_BULK
+ // If emulating bulk transfers over the interrupt endpoint, and
+ // the transfer is an exact multiple of 64 bytes, then an extra
+ // zero-byte terminating packet needs to be sent. Care has to be
+ // taken to do this only once.
+ if ( (ep == &ep5) && (0 == (ep5.common.buffer_size % 64)) ) {
+ static cyg_bool sending_zero = false;
+ if (!sending_zero) {
+ sending_zero = true;
+ uncached->ep5_tx_bufdesc.buffer = uncached->ep0_tx_buffer;
+ uncached->ep5_tx_bufdesc.control = 0 | TXBUFDESC_CTRL_LAST | TXBUFDESC_CTRL_BUFDESC_BUFDESC;
+ cyg_drv_isr_lock();
+ while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
+ // Do nothing: this situation should be short-lived.
+ }
+ *USBS_CA = IBUS_SWAPPTR(void, (void*) &(uncached->ep5_tx_bufdesc)); FLUSH_IBUS();
+ *USBS_CMR = IBUS_SWAP32(USBS_CMR_COMMAND_TX_EP5 | 0); FLUSH_IBUS();
+ cyg_drv_isr_unlock();
+
+ // Do not complete the transfer. Instead completion has to
+ // wait for another interrupt.
+ return;
+ } else {
+ // This interrupt was for the zero-byte packet, so drop through
+ sending_zero = false;
+ }
+ }
+#endif
+
+ // If the endpoint should be halted but there was a transmit
+ // in progress, update the hardware now.
+ if (ep->common.halted) {
+ *(ep->cr) |= IBUS_SWAP32(EPtx_CR_SSx); FLUSH_IBUS();
+ }
+
+ // Allow any blocked transmits to proceed.
+ TX_UNLOCK();
+
+ if (0 != (mbox.status & TXMBOX_STATUS_IBUS_ERROR)) {
+ // This appears to be the only type of error that can be
+ // detected. Possibly the transmit should be retried here
+ // rather than reported.
+ ep35_tx_complete(ep, -EPIPE);
+ } else {
+ ep35_tx_complete(ep, ep->common.buffer_size);
+ }
+}
+#endif // Endpoints 3 or 5
+
+// ----------------------------------------------------------------------------
+// Endpoint 3 - bulk transmits.
+
+# ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+static void
+ep3_start_tx(usbs_tx_endpoint* endpoint)
+{
+ CYG_ASSERT( endpoint == &ep3.common, "USB data transfer involves the wrong endpoint");
+ CYG_ASSERT( ep3.common.buffer_size < (64 * 1024), "Specified transfer size too large for current implementation");
+ if (TX_TRY_LOCK(&ep3_tx_pending)) {
+ ep35_start_tx(&ep3);
+ }
+}
+
+static void
+ep3_set_halted(usbs_tx_endpoint* endpoint, cyg_bool new_value)
+{
+ CYG_ASSERT(endpoint = &ep3.common, "USB set-stall operation involves the wrong endpoint");
+ ep35_set_halted(&ep3, new_value);
+}
+
+// Initialization. This gets called during the device driver
+// initialization and after a reset. The main job is to initialize the
+// EP3 control register, but the relevant bits of the interrupt mask
+// are set here as well. The tx mailboxes are shared with other
+// endpoints, so that is handled by ep0_init(). Any traffic that
+// happened before the reset needs to be cleaned up.
+static void
+ep3_init(void)
+{
+ // Assume 64 byte packets, terminate transfers with a zero-byte packet
+ // if necessary since this endpoint is used for bulk transfers.
+ *EP3_CR = IBUS_SWAP32(EP3_CR_EP3EN | EP3_CR_TM3_SZLP | 64); FLUSH_IBUS();
+ *USBS_IMR1 |= IBUS_SWAP32(USBS_GSR1_EP3TF); FLUSH_IBUS();
+ usbs_upd985xx_gsr1_mask |= IBUS_SWAP32(USBS_GSR1_EP3TF);
+ ep3.common.halted = false;
+ ep3.tx_indicator_valid = false;
+ ep3.tx_bufdesc = &(uncached->ep3_tx_bufdesc);
+ ep35_tx_complete(&ep3, -EPIPE);
+}
+#else
+static inline void
+ep3_init(void)
+{
+ *EP3_CR = 0; // Clear EP3EN bit, thus disabling the endpoint
+ FLUSH_IBUS();
+}
+# endif // Endpoint 3 configured in
+
+// ----------------------------------------------------------------------------
+// Repeat for endpoint 5
+# ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+
+static void
+ep5_start_tx(usbs_tx_endpoint* endpoint)
+{
+ CYG_ASSERT( endpoint == &ep5.common, "USB data transfer involves the wrong endpoint");
+#ifdef CYGIMP_DEVS_USB_UPD985XX_EP5_BULK
+ CYG_ASSERT( ep5.common.buffer_size < (64 * 1024), "Specified transfer size too large for current implementation");
+#else
+ CYG_ASSERT( ep5.common.buffer_size <= 64, "Specified transfer size too large for current implementation");
+#endif
+ if (TX_TRY_LOCK(&ep5_tx_pending)) {
+ ep35_start_tx(&ep5);
+ }
+}
+
+static void
+ep5_set_halted(usbs_tx_endpoint* endpoint, cyg_bool new_value)
+{
+ CYG_ASSERT(endpoint = &ep5.common, "USB set-stall operation involves the wrong endpoint");
+ ep35_set_halted(&ep5, new_value);
+}
+
+// Initialization. This gets called during the device driver
+// initialization and after a reset. The main job is to initialize the
+// EP5 control register, but the relevant bits of the interrupt mask
+// are set here as well. The tx mailboxes are shared with other
+// endpoints, so that is handled by ep0_init(). Any traffic that
+// happened before the reset needs to be cleaned up.
+static void
+ep5_init(void)
+{
+ // Assume 64 byte packets, terminate transfers with a zero-byte packet
+ // if necessary since this endpoint is used for bulk transfers.
+ *EP5_CR = IBUS_SWAP32(EP5_CR_EP5EN | 64); FLUSH_IBUS();
+ *USBS_IMR1 |= IBUS_SWAP32(USBS_GSR1_EP5TF); FLUSH_IBUS();
+ usbs_upd985xx_gsr1_mask |= IBUS_SWAP32(USBS_GSR1_EP5TF);
+ ep5.common.halted = false;
+ ep5.tx_indicator_valid = false;
+ ep5.tx_bufdesc = &(uncached->ep5_tx_bufdesc);
+ ep35_tx_complete(&ep5, -EPIPE);
+}
+#else
+static inline void
+ep5_init(void)
+{
+ *EP5_CR = 0; // Clear EP5EN bit, thus disabling the endpoint
+ FLUSH_IBUS();
+}
+#endif // Endpoint 5 configured in
+
+
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
+// ----------------------------------------------------------------------------
+// Endpoint 4 - bulk receives.
+//
+// Bulk receives are mostly straightforward, but the cache does involve
+// a complication. The assumption is that the receive buffer will be in
+// cached memory, and is unlikely to be cacheline-aligned. Clearly the bulk
+// of the buffer has to be invalidated. However the receive buffer may share
+// some cache lines with other data at the head and tail, and invalidating
+// those would be wrong.
+//
+// The solution here is to split up a receive in to up to three areas,
+// head, main, and tail, where the head and tail are statically
+// allocated in uncached memory. Any one or two of these areas may be
+// unused, depending on alignment and transfer size. The main area
+// corresponds to the central section of the supplied receive buffer,
+// will be cacheline-aligned, and invalidated at the start of a receive.
+// Data will be copied from the head and tail areas into the receive
+// buffer by the dsr on completion of the transfer.
+//
+// There are additional complications caused by the hardware's need for
+// linked buffers.
+
+static void
+ep4_rx_complete(int result)
+{
+ void (*complete_fn)(void*, int) = ep4.common.complete_fn;
+ void* complete_data = ep4.common.complete_data;
+
+#if 0
+ *EP4_CR = IBUS_SWAP32(EP4_CR_EP4EN | EP4_CR_RM4_ASSEMBLE | EP4_CR_NAK4 | 64); FLUSH_IBUS();
+#endif
+
+#if 0
+ if (result > 0) {
+ diag_printf("Rx: %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep4.common.buffer[0], ep4.common.buffer[1], ep4.common.buffer[2], ep4.common.buffer[3],
+ ep4.common.buffer[4], ep4.common.buffer[5], ep4.common.buffer[6], ep4.common.buffer[7]);
+ diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep4.common.buffer[8], ep4.common.buffer[9], ep4.common.buffer[10], ep4.common.buffer[11],
+ ep4.common.buffer[12], ep4.common.buffer[13], ep4.common.buffer[14], ep4.common.buffer[15]);
+ diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep4.common.buffer[16], ep4.common.buffer[17], ep4.common.buffer[18], ep4.common.buffer[19],
+ ep4.common.buffer[20], ep4.common.buffer[21], ep4.common.buffer[22], ep4.common.buffer[23]);
+ diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep4.common.buffer[24], ep4.common.buffer[25], ep4.common.buffer[26], ep4.common.buffer[27],
+ ep4.common.buffer[28], ep4.common.buffer[29], ep4.common.buffer[30], ep4.common.buffer[31]);
+ diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep4.common.buffer[32], ep4.common.buffer[33], ep4.common.buffer[34], ep4.common.buffer[35],
+ ep4.common.buffer[36], ep4.common.buffer[37], ep4.common.buffer[38], ep4.common.buffer[39]);
+ diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ ep4.common.buffer[40], ep4.common.buffer[41], ep4.common.buffer[42], ep4.common.buffer[43],
+ ep4.common.buffer[44], ep4.common.buffer[45], ep4.common.buffer[46], ep4.common.buffer[47]);
+ }
+#endif
+
+ ep4.common.buffer = (unsigned char*) 0;
+ ep4.common.buffer_size = 0;
+ ep4.common.complete_fn = (void (*)(void*, int)) 0;
+ ep4.common.complete_data = (void*) 0;
+
+ if ((void (*)(void*, int))0 != complete_fn) {
+ (*complete_fn)(complete_data, result);
+ }
+}
+
+static void
+ep4_start_rx(usbs_rx_endpoint* ep)
+{
+ CYG_ASSERT( ep == &ep4.common, "USB data transfer involves the wrong endpoint");
+
+ // Is this endpoint currently stalled? If so then a size of 0 can
+ // be used to block until the stall condition is clear, anything
+ // else should result in an immediate callback.
+ if (ep4.common.halted) {
+ if (0 != ep4.common.buffer_size) {
+ ep4_rx_complete(-EAGAIN);
+ }
+ } else if (0 == ep4.common.buffer_size) {
+ // A check to see if the endpoint is halted. It isn't.
+ ep4_rx_complete(0);
+ } else {
+
+ // Time to work out how much data should go into the uncached
+ // head and tail buffers, how much can go directly into the
+ // receive buffer, how much memory needs to be invalidated, and so on.
+ cyg_uint32 buffer_arith;
+
+ // Where to start filling in buffer descriptors.
+ cyg_uint32 first_bufdesc;
+
+ // And the current buffer descriptor.
+ cyg_uint32 current_bufdesc;
+
+ CYG_ASSERT( ep4.common.buffer_size < (64 * 1024), "Specified transfer size too large for current implementation");
+
+ // If there has not been a receive operation, tail_index
+ // will still be set to -1. Otherwise it will be somewhere
+ // between 1 and 3, or between 5 and 7, depending on
+ // whether the previous receive operation used the
+ // first four buffer descriptors or the last four.
+ if (ep4.tail_index < 4) {
+ first_bufdesc = 4;
+ } else {
+ first_bufdesc = 0;
+ }
+ current_bufdesc = first_bufdesc;
+
+ // Arithmetic, especially remainder operators, requires
+ // integers rather than a pointer.
+ buffer_arith = (cyg_uint32) ep4.common.buffer;
+
+ // The size of the "head" area. This involves up to
+ // (cacheline-1) bytes, so that the main receive buffer
+ // is suitably aligned.
+ ep4.head_size = ((buffer_arith + HAL_DCACHE_LINE_SIZE - 1) & ~(HAL_DCACHE_LINE_SIZE - 1)) - buffer_arith;
+ if (ep4.head_size > ep4.common.buffer_size) {
+ ep4.head_size = ep4.common.buffer_size;
+ }
+ if (0 < ep4.head_size) {
+ // It is necessary to receive some data into the uncached head area.
+ uncached->ep4_rx_bufdescs[current_bufdesc].buffer = uncached->ep4_head;
+ uncached->ep4_rx_bufdescs[current_bufdesc].control = RXBUFDESC_CTRL_BUFDESC_BUFDESC | ep4.head_size;
+ current_bufdesc++;
+ }
+
+ // Now for the size of the main area. This is the rest of the
+ // transfer size, minus the tail area.
+ ep4.direct_size = ep4.common.buffer_size - ep4.head_size;
+ ep4.direct_size &= ~(HAL_DCACHE_LINE_SIZE - 1);
+ if (ep4.direct_size > 0) {
+ uncached->ep4_rx_bufdescs[current_bufdesc].buffer = MIPS_TO_UNCACHED(ep4.common.buffer + ep4.head_size);
+ uncached->ep4_rx_bufdescs[current_bufdesc].control = RXBUFDESC_CTRL_BUFDESC_BUFDESC | ep4.direct_size;
+ current_bufdesc++;
+ HAL_DCACHE_INVALIDATE(ep4.common.buffer + ep4.head_size, ep4.direct_size);
+ }
+
+ // And the size of the tail. This is the transfer size minus what we have accumulated so far.
+ ep4.tail_size = ep4.common.buffer_size - (ep4.head_size + ep4.direct_size);
+ if (ep4.tail_size > 0) {
+ uncached->ep4_rx_bufdescs[current_bufdesc].buffer = uncached->ep4_tail;
+ uncached->ep4_rx_bufdescs[current_bufdesc].control = RXBUFDESC_CTRL_BUFDESC_BUFDESC | ep4.tail_size;
+ current_bufdesc++;
+ }
+
+ // Or the LAST bit into the last of these buffer descriptors.
+ uncached->ep4_rx_bufdescs[current_bufdesc - 1].control |= RXBUFDESC_CTRL_LAST;
+
+ // Turn the current one into a link descriptor.
+ uncached->ep4_rx_bufdescs[current_bufdesc].control = RXBUFDESC_CTRL_BUFDESC_LINK;
+ uncached->ep4_rx_bufdescs[current_bufdesc].buffer = 0;
+
+ // The buffer descriptors have now been sorted out. Time to
+ // add this receive buffer to the pool. Atomicity becomes
+ // important for some of these steps.
+ cyg_drv_isr_lock();
+
+ // Update the link pointer used for the last receive operation
+ // to point at the new set of buffer descriptors.
+ if (-1 != ep4.tail_index) {
+ uncached->ep4_rx_bufdescs[ep4.tail_index].buffer = (void*) &(uncached->ep4_rx_bufdescs[first_bufdesc]);
+ }
+
+ // Keep track of the link pointer used for the last receive
+ // operation.
+ ep4.tail_index = current_bufdesc;
+
+ while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
+ // Do nothing: this situation should be short-lived.
+ }
+ *USBS_CA = IBUS_SWAPPTR(void, (void*)&(uncached->ep4_rx_bufdescs[first_bufdesc])); FLUSH_IBUS();
+ *USBS_CMR = IBUS_SWAP32(USBS_CMR_COMMAND_ADD_POOL2 | 1); FLUSH_IBUS();
+#if 0
+ *EP4_CR = IBUS_SWAP32(EP4_CR_EP4EN | EP4_CR_RM4_ASSEMBLE | 64); FLUSH_IBUS();
+#endif
+ cyg_drv_isr_unlock();
+ }
+}
+
+// The stalled state is controlled by a single bit in the appropriate
+// control register. When it comes to ongoing receives, the reasoning
+// here is much the same as for ep3_set_halted(). Arguably this is not
+// quite right. set_halted() is most likely to be called in response
+// to a control request from the host, and the host is unlikely to
+// transmit any data at the same time as making this request. Hence the
+// host will see the wrong behaviour: it can still make one transfer
+// after asking for the stalled bit to be set. Since there does not
+// appear to be any way to cancel a supplied receive, this behaviour
+// still seems the most sensible.
+static void
+ep4_set_halted(usbs_rx_endpoint* ep, cyg_bool new_state)
+{
+ CYG_ASSERT(ep == &ep4.common, "USB set-stall operation involves the wrong endpoint");
+
+ if (ep4.common.halted == new_state) {
+ return;
+ }
+
+ // Avoid race conditions with the DSR updating the buffer fields.
+ cyg_drv_dsr_lock();
+
+ if (new_state){
+ // Set the halted flag to prevent further transmits, and if
+ // there is no receive currently in progress then set
+ // the stalled bit immediately.
+ ep4.common.halted = true;
+ if ((void*)0 == ep4.common.buffer) {
+ *EP4_CR |= IBUS_SWAP32(EP4_CR_SS4); FLUSH_IBUS();
+ }
+ } else {
+ // Update the hardware (that may be a no-op if the stalled bit
+ // never got set by the DSR), and clear the halted flag.
+ *EP4_CR &= IBUS_SWAP32(~EP4_CR_SS4); FLUSH_IBUS();
+ ep4.common.halted = false;
+
+ // If there is a pending request to wait until the endpoint stall
+ // condition is clear, inform higher-level code. This test may
+ // give false positives but those would be harmless.
+ if (0 == ep4.common.buffer_size) {
+ ep4_rx_complete(0);
+ }
+ }
+
+ cyg_drv_dsr_unlock();
+}
+
+// An interrupt has occured related to endpoint 4 - i.e. the EP4RF
+// interrupt, nothing else seems especially relevant. The ISR will
+// have set the NAK bit in the control register. It is necessary to
+// extract the appropriate receive indicator from the rx mailbox to
+// determine whether or not the transmission was successful and how
+// much data was actually received, clear the interrupt bit, and
+// report status to higher-level code.
+static void
+ep4_dsr(void)
+{
+ // Extract the transmit indicator if that has not happened
+ // already courtesy of another DSR.
+ if (!ep4.rx_indicator_valid) {
+ drain_rx_mailbox();
+ if (!ep4.rx_indicator_valid) {
+ // A receive interrupt when there does not appear to be
+ // any data? It appears that this can happen when there
+ // are error conditions.
+#if 1
+ CYG_FAIL("EP4_DSR invoked when there is no valid rx indicator");
+#endif
+ return;
+ }
+ }
+ ep4.rx_indicator_valid = false;
+
+ // If the endpoint should be halted but there was a transmit
+ // in progress, update the hardware now.
+ if (ep4.common.halted) {
+ *EP4_CR |= IBUS_SWAP32(EP4_CR_SS4); FLUSH_IBUS();
+ }
+ if (0 != (ep4.rx_indicator.status & (RXMBOX_STATUS_IBUS_ERROR | 0))) {
+ // This appears to be the only type of error that can be
+ // detected. Everything else gets retried by the hardware,
+ // except when using the isochronous endpoint.
+ ep4_rx_complete(-EPIPE);
+ } else {
+ cyg_uint32 actual_size = ep4.rx_indicator.status & RXMBOX_STATUS_SIZE_MASK;
+
+ // Either the transfer size must match the requested size, or the
+ // supplied buffer should have been aligned to cacheline boundaries.
+ // Anything else risks leaving the receive pool in a confused
+ // state and there is no way of cleaning things up.
+ CYG_ASSERT((actual_size == ep4.common.buffer_size) || ((0 == ep4.head_size) && (0 == ep4.tail_size)), \
+ "Buffers should be cacheline aligned if the protocol involves partial transfers");
+
+ // If there was some data in the head, move it from uncached
+ // to cached. Ditto for tail. Note that these copies may be
+ // for data that has not actually been transferred if the
+ // actual transfer is less than expected, but overwriting bits
+ // of the receive buffer in such circumstances should be
+ // harmless.
+ if (ep4.head_size > 0) {
+ memcpy(ep4.common.buffer, uncached->ep4_head, ep4.head_size);
+ }
+ if (ep4.tail_size > 0) {
+ memcpy(ep4.common.buffer + ep4.head_size + ep4.direct_size, uncached->ep4_tail, ep4.tail_size);
+ }
+ ep4_rx_complete(actual_size);
+ }
+}
+
+// Initialization. This gets called during the device driver
+// initialization and after a reset. The main job is to initialize the
+// EP4 control register, but the relevant bits of the interrupt mask
+// are set here as well. The rx mailboxes are shared with other
+// endpoints, so that is handled by ep0_init(). Any traffic that
+// happened before the reset needs to be cleaned up.
+static void
+ep4_init(void)
+{
+ // Assume 64 byte packets, and use assemble mode so that we get a
+ // single rx indication per transfer. In practice the buffer
+ // directory will only ever contain one entry so there should be
+ // no discernible difference between normal, assemble, or separate
+ // mode.
+#if 0
+ *EP4_CR = IBUS_SWAP32(EP4_CR_EP4EN | EP4_CR_RM4_ASSEMBLE | EP4_CR_NAK4 | 64); FLUSH_IBUS();
+#else
+ *EP4_CR = IBUS_SWAP32(EP4_CR_EP4EN | EP4_CR_RM4_ASSEMBLE | 64); FLUSH_IBUS();
+#endif
+
+ *USBS_IMR1 |= IBUS_SWAP32(USBS_GSR1_EP4RF); FLUSH_IBUS();
+ usbs_upd985xx_gsr1_mask |= USBS_GSR1_EP4RF;
+ ep4.common.halted = false;
+ ep4.rx_indicator_valid = false;
+ ep4.tail_index = -1;
+ ep4_rx_complete(-EPIPE);
+}
+#else
+static inline void
+ep4_init(void)
+{
+ *EP4_CR = 0; // Clear EP4EN bit, thus disabling the endpoint
+ FLUSH_IBUS();
+}
+#endif // Endpoint 4 configured in
+
+// ----------------------------------------------------------------------------
+// Endpoint 6 - interrupt receives
+#if 0
+// A real implementation
+#else
+static inline void
+ep6_init(void)
+{
+ *EP6_CR = 0; // Clear EP6EN bit, thus disabling the endpoint
+ FLUSH_IBUS();
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// Make sure the hardware is in a known state by completely resetting
+// the USB controller. This gets called during device driver
+// initialization, and again whenever the host issues a reset signal.
+// The previous state is unknown. Even during eCos initialization
+// RedBoot may have involved USB I/O, or some POST code may have
+// performed loopback tests. The various endpoint init routines will
+// also perform software resets as appropriate.
+
+static void
+usbs_upd985xx_handle_reset(void)
+{
+ // Reset the USB hardware. This involves poking the warm reset
+ // register and then polling the matching status register. It is
+ // assumed that this poll will take a short time, and in practice
+ // the loop appears to terminate immediately.
+ *S_WRCR = S_WRCR_USBWR; FLUSH_IBUS();
+ while (0 == (*S_WRSR & S_WRCR_USBWR)) {
+ // Do nothing.
+ }
+
+ // Get all the endpoints into a known state - for disabled
+ // endpoints these init calls are inlined and just disable the
+ // relevant hardware.
+ ep0_init();
+ ep1_init();
+ ep2_init();
+ ep3_init();
+ ep4_init();
+ ep5_init();
+ ep6_init();
+}
+
+// ----------------------------------------------------------------------------
+// Start(). This is typically called by the application itself once
+// everything else has been initialized, i.e. when the host should be
+// able to start talking to this device. There is no actual bit in the
+// chip itself to switch the USB pins from tri-state, so instead the
+// platform HAL has to supply appropriate functionality. In the absence
+// of such functionality things will only work if you start up eCos
+// with the USB cable disconnected, then plug in the cable once
+// start() has been called.
+//
+// The device driver initialization will have already set up the
+// hardware, and the first action from the host should be a reset
+// signal which will cause a re-initialization. There is no need
+// to do anything else here.
+
+static void
+usbs_upd985xx_ep0_start(usbs_control_endpoint* endpoint)
+{
+ CYG_ASSERT( endpoint == &ep0.common, "USB startup involves the wrong endpoint");
+
+ // If there is additional platform-specific initialization to
+ // perform, do it now. This macro can come from the platform HAL,
+ // but may not be available on all platforms.
+#ifdef UPD985XX_USB_PLATFORM_INIT
+ UPD985XX_USB_PLATFORM_INIT();
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// The main DSR
+//
+// This gets called by the interrupt system or by the polling code
+// when one or more USB-related events have occurred. The ISR code
+// will have updated globals usbs_upd985xx_gsr1 and usbs_upd98x0x_gsr2
+// to indicate which events are pending. When running in interrupt
+// mode it is possible that further interrupts will occur while the
+// DSR is running, and hence that these globals will be updated
+// while the DSR is running. This is handled by a loop. A side effect
+// is that the DSR may get called when all the work has already
+// been done by a previous DSR, but that is harmless.
+
+static void
+usbs_upd985xx_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ CYG_ASSERT(CYGNUM_HAL_INTERRUPT_USB == vector, "USB DSR should only be invoked for USB interrupts" );
+ CYG_ASSERT(0 == data, "The USB DSR needs no global data pointer");
+
+ while ((0 != usbs_upd985xx_gsr1) || (0 != usbs_upd985xx_gsr2)) {
+ // Only update the globals in one place since it involves
+ // the overhead of two function calls.
+ cyg_uint32 gsr1, gsr2;
+ cyg_drv_isr_lock();
+ gsr1 = usbs_upd985xx_gsr1;
+ gsr2 = usbs_upd985xx_gsr2;
+ usbs_upd985xx_gsr1 = 0;
+ usbs_upd985xx_gsr2 = 0;
+ cyg_drv_isr_unlock();
+
+ if (0 != gsr2) {
+ // Treat reset specially. If there has been a reset then none of
+ // the other bits are of any interest.
+ if (0 != (USBS_GSR2_URST & gsr2)) {
+ int old_state = ep0.common.state;
+ // Update the state. ep0_init() detects this state change and
+ // updates imr2 appropriate, preventing a continuous storm
+ // of reset interrupts.
+ ep0.common.state = USBS_STATE_DEFAULT;
+ usbs_upd985xx_handle_reset();
+ // This state change must be reported to higher-level code
+ if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ USBS_STATE_CHANGE_RESET, old_state);
+ }
+ break;
+ }
+ // There is possible confusion if both suspend and resume
+ // bits are set. Was there a suspend, quickly followed by
+ // a resume? Were we already suspended, then resumed, now
+ // suspended again? For now this complication is ignored and
+ // resume is given priority over suspend.
+ if (0 != (USBS_GSR2_URSM & gsr2)) {
+ int old_state = ep0.common.state;
+ if (0 != (old_state & USBS_STATE_SUSPENDED)) {
+ ep0.common.state &= ~USBS_STATE_SUSPENDED;
+ if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ USBS_STATE_CHANGE_RESUMED, old_state);
+ }
+ }
+ } else if (0 != (USBS_GSR2_USPD & gsr2)) {
+ int old_state = ep0.common.state;
+ if (0 == (old_state & USBS_STATE_SUSPENDED)) {
+ ep0.common.state |= USBS_STATE_SUSPENDED;
+ if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ USBS_STATE_CHANGE_SUSPENDED, old_state);
+ }
+ }
+ } else {
+ // Handle error conditions on the isochronous endpoints?
+ }
+ }
+ if (0 != gsr1) {
+
+ if (0 != (USBS_GSR1_EP0TF & gsr1)) {
+ ep0_tx_dsr();
+ }
+ if (0 != (USBS_GSR1_EP0RF & gsr1)) {
+ ep0_rx_dsr();
+ }
+#if 0
+ // EP1FU?
+ if (0 != (USBS_GSR1_EP1TF & gsr1)) {
+ ep1_dsr();
+ }
+#endif
+#if 0
+ // EP2FO?
+ if (0 != (USBS_GSR1_EP2RF & gsr1)) {
+ ep1_dsr();
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+ if (0 != (USBS_GSR1_EP3TF & gsr1)) {
+ ep35_dsr(&ep3);
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
+ if (0 != (USBS_GSR1_EP4RF & gsr1)) {
+ ep4_dsr();
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+ if (0 != (USBS_GSR1_EP5TF & gsr1)) {
+ ep35_dsr(&ep5);
+ }
+#endif
+#if 0
+ if (0 != (USBS_GSR1_EP6RF & gsr1)) {
+ ep6_dsr();
+ }
+#endif
+ }
+ } // while there are unprocessed interrupts
+}
+
+// ----------------------------------------------------------------------------
+// Interrupt handling.
+//
+// There are two status registers to look at. These are read-once
+// registers, i.e. reading the register causes all bits to be cleared,
+// so the relevant state has to be preserved in volatile globals which
+// can then be examined by the DSR. In theory the top bit of the first
+// status register can be used to check whether or not there is
+// anything of interest in the second one, but it seems quicker to
+// just read both registers. After masking out interrupts that are of
+// no interest, some global flags are updated. If this leaves a
+// non-zero value then the DSR must be invoked.
+
+static cyg_uint32
+usbs_upd985xx_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ CYG_ASSERT(CYGNUM_HAL_INTERRUPT_USB == vector, "USB ISR should only be invoked for USB interrupts");
+ CYG_ASSERT(0 == data, "The UPD985xx ISR needs no global data pointer");
+
+ usbs_upd985xx_gsr1 |= IBUS_SWAP32(*USBS_GSR1) & usbs_upd985xx_gsr1_mask;
+ usbs_upd985xx_gsr2 |= IBUS_SWAP32(*USBS_GSR2) & usbs_upd985xx_gsr2_mask;
+
+ cyg_drv_interrupt_acknowledge(vector);
+ return ((0 == usbs_upd985xx_gsr1) && (0 == usbs_upd985xx_gsr2)) ?
+ CYG_ISR_HANDLED : CYG_ISR_CALL_DSR;
+}
+
+// ----------------------------------------------------------------------------
+// Polling support. It is not clear that this is going to work particularly
+// well since according to the documentation the hardware does not generate
+// NAKs automatically - instead the ISR has to set the appropriate bits
+// sufficiently quickly to avoid confusing the host.
+//
+// Calling the isr directly avoids duplicating code, but means that
+// cyg_drv_interrupt_acknowledge() will get called when not inside a
+// real interrupt handler. This should be harmless.
+
+static void
+usbs_upd985xx_poll(usbs_control_endpoint* endpoint)
+{
+ CYG_ASSERT(endpoint == &ep0.common, "USB poll involves the wrong endpoint");
+ if (CYG_ISR_CALL_DSR == usbs_upd985xx_isr(CYGNUM_HAL_INTERRUPT_USB, 0)) {
+ usbs_upd985xx_dsr(CYGNUM_HAL_INTERRUPT_USB, 0, 0);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Initialization
+//
+// This routine gets called from a prioritized static constructor during
+// eCos startup.
+void
+usbs_upd985xx_init(void)
+{
+ // Make sure the uncached data structure is accessed through
+ // kseg1.
+ uncached = (uncached_data*) MIPS_TO_UNCACHED(&cached_copy);
+
+ // Perform a full hardware reset.
+ usbs_upd985xx_handle_reset();
+
+ // It is possible and desirable to install the interrupt handler
+ // here, even though there will be no interrupts for a while yet.
+ // FIXME: is 99 a sensible interrupt priority :-?
+ cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_USB,
+ 99, // priority
+ 0, // data
+ &usbs_upd985xx_isr,
+ &usbs_upd985xx_dsr,
+ &usbs_upd985xx_intr_handle,
+ &usbs_upd985xx_intr_data);
+
+ cyg_drv_interrupt_attach(usbs_upd985xx_intr_handle);
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_USB);
+}
+
+// ----------------------------------------------------------------------------
+// Testing support.
+
+usbs_testing_endpoint usbs_testing_endpoints[] = {
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL,
+ endpoint_number : 0,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &ep0.common,
+#ifdef CYGVAR_DEVS_USB_UPD985XX_EP0_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "0c",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1, // zero-byte control transfers are meaningless
+#if (CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE < CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE)
+ max_size : CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE,
+#else
+ max_size : CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE,
+#endif
+ max_in_padding : 0,
+ alignment : 0
+ },
+
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 3,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &ep3.common,
+# ifdef CYGVAR_DEVS_USB_UPD985XX_EP3_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "3w",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 0,
+ max_size : 0x0FFFF, // Driver limitation, only a single buffer descriptor is used
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 4,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
+ endpoint : (void*) &ep4.common,
+# ifdef CYGVAR_DEVS_USB_UPD985XX_EP4_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "4r",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 1,
+ max_size : 0x0FFFF, // Driver limitation
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+
+#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
+ {
+# ifdef CYGIMP_DEVS_USB_UPD985XX_EP5_BULK
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+# else
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
+# endif
+ endpoint_number : 5,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &ep5.common,
+# ifdef CYGVAR_DEVS_USB_UPD985XX_EP5_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "5w",
+# else
+ devtab_entry : (const char*) 0,
+# endif
+ min_size : 1,
+ max_size : 0x0FFFF, // Driver limitation, only a single buffer descriptor is used
+ max_in_padding : 0,
+ alignment : HAL_DCACHE_LINE_SIZE
+ },
+#endif
+
+ USBS_TESTING_ENDPOINTS_TERMINATOR
+};
diff --git a/ecos/packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx_data.cxx b/ecos/packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx_data.cxx
new file mode 100644
index 0000000..45acda8
--- /dev/null
+++ b/ecos/packages/devs/usb/nec_upd985xx/current/src/usbs_upd985xx_data.cxx
@@ -0,0 +1,189 @@
+//==========================================================================
+//
+// usbs_nec_upd9850x.c
+//
+// Static data for the NEC uPD9850x USB device driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors: bartv
+// Date: 2001-05-22
+//
+// This file contains various objects that should go into extras.o
+// rather than libtarget.a, e.g. devtab entries that would normally
+// be eliminated by the selective linking.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/diag.h>
+#include <cyg/io/devtab.h>
+#include <cyg/io/usb/usbs_upd985xx.h>
+#include <pkgconf/devs_usb_upd985xx.h>
+
+// ----------------------------------------------------------------------------
+// Initialization. The goal here is to call usbs_upd985xx_init()
+// early on during system startup, to take care of things like
+// registering interrupt handlers etc. which are best done
+// during system init.
+//
+// If the endpoint 0 devtab entry is available then its init()
+// function can be used to take care of this. However the devtab
+// entries are optional so an alternative mechanism must be
+// provided. Unfortunately although it is possible to give
+// a C function the constructor attribute, it cannot be given
+// an initpri attribute. Instead it is necessary to define a
+// dummy C++ class.
+
+extern "C" void usbs_upd985xx_init(void);
+
+#ifndef CYGVAR_DEVS_USB_UPD985XX_EP0_DEVTAB_ENTRY
+class usbs_upd985xx_initialization {
+ public:
+ usbs_upd985xx_initialization() {
+ usbs_upd985xx_init();
+ }
+};
+
+static usbs_upd985xx_initialization usbs_upd985xx_init_object CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);
+#endif
+
+// ----------------------------------------------------------------------------
+// The devtab entries. Each of these is optional, many applications
+// will want to use the lower-level API rather than go via
+// open/read/write/ioctl.
+
+#ifdef CYGVAR_DEVS_USB_UPD985XX_EP0_DEVTAB_ENTRY
+
+// For endpoint 0 the only legal operations are get_config() and
+// set_config(), and these are provided by the common package.
+
+static bool
+usbs_upd985xx_devtab_ep0_init(struct cyg_devtab_entry* tab)
+{
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+ usbs_upd985xx_init();
+ return true;
+}
+
+static CHAR_DEVIO_TABLE(usbs_upd985xx_ep0_devtab_functions,
+ &cyg_devio_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static CHAR_DEVTAB_ENTRY(usbs_upd985xx_ep0_devtab_entry,
+ CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "0c",
+ 0,
+ &usbs_upd985xx_ep0_devtab_functions,
+ &usbs_upd985xx_devtab_ep0_init,
+ 0,
+ (void*) &usbs_upd985xx_ep0);
+#endif
+
+// ----------------------------------------------------------------------------
+// Common routines for ep3, ep4 and ep5
+#if defined(CYGVAR_DEVS_USB_UPD985XX_EP3_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_UPD985XX_EP4_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_UPD985XX_EP5_DEVTAB_ENTRY)
+static bool
+usbs_upd985xx_devtab_dummy_init(struct cyg_devtab_entry* tab)
+{
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+ return true;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// ep3 devtab entry. This can only be used for slave->host, so only
+// the cwrite() function makes sense. The same function table can be
+// used for ep5.
+
+#if defined(CYGVAR_DEVS_USB_UPD985XX_EP3_DEVTAB_ENTRY) || \
+ defined(CYGVAR_DEVS_USB_UPD985XX_EP5_DEVTAB_ENTRY)
+static CHAR_DEVIO_TABLE(usbs_upd985xx_ep35_devtab_functions,
+ &usbs_devtab_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+# if defined(CYGVAR_DEVS_USB_UPD985XX_EP3_DEVTAB_ENTRY)
+static CHAR_DEVTAB_ENTRY(usbs_upd985xx_ep3_devtab_entry,
+ CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "3w",
+ 0,
+ &usbs_upd985xx_ep35_devtab_functions,
+ &usbs_upd985xx_devtab_dummy_init,
+ 0,
+ (void*) &usbs_upd985xx_ep3);
+
+# endif
+
+# if defined(CYGVAR_DEVS_USB_UPD985XX_EP5_DEVTAB_ENTRY)
+static CHAR_DEVTAB_ENTRY(usbs_upd985xx_ep5_devtab_entry,
+ CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "5w",
+ 0,
+ &usbs_upd985xx_ep35_devtab_functions,
+ &usbs_upd985xx_devtab_dummy_init,
+ 0,
+ (void*) &usbs_upd985xx_ep5);
+# endif
+#endif
+
+// ----------------------------------------------------------------------------
+// ep4 devtab entry. This can only be used for host->slave, so only the
+// cread() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_UPD985XX_EP4_DEVTAB_ENTRY
+
+static CHAR_DEVIO_TABLE(usbs_upd985xx_ep4_devtab_functions,
+ &cyg_devio_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static CHAR_DEVTAB_ENTRY(usbs_upd985xx_ep4_devtab_entry,
+ CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "4r",
+ 0,
+ &usbs_upd985xx_ep4_devtab_functions,
+ &usbs_upd985xx_devtab_dummy_init,
+ 0,
+ (void*) &usbs_upd985xx_ep4);
+#endif
+
diff --git a/ecos/packages/devs/usb/sa11x0/current/ChangeLog b/ecos/packages/devs/usb/sa11x0/current/ChangeLog
new file mode 100644
index 0000000..1571bbe
--- /dev/null
+++ b/ecos/packages/devs/usb/sa11x0/current/ChangeLog
@@ -0,0 +1,185 @@
+2003-02-25 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * doc/usbs_sa11x0.sgml: Declare as <part> not <reference> to get
+ correct TOC numbering.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/usbs_sa11x0.cdl: Fix doc link.
+
+ * doc/usbs_sa11x0.sgml: Comment out DOCTYPE for now to allow building
+ with standard doc build.
+ Add an enclosing <reference> so it's structured better with standard
+ doc build.
+
+2002-02-11 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Add a handler for the SET_INTERFACE standard control message.
+ This should not be needed, but appears to avoid hardware problems
+ when a compliance testing program sends certain requests. Also
+ improve the handling of halted endpoints since the hardware
+ does not allow transfers to be aborted.
+
+2002-01-23 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Add missing assertions for non-NULL buffers
+ Try to improve the behaviour when the host sends data before
+ the target is ready. The hardware is not capable of handling
+ this situation, but some recovery is possible some of the time.
+
+2001-09-14 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Update support for USB testing
+
+2001-08-06 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Add initial support for USB testing.
+
+2001-05-21 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c (usbs_sa11x0_ep2_dsr):
+ Fix the boundary condition where the transmission is an exact
+ multiple of 64 bytes. ep2_process_packet() already did the
+ right thing but was not getting called.
+ Also, some cosmetic changes to the receive code for the
+ same boundary condition. These actually have no effect
+ because of the hardware, but may be useful for other
+ people writing USB device drivers.
+
+2001-04-05 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c (usbs_sa11x0_ep0_fill_fifo):
+ Set the DATA_END and IN_READY bits in one operation.
+ This seems to avoid problems when the target needs to send
+ back a zero-length control packet.
+
+2001-02-02 Bart Veer <bartv@redhat.com>
+
+ * cdl/usbs_sa11x0.cdl:
+ Add doc property to the html
+
+ * doc/usbs_sa11x0.sgml, devs-usbs-sa11x0.html:
+ Incorporate changes from docs department, regenerate html
+
+2001-01-25 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0_data.cxx:
+ * cdl/usbs_sa11x0.cdl:
+ Devtab entries were never actually being built - and did not
+ build...
+
+ * cdl/usbs_sa11x0.cdl:
+ Sort out the dependencies for minimal environments such as
+ RedBoot.
+
+2001-01-24 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Invoke additional platform-specific initialization, if defined
+ via <cyg/hal/hal_io.h> and CYGBLD_HAL_PLATFORM_IO_H
+
+2001-01-22 Bart Veer <bartv@redhat.com>
+
+ * doc/usbs_sa11x0.sgml, doc/makefile:
+ Added documentation.
+
+2001-01-16 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Make sure that the resume interrupt source is enabled,
+ even when the USB bus is not suspended. For some reason
+ this makes it possible to disconnect and reconnect.
+
+2001-01-16 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Use the HAL macros for virtual->physical address translation
+ Update poll() and start() to match the documentation
+ Fix the handling of control messages affecting endpoints 1 and 2
+ if those endpoints are not currently configured.
+
+
+2001-01-02 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Change ep2_tx_packet() to start the DMA operation after the
+ UDC packet-complete bit has been set. This avoids a very high
+ error rate. Add some scheduler locking to eliminate a resulting
+ race condition, and sort out the error handling to match.
+ Comment out some assertions relating to spurious interrupts, which
+ have been observed. Instead the code now recovers from these.
+
+2000-12-15 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Add debug code for tracking stats and simulating failures.
+ Change the EP1 code to switch between DMA channels A and B as
+ required, rather than always using channel A. This is more robust
+ and was needed for the failure simulation.
+
+ Make the ep1 packet processing code robust in case an unexpected
+ failure occurs during its invocation. It is not clear how this
+ can ever happen, but on a couple of occasions it did and caused an
+ infinite loop.
+
+2000-11-30 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Fix DMA_CONTROL_CLEAR_ALL constant, it was ignoring START_B
+ In ep2_init(), separate out the fifo write and the IN_SIZE
+ write to avoid a hardware problem.
+
+2000-11-29 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Disable some debugging features and add retries when manipulating
+ certain DMA registers - needed with some Silicon revisions.
+
+2000-11-28 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ More rewriting, plus implementing the endpoint halt support.
+
+2000-11-24 Bart Veer <bartv@redhat.com>
+
+ * src/usbs_sa11x0.c:
+ Clean up some of the debugging.
+ Largely rewrite the endpoint 2 support to try and get it working
+ Transmit a runt packet during initialization to work around
+ hardware problem.
+
+2000-11-22 Bart Veer <bartv@redhat.com>
+
+ * include/usbs_sa11x0.h: Fix nested #include protection
+
+2000-11-21 Bart Veer <bartv@redhat.com>
+
+ * First check-in of eCos USB support.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/usb/sa11x0/current/cdl/usbs_sa11x0.cdl b/ecos/packages/devs/usb/sa11x0/current/cdl/usbs_sa11x0.cdl
new file mode 100644
index 0000000..704319f
--- /dev/null
+++ b/ecos/packages/devs/usb/sa11x0/current/cdl/usbs_sa11x0.cdl
@@ -0,0 +1,202 @@
+# ====================================================================
+#
+# usbs_sa11x0.cdl
+#
+# SA11X0 USB support.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Original data: bartv
+# Contributors:
+# Date: 2000-10-04
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_USB_SA11X0 {
+ display "SA11X0 USB Device Driver"
+ include_dir "cyg/io/usb"
+ parent CYGPKG_USB
+ implements CYGHWR_IO_USB_SLAVE
+ doc ref/devs-usb-sa11x0.html
+
+ # Make sure that we are running on the right hardware.
+ requires CYGPKG_HAL_ARM
+ requires CYGPKG_HAL_ARM_SA11X0
+
+
+ description "
+ The on-chip serial port 0 on the SA11X0 implements a USB
+ device controller, facilitating the use of this processor
+ in USB peripherals. This package provides a suitable eCos
+ device driver."
+
+
+ cdl_option CYGFUN_DEVS_USB_SA11X0_EP0 {
+ display "Support the control endpoint 0"
+ default_value CYGINT_IO_USB_SLAVE_CLIENTS
+ # And the USB support packages
+ requires CYGPKG_IO_USB CYGPKG_IO_USB_SLAVE
+ compile usbs_sa11x0.c
+ compile -library=libextras.a usbs_sa11x0_data.cxx
+ description "
+ Enable support for endpoint 0. If this support is disabled
+ then the entire USB port is unusable."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_SA11X0_EP0_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 0"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If endpoint 0 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and ioctl calls then a devtab entry is needed.
+ "
+ }
+
+ cdl_component CYGPKG_DEVS_USB_SA11X0_EP1 {
+ display "Support endpoint 1, used for host->slave communications"
+ implements CYGHWR_IO_USB_SLAVE_OUT_ENDPOINTS
+ requires CYGFUN_DEVS_USB_SA11X0_EP0
+ default_value CYGFUN_DEVS_USB_SA11X0_EP0
+ description "
+ In the SA11X0 USB implementation endpoint 1 can only be
+ used for host->slave communication. If the intended application
+ only involves slave->host transfers then the support for
+ endpoint 1 can be disabled. Note that this does not affect
+ control messages which always go via endpoint 0."
+
+ cdl_option CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL {
+ display "Control DMA usage for endpoint 1"
+ flavor booldata
+ legal_values 0 to 5
+ default_value 4
+ description "
+ In the SA11X0 USB implementation endpoint 1 only has
+ a 20-byte fifo. If the application only involves
+ small transfers then this may prove sufficient, but
+ for larger transfers the use of a DMA engine is
+ mandated. This configuration option allows the
+ use of DMA engine to be disabled or enabled, and the
+ specific DMA channel to be selected. The SA11X0
+ supports 6 DMA channels numbered 0 to 5. If DMA
+ is enabled for endpoint 1 then the selected channel
+ cannot be used by any other code."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_SA11X0_EP1_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 1"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If endpoint 1 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and read calls then a devtab entry is needed.
+ "
+ }
+ }
+
+ cdl_component CYGPKG_DEVS_USB_SA11X0_EP2 {
+ display "Support endpoint 2, used for slave->host communications"
+ implements CYGHWR_IO_USB_SLAVE_IN_ENDPOINTS
+ requires CYGFUN_DEVS_USB_SA11X0_EP0
+ default_value CYGFUN_DEVS_USB_SA11X0_EP0
+ description "
+ In the SA11X0 USB implementation endpoint 2 can only be
+ used for slave->host communication. If the intended application
+ only involves host->slave transfers then the support for
+ endpoint 2 can be disabled. Note that this does not affect
+ control messages which always go via endpoint 0."
+
+ cdl_option CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL {
+ display "Control DMA usage for endpoint 2"
+ flavor booldata
+ legal_values 0 to 5
+ default_value 5
+ description "
+ In the SA11X0 USB implementation endpoint 2 only has
+ a 16-byte fifo. If the application only involves
+ small transfers then this may prove sufficient, but
+ for larger transfers the use of a DMA engine is
+ mandated. This configuration option allows the
+ use of DMA engine to be disabled or enabled, and the
+ specific DMA channel to be selected. The SA11X0
+ supports 6 DMA channels numbered 0 to 5. If DMA
+ is enabled for endpoint 2 then the selected channel
+ cannot be used by any other code."
+ }
+
+ cdl_option CYGVAR_DEVS_USB_SA11X0_EP2_DEVTAB_ENTRY {
+ display "Provide a devtab entry for endpoint 2"
+ default_value CYGGLO_IO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES
+ requires CYGPKG_IO
+ description "
+ If endpoint 2 will only be accessed via the low-level
+ USB-specific calls then there is no need for an entry
+ in the device table, saving some memory. If the
+ application intends to access the endpoint by means
+ of open and write calls then a devtab entry is needed.
+ "
+ }
+ }
+
+ cdl_option CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME {
+ display "Base name for devtab entries"
+ flavor data
+ active_if { CYGVAR_DEVS_USB_SA11X0_EP0_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_SA11X0_EP1_DEVTAB_ENTRY ||
+ CYGVAR_DEVS_USB_SA11X0_EP2_DEVTAB_ENTRY
+ }
+ default_value { "\"/dev/usbs\"" }
+ description "
+ If the SA11X0 USB device driver package provides devtab
+ entries for any of the endpoints then this option gives
+ control over the names of these entries. By default the
+ endpoints will be called \"/dev/usbs0c\", \"/dev/usbs1r\"
+ and \"/dev/usbs2w\" (assuming all three endpoints are
+ enabled. The common part \"/dev/usbs\" is determined
+ by this configuration option. It may be necessary to
+ change this if there are multiple USB slave-side
+ devices on the target hardware to prevent a name clash.
+ "
+ }
+}
diff --git a/ecos/packages/devs/usb/sa11x0/current/doc/devs-usb-sa11x0.html b/ecos/packages/devs/usb/sa11x0/current/doc/devs-usb-sa11x0.html
new file mode 100644
index 0000000..4c3791f
--- /dev/null
+++ b/ecos/packages/devs/usb/sa11x0/current/doc/devs-usb-sa11x0.html
@@ -0,0 +1,341 @@
+<!-- Copyright (C) 2001 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of substantively modified versions of this -->
+<!-- document is prohibited without the explicit permission of the -->
+<!-- copyright holder. -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<HTML>
+<HEAD>
+<TITLE>
+SA11X0 USB Device Driver</TITLE>
+<META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.54"></HEAD>
+<BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF">
+<H1>
+<A
+NAME="DEVS-USB-SA11X0">
+SA11X0 USB Device Driver</A>
+</H1>
+<DIV
+CLASS="REFNAMEDIV">
+<A
+NAME="AEN4">
+</A>
+<H2>
+Name</H2>
+SA11X0 USB Support&nbsp;--&nbsp;Device driver for the on-chip SA11X0 USB device</DIV>
+<DIV
+CLASS="REFSECT1">
+<A
+NAME="AEN7">
+</A>
+<H2>
+SA11X0 USB Hardware</H2>
+<P>
+The Intel StrongARM SA11x0 family of processors is supplied with an
+on-chip USB slave device, the UDC (USB Device Controller). This
+supports three endpoints. Endpoint 0 can only be used for control
+messages. Endpoint 1 can only be used for bulk transfers from host to
+peripheral. Endpoint 2 can only be used for bulk transfers from
+peripheral to host. Isochronous and interrupt transfers are not
+supported.</P>
+<DIV
+CLASS="CAUTION">
+<P>
+</P>
+<TABLE
+CLASS="CAUTION"
+BORDER="1"
+WIDTH="100%">
+<TR>
+<TD
+ALIGN="CENTER">
+<B>
+Caution</B>
+</TD>
+</TR>
+<TR>
+<TD
+ALIGN="LEFT">
+<P>
+Different revisions of the SA11x0 silicon have had various problems
+with the USB support. The device driver has been tested primarily
+against stepping B4 of the SA1110 processor, and may not function as
+expected with other revisions. Application developers should obtain
+the manufacturer's current errata sheets and specification updates.
+The B4 stepping still has a number of problems, but the device driver
+can work around these. However there is a penalty in terms of extra
+code, extra cpu cycles, and increased dispatch latency because extra
+processing is needed at DSR level. Interrupt latency should not be
+affected.</P>
+<P>
+There is one specific problem inherent in the UDC design of which
+application developers should be aware: the hardware cannot fully
+implement the USB standard for bulk transfers. A bulk transfer
+typically consists of some number of full-size 64-byte packets and is
+terminated by a packet less than the full size. If the amount of data
+transferred is an exact multiple of 64 bytes then this requires a
+terminating packet of 0 bytes of data (plus header and checksum). The
+SA11x0 USB hardware does not allow a 0-byte packet to be transmitted,
+so the device driver is forced to substitute a 1-byte packet and the
+host receives more data than expected. Protocol support is needed so
+that the appropriate host-side device driver can allow buffer space
+for the extra byte, detect when it gets sent, and discard it.
+Consequently certain standard USB class protocols cannot be
+implemented using the SA11x0, and therefore custom host-side device
+drivers will generally have to be provided, rather than re-using
+existing ones that understand the standard protocol.</P>
+</TD>
+</TR>
+</TABLE>
+</DIV>
+</DIV>
+<DIV
+CLASS="REFSECT1">
+<A
+NAME="AEN13">
+</A>
+<H2>
+Endpoint Data Structures</H2>
+<P>
+The SA11x0 USB device driver can provide up to three data structures
+corresponding to the three endpoints: a
+<SPAN
+CLASS="STRUCTNAME">
+usbs_control_endpoint</SPAN>
+ structure
+<TT
+CLASS="LITERAL">
+usbs_sa11x0_ep0</TT>
+; a
+<SPAN
+CLASS="STRUCTNAME">
+usbs_rx_endpoint</SPAN>
+
+<TT
+CLASS="LITERAL">
+usbs_sa11x0_ep1</TT>
+; and a
+<SPAN
+CLASS="STRUCTNAME">
+usbs_tx_endpoint</SPAN>
+
+<TT
+CLASS="LITERAL">
+usbs_sa11x0_ep2</TT>
+. The header file
+<TT
+CLASS="FILENAME">
+cyg/io/usb/usbs_sa11x0.h</TT>
+
+provides declarations for these.</P>
+<P>
+Not all applications will require support for all the endpoints. For
+example, if the intended use of the UDC only involves peripheral to
+host transfers then <TT
+CLASS="LITERAL">
+usbs_sa11x0_ep1</TT>
+ is redundant.
+The device driver provides configuration options to control the
+presence of each endpoint:</P>
+<P>
+</P>
+<OL
+TYPE="1">
+<LI>
+<P>
+Endpoint 0 is controlled by
+<TT
+CLASS="LITERAL">
+CYGFUN_DEVS_USB_SA11X0_EP0</TT>
+. This defaults to
+enabled if there are any higher-level packages that require USB
+hardware or if the global preference
+<TT
+CLASS="LITERAL">
+CYGGLO_IO_USB_SLAVE_APPLICATION</TT>
+ is enabled,
+otherwise it is disabled. Usually this has the desired effect. It may
+be necessary to override this in special circumstances, for example if
+the target board uses an external USB chip in preference to the UDC
+and it is that external chip's device driver that should be used
+rather than the on-chip UDC. It is not possible to disable endpoint 0
+and at the same time enable one or both of the other endpoints, since
+a USB device is only usable if it can process the standard control
+messages.</P>
+</LI>
+<LI>
+<P>
+Endpoint 1 is controlled by
+<TT
+CLASS="LITERAL">
+CYGPKG_DEVS_USB_SA11X0_EP1</TT>
+. By default it is
+enabled whenever endpoint 0 is enabled, but it can be disabled
+manually when not required.</P>
+</LI>
+<LI>
+<P>
+Similarly endpoint 2 is controlled by
+<TT
+CLASS="LITERAL">
+CYGPKG_DEVS_USB_SA11X0_EP2</TT>
+. This is also enabled by
+default whenever endpoint 0 is enabled, but it can be disabled manually.</P>
+</LI>
+</OL>
+<P>
+The SA11X0 USB device driver implements the interface specified by the
+common eCos USB Slave Support package. The documentation for that
+package should be consulted for further details. There is only one
+major deviation: when there is a peripheral to host transfer on
+endpoint 2 which is an exact multiple of the bulk transfer packet size
+(usually 64 bytes) the device driver has to pad the transfer with one
+extra byte. This is because of a hardware limitation: the UDC is
+incapable of transmitting 0-byte packets as required by the USB
+specification. Higher-level code, including the host-side device
+driver, needs to be aware of this and adapt accordingly.</P>
+<P>
+The device driver assumes a bulk packet size of 64 bytes, so this
+value should be used in the endpoint descriptors in the enumeration
+data provided by application code. There is experimental code
+for running with <A
+HREF="devs-usb-sa11x0.html#AEN58">
+DMA disabled</A>
+,
+in which case the packet size will be 16 bytes rather than 64.</P>
+</DIV>
+<DIV
+CLASS="REFSECT1">
+<A
+NAME="AEN39">
+</A>
+<H2>
+Devtab Entries</H2>
+<P>
+In addition to the endpoint data structures the SA11X0 USB device
+driver can also provide devtab entries for each endpoint. This allows
+higher-level code to use traditional I/O operations such as
+<TT
+CLASS="FUNCTION">
+open</TT>
+/<TT
+CLASS="FUNCTION">
+read</TT>
+/<TT
+CLASS="FUNCTION">
+write</TT>
+
+rather than the USB-specific non-blocking functions like
+<TT
+CLASS="FUNCTION">
+usbs_start_rx_buffer</TT>
+. These devtab entries are
+optional since they are not always required. The relevant
+configuration options are
+<TT
+CLASS="LITERAL">
+CYGVAR_DEVS_USB_SA11X0_EP0_DEVTAB_ENTRY</TT>
+,
+<TT
+CLASS="LITERAL">
+CYGVAR_DEVS_USB_SA11X0_EP1_DEVTAB_ENTRY</TT>
+ and
+<TT
+CLASS="LITERAL">
+CYGVAR_DEVS_USB_SA11X0_EP2_DEVTAB_ENTRY</TT>
+. By default
+these devtab entries are provided if the global preference
+<TT
+CLASS="LITERAL">
+CYGGLO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES</TT>
+ is enabled,
+which is usually the case. Obviously a devtab entry for a given
+endpoint will only be provided if the underlying endpoint is enabled.
+For example, there will not be a devtab entry for endpoint 1 if
+<TT
+CLASS="LITERAL">
+CYGPKG_DEVS_USB_SA11X0_EP1</TT>
+ is disabled.</P>
+<P>
+The names for the three devtab entries are determined by using a
+configurable base name and appending <TT
+CLASS="LITERAL">
+0c</TT>
+,
+<TT
+CLASS="LITERAL">
+1r</TT>
+ or <TT
+CLASS="LITERAL">
+2w</TT>
+. The base name is
+determined by the configuration option
+<TT
+CLASS="LITERAL">
+CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME</TT>
+ and has a
+default value of <TT
+CLASS="LITERAL">
+/dev/usbs</TT>
+, so the devtab entry for
+endpoint 1 would default to <TT
+CLASS="LITERAL">
+/dev/usbs1r</TT>
+. If the
+target hardware involves multiple USB devices then application
+developers may have to change the base name to prevent a name clash.</P>
+</DIV>
+<DIV
+CLASS="REFSECT1">
+<A
+NAME="AEN58">
+</A>
+<H2>
+DMA Engines</H2>
+<P>
+The SA11X0 UDC provides only limited fifos for bulk transfers on
+endpoints 1 and 2; smaller than the normal 64-byte bulk packet size.
+Therefore a typical transfer requires the use of DMA engines. The
+SA11x0 provides six DMA engines that can be used for this, and the
+endpoints require one each (assuming both endpoints are enabled). At
+the time of writing there is no arbitration mechanism to control
+access to the DMA engines. By default the device driver will use
+DMA engine 4 for endpoint 1 and DMA engine 5 for endpoint 2, and it
+assumes that no other code uses these particular engines.</P>
+<P>
+The exact DMA engines that will be used are determined by the
+configuration options
+<TT
+CLASS="LITERAL">
+CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL</TT>
+ and
+<TT
+CLASS="LITERAL">
+CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL</TT>
+. These
+options have the booldata flavor, allowing the use of DMA to be
+disabled completely in addition to controlling which DMA engines are
+used. If DMA is disabled then the device driver will attempt to
+work purely using the fifos, and the packet size will be limited to
+only 16 bytes. This limit should be reflected in the appropriate
+endpoint descriptors in the enumeration data. The code for driving the
+endpoints without DMA should be considered experimental. At best it
+will be suitable only for applications where the amount of data
+transferred is relatively small, because four times as many interrupts
+will be raised and performance will suffer accordingly.</P>
+</DIV>
+</BODY>
+</HTML>
diff --git a/ecos/packages/devs/usb/sa11x0/current/doc/makefile b/ecos/packages/devs/usb/sa11x0/current/doc/makefile
new file mode 100644
index 0000000..95cd4e9
--- /dev/null
+++ b/ecos/packages/devs/usb/sa11x0/current/doc/makefile
@@ -0,0 +1,54 @@
+#=============================================================================
+#
+# makefile
+#
+# For building the SA11x0 USB device driver documentation
+#
+#=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+#=============================================================================
+#####DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Date: 2001-01-11
+#####DESCRIPTIONEND####
+#=============================================================================
+
+TOPLEVEL := ../../../../..
+MAIN_SGML := usbs_sa11x0.sgml
+MAIN_HTML := devs-usb-sa11x0.html
+MAIN_PDF := devs-usb-sa11x0.pdf
+OTHER_SGML :=
+PICTURES :=
+
+include $(TOPLEVEL)/pkgconf/rules.doc
diff --git a/ecos/packages/devs/usb/sa11x0/current/doc/usbs_sa11x0.sgml b/ecos/packages/devs/usb/sa11x0/current/doc/usbs_sa11x0.sgml
new file mode 100644
index 0000000..cb6432c
--- /dev/null
+++ b/ecos/packages/devs/usb/sa11x0/current/doc/usbs_sa11x0.sgml
@@ -0,0 +1,234 @@
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- usbs_sa11x0.sgml -->
+<!-- -->
+<!-- Documentation for the SA11x0 USB Device Driver. -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2001, 2002 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2001/01/11 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-usb-sa11x0-ref">
+<!-- reference id="devs-usb-sa11x0-ref" -->
+ <title>SA11X0 USB Device Driver</title>
+
+<refentry id="devs-usb-sa11x0">
+<refmeta>
+<refentrytitle>SA11X0 USB Device Driver</refentrytitle>
+</refmeta>
+<refnamediv>
+<refname>SA11X0 USB Support</refname>
+<refpurpose>Device driver for the on-chip SA11X0 USB device</refpurpose>
+</refnamediv>
+
+<refsect1><title>SA11X0 USB Hardware</title>
+<para>
+The Intel StrongARM SA11x0 family of processors is supplied with an
+on-chip USB slave device, the UDC (USB Device Controller). This
+supports three endpoints. Endpoint 0 can only be used for control
+messages. Endpoint 1 can only be used for bulk transfers from host to
+peripheral. Endpoint 2 can only be used for bulk transfers from
+peripheral to host. Isochronous and interrupt transfers are not
+supported.
+</para>
+<caution>
+<para>
+Different revisions of the SA11x0 silicon have had various problems
+with the USB support. The device driver has been tested primarily
+against stepping B4 of the SA1110 processor, and may not function as
+expected with other revisions. Application developers should obtain
+the manufacturer's current errata sheets and specification updates.
+The B4 stepping still has a number of problems, but the device driver
+can work around these. However there is a penalty in terms of extra
+code, extra cpu cycles, and increased dispatch latency because extra
+processing is needed at DSR level. Interrupt latency should not be
+affected.
+</para>
+<para>
+There is one specific problem inherent in the UDC design of which
+application developers should be aware: the hardware cannot fully
+implement the USB standard for bulk transfers. A bulk transfer
+typically consists of some number of full-size 64-byte packets and is
+terminated by a packet less than the full size. If the amount of data
+transferred is an exact multiple of 64 bytes then this requires a
+terminating packet of 0 bytes of data (plus header and checksum). The
+SA11x0 USB hardware does not allow a 0-byte packet to be transmitted,
+so the device driver is forced to substitute a 1-byte packet and the
+host receives more data than expected. Protocol support is needed so
+that the appropriate host-side device driver can allow buffer space
+for the extra byte, detect when it gets sent, and discard it.
+Consequently certain standard USB class protocols cannot be
+implemented using the SA11x0, and therefore custom host-side device
+drivers will generally have to be provided, rather than re-using
+existing ones that understand the standard protocol.
+</para>
+</caution>
+</refsect1>
+
+<refsect1><title>Endpoint Data Structures</title>
+<para>
+The SA11x0 USB device driver can provide up to three data structures
+corresponding to the three endpoints: a
+<structname>usbs_control_endpoint</structname> structure
+<literal>usbs_sa11x0_ep0</literal>; a
+<structname>usbs_rx_endpoint</structname>
+<literal>usbs_sa11x0_ep1</literal>; and a
+<structname>usbs_tx_endpoint</structname>
+<literal>usbs_sa11x0_ep2</literal>. The header file
+<filename class="headerfile">cyg/io/usb/usbs_sa11x0.h</filename>
+provides declarations for these.
+</para>
+<para>
+Not all applications will require support for all the endpoints. For
+example, if the intended use of the UDC only involves peripheral to
+host transfers then <literal>usbs_sa11x0_ep1</literal> is redundant.
+The device driver provides configuration options to control the
+presence of each endpoint:
+</para>
+<orderedlist>
+<listitem>
+<para>
+Endpoint 0 is controlled by
+<literal>CYGFUN_DEVS_USB_SA11X0_EP0</literal>. This defaults to
+enabled if there are any higher-level packages that require USB
+hardware or if the global preference
+<literal>CYGGLO_IO_USB_SLAVE_APPLICATION</literal> is enabled,
+otherwise it is disabled. Usually this has the desired effect. It may
+be necessary to override this in special circumstances, for example if
+the target board uses an external USB chip in preference to the UDC
+and it is that external chip's device driver that should be used
+rather than the on-chip UDC. It is not possible to disable endpoint 0
+and at the same time enable one or both of the other endpoints, since
+a USB device is only usable if it can process the standard control
+messages.
+</para>
+</listitem>
+<listitem>
+<para>
+Endpoint 1 is controlled by
+<literal>CYGPKG_DEVS_USB_SA11X0_EP1</literal>. By default it is
+enabled whenever endpoint 0 is enabled, but it can be disabled
+manually when not required.
+</para>
+</listitem>
+<listitem>
+<para>
+Similarly endpoint 2 is controlled by
+<literal>CYGPKG_DEVS_USB_SA11X0_EP2</literal>. This is also enabled by
+default whenever endpoint 0 is enabled, but it can be disabled manually.
+</para>
+</listitem>
+</orderedlist>
+<para>
+The SA11X0 USB device driver implements the interface specified by the
+common eCos USB Slave Support package. The documentation for that
+package should be consulted for further details. There is only one
+major deviation: when there is a peripheral to host transfer on
+endpoint 2 which is an exact multiple of the bulk transfer packet size
+(usually 64 bytes) the device driver has to pad the transfer with one
+extra byte. This is because of a hardware limitation: the UDC is
+incapable of transmitting 0-byte packets as required by the USB
+specification. Higher-level code, including the host-side device
+driver, needs to be aware of this and adapt accordingly.
+</para>
+<para>
+The device driver assumes a bulk packet size of 64 bytes, so this
+value should be used in the endpoint descriptors in the enumeration
+data provided by application code. There is experimental code
+for running with <link linkend="usbs-sa11x0-dma">DMA disabled</link>,
+in which case the packet size will be 16 bytes rather than 64.
+</para>
+</refsect1>
+
+<refsect1><title>Devtab Entries</title>
+<para>
+In addition to the endpoint data structures the SA11X0 USB device
+driver can also provide devtab entries for each endpoint. This allows
+higher-level code to use traditional I/O operations such as
+<function>open</function>/<function>read</function>/<function>write</function>
+rather than the USB-specific non-blocking functions like
+<function>usbs_start_rx_buffer</function>. These devtab entries are
+optional since they are not always required. The relevant
+configuration options are
+<literal>CYGVAR_DEVS_USB_SA11X0_EP0_DEVTAB_ENTRY</literal>,
+<literal>CYGVAR_DEVS_USB_SA11X0_EP1_DEVTAB_ENTRY</literal> and
+<literal>CYGVAR_DEVS_USB_SA11X0_EP2_DEVTAB_ENTRY</literal>. By default
+these devtab entries are provided if the global preference
+<literal>CYGGLO_USB_SLAVE_PROVIDE_DEVTAB_ENTRIES</literal> is enabled,
+which is usually the case. Obviously a devtab entry for a given
+endpoint will only be provided if the underlying endpoint is enabled.
+For example, there will not be a devtab entry for endpoint 1 if
+<literal>CYGPKG_DEVS_USB_SA11X0_EP1</literal> is disabled.
+</para>
+<para>
+The names for the three devtab entries are determined by using a
+configurable base name and appending <literal>0c</literal>,
+<literal>1r</literal> or <literal>2w</literal>. The base name is
+determined by the configuration option
+<literal>CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME</literal> and has a
+default value of <literal>/dev/usbs</literal>, so the devtab entry for
+endpoint 1 would default to <literal>/dev/usbs1r</literal>. If the
+target hardware involves multiple USB devices then application
+developers may have to change the base name to prevent a name clash.
+</para>
+</refsect1>
+
+<refsect1><title id="usbs-sa11x0-dma">DMA Engines</title>
+<para>
+The SA11X0 UDC provides only limited fifos for bulk transfers on
+endpoints 1 and 2; smaller than the normal 64-byte bulk packet size.
+Therefore a typical transfer requires the use of DMA engines. The
+SA11x0 provides six DMA engines that can be used for this, and the
+endpoints require one each (assuming both endpoints are enabled). At
+the time of writing there is no arbitration mechanism to control
+access to the DMA engines. By default the device driver will use
+DMA engine 4 for endpoint 1 and DMA engine 5 for endpoint 2, and it
+assumes that no other code uses these particular engines.
+</para>
+<para>
+The exact DMA engines that will be used are determined by the
+configuration options
+<literal>CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL</literal> and
+<literal>CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL</literal>. These
+options have the booldata flavor, allowing the use of DMA to be
+disabled completely in addition to controlling which DMA engines are
+used. If DMA is disabled then the device driver will attempt to
+work purely using the fifos, and the packet size will be limited to
+only 16 bytes. This limit should be reflected in the appropriate
+endpoint descriptors in the enumeration data. The code for driving the
+endpoints without DMA should be considered experimental. At best it
+will be suitable only for applications where the amount of data
+transferred is relatively small, because four times as many interrupts
+will be raised and performance will suffer accordingly.
+</para>
+</refsect1>
+
+</refentry>
+</part>
+<!-- /reference -->
diff --git a/ecos/packages/devs/usb/sa11x0/current/include/usbs_sa11x0.h b/ecos/packages/devs/usb/sa11x0/current/include/usbs_sa11x0.h
new file mode 100644
index 0000000..f2288cc
--- /dev/null
+++ b/ecos/packages/devs/usb/sa11x0/current/include/usbs_sa11x0.h
@@ -0,0 +1,73 @@
+#ifndef CYGONCE_USBS_SA11X0_H
+# define CYGONCE_USBS_SA11X0_H
+//==========================================================================
+//
+// include/usbs_sa11x0.h
+//
+// The interface exported by the SA11X0 USB device driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors: bartv
+// Date: 2000-10-04
+// Purpose:
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/io/usb/usbs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The SA11x0 family comes with on-chip USB slave support. This
+ * provides three endpoints. Endpoint 0 can only be used for control
+ * messages. Endpoints 1 and 2 can only be used for bulk transfers,
+ * host->slave for endpoint 1 and slave->host for endpoint 2.
+ */
+extern usbs_control_endpoint usbs_sa11x0_ep0;
+extern usbs_rx_endpoint usbs_sa11x0_ep1;
+extern usbs_tx_endpoint usbs_sa11x0_ep2;
+
+#ifdef __cplusplus
+} /* extern "C" { */
+#endif
+
+
+#endif /* CYGONCE_USBS_SA11X0_H */
diff --git a/ecos/packages/devs/usb/sa11x0/current/src/usbs_sa11x0.c b/ecos/packages/devs/usb/sa11x0/current/src/usbs_sa11x0.c
new file mode 100644
index 0000000..56b105f
--- /dev/null
+++ b/ecos/packages/devs/usb/sa11x0/current/src/usbs_sa11x0.c
@@ -0,0 +1,2550 @@
+//==========================================================================
+//
+// usbs_sa11x0.c
+//
+// Device driver for the SA11x0 USB port.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors: bartv
+// Date: 2000-10-04
+//
+// This code implements support for the on-chip USB port on the SA11x0
+// family of processors. The code has been developed on the SA1110 and
+// may or may not work on other members of the SA11x0 family. There
+// have problems with the USB support on certain revisions of the silicon,
+// so the errata sheet appropriate to the specific processor being used
+// should be consulted. There also appear to be problems which do not
+// appear on any errata, which this code attempts to work around.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/diag.h>
+
+#include <pkgconf/hal_arm.h>
+#include <pkgconf/devs_usb_sa11x0.h>
+
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_sa11x0.h>
+#include <cyg/error/codes.h>
+
+#include <cyg/io/usb/usb.h>
+#include <cyg/io/usb/usbs.h>
+
+// Debugging support. By default this driver operates mostly at
+// DSR level, with the ISR doing a minimal amount of processing.
+// However is also possible to run most of the code at thread-level,
+// This is subject to some restrictions because the USB standard
+// imposes timing constraints, e.g. some control operations such
+// as SET-ADDRESS have to complete within 50ms. However it is
+// very useful for debugging, specifically it allows you to put
+// printf()'s in various places.
+//
+// Right now these configuration options are not exported to the
+// user because running at DSR level is likely to be good enough
+// for everybody not actively debugging this code. The options
+// could be exported if necessary.
+//#define CYGPKG_DEVS_USB_SA11X0_THREAD
+#undef CYGPKG_DEVS_USB_SA11X0_THREAD
+#ifdef CYGPKG_DEVS_USB_SA11X0_THREAD
+ // Default stack size should be CYGNUM_HAL_STACK_SIZE_TYPICAL
+# define CYGNUM_DEVS_USB_SA11X0_THREAD_STACK_SIZE 4096
+# define CYGNUM_DEVS_USB_SA11X0_THREAD_PRIORITY 7
+# include <cyg/kernel/kapi.h>
+#endif
+
+#if 0
+# define DBG(a) diag_printf a
+#else
+# define DBG(a)
+#endif
+
+#undef FAILURES
+#ifdef FAILURES
+static volatile int ep1_failure = 7;
+#endif
+
+#undef STATS
+#ifdef STATS
+int ep1_receives = 0;
+int ep1_errors = 0;
+int ep2_transmits = 0;
+int ep2_errors = 0;
+# define INCR_STAT(a) (a) += 1
+# define SET_STAT(a, b) (a) = (b)
+#else
+# define INCR_STAT(a)
+# define SET_STAT(a, b)
+#endif
+
+// ----------------------------------------------------------------------------
+// Serial port 0 on the SA11x0 provides a USB slave connection (aka a
+// USB device controller or UDC). The functionality is somewhat
+// limited, there are just three endpoints.
+//
+// Endpoint 0 can only be used for control messages. It has an 8 byte
+// fifo which cannot be connected to a DMA engine. Hence incoming
+// control packets have to be limited to 8 bytes by the enumeration
+// data. The endpoint has to be managed at a low-level, i.e. the
+// incoming request has to be extracted from the fifo, processed, and
+// any response put back into the fifo within the permitted USB
+// response times.
+//
+// Endpoint 1 can only be used for host->slave bulk OUT transfers. It
+// has a 20 byte receive fifo, and it can be hooked up to any of the
+// six DMA engines. Since bulk transfers will typically involve 64
+// byte packets, most applications will require the use of DMA.
+//
+// Endpoint 2 can only be used for slave-host bulk IN transfers. There
+// is a 16 byte transmit fifo so small messages can be transferred in
+// software. The fifo can also be hooked up to DMA, which is a more
+// likely scenario.
+//
+// Start with definitions of the hardware. The use of a structure and
+// a const base pointer should allow the compiler to do base/offset
+// addressing and keep the hardware base address in a register. This
+// is better than defining each hardware register via a separate
+// address. Although the registers are only a byte wide, the peripheral
+// bus only supports word accesses.
+//
+// The USBS_CONTROL etc. macros allow for an alternative way of
+// accessing the hardware if a better approach is presented, without
+// having to rewrite all the code. Macros that correspond to registers
+// are actually addresses, making it easier in the code to distinguish
+// them from bit values: the & and * operators will just cancel out.
+
+typedef struct usbs_sa11x0_hardware {
+ volatile int control;
+ volatile int address;
+ volatile int out_size;
+ volatile int in_size;
+ volatile int ep0_control;
+ volatile int ep1_control;
+ volatile int ep2_control;
+ volatile int ep0_data;
+ volatile int ep0_write_count;
+ int dummy1;
+ volatile int fifo;
+ int dummy2;
+ volatile int status;
+} usbs_sa11x0_hardware;
+
+static usbs_sa11x0_hardware* const usbs_sa11x0_base = (usbs_sa11x0_hardware* const) 0x80000000;
+#define USBS_CONTROL (&(usbs_sa11x0_base->control))
+#define USBS_ADDRESS (&(usbs_sa11x0_base->address))
+#define USBS_OUT_SIZE (&(usbs_sa11x0_base->out_size))
+#define USBS_IN_SIZE (&(usbs_sa11x0_base->in_size))
+#define EP0_CONTROL (&(usbs_sa11x0_base->ep0_control))
+#define EP1_CONTROL (&(usbs_sa11x0_base->ep1_control))
+#define EP2_CONTROL (&(usbs_sa11x0_base->ep2_control))
+#define EP0_DATA (&(usbs_sa11x0_base->ep0_data))
+#define EP0_WRITE_COUNT (&(usbs_sa11x0_base->ep0_write_count))
+#define EP1_DATA (&(usbs_sa11x0_base->fifo))
+#define EP2_DATA (&(usbs_sa11x0_base->fifo))
+#define USBS_STATUS (&(usbs_sa11x0_base->status))
+
+#define CONTROL_DISABLE (1 << 0)
+#define CONTROL_ACTIVE (1 << 1)
+// The meaning of bit 2 changed, see errata
+#define CONTROL_RESUME_INTR (1 << 2)
+#define CONTROL_EP0_INTR (1 << 3)
+#define CONTROL_EP1_INTR (1 << 4)
+#define CONTROL_EP2_INTR (1 << 5)
+// The meaning of bit 6 also changed, see errata
+#define CONTROL_SUSPEND_INTR (1 << 6)
+#define CONTROL_RESET_INTR (1 << 7)
+
+// Getting the control register settings right is a little bit tricky.
+// Bit 0 is the disable bit so touching that is dangerous, and the
+// other bits have inverted meanings i.e. 0 enables interrupts. The
+// following macro encapsulates this.
+#define CONTROL_ALL_INTR 0x00FC
+#define CONTROL_INTR_ENABLE(bits) ((~(bits)) & CONTROL_ALL_INTR)
+#define CONTROL_INTR_CLEAR(bits) ((bits) & CONTROL_ALL_INTR)
+
+// All the endpoint interrupt numbers can be handled en masse,
+// but some of the endpoints may be disabled.
+#if defined(CYGPKG_DEVS_USB_SA11X0_EP1) && defined(CYGPKG_DEVS_USB_SA11X0_EP2)
+# define CONTROL_EP_INTR_BITS (CONTROL_EP0_INTR | CONTROL_EP1_INTR | CONTROL_EP2_INTR)
+#elif defined(CYGPKG_DEVS_USB_SA11X0_EP1)
+# define CONTROL_EP_INTR_BITS (CONTROL_EP0_INTR | CONTROL_EP1_INTR)
+#elif defined(CYGPKG_DEVS_USB_SA11X0_EP2)
+# define CONTROL_EP_INTR_BITS (CONTROL_EP0_INTR | CONTROL_EP2_INTR)
+#else
+# define CONTROL_EP_INTR_BITS (CONTROL_EP0_INTR)
+#endif
+
+#define EP0_OUT_READY (1 << 0)
+#define EP0_IN_READY (1 << 1)
+#define EP0_SENT_STALL (1 << 2)
+#define EP0_FORCE_STALL (1 << 3)
+#define EP0_DATA_END (1 << 4)
+#define EP0_SETUP_END (1 << 5)
+#define EP0_SERVICED_OPR (1 << 6)
+#define EP0_SERVICED_SETUP_END (1 << 7)
+
+#define EP1_FIFO_SERVICE (1 << 0)
+#define EP1_PACKET_COMPLETE (1 << 1)
+#define EP1_PACKET_ERROR (1 << 2)
+#define EP1_SENT_STALL (1 << 3)
+#define EP1_FORCE_STALL (1 << 4)
+#define EP1_FIFO_NOT_EMPTY (1 << 5)
+
+#define EP2_FIFO_SERVICE (1 << 0)
+#define EP2_PACKET_COMPLETE (1 << 1)
+#define EP2_PACKET_ERROR (1 << 2)
+#define EP2_PACKET_UNDERRUN (1 << 3)
+#define EP2_SENT_STALL (1 << 4)
+#define EP2_FORCE_STALL (1 << 5)
+
+#define STATUS_EP0_INTR (1 << 0)
+#define STATUS_EP1_INTR (1 << 1)
+#define STATUS_EP2_INTR (1 << 2)
+#define STATUS_SUSPEND_INTR (1 << 3)
+#define STATUS_RESUME_INTR (1 << 4)
+#define STATUS_RESET_INTR (1 << 5)
+
+#define EP0_FIFO_SIZE 8
+#define EP0_MTU 8
+
+#define EP1_FIFO_SIZE 20
+#ifdef CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL
+# define EP1_MTU 64
+#else
+# define EP1_MTU 16
+#endif
+
+#define EP2_FIFO_SIZE 16
+#ifdef CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL
+# define EP2_MTU 64
+#else
+# define EP2_MTU 16
+#endif
+
+#if defined(CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL) || defined(CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL)
+typedef struct usbs_sa11x0_dma {
+ volatile int address;
+ volatile int control_set;
+ volatile int control_clear;
+ volatile int status;
+ volatile int buf_a_address; // Absolute, not remapped
+ volatile int buf_a_size;
+ volatile int buf_b_address; // Absolute, not remapped
+ volatile int buf_b_size;
+} usbs_sa11x0_dma;
+
+#define DMA_CONTROL_RUN (1 << 0)
+#define DMA_CONTROL_INTR_ENABLE (1 << 1)
+#define DMA_STATUS_ERROR (1 << 2)
+#define DMA_STATUS_DONE_A (1 << 3)
+#define DMA_CONTROL_START_A (1 << 4)
+#define DMA_STATUS_DONE_B (1 << 5)
+#define DMA_CONTROL_START_B (1 << 6)
+#define DMA_STATUS_BUFFER_IN_USE (1 << 7)
+// All the bits that are useful to clear. BUFFER_IN_USE is read-only.
+#define DMA_CONTROL_CLEAR_ALL (DMA_CONTROL_RUN | DMA_CONTROL_INTR_ENABLE | DMA_STATUS_ERROR | \
+ DMA_STATUS_DONE_A | DMA_CONTROL_START_A | DMA_STATUS_DONE_B | DMA_CONTROL_START_B)
+
+// The DMA engines operate eight-bytes at a time. This affects issues
+// such as alignment.
+#define DMA_BURST_SIZE 8
+
+// The DMA engines bypass the cache and MMU, accessing physical
+// memory directly. Newer HALS should provide appropriate macros.
+#ifndef HAL_VIRT_TO_PHYS_ADDRESS
+# error HAL macros for translating between virtual and physical memory are required.
+#endif
+
+// Make absolutely sure that the two endpoints use different
+// DMA channels. Right now this check cannot be done easily
+// at the CDL level.
+# if defined(CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL) && defined(CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL)
+# if (CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL == CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL)
+# error Different DMA channels must be selected for the two endpoints.
+# endif
+# endif
+
+# ifdef CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL
+static usbs_sa11x0_dma* const ep1_dma_base = (usbs_sa11x0_dma* const)(0xB0000000 | (0x20 * CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL));
+# define EP1_DMA_ADDRESS (&(ep1_dma_base->address))
+# define EP1_DMA_CONTROL_SET (&(ep1_dma_base->control_set))
+# define EP1_DMA_CONTROL_CLEAR (&(ep1_dma_base->control_clear))
+# define EP1_DMA_STATUS (&(ep1_dma_base->status))
+# define EP1_DMA_BUF_A_ADDRESS (&(ep1_dma_base->buf_a_address))
+# define EP1_DMA_BUF_A_SIZE (&(ep1_dma_base->buf_a_size))
+# define EP1_DMA_BUF_B_ADDRESS (&(ep1_dma_base->buf_b_address))
+# define EP1_DMA_BUF_B_SIZE (&(ep1_dma_base->buf_b_size))
+
+// The correct value for the DMA address register is fixed for USB transfers
+// See table 11.6 of the SA1110 Advanced Developer's Manual
+// Device datum width == 1 byte
+// Device burst size == 8 bytes
+// Device transfer direction == read (device->memory)
+// Endianness is controlled by the ARM architectural HAL package
+# ifdef CYGHWR_HAL_ARM_BIGENDIAN
+# define EP1_DMA_ADDRESS_VALUE (0x80000A00 | 0x10 | 0x0 | 0x4 | 0x2 | 0x1)
+# else
+# define EP1_DMA_ADDRESS_VALUE (0x80000A00 | 0x10 | 0x0 | 0x4 | 0x0 | 0x1)
+# endif
+# endif // EP1_DMA
+
+# ifdef CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL
+
+static usbs_sa11x0_dma* const ep2_dma_base = (usbs_sa11x0_dma* const)(0xB0000000 | (0x20 * CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL));
+# define EP2_DMA_ADDRESS (&(ep2_dma_base->address))
+# define EP2_DMA_CONTROL_SET (&(ep2_dma_base->control_set))
+# define EP2_DMA_CONTROL_CLEAR (&(ep2_dma_base->control_clear))
+# define EP2_DMA_STATUS (&(ep2_dma_base->status))
+# define EP2_DMA_BUF_A_ADDRESS (&(ep2_dma_base->buf_a_address))
+# define EP2_DMA_BUF_A_SIZE (&(ep2_dma_base->buf_a_size))
+# define EP2_DMA_BUF_B_ADDRESS (&(ep2_dma_base->buf_b_address))
+# define EP2_DMA_BUF_B_SIZE (&(ep2_dma_base->buf_b_size))
+
+# ifdef CYGHWR_HAL_ARM_BIGENDIAN
+# define EP2_DMA_ADDRESS_VALUE (0x80000A00 | 0x00 | 0x0 | 0x4 | 0x2 | 0x0)
+# else
+# define EP2_DMA_ADDRESS_VALUE (0x80000A00 | 0x00 | 0x0 | 0x4 | 0x0 | 0x0)
+# endif
+# endif // EP2_DMA
+
+#endif // EP1_DMA || EP2_DMA
+
+// ----------------------------------------------------------------------------
+// Static data. There is a data structure for each endpoint. The
+// implementation is essentially a private class that inherits from
+// common classes for control and data endpoints, but device drivers
+// are supposed to be written in C so some ugliness is required.
+//
+// Devtab entries are defined in usbs_sa11x0_data.cxx to make sure
+// that the linker does not garbage-collect them.
+
+// Support for the interrupt handling code.
+static cyg_interrupt usbs_sa11x0_intr_data;
+static cyg_handle_t usbs_sa11x0_intr_handle;
+static volatile int isr_status_bits = 0;
+
+// Endpoint 0 is always present, this module would not get compiled
+// otherwise.
+static void usbs_sa11x0_ep0_start(usbs_control_endpoint*);
+static void usbs_sa11x0_poll(usbs_control_endpoint*);
+
+typedef enum ep0_state {
+ EP0_STATE_IDLE = 0,
+ EP0_STATE_IN = 1,
+ EP0_STATE_OUT = 2
+} ep0_state;
+
+typedef struct ep0_impl {
+ usbs_control_endpoint common;
+ ep0_state ep_state;
+ int length;
+ int transmitted;
+} ep0_impl;
+
+static ep0_impl ep0 = {
+ common:
+ {
+ state: USBS_STATE_POWERED, // The hardware does not distinguish between detached, attached and powered.
+ enumeration_data: (usbs_enumeration_data*) 0,
+ start_fn: &usbs_sa11x0_ep0_start,
+ poll_fn: &usbs_sa11x0_poll,
+ interrupt_vector: SA11X0_IRQ_USB_SERVICE_REQUEST,
+ control_buffer: { 0, 0, 0, 0, 0, 0, 0, 0 },
+ state_change_fn: (void (*)(usbs_control_endpoint*, void*, usbs_state_change, int)) 0,
+ state_change_data: (void*) 0,
+ standard_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
+ standard_control_data: (void*) 0,
+ class_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
+ class_control_data: (void*) 0,
+ vendor_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
+ vendor_control_data: (void*) 0,
+ reserved_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
+ reserved_control_data: (void*) 0,
+ buffer: (unsigned char*) 0,
+ buffer_size: 0,
+ fill_buffer_fn: (void (*)(usbs_control_endpoint*)) 0,
+ fill_data: (void*) 0,
+ fill_index: 0,
+ complete_fn: (usbs_control_return (*)(usbs_control_endpoint*, int)) 0
+ },
+ ep_state: EP0_STATE_IDLE,
+ length: 0,
+ transmitted: 0
+};
+
+extern usbs_control_endpoint usbs_sa11x0_ep0 __attribute__((alias ("ep0")));
+
+// Endpoint 1 is optional. If the application only involves control
+// messages or only slave->host transfers then the endpoint 1
+// support can be disabled.
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP1
+
+typedef struct ep1_impl {
+ usbs_rx_endpoint common;
+ int fetched;
+ cyg_bool using_buf_a;
+} ep1_impl;
+
+static void ep1_start_rx(usbs_rx_endpoint*);
+static void ep1_set_halted(usbs_rx_endpoint*, cyg_bool);
+
+static ep1_impl ep1 = {
+ common: {
+ start_rx_fn: &ep1_start_rx,
+ set_halted_fn: &ep1_set_halted,
+ complete_fn: (void (*)(void*, int)) 0,
+ complete_data: (void*) 0,
+ buffer: (unsigned char*) 0,
+ buffer_size: 0,
+ halted: 0,
+ },
+ fetched: 0,
+ using_buf_a: 0
+};
+
+extern usbs_rx_endpoint usbs_sa11x0_ep1 __attribute__((alias ("ep1")));
+#endif
+
+// Endpoint 2 is optional. If the application only involves control
+// messages or only host->slave transfers then the endpoint 2 support
+// can be disabled.
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP2
+
+typedef struct ep2_impl {
+ usbs_tx_endpoint common;
+ int transmitted;
+ int pkt_size;
+} ep2_impl;
+
+static void ep2_start_tx(usbs_tx_endpoint*);
+static void ep2_set_halted(usbs_tx_endpoint*, cyg_bool);
+
+static ep2_impl ep2 = {
+ common: {
+ start_tx_fn: &ep2_start_tx,
+ set_halted_fn: &ep2_set_halted,
+ complete_fn: (void (*)(void*, int)) 0,
+ complete_data: (void*) 0,
+ buffer: (const unsigned char*) 0,
+ buffer_size: 0,
+ halted: 0,
+ },
+ transmitted: 0,
+ pkt_size: 0
+};
+
+extern usbs_tx_endpoint usbs_sa11x0_ep2 __attribute__ ((alias ("ep2")));
+
+#endif
+
+// ----------------------------------------------------------------------------
+// Hardware problem: experiments indicate that manipulating the USB
+// controller registers does not always work as expected. The control
+// fifo is especially badly affected, with e.g. writes just being lost
+// completely. It is necessary to work around these problems using
+// retry loops. MAX_RETRIES controls the total number of attempts to
+// access a register. MAX_CHECKS controls the number of times a
+// register is checked to determine whether or not the attempt has
+// been succesful. These constants are used to access the data fifo,
+// so MAX_RETRIES has to be > 20 bytes.
+#define MAX_RETRIES 32
+#define MAX_CHECKS 8
+
+// Write one or more bits to a register. This should result in some
+// bits ending up set and other bits ending up clear. Some register
+// bits are write-1-to-clear or may have side effects.
+static cyg_bool
+usbs_sa11x0_poke(volatile int* addr, int value, int should_be_set, int should_be_clear)
+{
+ cyg_bool result = false;
+ int retries, checks;
+
+ for (retries = 0; !result && (retries < MAX_RETRIES); retries++) {
+ *addr = value;
+ (void) *addr; // The first read is always invalid.
+ for (checks = 0; !result && (checks < MAX_CHECKS); checks++) {
+ int current_value = *addr;
+ if (should_be_set != (should_be_set & current_value)) {
+ continue;
+ }
+ if ((0 != should_be_clear) && (0 != (should_be_clear & current_value))) {
+ continue;
+ }
+ result = true;
+ }
+ }
+ if (!result) {
+ DBG(("usbs_sa11x0_poke failed: addr %x, value %x, should_be_set %x, should_be_clear %x, actual %x\n", \
+ (int) addr, value, should_be_set, should_be_clear, *addr));
+ }
+ return result;
+}
+
+// Write a whole value to a register, rather than just manipulating
+// individual bits.
+static cyg_bool
+usbs_sa11x0_poke_value(volatile int* addr, int value)
+{
+ cyg_bool result = false;
+ int retries, checks;
+
+ for (retries = 0; !result && (retries < MAX_RETRIES); retries++) {
+ *addr = value;
+ (void) *addr; // The first read is always invalid.
+ for (checks = 0; !result && (checks < MAX_CHECKS); checks++) {
+ if (value == *addr) {
+ result = true;
+ }
+ }
+ }
+ if (!result) {
+ DBG(("usbs_sa11x0_poke_value failed: addr %x, value %x, actual %x\n", (int) addr, value, *addr));
+ }
+ return result;
+}
+
+
+// ----------------------------------------------------------------------------
+// Control transfers
+//
+// Endpoint 0 is rather more complicated than the others. This is
+// partly due to the nature of the control protocol, for example it is
+// bidirectional and transfer sizes are unpredictable.
+//
+// The USB standard imposes some timing constraints on endpoint 0, see
+// section 9.2.6 of the spec. For example the set-address operation is
+// supposed to take at most 50ms. In general the timings are reasonably
+// generous so no special action is taken here. There could be problems
+// when debugging, but that is pretty much inevitable.
+//
+// It is necessary to maintain a state for the control endpoint, the
+// default state being idle. Control operations involve roughly the
+// following sequence of events:
+//
+// 1) the host transmits a special setup token, indicating the start
+// of a control operation and possibly cancelling any existing control
+// operation that may be in progress. USB peripherals cannot NAK this
+// even if they are busy.
+//
+// 2) the setup operation is followed by an eight-byte packet from the host
+// that describes the specific control operation. This fits into the
+// SA11X0's eight-byte control fifo. There will be an endpoint 0
+// interrupt with the out-packet-ready bit set. If the setup token
+// was sent while a previous control operation was also in progress
+// then the setup-end bit will be set as well.
+//
+// 3) the eight-byte packet is described in section 9.3 of the USB spec.
+// The first byte holds three fields, with the top bit indicating the
+// direction of subsequent data transfer. There are also two bytes
+// specifying the size of the subsequent transfer. Obviously the
+// packet also contains information such as the request type.
+//
+// If the specified size is zero then the endpoint will remain in
+// its idle state. Otherwise the endpoint will switch to either
+// IN or OUT state, depending on the direction of subsequent
+// transfers.
+//
+// 4) some standard control operations can be handled by the code
+// here. Set-address involves poking the address register and
+// a change of state. Set-feature and clear-feature on the
+// data endpoints can be used in conjunction with endpoint-halt.
+// Get-status on the data endpoints tests the halt condition.
+// It is also possible for the hardware-specific code to
+// implement set-feature, clear-feature and get-status
+// for the device as a whole since the SA11x0 always has to
+// be self-powered and is incapable of initiating a remote
+// wakeup.
+//
+// Other standard control operations will be handled by the
+// application-specific installed handler, if any, or by the
+// default handler usbs_handle_standard_control(). Class-specific
+// and vendor-specific functions require appropriate handlers to be
+// installed as well, If a particular request is not recognized
+// then a stall condition should be raised. This will not prevent
+// subsequent control operations, just the current one.
+//
+// Data transfers on endpoint 0 involve at most eight bytes at
+// a time. More data will only be accepted if the out-packet-ready
+// bit has been cleared via the serviced-opr bit, with the
+// hardware nak'ing OUT requests. To send data back to the host
+// the FIFO should be filled and then the in-packet-ready bit
+// should be set.
+//
+// It looks like processing all control packets at DSR level should be
+// sufficient. During the data phase the hardware will NAK IN and
+// OUT requests if the fifo is still empty/full, so timing is not
+// an issue. Timing after receipt of the initial control message
+// may be more important, e.g. the 50ms upper limit on processing
+// the set-address control message, but this should still be ok.
+// This decision may have to be re-examined in the light of
+// experience.
+
+// Init may get called during system startup or following a reset.
+// During startup no work is needed since the hardware will
+// have been reset and everything should be fine. After a reset
+// the hardware will also be ok but there may be state information
+// in ep0 that needs to be reset.
+static void
+usbs_sa11x0_ep0_init(void)
+{
+ if ((EP0_STATE_IDLE != ep0.ep_state) &&
+ ((usbs_control_return (*)(usbs_control_endpoint*, int)) 0 != ep0.common.complete_fn)) {
+ (*ep0.common.complete_fn)(&ep0.common, -EPIPE);
+ }
+ ep0.common.state = USBS_STATE_POWERED;
+ memset(ep0.common.control_buffer, 0, 8);
+ ep0.common.buffer = (unsigned char*) 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
+ ep0.common.fill_data = (void*) 0;
+ ep0.common.fill_index = 0;
+ ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
+ ep0.ep_state = EP0_STATE_IDLE;
+ ep0.length = 0;
+ ep0.transmitted = 0;
+}
+
+// The start function is called by higher-level code when things have
+// been set up, i.e. the enumeration data is available, appropriate
+// handlers have been installed for the different types of control
+// messages, and communication with the host is allowed to start. The
+// next event that should happen is a reset operation from the host,
+// so all other interrupts should be blocked. However it is likely
+// that the hardware will detect a suspend state before the reset
+// arrives, and hence the reset will act as a resume as well as a
+// reset.
+static void
+usbs_sa11x0_ep0_start(usbs_control_endpoint* endpoint)
+{
+ CYG_ASSERT( endpoint == &ep0.common, "USB startup involves the wrong endpoint");
+
+ // Activate the hardware. Write a 0 to the enable/disable bit 0.
+ // Bit 1 is read-only. The other bits are set to 1 to disable
+ // the corresponding interrupt source.
+ usbs_sa11x0_poke(USBS_CONTROL, CONTROL_ALL_INTR, CONTROL_ALL_INTR, 0);
+
+ // If there is additional platform-specific initialization to
+ // perform, do it now. This macro can come from the platform HAL.
+#ifdef SA11X0_USB_PLATFORM_INIT
+ SA11X0_USB_PLATFORM_INIT;
+#endif
+
+ // Clear any pending interrupts. There should not be any, but just
+ // in case. Note: passing 0x00FF as the should_be_clear argument
+ // is a race condition, an external event can happen at any time,
+ // so we may loop unnecessarily and lose an interrupt. However
+ // the initial reset should last for 10ms.
+ usbs_sa11x0_poke(USBS_STATUS, 0x00FF, 0x00, 0x00FF);
+
+ // The only interrupt really of interest right now is reset, but
+ // it is likely to be preceded by a resume.
+ usbs_sa11x0_poke(USBS_CONTROL,
+ CONTROL_INTR_ENABLE(CONTROL_RESET_INTR | CONTROL_RESUME_INTR),
+ 0,
+ CONTROL_INTR_CLEAR(CONTROL_RESET_INTR | CONTROL_RESUME_INTR));
+}
+
+
+// Filling the fifo with a reply to the host. This can be called
+// immediately at the end of a control message, to prepare for
+// the next IN token. It will also get called after each subsequent
+// IN operation when the fifo has been emptied.
+//
+// Experiments have indicated serious problems with the control fifo:
+// some writes to the fifo just get lost completely. The failure rate
+// is sufficiently high that more often than not the host will be
+// unable to read all the enumeration data. However, the write-count
+// register appears to give a valid indication of the current fifo
+// contents. This means the code can retry stuffing a particular byte
+// into the fifo until the write-count goes up.
+
+static void
+usbs_sa11x0_ep0_fill_fifo(void)
+{
+ cyg_bool ok = true;
+ int filled = 0;
+ int max;
+ int fifo_count = *EP0_WRITE_COUNT;
+ int bits_to_set = 0;
+
+ // The host can interrupt the current control message at any time
+ // with a new one. In practice this is unlikely, things could get
+ // rather confused on the host side. However if a control message
+ // has been received then the fifo should obviously not be filled.
+ // A new control message is indicated by the SETUP_END bit.
+ //
+ // The hardware design means that there is a race condition: the
+ // new control message can come in at any time, even in the middle
+ // of filling the fifo. Checking the SETUP_END more often would
+ // reduce the probability of things getting messed up, but not
+ // eliminate it.
+ //
+ // There is a check for SETUP_END at the start of the DSR, so
+ // the setting of this bit should have resulted in another ISR
+ // and another DSR being scheduled. Hence there is no need for
+ // special action here.
+ if (0 != (*EP0_CONTROL & EP0_SETUP_END)) {
+ DBG(("EP0_fill_fifo(), interrupted by SETUP_END\n"));
+ return;
+ }
+
+ // There should never be any data in the fifo. Any such data could
+ // be the remnant of a previous transfer to the host, but that
+ // should all have gone out already. Alternatively it could be
+ // incoming data, but that means a new control message.
+ if (0 != fifo_count) {
+ DBG(("EP0_fill_fifo(), fifo already contains %d bytes", fifo_count));
+ return;
+ }
+
+ // The IN_READY bit should never be set on entry. It can only get
+ // set by a previous call to fill_fifo(), and the data should
+ // have gone out before we get back here.
+ if (0 != (*EP0_CONTROL & EP0_IN_READY)) {
+ DBG(("EP0 fill_fifo(), in-packet-ready bit already set, state %x\n", *EP0_CONTROL));
+ return;
+ }
+
+ // Now put up to another eight bytes into the fifo.
+ max = ((ep0.length - ep0.transmitted) > EP0_FIFO_SIZE) ? EP0_FIFO_SIZE : (ep0.length - ep0.transmitted);
+ while (ok && (filled < max)) {
+ if (0 != ep0.common.buffer_size) {
+ int datum;
+ int retries, checks;
+ cyg_bool written;
+
+ datum = *ep0.common.buffer++;
+ ep0.common.buffer_size--;
+ written = false;
+
+ for (retries = 0; ok && !written && (retries < MAX_RETRIES); retries++) {
+ if (filled != *EP0_WRITE_COUNT) {
+ DBG(("EP0 fill_fifo, inconsistency, written %d but write count %d\n", filled, *EP0_WRITE_COUNT));
+ ok = false;
+ }
+ *EP0_DATA = datum;
+ // The write-count may take a few cycles to settle down.
+ for (checks = 0; !written && (checks < MAX_CHECKS); checks++) {
+ if (filled < *EP0_WRITE_COUNT) {
+ filled++;
+ written = true;
+ // DBG(("Transferred %d byte (%x) after %d checks, %d retries\n", filled - 1, datum, checks, retries));
+ }
+ }
+ }
+ } else if ((void (*)(usbs_control_endpoint*))0 != ep0.common.fill_buffer_fn) {
+ (*ep0.common.fill_buffer_fn)(&ep0.common);
+ } else {
+ break;
+ }
+ }
+
+ // At this point either it has proved impossible to fill the fifo,
+ // e.g. because of a new control message, or up to another eight
+ // bytes have been sent.
+ if (!ok) {
+ if (0 == (EP0_SETUP_END & *EP0_CONTROL)) {
+ // There is something seriously wrong.
+ DBG(("ep0_fill_fifo(), failed, only filled %d bytes, status %x\n", filled, *EP0_CONTROL));
+ usbs_sa11x0_poke(EP0_CONTROL, EP0_FORCE_STALL, EP0_FORCE_STALL, 0);
+ }
+ return;
+ }
+
+ // The following conditions are possible:
+ // 1) amount transferred == amount requested, transfer complete.
+ // 2) amount transferred < amount requested, this fill involved
+ // <eight bytes, transfer complete by definition of the protocol.
+ // 3) amount transferred < amount requested but exactly eight
+ // bytes were sent this time. It will be necessary to send
+ // another packet of zero bytes to complete the transfer.
+ ep0.transmitted += filled;
+ if ((ep0.transmitted == ep0.length) || (filled < EP0_FIFO_SIZE)) {
+
+ ep0.ep_state = EP0_STATE_IDLE;
+ if ((usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn) {
+ (void) (*ep0.common.complete_fn)(&ep0.common, 0);
+ }
+ ep0.common.buffer = (unsigned char*) 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
+
+ // This informs the hardware that the control message has been
+ // handled.
+ bits_to_set = EP0_DATA_END;
+ }
+
+ // This allows another IN operation to empty the fifo.
+ bits_to_set |= EP0_IN_READY;
+ usbs_sa11x0_poke(EP0_CONTROL, bits_to_set, bits_to_set, 0);
+}
+
+// Another utility function to empty the fifo. This involves similar
+// hardware problems to writing, it is possible to read a byte without
+// changing the fifo state so that next time the same byte would be
+// read again. Again there is a possible race condition if another
+// control message arrives while emptying the fifo.
+static int
+usbs_sa11x0_ep0_empty_fifo(unsigned char* buf)
+{
+ int count = *EP0_WRITE_COUNT & 0x00FF;
+ int emptied = 0;
+ cyg_bool ok = true;
+
+ CYG_ASSERT( (count >= 0) & (count <= 8), "EP0 write count must be in range");
+
+ while (ok && (emptied < count)) {
+ int retries, checks;
+ cyg_bool read = false;
+
+ for (retries = 0; !read && (retries < MAX_RETRIES); retries++) {
+ if ((count - emptied) != *EP0_WRITE_COUNT) {
+ DBG(("EP0_empty_fifo, inconsistency, read %d bytes of %d, but fifo count %d\n", emptied, count, *EP0_WRITE_COUNT));
+ ok = false;
+ } else {
+ buf[emptied] = *EP0_DATA;
+ for (checks = 0; !read && (checks < MAX_CHECKS); checks++) {
+ if ((count - emptied) > *EP0_WRITE_COUNT) {
+ //DBG(("Read %d byte (%x) after %d checks, %d retries\n", emptied, buf[emptied], checks, retries));
+ read = true;
+ emptied++;
+ }
+ }
+ }
+ }
+ if (ok && !read) {
+ DBG(("EP0 empty fifo, failed to read byte from fifo\n"));
+ ok = false;
+ }
+ }
+
+ return emptied;
+}
+
+// This is where all the hard work happens. It is a very large routine
+// for a DSR, but in practice nearly all of it is nested if's and very
+// little code actually gets executed. Note that there may be
+// invocations of callback functions and the driver has no control
+// over how much time those will take, but those callbacks should be
+// simple.
+static void
+usbs_sa11x0_ep0_dsr(void)
+{
+ int hw_state = *EP0_CONTROL;
+
+ // Handle the stall bits.
+ //
+ // Force-stall should not be a problem. It is set by the code here
+ // if the host needs to be told that the control message was
+ // unacceptable and is cleared automatically by the hardware after
+ // the stall is sent.
+ // NOTE: it is not clear the hardware actually works in this
+ // respect. The FORCE_STALL bit has been observed still set during
+ // the next interrupt, and the host appears to receive spurious
+ // data back in response to the next control packet.
+ //
+ // Sent-stall is set by the hardware following a protocol
+ // violation, e.g. if there is an IN token when a new control
+ // message is expected. There is nothing the software can do about
+ // this. However if we are in the middle of an IN or OUT transfer
+ // then those are not going to complete successfully.
+ if (0 != (hw_state & EP0_SENT_STALL)) {
+ if (EP0_STATE_IDLE != ep0.ep_state) {
+ if ((usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn) {
+ (*ep0.common.complete_fn)(&ep0.common, -EIO);
+ }
+ ep0.ep_state = EP0_STATE_IDLE;
+ ep0.common.buffer = (unsigned char*) 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.fill_buffer_fn = 0;
+ ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
+ }
+ usbs_sa11x0_poke(EP0_CONTROL, EP0_SENT_STALL, 0, EP0_SENT_STALL);
+ } // STALL condition
+
+ // Next, check whether we have received a new control message
+ // while still busy processing an old one.
+ if (0 != (hw_state & EP0_SETUP_END)) {
+ if (EP0_STATE_IDLE != ep0.ep_state) {
+ if ((usbs_control_return (*)(usbs_control_endpoint*, int)) 0 != ep0.common.complete_fn) {
+ (*ep0.common.complete_fn)(&ep0.common, -EIO);
+ }
+ ep0.ep_state = EP0_STATE_IDLE;
+ ep0.common.buffer = (unsigned char*) 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.fill_buffer_fn = 0;
+ ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
+ }
+ // We are now back in idle state so the control message will be
+ // extracted and processed.
+ usbs_sa11x0_poke(EP0_CONTROL, EP0_SERVICED_SETUP_END, 0, EP0_SETUP_END);
+ } // Interrupted control transaction
+
+ // The endpoint can be in one of three states: IN, OUT, or IDLE.
+ // For the first two it should mean that there is more data to be
+ // transferred, which is pretty straightforward. IDLE means
+ // that a new control message has arrived.
+ if ((EP0_STATE_IN == ep0.ep_state) && (0 == (EP0_IN_READY & hw_state))) {
+
+ usbs_sa11x0_ep0_fill_fifo();
+
+ } else if ((EP0_STATE_OUT == ep0.ep_state) && (0 != (EP0_OUT_READY & hw_state))) {
+
+ // A host->device transfer. Higher level code must have
+ // provided a suitable buffer.
+ CYG_ASSERT( (unsigned char*)0 != ep0.common.buffer, "A receive buffer should have been provided" );
+
+ ep0.transmitted += usbs_sa11x0_ep0_empty_fifo(ep0.common.buffer + ep0.transmitted);
+
+ if (ep0.transmitted != ep0.length) {
+ // The host is not allowed to send more data than it
+ // indicated in the original control message, and all
+ // messages until the last one should be full size.
+ CYG_ASSERT( ep0.transmitted < ep0.length, "The host must not send more data than expected");
+ CYG_ASSERT( 0 == (ep0.transmitted % EP0_FIFO_SIZE), "All OUT packets until the last one should be full-size");
+
+ usbs_sa11x0_poke(EP0_CONTROL, EP0_SERVICED_OPR, 0, EP0_OUT_READY);
+ } else {
+ // The whole transfer is now complete. Invoke the
+ // completion function, and based on its return value
+ // either generate a stall or complete the message.
+ usbs_control_return result;
+
+ CYG_ASSERT( (usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn, \
+ "A completion function should be provided for OUT control messages");
+
+ result = (*ep0.common.complete_fn)(&ep0.common, 0);
+ ep0.common.buffer = (unsigned char*) 0;
+ ep0.common.buffer_size = 0;
+ ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
+
+ if (USBS_CONTROL_RETURN_HANDLED == result) {
+ usbs_sa11x0_poke(EP0_CONTROL,
+ EP0_SERVICED_OPR | EP0_DATA_END,
+ EP0_DATA_END,
+ EP0_OUT_READY);
+ } else {
+ usbs_sa11x0_poke(EP0_CONTROL,
+ EP0_SERVICED_OPR | EP0_DATA_END | EP0_FORCE_STALL,
+ EP0_FORCE_STALL,
+ EP0_OUT_READY);
+ }
+ // Also remember to switch back to IDLE state
+ ep0.ep_state = EP0_STATE_IDLE;
+ }
+
+ } else if (0 != (EP0_OUT_READY & hw_state)) {
+
+ int emptied = usbs_sa11x0_ep0_empty_fifo(ep0.common.control_buffer);
+
+ if (8 != emptied) {
+ // This indicates a serious problem somewhere. Respond by
+ // stalling. Hopefully the host will take some action that
+ // sorts out the mess.
+ usbs_sa11x0_poke(EP0_CONTROL,
+ EP0_SERVICED_OPR | EP0_DATA_END | EP0_FORCE_STALL,
+ EP0_FORCE_STALL,
+ EP0_OUT_READY);
+
+ } else {
+ usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
+ usb_devreq* req = (usb_devreq*) ep0.common.control_buffer;
+ int length, direction, protocol, recipient;
+
+ // Now we need to do some decoding of the data. A non-zero
+ // length field indicates that there will be a subsequent
+ // IN or OUT phase. The direction is controlled by the
+ // top bit of the first byte. The protocol is determined
+ // by other bits of the top byte.
+ length = (req->length_hi << 8) | req->length_lo;
+ direction = req->type & USB_DEVREQ_DIRECTION_MASK;
+ protocol = req->type & USB_DEVREQ_TYPE_MASK;
+ recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
+
+#if 0
+ DBG(("ep0, new control request: type %x, code %x\n", req->type, req->request));
+ DBG((" %s, length %d, value hi %x lo %x, index hi %x lo %x\n",
+ (USB_DEVREQ_DIRECTION_OUT == direction) ? "out" : "in",
+ length, req->value_hi, req->value_lo, req->index_hi, req->index_lo));
+#endif
+ if (0 != length){
+ // Clear the fifo straightaway. There is no harm in
+ // doing this here. It may or may not do some good.
+ usbs_sa11x0_poke(EP0_CONTROL, EP0_SERVICED_OPR, 0, EP0_OUT_READY);
+ }
+
+ if (USB_DEVREQ_TYPE_STANDARD == protocol) {
+
+ // First see if the request can be handled entirely in
+ // this module.
+ if (USB_DEVREQ_SET_ADDRESS == req->request) {
+ // The USB device address should be in value_lo.
+ // No more data is expected.
+ int address = req->value_lo;
+ if ((0 != length) || (address > 127)) {
+ result = USBS_CONTROL_RETURN_STALL;
+ } else {
+ // poke_value() cannot be used here because
+ // setting the address does not take effect
+ // until the status phase.
+ *USBS_ADDRESS = address;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+ } else if (USB_DEVREQ_GET_STATUS == req->request) {
+ // GET_STATUS on the device as a whole is used to
+ // check the remote-wakeup and self-powered bits.
+ // GET_STATUS on an endpoint is used to determine
+ // the halted condition.
+ // GET_STATUS on anything else has to be left to
+ // other code.
+ if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {
+ // The host should expect two bytes back.
+ if ((2 == length) && (USB_DEVREQ_DIRECTION_IN == direction)) {
+ ep0.common.control_buffer[0] = 0; // Not self-powered, no remote wakeup
+ ep0.common.control_buffer[1] = 0;
+ ep0.common.buffer = ep0.common.control_buffer;
+ ep0.common.buffer_size = 2;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ } else {
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+
+ } else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {
+ if ((2 == length) && (USB_DEVREQ_DIRECTION_IN == direction)) {
+ int endpoint = req->index_lo;
+ if (0 == endpoint) {
+ // get-status on endpoint 0 is either undefined or always valid.
+ // endpoint 0 is always up.
+ ep0.common.control_buffer[0] = 0;
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP1
+ else if (((USB_DEVREQ_INDEX_DIRECTION_OUT | 1) == endpoint) &&
+ (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
+
+ ep0.common.control_buffer[0] = ep1.common.halted;
+ result = USBS_CONTROL_RETURN_HANDLED;
+
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP2
+ else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 2) == endpoint) &&
+ (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
+
+ ep0.common.control_buffer[0] = ep2.common.halted;
+ result = USBS_CONTROL_RETURN_HANDLED;
+
+ }
+#endif
+ else {
+ // An invalid endpoint has been specified or the
+ // endpoint can only be examined in configured state.
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+ if (USBS_CONTROL_RETURN_HANDLED == result) {
+ ep0.common.control_buffer[1] = 0;
+ ep0.common.buffer = ep0.common.control_buffer;
+ ep0.common.buffer_size = 2;
+ }
+ } else {
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+ } // Endpoint or device get-status
+
+ } else if (USB_DEVREQ_CLEAR_FEATURE == req->request) {
+
+ // CLEAR_FEATURE operates in much the same way as
+ // GET_STATUS
+ if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {
+
+ // No data should be transferred, and only remote-wakeup can be cleared.
+ if ((0 != length) || (USB_DEVREQ_FEATURE_DEVICE_REMOTE_WAKEUP != req->value_lo)) {
+ result = USBS_CONTROL_RETURN_STALL;
+ } else {
+ // Clearing remote-wakeup is a no-op.
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+
+ } else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {
+ // The only feature that can be cleared is endpoint-halt, no data should be transferred.
+ if ((0 != length) || (USB_DEVREQ_FEATURE_ENDPOINT_HALT != req->value_lo)) {
+ result = USBS_CONTROL_RETURN_STALL;
+ } else {
+ int endpoint = req->index_lo;
+ if (0 == endpoint) {
+ // Clearing halt on endpoint 0 is always a no-op since that endpoint cannot be halted
+ }
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP1
+ else if (((USB_DEVREQ_INDEX_DIRECTION_OUT | 1) == endpoint) &&
+ (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
+ ep1_set_halted(&ep1.common, false);
+ result = USBS_CONTROL_RETURN_HANDLED;
+
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP2
+ else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 2) == endpoint) &&
+ (USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
+ ep2_set_halted(&ep2.common, false);
+ result = USBS_CONTROL_RETURN_HANDLED;
+
+ }
+#endif
+ else {
+ // Invalid endpoint or not in configured state.
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+ }
+ } // Endpoing or device clear-feature
+
+ } else if (USB_DEVREQ_SET_FEATURE == req->request) {
+
+ // SET_FEATURE also operates in much the same way as
+ // GET_STATUS
+ if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {
+
+ // The only valid feature that can be set is remote-wakeup,
+ // which is not supported by the hardware.
+ result = USBS_CONTROL_RETURN_STALL;
+
+ } else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {
+
+ // Only the halt condition can be set, and no data should be transferred.
+ // Halting endpoint 0 should probably be disallowed although the
+ // standard does not explicitly say so.
+ if ((0 != length) ||
+ (USB_DEVREQ_FEATURE_ENDPOINT_HALT != req->value_lo) ||
+ (USBS_STATE_CONFIGURED != (ep0.common.state & USBS_STATE_MASK))) {
+
+ result = USBS_CONTROL_RETURN_STALL;
+
+ } else {
+ int endpoint = req->index_lo;
+ if (0) {
+ }
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP1
+ else if ((USB_DEVREQ_INDEX_DIRECTION_OUT | 1) == endpoint) {
+ ep1_set_halted(&ep1.common, true);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP2
+ else if ((USB_DEVREQ_INDEX_DIRECTION_IN | 2) == endpoint) {
+ ep2_set_halted(&ep2.common, true);
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+#endif
+ else {
+ result = USBS_CONTROL_RETURN_STALL;
+ }
+ }
+ } // Endpoint or device set-feature
+ }
+
+ // If the result has not been handled yet, pass it to
+ // the installed callback function (if any).
+ if (USBS_CONTROL_RETURN_UNKNOWN == result) {
+ if ((usbs_control_return (*)(usbs_control_endpoint*, void*))0 != ep0.common.standard_control_fn) {
+ result = (*ep0.common.standard_control_fn)(&ep0.common, ep0.common.standard_control_data);
+ }
+ }
+
+#if 1
+ if ((USBS_CONTROL_RETURN_UNKNOWN == result) &&
+ (USB_DEVREQ_SET_INTERFACE == req->request)) {
+
+ // This code should not be necessary. For
+ // non-trivial applications which involve
+ // alternate interfaces and the like, this request
+ // should be handled by the application itself.
+ // For other applications, the default handler
+ // will ignore this request so we end up falling
+ // through without actually handling the request
+ // and hence returning a stall condition. That
+ // is legitimate behaviour according to the standard.
+ //
+ // However, there are appear to be problems with
+ // the SA1110 USB hardware when it comes to stall
+ // conditions: they appear to affect some
+ // subsequent messages from target to host as
+ // well. Hence rather than returning a stall
+ // condition this code instead generates a dummy
+ // reply, which is also valid according to the
+ // standard. This avoids complications with certain
+ // USB compliance testers.
+ if ((0 != length) ||
+ (0 != req->value_hi) || (0 != req->index_hi) ||
+ (USBS_STATE_CONFIGURED != (ep0.common.state & USBS_STATE_MASK))) {
+
+ result = USBS_CONTROL_RETURN_STALL;
+ } else {
+ int interface_id;
+ int alternate;
+
+ CYG_ASSERT( (1 == ep0.common.enumeration_data->device.number_configurations) && \
+ (1 == ep0.common.enumeration_data->total_number_interfaces), \
+ "Higher level code should have handled this request");
+
+ interface_id = req->index_lo;
+ alternate = req->value_lo;
+ if ((interface_id != ep0.common.enumeration_data->interfaces[0].interface_id) ||
+ (alternate != ep0.common.enumeration_data->interfaces[0].alternate_setting)) {
+
+ result = USBS_CONTROL_RETURN_STALL;
+ } else {
+ result = USBS_CONTROL_RETURN_HANDLED;
+ }
+
+ }
+ }
+#endif
+
+ // If the result has still not been handled, leave it to
+ // the default implementation in the USB slave common package
+ if (USBS_CONTROL_RETURN_UNKNOWN == result) {
+ result = usbs_handle_standard_control(&ep0.common);
+ }
+
+ } else {
+ // The other three types of control message can be
+ // handled by similar code.
+ usbs_control_return (*callback_fn)(usbs_control_endpoint*, void*);
+ void* callback_arg;
+ //DBG(("non-standard control request %x", req->request));
+
+ if (USB_DEVREQ_TYPE_CLASS == protocol) {
+ callback_fn = ep0.common.class_control_fn;
+ callback_arg = ep0.common.class_control_data;
+ } else if (USB_DEVREQ_TYPE_VENDOR == protocol) {
+ callback_fn = ep0.common.vendor_control_fn;
+ callback_arg = ep0.common.vendor_control_data;
+ } else {
+ callback_fn = ep0.common.reserved_control_fn;
+ callback_arg = ep0.common.reserved_control_data;
+ }
+
+ if ((usbs_control_return (*)(usbs_control_endpoint*, void*)) 0 == callback_fn) {
+ result = USBS_CONTROL_RETURN_STALL;
+ } else {
+ result = (*callback_fn)(&ep0.common, callback_arg);
+ }
+ }
+ //DBG(("Control request done, %d\n", result));
+
+ if (USBS_CONTROL_RETURN_HANDLED != result) {
+ // This control request cannot be handled. Generate a stall.
+ usbs_sa11x0_poke(EP0_CONTROL,
+ EP0_FORCE_STALL | EP0_SERVICED_OPR | EP0_DATA_END,
+ EP0_FORCE_STALL,
+ EP0_OUT_READY);
+ } else {
+ // The control request has been handled. Is there any more
+ // data to be transferred?
+ if (0 == length) {
+ usbs_sa11x0_poke(EP0_CONTROL,
+ EP0_SERVICED_OPR | EP0_DATA_END,
+ EP0_DATA_END,
+ EP0_OUT_READY);
+ } else {
+ // The endpoint should now go into IN or OUT mode while the
+ // remaining data is transferred.
+ ep0.transmitted = 0;
+ ep0.length = length;
+ if (USB_DEVREQ_DIRECTION_OUT == direction) {
+ // Wait for the next packet from the host.
+ ep0.ep_state = EP0_STATE_OUT;
+ CYG_ASSERT( (unsigned char*) 0 != ep0.common.buffer, "A receive buffer should have been provided");
+ CYG_ASSERT( (usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn, \
+ "A completion function should be provided for OUT control messages");
+ } else {
+ ep0.ep_state = EP0_STATE_IN;
+ usbs_sa11x0_ep0_fill_fifo();
+ }
+ }
+ } // Control message handled
+ } // Received 8-byte control message
+ } // Idle state, i.e. control message
+} // ep0_dsr
+
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP1
+// ----------------------------------------------------------------------------
+// Endpoint 1 is used for OUT transfers, i.e. receive operations. Only
+// the bulk protocol is supported by the hardware. The semantics allow
+// for two different modes of operation: higher-level code can ask for
+// exactly one or more bulk packets of 64 bytes each, allowing buffer
+// requirements to be determined from a header; alternatively the
+// rx request can just supply a large buffer. Processing the first
+// packet of a larger transfer separately does not introduce any
+// special problems at the protocol level.
+//
+// It is not legal to receive just part of a packet and expect the
+// hardware or the driver to buffer the rest. Not all hardware will
+// be capable of doing this buffering, and there should not be
+// a driver design requirement to provide buffering space.
+//
+//
+// The hardware design for endpoint 1 is flawed in a number of
+// respects. The receive fifo is only 20 bytes, less than the packet
+// size, so it is essential to use DMA (there is a configuration
+// option to allow for communication protocols where packets will
+// never exceed 16 bytes, but that is not the normal case). The DMA
+// engine is triggered by a receive-fifo-service high-water mark
+// bit. DMA transfers operate in bursts of eight bytes. Therefore
+// it would make sense if the high-water mark was set when the
+// receive fifo contained eight bytes or more.
+//
+// Instead the high-water mark is set when the fifo contains twelve
+// bytes or more. Worse, there is no way of measuring how many bytes
+// there are left in the fifo without actually extracting those bytes.
+//
+// For a full-size 64-byte packet, the first 56 bytes will be
+// transferred by DMA and the remainder will remain in the fifo. For a
+// partial packet of between 56 and 63 bytes, the first 56 bytes will
+// be transferred by DMA and the remainder will remain in the fifo. There
+// is no way to distinguish between these scenarios without emptying
+// the fifo.
+//
+// The result is that there is never any point in attempting a DMA
+// transfer of more than 56 bytes, and for every endpoint 1 interrupt
+// it is necessary to read the remainder from the fifo. This adds
+// a lot of software overhead, and it is not clear that DMA is
+// particularly useful. It is still necessary because of the limited
+// fifo size.
+//
+//
+// Because DMA involves the use of physical rather than virtual
+// memory, there are also cache interaction problems. Specifically it
+// would be necessary to invalidate cache lines after a DMA transfer
+// has completed, but that only works sensibly if the buffer is
+// aligned to a cache-line boundary and is a multiple of the
+// cache-line size. Imposing such restrictions on higher-level code
+// is undesirable. Also the DMA engines have an apparently undocumented
+// restriction that the buffer must be eight-byte aligned.
+//
+// To work around all these problems, the receive code works in terms
+// of a small private buffer. After a packet has been received, data
+// will be copied from this private buffer to the destination. Obviously
+// this copy operation is overhead and, because the code is expected
+// to run at DSR level, However the copy operation is limited to at
+// most 64 bytes, which is not good but not disastrous either.
+//
+// For data transfers the entry points are:
+//
+// 1) ep1_start_rx_packet() - prepare to receive another packet from
+// the host.
+// 2) ep1_clear_error() - an error condition has occurred (CRC,
+// bit-stuffing, fifo overrun). It appears that the only way
+// to clear this is to clear the receive-packet-complete bit,
+// which unfortunately allows in another packet from the host
+// before we are ready for it. Doing anything else while
+// the error bit is set does not work, for example it is not
+// possible to empty the fifo by hand.
+// 3) ep1_process_packet() - a whole packet has been received
+// and now needs to be moved into application space.
+//
+// These three routines are called by the start_rx() routine and
+// by the DSR. There are different implementations for DMA and
+// non-DMA.
+//
+// There is another hardware problem: the receive-packet-complete bit
+// comes up with the wrong default value, allowing the host to start
+// transmitting before the target is ready to receive. Unfortunately
+// there is not much that can be done about this: the
+// receive-packet-complete bit cannot be set by software and the OUT
+// max register has a minimum size of eight bytes. Fortunately for
+// many protocols the target-side code has a chance to start a receive
+// before the host is allowed to send, so this problem is mostly
+// ignored for now.
+//
+// Another potential problem arises if the host sends more data than
+// is expected for a given transfer. It would be possible to address
+// this by manipulating the OUT max packet register and getting the
+// hardware to generate protocol violation stalls. This would also
+// eliminate the need to test for buffer overflows. For now it is
+// left to higher-level code to sort it all out.
+
+#ifdef CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL
+
+// DMA needs an area of physical memory. To avoid conflicts with
+// the cached shadow of this memory, this area needs to start at
+// a cache line boundary and there must be padding at the end
+// to the next cache line boundary, thus ensuring that the
+// processor will not accidentally overwrite the physical
+// memory because it is manipulating some other variable.
+//
+// NOTE: at the time of writing the toolchain has a problem with
+// the aligned attribute, so instead the start alignment has
+// to be handled in software.
+
+# define EP1_DMA_MTU 56
+# define EP1_DMA_BUFSIZE ((EP1_DMA_MTU + HAL_DCACHE_LINE_SIZE - 1) - \
+ ((EP1_DMA_MTU + HAL_DCACHE_LINE_SIZE - 1) % HAL_DCACHE_LINE_SIZE))
+# define EP1_DMA_ALLOCSIZE (EP1_DMA_BUFSIZE + HAL_DCACHE_LINE_SIZE - 1)
+
+static unsigned char ep1_dma_data[EP1_DMA_ALLOCSIZE];
+
+// This variable cannot be initialized statically, instead it is
+// set by ep1_init(). It corresponds to the physical address
+// for the buffer.
+static unsigned char* ep1_dma_buf;
+
+static void
+ep1_start_rx_packet(void)
+{
+ int dma_size = EP1_DMA_MTU;
+
+ // This assertion does not always hold: clearing an error condition
+ // involves the packet-complete bit so another message may have
+ // started to arrive.
+ // CYG_ASSERT( 0 == (EP1_FIFO_NOT_EMPTY & *EP1_CONTROL), "The receive fifo should be empty");
+
+ CYG_ASSERT( 0 == ((DMA_CONTROL_RUN | DMA_CONTROL_START_A) & *EP1_DMA_STATUS), "EP1 DMA should be inactive");
+
+#ifdef FAILURES
+ ep1_failure = (ep1_failure + 1) % 32;
+ if (0 == ep1_failure) {
+ dma_size = 8;
+ }
+#endif
+
+ // The full flexibility of the DMA engines is not required here,
+ // specifically the automatic chaining between buffers A and B.
+ // Instead always using buffer A is sufficient. To avoid the
+ // However the hardware still requires the software to alternate
+ // between A and B. To avoid switching between buffers during a
+ // transfer an excessive size field is used, EP1_MTU rather than
+ // EP1_DMA_MTU, and hence the DMA transfer will never complete.
+ //
+ // With some silicon revisions writing to the DMA registers does
+ // not always work either, so a retry is in order. Possibly
+ // some short delays immediately after the clear and before the
+ // set would be sufficient.
+ *EP1_DMA_CONTROL_CLEAR = DMA_CONTROL_CLEAR_ALL;
+ if (0 == (DMA_STATUS_BUFFER_IN_USE & *EP1_DMA_STATUS)) {
+ ep1.using_buf_a = true;
+ usbs_sa11x0_poke_value(EP1_DMA_BUF_A_ADDRESS, (unsigned int) ep1_dma_buf);
+ usbs_sa11x0_poke_value(EP1_DMA_BUF_A_SIZE, dma_size);
+ *EP1_DMA_CONTROL_SET = DMA_CONTROL_RUN | DMA_CONTROL_START_A;
+ } else {
+ ep1.using_buf_a = false;
+ usbs_sa11x0_poke_value(EP1_DMA_BUF_B_ADDRESS, (unsigned int) ep1_dma_buf);
+ usbs_sa11x0_poke_value(EP1_DMA_BUF_B_SIZE, dma_size);
+ *EP1_DMA_CONTROL_SET = DMA_CONTROL_RUN | DMA_CONTROL_START_B;
+ }
+
+ // This should not be necessary, but occasionally the equivalent
+ // operation during ep1_init() fails. Strictly speaking it should
+ // be calling poke_value(), but the added overheads for that are
+ // not worthwhile.
+ *USBS_OUT_SIZE = EP1_MTU - 1;
+
+ // Now allow the host to send the packet.
+ usbs_sa11x0_poke(EP1_CONTROL, EP1_PACKET_COMPLETE | EP1_SENT_STALL, 0,
+ EP1_PACKET_COMPLETE | EP1_SENT_STALL | EP1_FORCE_STALL);
+}
+
+// Clear an error condition following a CRC, bit stuffing or overrun
+// error. The only reliable way to do this is to halt DMA and clear
+// the packet-complete bit. Unfortunately this allows the host to send
+// another packet immediately, before start_rx_packet can be called,
+// introducing another race condition. The hardware does not appear
+// to offer any alternatives.
+static void
+ep1_clear_error(void)
+{
+ *EP1_DMA_CONTROL_CLEAR = DMA_CONTROL_CLEAR_ALL;
+ usbs_sa11x0_poke(EP1_CONTROL, EP1_PACKET_COMPLETE | EP1_SENT_STALL, 0,
+ EP1_PACKET_COMPLETE | EP1_PACKET_ERROR | EP1_SENT_STALL | EP1_FORCE_STALL | EP1_FIFO_NOT_EMPTY);
+
+ // Clearing the packet-complete bit may cause the host to send
+ // another packet, immediately causing another error, so this
+ // assertion does not hold.
+ // CYG_ASSERT( 0 == (*EP1_CONTROL & (EP1_PACKET_ERROR | EP1_FIFO_NOT_EMPTY)), "Receive error should have been cleared");
+}
+
+// A packet has been received. Some of it may still be in the fifo
+// and must be extracted by hand. The data then has to copied to
+// a higher-level buffer.
+static int
+ep1_process_packet(void)
+{
+ int pkt_size;
+
+ // First, work out how much data has been processed by the DMA
+ // engine. This is the amount originally poked into the size
+ // register minus its current value.
+ *EP1_DMA_CONTROL_CLEAR = DMA_CONTROL_CLEAR_ALL;
+ if (ep1.using_buf_a) {
+ pkt_size = EP1_DMA_MTU - *EP1_DMA_BUF_A_SIZE;
+ } else {
+ pkt_size = EP1_DMA_MTU - *EP1_DMA_BUF_B_SIZE;
+ }
+ CYG_ASSERT( 0 == (pkt_size % DMA_BURST_SIZE), "DMA transfers must be in multiples of the burst size");
+
+ // Move these bytes from physical memory to the target buffer.
+ if ((pkt_size > 0) && ((ep1.fetched + pkt_size) < ep1.common.buffer_size)) {
+ memcpy(ep1.common.buffer + ep1.fetched, ep1_dma_buf, pkt_size);
+ }
+
+ // Copy remaining bytes into the target buffer directly.
+ // The DMA buffer could be used instead, moving the memcpy()
+ // down and avoiding the need for a buffer overflow check
+ // inside the loop, but at the cost of accessing physical
+ // memory every time. That cost is too high.
+ while (1) {
+ int status = *EP1_CONTROL;
+ if ((EP1_PACKET_COMPLETE | EP1_PACKET_ERROR) == ((EP1_PACKET_COMPLETE | EP1_PACKET_ERROR) & status)) {
+ break;
+ } else if (0 == (EP1_FIFO_NOT_EMPTY & status)) {
+ break;
+ } else {
+ int datum = *EP1_DATA;
+ if (ep1.fetched < ep1.common.buffer_size) {
+ ep1.common.buffer[ep1.fetched + pkt_size] = datum;
+ }
+ pkt_size++;
+ }
+ }
+ ep1.fetched += pkt_size;
+ return pkt_size;
+}
+
+#else
+
+// Transfers not involving DMA. Obviously these are much simpler
+// but restricted to packets of 16 bytes.
+static void
+ep1_start_rx_packet(void)
+{
+ // Nothing to be done, just let the host send a packet and it will
+ // end up in the fifo.
+ usbs_sa11x0_poke(EP1_CONTROL, EP1_PACKET_COMPLETE | EP1_SENT_STALL, 0,
+ EP1_PACKET_COMPLETE | EP1_SENT_STALL | EP1_FORCE_STALL);
+}
+
+static void
+ep1_clear_error(void)
+{
+ usbs_sa11x0_poke(EP1_CONTROL, EP1_PACKET_COMPLETE | EP1_SENT_STALL, 0,
+ EP1_PACKET_COMPLETE | EP1_SENT_STALL | EP1_FORCE_STALL);
+}
+
+static int
+ep1_process_packet(void)
+{
+ int pkt_size = 0;
+ while (0 != (*EP1_CONTROL & EP1_FIFO_NOT_EMPTY)) {
+ int datum = *EP1_DATA;
+ pkt_size++;
+ if (ep1.fetched < ep1.common.buffer_size) {
+ ep1.common.buffer[ep1.fetched + pkt_size] = datum;
+ }
+ }
+ return pkt_size;
+}
+#endif
+
+// Complete a transfer. This takes care of invoking the completion
+// callback and resetting the buffer.
+static void
+ep1_rx_complete(int result)
+{
+ void (*complete_fn)(void*, int) = ep1.common.complete_fn;
+ void* complete_data = ep1.common.complete_data;
+
+ ep1.common.buffer = (unsigned char*) 0;
+ ep1.common.buffer_size = 0;
+ ep1.common.complete_fn = (void (*)(void*, int)) 0;
+ ep1.common.complete_data = (void*) 0;
+
+ if ((void (*)(void*, int))0 != complete_fn) {
+ (*complete_fn)(complete_data, result);
+ }
+}
+
+// Start a transmission. This functionality is overloaded to cope with
+// waiting for stalls to complete.
+static void
+ep1_start_rx(usbs_rx_endpoint* endpoint)
+{
+ CYG_ASSERT( endpoint == &ep1.common, "USB data transfer involves the wrong endpoint");
+
+ // Is this endpoint currently stalled? If so then a size of 0 can
+ // be used to block until the stall condition is clear, anything
+ // else should result in an immediate callback.
+ if (ep1.common.halted) {
+ if (0 != ep1.common.buffer_size) {
+ ep1_rx_complete(-EAGAIN);
+ }
+ } else if (0 == ep1.common.buffer_size) {
+ // A check to see if the endpoint is halted. It isn't.
+ ep1_rx_complete(0);
+ } else {
+ int status = *EP1_CONTROL;
+
+ CYG_ASSERT((void*) 0 != ep1.common.buffer, "USB receives should not override the interrupt vectors");
+
+ // This indicates the start of a transfer.
+ ep1.fetched = 0;
+
+ // The sent-stall bit may get set by hardware because of
+ // a protocol violation. If so it must be cleared here.
+ if (0 != (status & EP1_SENT_STALL)) {
+ usbs_sa11x0_poke(EP1_CONTROL, EP1_SENT_STALL, 0, EP1_SENT_STALL | EP1_FORCE_STALL);
+ status = *EP1_CONTROL;
+ }
+
+ // The bogus initial value for the receive-packet-complete
+ // bit means that we may start off with an error condition.
+ if ((EP1_PACKET_COMPLETE | EP1_PACKET_ERROR) == (status & (EP1_PACKET_COMPLETE | EP1_PACKET_ERROR))) {
+ ep1_clear_error();
+ ep1_start_rx_packet();
+ } else if (0 != (status & EP1_FIFO_NOT_EMPTY)) {
+ // No error but data in the fifo. This implies a small
+ // initial packet, all held in the fifo.
+#ifdef CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL
+ *EP1_DMA_BUF_A_SIZE = EP1_MTU;
+ ep1.using_buf_a = true;
+#endif
+ (void) ep1_process_packet();
+ ep1_rx_complete(ep1.fetched);
+ } else {
+ // Start a new transfer.
+ ep1_start_rx_packet();
+ }
+ }
+}
+
+static void
+ep1_set_halted(usbs_rx_endpoint* endpoint, cyg_bool new_value)
+{
+ CYG_ASSERT( endpoint == &ep1.common, "USB set-stall operation involves the wrong endpoint");
+
+ if (ep1.common.halted == new_value) {
+ return;
+ }
+ if (new_value) {
+ // The endpoint should be stalled. There is a potential race
+ // condition here with a current transfer. Updating the
+ // stalled flag means that the dsr will do nothing.
+ ep1.common.halted = true;
+ HAL_REORDER_BARRIER();
+
+ // Now perform the actual stall. If we are in the middle of a
+ // transfer then the stall bit may not get set for a while, so
+ // poke() is inappropriate.
+ *EP1_CONTROL = EP1_FORCE_STALL;
+ } else {
+ // The stall condition should be cleared. First take care of
+ // things at the hardware level so that a new transfer is
+ // allowed.
+ usbs_sa11x0_poke(EP1_CONTROL, EP1_SENT_STALL, 0, EP1_SENT_STALL | EP1_FORCE_STALL);
+
+ // Now allow new transfers to begin.
+ ep1.common.halted = false;
+ }
+}
+
+// The DSR is invoked following an interrupt. According to the docs an
+// endpoint 1 interrupt can only happen if the receive-packet-complete
+// bit is set.
+static void
+usbs_sa11x0_ep1_dsr(void)
+{
+ int status = *EP1_CONTROL;
+
+ // This assertion does not always hold. During long runs
+ // spurious interrupts have been observed.
+ // CYG_ASSERT( 0 != (status & EP1_PACKET_COMPLETE), "ep1 dsr should only be invoked when there is data");
+ if (0 == (status & EP1_PACKET_COMPLETE)) {
+ return;
+ }
+
+ if (ep1.common.halted) {
+ // Do nothing. What may have happened is that a transfer
+ // was in progress when the stall bit was set. The
+ // set_halted() call above will have taken care of things.
+ return;
+ }
+
+ // The sent-stall bit should never get set, since we always
+ // accept full-size 64-byte packets. Just in case...
+ if (0 != (status & EP1_SENT_STALL)) {
+ DBG(("ep1_dsr(), sent-stall bit\n"));
+ usbs_sa11x0_poke(EP1_CONTROL, EP1_SENT_STALL, 0, EP1_SENT_STALL | EP1_FORCE_STALL);
+ }
+
+ // Was there a receive error (CRC, bit-stuffing, fifo-overrun?).
+ // Whichever bits of the current packet have been received must be
+ // discarded, and the current packet must be retried.
+ if (0 != (status & EP1_PACKET_ERROR)) {
+ INCR_STAT(ep1_errors);
+ ep1_clear_error();
+ ep1_start_rx_packet();
+ } else {
+ // Another packet has been received. Process it, which may
+ // complete the transfer or it may leave more to be done.
+ //
+ // The hardware starts with the wrong default value for
+ // the receive-packet-complete bit, so a packet may arrive
+ // even though no rx operation has started yet. The
+ // packets must be ignored for now. start_rx_packet()
+ // will detect data in the fifo and do the right thing.
+ int pkt_size;
+
+ if ((unsigned char*)0 != ep1.common.buffer) {
+
+ pkt_size = ep1_process_packet();
+ INCR_STAT(ep1_receives);
+ if (0 != (EP1_PACKET_ERROR & *EP1_CONTROL)) {
+ CYG_ASSERT( 0, "an error has occurred inside ep1_process_packet()\n");
+
+ } else if ((ep1.fetched != ep1.common.buffer_size) && (0 != pkt_size) && (0 == (ep1.fetched % EP1_MTU))) {
+ ep1_start_rx_packet();
+ } else if (ep1.fetched > ep1.common.buffer_size) {
+ // The host has sent too much data.
+ ep1_rx_complete(-EMSGSIZE);
+ } else {
+#if 0
+ int i;
+ diag_printf("------------------------------------------------------\n");
+ diag_printf("rx: buf %x, total size %d\n", ep1.common.buffer, ep1.fetched);
+ for (i = 0; (i < ep1.fetched) && (i < 128); i+= 8) {
+ diag_printf("rx %x %x %x %x %x %x %x %x\n",
+ ep1.common.buffer[i+0], ep1.common.buffer[i+1], ep1.common.buffer[i+2], ep1.common.buffer[i+3],
+ ep1.common.buffer[i+4], ep1.common.buffer[i+5], ep1.common.buffer[i+6], ep1.common.buffer[i+7]);
+ }
+ diag_printf("------------------------------------------------------\n");
+#endif
+ ep1_rx_complete(ep1.fetched);
+ }
+ }
+ }
+}
+
+// Initialization.
+//
+// This may get called during system start-up or following a reset
+// from the host.
+static void
+usbs_sa11x0_ep1_init(void)
+{
+#ifdef CYGNUM_DEVS_USB_SA11X0_EP1_DMA_CHANNEL
+ // What is the physical address that should be used for
+ // transfers?
+ unsigned int phys;
+ HAL_VIRT_TO_PHYS_ADDRESS( ep1_dma_data, phys);
+ phys += (HAL_DCACHE_LINE_SIZE - 1);
+ phys -= (phys % HAL_DCACHE_LINE_SIZE);
+ CYG_ASSERT( 0 == (phys % HAL_DCACHE_LINE_SIZE), "DMA buffer must be aligned to a cache-line boundary");
+ ep1_dma_buf = (unsigned char*)phys;
+
+ // Clear the DMA channel and fix the DMA address register. The
+ // value is determined above.
+ *EP1_DMA_CONTROL_CLEAR = DMA_CONTROL_CLEAR_ALL;
+ *EP1_DMA_ADDRESS = EP1_DMA_ADDRESS_VALUE;
+#endif
+
+ // Always allow the host to send full-size packets. If there is a
+ // protocol problem and the host sends packets that are too large,
+ // it will have to be handled at a level above the device driver.
+ //
+ // With some silicon revisions reading back the register does not
+ // work, so poke_value() is not applicable. This may be an issue
+ // with reset timing.
+ *USBS_OUT_SIZE = EP1_MTU - 1;
+
+ // Endpoints should never be halted during a start-up.
+ ep1.common.halted = false;
+
+ // If there has been a reset and there was a receive in progress,
+ // abort it. This also takes care of sorting out the endpoint
+ // fields ready for the next rx.
+ ep1_rx_complete(-EPIPE);
+}
+
+#endif // CYGPKG_DEVS_USB_SA11X0_EP1
+
+
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP2
+// ----------------------------------------------------------------------------
+// Endpoint 2 is used for IN transfers, i.e. transmitting data to the
+// host. The code is mostly similar to that for endpoint 1, although
+// a little bit simpler (e.g. there is no need to worry about
+// buffer overflow, that is the host's problem).
+//
+// There is a flaw in the hardware design. If the transfer involves an
+// exact multiple of 64 bytes then according to the USB spec there
+// should be a terminating packet of 0 bytes. However the size of the
+// current outgoing packet is determined by the IN_SIZE register and
+// that only allows for packets between 1 and 256 bytes - even though
+// USB bulk transfers can only go up to 64 bytes. This can be worked
+// around at this level by transmitting an extra byte, at the risk of
+// upsetting host-side device drivers. Both higher-level and host-side
+// code need to be aware of this problem.
+//
+// Again there appear to be problems with the DMA engine. This time it
+// appears that the transmit-fifo-service bit does not always work
+// correctly. If you set up a DMA transfer for more than the packet
+// size than once the packet has gone out the fifo-service bit just
+// remains set, the DMA engine continues to fill the fifo, and the
+// data gets lost. Instead DMA can only happen one packet at a time.
+// The same issues regarding cache line alignment etc. arise, so
+// using a small buffer here is convenient.
+//
+// 1) process_packet moves a packet from the main transmit buffer
+// into the dma buffer.
+// 2) start_tx_packet() starts a transfer to the host
+// 3) clear_error() copes with error conditions.
+
+#ifdef CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL
+// See the equivalent EP1 DMA definitions.
+# define EP2_DMA_MTU 64
+# define EP2_DMA_BUFSIZE ((EP2_DMA_MTU + HAL_DCACHE_LINE_SIZE - 1) - \
+ ((EP2_DMA_MTU + HAL_DCACHE_LINE_SIZE - 1) % HAL_DCACHE_LINE_SIZE))
+# define EP2_DMA_ALLOCSIZE (EP2_DMA_BUFSIZE + HAL_DCACHE_LINE_SIZE - 1)
+
+static unsigned char ep2_dma_data[EP2_DMA_ALLOCSIZE];
+static unsigned char* ep2_dma_buf;
+
+static void
+ep2_process_packet(void)
+{
+ ep2.pkt_size = ep2.common.buffer_size - ep2.transmitted;
+ if (ep2.pkt_size > EP2_MTU) {
+ ep2.pkt_size = EP2_MTU;
+ }
+ // Work around the hardware's inability to send a zero-byte packet.
+ if (0 == ep2.pkt_size) {
+ ep2.pkt_size = 1;
+ ep2_dma_buf[0] = 0;
+ } else {
+ memcpy(ep2_dma_buf, ep2.common.buffer + ep2.transmitted, ep2.pkt_size);
+ }
+}
+
+static void
+ep2_tx_packet(void)
+{
+ int dma_size, dma_control_settings;
+
+ // CYG_ASSERT( 0 != (*EP2_CONTROL & EP2_FIFO_SERVICE), "Fifo should be empty");
+
+ // Halt any DMA that may still be going on (there should not
+ // be any). Then work out the desired DMA settings for the
+ // current packet. The DMA engine needs to transfer a multiple
+ // of the burst size. If the packet size is not a multiple of
+ // the burst size, this presents a minor problem. The chances
+ // of an interrupt handler running in time to put the
+ // remaining bytes into the fifo by hand are not good, so
+ // instead more data is DMA'd in then is absolutely necessary
+ // and the surplus bytes will be cleared out during the next
+ // tx_packet.
+ //
+ // A possible optimisation is to detect small packets of
+ // less than the fifo size and byte-stuff those, bypassing
+ // DMA. It is not clear that would give any performance benefits.
+ *EP2_DMA_CONTROL_CLEAR = DMA_CONTROL_CLEAR_ALL;
+
+ dma_size = ep2.pkt_size + DMA_BURST_SIZE - 1;
+ dma_size -= (dma_size % DMA_BURST_SIZE);
+
+ CYG_ASSERT(dma_size > 0, "DMA calculations should result in a transfer of at least 8 bytes");
+
+ // Now clear the fifo, after DMA has stopped.
+ usbs_sa11x0_poke(EP2_CONTROL, EP2_SENT_STALL, 0, EP2_SENT_STALL);
+
+ // Should we be using buf_a or buf_b for this transfer?
+ // Getting this wrong means that the DMA engine just idles.
+ if (0 == (*EP2_DMA_STATUS & DMA_STATUS_BUFFER_IN_USE)) {
+ usbs_sa11x0_poke_value(EP2_DMA_BUF_A_ADDRESS, (int) ep2_dma_buf);
+ usbs_sa11x0_poke_value(EP2_DMA_BUF_A_SIZE, dma_size);
+ dma_control_settings = DMA_CONTROL_RUN | DMA_CONTROL_START_A;
+ } else {
+ usbs_sa11x0_poke_value(EP2_DMA_BUF_B_ADDRESS, (int) ep2_dma_buf);
+ usbs_sa11x0_poke_value(EP2_DMA_BUF_B_SIZE, dma_size);
+ dma_control_settings = DMA_CONTROL_RUN | DMA_CONTROL_START_B;
+ }
+
+ // Poke the tx size register while the fifo is clearing.
+ // This operation must be reliable or the host will get
+ // confused by funny-sized packets.
+ usbs_sa11x0_poke_value(USBS_IN_SIZE, ep2.pkt_size - 1);
+
+ // The USB hardware must be updated before the DMA engine
+ // starts filling the fifo. Otherwise ~48% of outgoing
+ // packets fail with a DMA underrun. When called from
+ // start_tx() there is a race condition: if the host
+ // request comes in before the DMA starts then an
+ // error interrupt will be raised, to be processed by
+ // the DSR, and then the DMA engine gets updated again.
+ // Locking the scheduler eliminates this race.
+ cyg_drv_dsr_lock();
+ usbs_sa11x0_poke(EP2_CONTROL, EP2_PACKET_COMPLETE, 0, EP2_PACKET_COMPLETE | EP2_PACKET_ERROR | EP2_PACKET_UNDERRUN);
+ *EP2_DMA_CONTROL_SET = dma_control_settings;
+ cyg_drv_dsr_unlock();
+
+ // CYG_ASSERT(0 == (*EP2_CONTROL & EP2_FIFO_SERVICE), "DMA engine should have filled up the fifo by now");
+}
+
+// Clearing an error should be a no-op when DMA is involved.
+// In practice clearing the packet-complete bit appears to
+// have some desirable effects, at the risk of the host
+// getting bogus data. This should only happen when there
+// is a real transfer in progress: an error early on is
+// likely because the PACKET_COMPLETE bit has a bogus initial
+// value.
+static void
+ep2_clear_error(void)
+{
+ usbs_sa11x0_poke(EP2_CONTROL, EP2_PACKET_COMPLETE, 0, EP2_PACKET_COMPLETE | EP2_PACKET_ERROR | EP2_PACKET_UNDERRUN);
+}
+
+#else // EP2_DMA
+
+// When not using DMA, process_packet() is responsible for filling the
+// fifo and keeping a shadow copy in a static buffer. clear_error()
+// refills the fifo using the shadow copy. tx_packet() starts the
+// actual transfer.
+static unsigned char ep2_tx_buf[EP2_MTU];
+
+static void
+ep2_process_packet()
+{
+ int i;
+
+ // Clear the fifo, just in case.
+ usbs_sa11x0_poke(EP2_CONTROL, EP2_SENT_STALL, 0, EP2_SENT_STALL);
+
+ ep2.pkt_size = ep2.common.buffer_size - ep2.transmitted;
+ if (ep2.pkt_size > EP2_MTU) {
+ ep2.pkt_size = EP2_MTU;
+ }
+ if (0 == ep2.pkt_size) {
+ ep2.pkt_size = 1;
+ ep2_tx_buf[i] = 0;
+ *EP2_DATA = 0;
+ } else {
+ for (i = 0; i < ep2.pkt_size; i++) {
+ unsigned int datum = ep2.common.buffer[ep2.transmitted + i];
+ ep2_tx_buf[i] = datum;
+ *EP2_DATA = datum;
+ }
+ }
+}
+
+static void
+ep2_tx_packet()
+{
+ usbs_sa11x0_poke_value(USBS_IN_SIZE, ep2.pkt_size - 1);
+ usbs_sa11x0_poke(EP2_CONTROL, EP2_PACKET_COMPLETE, 0, EP2_PACKET_COMPLETE | EP2_PACKET_ERROR | EP2_PACKET_UNDERRUN);
+}
+
+static void
+ep2_clear_error()
+{
+ int i;
+ // Clear the fifo, just in case.
+ usbs_sa11x0_poke(EP2_CONTROL, EP2_SENT_STALL, 0, EP2_SENT_STALL);
+ for (i = 0; i < ep2.pkt_size; i++) {
+ *EP2_DATA = ep2_tx_buf[i];
+ }
+}
+
+#endif // !EP2_DMA
+
+// A utility routine for completing a transfer. This takes care of the
+// callback as well as resetting the buffer.
+static void
+ep2_tx_complete(int result)
+{
+ void (*complete_fn)(void*, int) = ep2.common.complete_fn;
+ void* complete_data = ep2.common.complete_data;
+
+ ep2.common.buffer = (unsigned char*) 0;
+ ep2.common.buffer_size = 0;
+ ep2.common.complete_fn = (void (*)(void*, int)) 0;
+ ep2.common.complete_data = (void*) 0;
+
+ if ((void (*)(void*, int))0 != complete_fn) {
+ (*complete_fn)(complete_data, result);
+ }
+}
+
+
+// The exported interface to start a transmission.
+static void
+ep2_start_tx(usbs_tx_endpoint* endpoint)
+{
+ CYG_ASSERT( endpoint == &ep2.common, "USB data transfer involves the wrong endpoint");
+
+ // Is this endpoint currently stalled? If so then a size of 0 can
+ // be used to block until the stall condition is clear, anything
+ // else should result in an immediate callback.
+ if (ep2.common.halted) {
+ if (0 != ep2.common.buffer_size) {
+ ep2_tx_complete(-EAGAIN);
+ }
+ } else if (0 == ep2.common.buffer_size) {
+ // A check to see if the endpoint is halted. It isn't.
+ ep2_tx_complete(0);
+ } else {
+ // There should not be any errors at the start of a
+ // transmission, but if there is one then there is no safe way
+ // to recover. process_packet() and tx_packet() will hopefully
+ // do the right thing.
+ CYG_ASSERT((void*) 0 != ep2.common.buffer, "Transmitting the interrupt vectors is unlikely to be useful");
+#if 0
+ {
+ int i;
+ diag_printf("----------------------------------------------\n");
+ diag_printf("ep2_start_tx: buf %x, %d bytes\n", ep2.common.buffer, ep2.common.buffer_size);
+ for (i = 0; (i < ep2.common.buffer_size) && (i < 128); i+= 8) {
+ diag_printf("tx: %x %x %x %x %x %x %x %x\n",
+ ep2.common.buffer[i+0], ep2.common.buffer[i+1], ep2.common.buffer[i+2], ep2.common.buffer[i+3],
+ ep2.common.buffer[i+4], ep2.common.buffer[i+5], ep2.common.buffer[i+6], ep2.common.buffer[i+7]);
+ }
+ diag_printf("----------------------------------------------\n");
+ }
+#endif
+
+ // Prepare the first packet for transmission, then send it.
+ ep2.transmitted = 0;
+ ep2_process_packet();
+ ep2_tx_packet();
+ }
+}
+
+static void
+ep2_set_halted(usbs_tx_endpoint* endpoint, cyg_bool new_value)
+{
+ CYG_ASSERT(endpoint == &ep2.common, "USB set-stall operation involves the wrong endpoint");
+
+ if (ep2.common.halted == new_value) {
+ return;
+ }
+ if (new_value) {
+ // The endpoint should be stalled. There is a potential race
+ // condition here with the current transfer and DSR invocation.
+ // Updating the stalled flag means that the DSR will do nothing.
+ ep2.common.halted = true;
+ HAL_REORDER_BARRIER();
+
+ // Now perform the actual stall. This may be delayed by the hardware
+ // so poke() cannot be used.
+ *EP2_CONTROL = EP2_FORCE_STALL;
+
+ // If in the middle of a transfer then that cannot be aborted,
+ // the DMA engines etc. would get very confused.
+ } else {
+ // Take care of the hardware so that a new transfer is allowed.
+ usbs_sa11x0_poke(EP2_CONTROL, EP2_SENT_STALL, 0, EP2_SENT_STALL | EP2_FORCE_STALL);
+ ep2.common.halted = false;
+ }
+}
+
+// The dsr will be invoked when the transmit-packet-complete bit is
+// set. Typically this happens when a packet has been completed
+// (surprise surprise) but it can also happen for error conditions.
+static void
+usbs_sa11x0_ep2_dsr(void)
+{
+ int status = *EP2_CONTROL;
+ // This assertion does not always hold - spurious interrupts have
+ // been observed if you run for a few hours.
+ // CYG_ASSERT( 0 != (status & EP2_PACKET_COMPLETE), "ep2 dsr should only be invoked when the packet-complete bit is set");
+
+ if (0 == (status & EP2_PACKET_COMPLETE)) {
+ // Spurious interrupt, do nothing.
+ } else if (ep2.common.halted) {
+ // There is a possible race condition between a packet
+ // completing and the stalled condition being set.
+ // set_halted() above does everything that is needed.
+ } else if (0 == ep2.pkt_size) {
+ // This can happen because of the initial value for the
+ // packet-complete bit, allowing the host to retrieve data
+ // before the target is ready. The correct action is to do
+ // nothing.
+ } else if (0 != (status & (EP2_PACKET_ERROR | EP2_PACKET_UNDERRUN))) {
+ // A transmit error occurred, the details are not important.
+ INCR_STAT(ep2_errors);
+ ep2_clear_error();
+ ep2_tx_packet();
+ } else {
+ // Another packet has gone out.
+ INCR_STAT(ep2_transmits);
+ ep2.transmitted += ep2.pkt_size;
+ if ((ep2.transmitted < ep2.common.buffer_size) ||
+ ((ep2.transmitted == ep2.common.buffer_size) && (0 == (ep2.common.buffer_size % EP2_MTU)))) {
+ ep2_process_packet();
+ ep2_tx_packet();
+ } else {
+ ep2_tx_complete(ep2.transmitted);
+ }
+ }
+}
+
+// Endpoint 2 initialization.
+//
+// This may be called during system start-up or following a reset
+// from the host.
+static void
+usbs_sa11x0_ep2_init(void)
+{
+#ifdef CYGNUM_DEVS_USB_SA11X0_EP2_DMA_CHANNEL
+ // What is the physical address that should be used for
+ // transfers?
+ unsigned int phys;
+ HAL_VIRT_TO_PHYS_ADDRESS(ep2_dma_data, phys);
+ phys += (HAL_DCACHE_LINE_SIZE - 1);
+ phys -= (phys % HAL_DCACHE_LINE_SIZE);
+ CYG_ASSERT(0 == (phys % HAL_DCACHE_LINE_SIZE), "DMA buffer must be aligned to a cache-line boundary");
+ ep2_dma_buf = (unsigned char*) phys;
+
+ // Clear the DMA channel completely, otherwise it may not be
+ // possible to write the ADDRESS register. Then set the DMA
+ // address register. The value is determined above.
+ *EP2_DMA_CONTROL_CLEAR = DMA_CONTROL_CLEAR_ALL;
+ *EP2_DMA_ADDRESS = EP2_DMA_ADDRESS_VALUE;
+#endif
+
+ // Endpoints should never be halted after a reset
+ ep2.common.halted = false;
+
+ // If there has been a reset and there was a receive in progress,
+ // abort it. This also takes care of clearing the endpoint
+ // structure fields.
+ ep2_tx_complete(-EPIPE);
+}
+
+#endif // CYGPKG_DEVS_USB_SA11X0_EP2
+
+// ----------------------------------------------------------------------------
+// Interrupt handling
+//
+// As much work as possible is deferred to the DSR (or to the debug
+// thread). Interrupts for the endpoints are never a problem: the
+// variuos packet-complete etc. bits ensure that the endpoints
+// remain quiescent until the relevant interrupt has been serviced.
+// Suspend and resume are more complicated. A suspend means that
+// there has been no activity for 3ms, which should be enough
+// time for the whole thing to be handled. A resume means that there
+// has been bus activity after a suspend, and again it is infrequent.
+//
+// Reset appears to be much more complicated. A reset means that the
+// host is holding the USB lines to a specific state for 10ms. This is
+// detected by the hardware, causing the USB controller to be reset
+// (i.e. any pending transfers are discarded, etc.). The reset bit in
+// the status register will be set, and an interrupt will be raised.
+// Now, in theory the correct thing to do is to process this
+// interrupt, block reset interrupts for the duration of these 10ms,
+// and wait for further activity such as the control message to set
+// the address.
+//
+// In practice this does not seem to work. Possibly the USB controller
+// gets reset continuously while the external reset signal is applied,
+// but I have not been able to confirm this. Messing about with the
+// reset interrupt control bit causes the system to go off into
+// never-never land. 10ms is too short a time to allow for manual
+// debugging of what happens. So for now the interrupt source is
+// blocked at the interrupt mask level and the dsr will do the
+// right thing. This causes a significant number of spurious interrupts
+// for the duration of the reset signal and not a lot else can happen.
+
+
+// Perform reset operations on all endpoints that have been
+// configured in. It is convenient to keep this in a separate
+// routine to allow for polling, where manipulating the
+// interrupt controller mask is a bad idea.
+static void
+usbs_sa11x0_handle_reset(void)
+{
+ int old_state = ep0.common.state;
+
+ // Any state change must be reported to higher-level code
+ ep0.common.state = USBS_STATE_DEFAULT;
+ if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ USBS_STATE_CHANGE_RESET, old_state);
+ }
+
+ // Reinitialize all the endpoints that have been configured in.
+ usbs_sa11x0_ep0_init();
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP1
+ usbs_sa11x0_ep1_init();
+#endif
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP2
+ usbs_sa11x0_ep2_init();
+#endif
+
+ // After a reset we need to handle endpoint interrupts, reset
+ // interrupts, and suspend interrupts. There should not be a
+ // resume since we have not suspended, but leaving resume
+ // interrupts enabled appears to be desirable with some hardware.
+ //
+ // With some silicon revisions it appears that a longer delay
+ // is needed after reset, so this poke() may not work.
+ if (!usbs_sa11x0_poke(USBS_CONTROL,
+ CONTROL_INTR_ENABLE(CONTROL_EP_INTR_BITS|CONTROL_RESET_INTR|CONTROL_SUSPEND_INTR|CONTROL_RESUME_INTR),
+ 0,
+ CONTROL_INTR_CLEAR(CONTROL_EP_INTR_BITS|CONTROL_RESET_INTR|CONTROL_SUSPEND_INTR|CONTROL_RESUME_INTR))) {
+ // DBG(("usbs_sa11x0_handle_reset(), update of control register failed, status %x\n", *USBS_STATUS));
+ }
+}
+
+// The DSR. This can be invoked directly by poll(), or via the usual
+// interrupt subsystem. It acts as per the current value of
+// isr_status_bits. If another interrupt goes off while this
+// DSR is running, there will be another invocation of the DSR and
+// the status bits will be updated.
+static void
+usbs_sa11x0_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ int status = 0;
+
+ CYG_ASSERT(SA11X0_IRQ_USB_SERVICE_REQUEST == vector, "USB DSR should only be invoked for USB interrupts" );
+ CYG_ASSERT(0 == data, "The SA11X0 USB DSR needs no global data pointer");
+
+ // There is no atomic swap support, so interrupts have to be
+ // blocked. It might be possible to do this via the USBS_CONTROL
+ // register, but at the risk of messing up the status register
+ // if another interrupt comes in. Blocking interrupts at the
+ // processor level is less intrusive on the USB code.
+
+ cyg_drv_isr_lock();
+ status = isr_status_bits;
+ isr_status_bits = 0;
+ cyg_drv_isr_unlock();
+
+ // Reset is special, since it invalidates everything else.
+ // If the reset is still ongoing then do not attempt any
+ // further processing, there will just be another interrupt.
+ // Otherwise handle_reset() does the hard work. Unmasking
+ // the interrupt means that another interrupt will occur
+ // immediately if reset is still asserted, i.e. no threads
+ // will run, but there is no easy way of triggering action
+ // at the end of reset.
+ if (0 != (status & STATUS_RESET_INTR)) {
+
+ int new_status = *USBS_STATUS;
+ if (0 == (new_status & STATUS_RESET_INTR)) {
+ usbs_sa11x0_handle_reset();
+ }
+ // This unmask is likely to cause another interrupt immediately
+ cyg_drv_interrupt_unmask(SA11X0_IRQ_USB_SERVICE_REQUEST);
+
+ } else {
+ // Process resume first. Ignore any resumes when we are not
+ // actually suspended yet, this happens mainly during system
+ // startup. If there has been a state change to suspended
+ // then we need a matching state change to resumed.
+ if (0 != (status & STATUS_RESUME_INTR)) {
+ int old_state = ep0.common.state;
+ if (0 != (old_state & USBS_STATE_SUSPENDED)) {
+ ep0.common.state &= ~USBS_STATE_SUSPENDED;
+ if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ USBS_STATE_CHANGE_RESUMED, old_state);
+ }
+ // After a resume, all interrupts should be enabled.
+ // In theory there is no need to worry about further
+ // resume interrupts, but strange hardware behaviour
+ // has been observed if resume interrupts are left
+ // disabled.
+ usbs_sa11x0_poke(USBS_CONTROL,
+ CONTROL_INTR_ENABLE(CONTROL_EP_INTR_BITS|CONTROL_RESET_INTR|CONTROL_SUSPEND_INTR|CONTROL_RESUME_INTR),
+ 0,
+ CONTROL_INTR_CLEAR(CONTROL_EP_INTR_BITS|CONTROL_RESET_INTR|CONTROL_SUSPEND_INTR|CONTROL_RESUME_INTR));
+ }
+ }
+
+ // Now process endpoint interrupts. Control operations on
+ // endpoint 0 may have side effects on the other endpoints
+ // so it is better to leave them until last.
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP1
+ if (0 != (status & STATUS_EP1_INTR)) {
+ usbs_sa11x0_ep1_dsr();
+ }
+#endif
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP2
+ if (0 != (status & STATUS_EP2_INTR)) {
+ usbs_sa11x0_ep2_dsr();
+ }
+#endif
+ if (0 != (status & STATUS_EP0_INTR)) {
+ usbs_sa11x0_ep0_dsr();
+ }
+
+ // Process suspend last, but only if there has not also been
+ // a resume. A suspend immediately followed by a resume should
+ // be ignored. A resume immediately followed by a suspend
+ // would be unfortunate, but suspend means that there has been
+ // at least 3ms of inactivity so the DSR latency would have
+ // to be pretty bad.
+ //
+ // Total robustness is possible but requires more work in the ISR.
+ if ((0 != (status & STATUS_SUSPEND_INTR)) && (0 == (status & STATUS_RESUME_INTR))) {
+ int old_state = ep0.common.state;
+ ep0.common.state |= USBS_STATE_SUSPENDED;
+ if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
+ (*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
+ USBS_STATE_CHANGE_SUSPENDED, old_state);
+ }
+ // We are no longer interested in further suspend interrupts,
+ // which could happen every 3 ms, but resume has become
+ // very interesting.
+ usbs_sa11x0_poke(USBS_CONTROL,
+ CONTROL_INTR_ENABLE(CONTROL_EP_INTR_BITS | CONTROL_RESET_INTR | CONTROL_RESUME_INTR),
+ 0,
+ CONTROL_INTR_CLEAR(CONTROL_EP_INTR_BITS | CONTROL_RESET_INTR | CONTROL_RESUME_INTR));
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Optionally the USB code can do most of its processing in a thread
+// rather than in a DSR.
+#ifdef CYGPKG_DEVS_USB_SA11X0_THREAD
+static unsigned char usbs_sa11x0_thread_stack[CYGNUM_DEVS_USB_SA11X0_THREAD_STACK_SIZE];
+static cyg_thread usbs_sa11x0_thread;
+static cyg_handle_t usbs_sa11x0_thread_handle;
+static cyg_sem_t usbs_sa11x0_sem;
+
+
+static void
+usbs_sa11x0_thread_fn(cyg_addrword_t param)
+{
+ for (;;) {
+ cyg_semaphore_wait(&usbs_sa11x0_sem);
+ usbs_sa11x0_dsr(SA11X0_IRQ_USB_SERVICE_REQUEST, 0, 0);
+ }
+ CYG_UNUSED_PARAM(cyg_addrword_t, param);
+}
+
+static void
+usbs_sa11x0_thread_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+ CYG_ASSERT( 0 != isr_status_bits, "DSR's should only be scheduled when there is work to do");
+ cyg_semaphore_post(&usbs_sa11x0_sem);
+
+ CYG_UNUSED_PARAM(cyg_vector_t, vector);
+ CYG_UNUSED_PARAM(cyg_ucount32, count);
+ CYG_UNUSED_PARAM(cyg_addrword_t, data);
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+// The interrupt handler. This does as little as possible.
+static cyg_uint32
+usbs_sa11x0_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ int old_status_bits = isr_status_bits;
+ int status_bits;
+
+ CYG_ASSERT(SA11X0_IRQ_USB_SERVICE_REQUEST == vector, "USB ISR should only be invoked for USB interrupts" );
+ CYG_ASSERT(0 == data, "The SA11X0 USB ISR needs no global data pointer" );
+
+ // Read the current status. Reset is special, it means that the
+ // whole chip has been reset apart from the one bit in the status
+ // register. Nothing should be done about this until the DSR sets
+ // the endpoints back to a consistent state and re-enables
+ // interrupts in the control register.
+ status_bits = *USBS_STATUS;
+
+ if (0 != (status_bits & STATUS_RESET_INTR)) {
+ isr_status_bits = STATUS_RESET_INTR;
+ *USBS_STATUS = status_bits;
+ cyg_drv_interrupt_mask(SA11X0_IRQ_USB_SERVICE_REQUEST);
+ } else {
+ *USBS_STATUS = status_bits;
+ isr_status_bits |= status_bits;
+ }
+
+ // Now keep the rest of the system happy.
+ cyg_drv_interrupt_acknowledge(vector);
+ return (old_status_bits != isr_status_bits) ? CYG_ISR_CALL_DSR : CYG_ISR_HANDLED;
+}
+
+// ----------------------------------------------------------------------------
+// Polling support. This acts mostly like the interrupt handler: it
+// sets the isr status bits and causes the dsr to run. Reset has to be
+// handled specially: polling does nothing as long as reset is asserted.
+
+static void
+usbs_sa11x0_poll(usbs_control_endpoint* endpoint)
+{
+ CYG_ASSERT( endpoint == &ep0.common, "USB poll involves the wrong endpoint");
+
+ if (0 != (isr_status_bits & STATUS_RESET_INTR)) {
+ // Reset was detected the last time poll() was invoked. If
+ // reset is still active, do nothing. Once the reset has
+ // completed things can continue.
+ if (0 == (STATUS_RESET_INTR & *USBS_STATUS)) {
+ isr_status_bits = 0;
+ usbs_sa11x0_handle_reset();
+ }
+ } else {
+ isr_status_bits = *USBS_STATUS;
+ if (0 != (STATUS_RESET_INTR & isr_status_bits)) {
+ // Reset has just been asserted. Do nothing, just continue
+ // polling for the duration of the reset signal.
+ } else if (0 != isr_status_bits) {
+ usbs_sa11x0_dsr(SA11X0_IRQ_USB_SERVICE_REQUEST, 0, (cyg_addrword_t) 0);
+ }
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// Initialization.
+
+void
+usbs_sa11x0_init(void)
+{
+ // Start by disabling/resetting the hardware. This is easy.
+ *USBS_CONTROL = CONTROL_DISABLE;
+ *USBS_CONTROL = CONTROL_DISABLE;
+ *USBS_CONTROL = CONTROL_DISABLE;
+
+ // The USB bus is now tristated, preventing any communications.
+ // This is a good thing, the situation should change only when
+ // higher-level code has provided the enumeration data and done an
+ // explicit start.
+ usbs_sa11x0_ep0_init();
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP1
+ usbs_sa11x0_ep1_init();
+#endif
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP2
+ usbs_sa11x0_ep2_init();
+#endif
+
+ // If processing is supposed to happen in a thread rather
+ // than in DSR, initialize the threads.
+#ifdef CYGPKG_DEVS_USB_SA11X0_THREAD
+ cyg_semaphore_init(&usbs_sa11x0_sem, 0);
+ cyg_thread_create(CYGNUM_DEVS_USB_SA11X0_THREAD_PRIORITY,
+ &usbs_sa11x0_thread_fn,
+ 0,
+ "SA11X0 USB support",
+ usbs_sa11x0_thread_stack,
+ CYGNUM_DEVS_USB_SA11X0_THREAD_STACK_SIZE,
+ &usbs_sa11x0_thread_handle,
+ &usbs_sa11x0_thread
+ );
+ cyg_thread_resume(usbs_sa11x0_thread_handle);
+#endif
+
+ // It is also possible and desirable to install the interrupt
+ // handler here, even though there will be no interrupts for a
+ // while yet.
+ cyg_drv_interrupt_create(SA11X0_IRQ_USB_SERVICE_REQUEST,
+ 99, // priority
+ 0, // data
+ &usbs_sa11x0_isr,
+#ifdef CYGPKG_DEVS_USB_SA11X0_THREAD
+ &usbs_sa11x0_thread_dsr,
+#else
+ &usbs_sa11x0_dsr,
+#endif
+ &usbs_sa11x0_intr_handle,
+ &usbs_sa11x0_intr_data);
+ cyg_drv_interrupt_attach(usbs_sa11x0_intr_handle);
+ cyg_drv_interrupt_unmask(SA11X0_IRQ_USB_SERVICE_REQUEST);
+}
+
+// ----------------------------------------------------------------------------
+// Testing support.
+usbs_testing_endpoint usbs_testing_endpoints[] = {
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL,
+ endpoint_number : 0,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &ep0.common,
+#ifdef CYGVAR_DEVS_USB_SA11X0_EP0_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME "0c",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1, // zero-byte control transfers are meaningless
+ max_size : 0x0FFFF, // limit imposed by protocol
+ max_in_padding : 0,
+ alignment : 0
+ },
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP1
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 1,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
+ endpoint : (void*) &ep1.common,
+#ifdef CYGVAR_DEVS_USB_SA11X0_EP1_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME "1r",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1,
+ max_size : -1, // No hardware or driver limitation
+ max_in_padding : 0,
+ alignment : 0
+ },
+#endif
+#ifdef CYGPKG_DEVS_USB_SA11X0_EP2
+ {
+ endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
+ endpoint_number : 2,
+ endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
+ endpoint : (void*) &ep2.common,
+#ifdef CYGVAR_DEVS_USB_SA11X0_EP2_DEVTAB_ENTRY
+ devtab_entry : CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME "2w",
+#else
+ devtab_entry : (const char*) 0,
+#endif
+ min_size : 1,
+ max_size : -1, // No hardware or driver limitation
+ max_in_padding : 1, // hardware limitation
+ alignment : 0
+ },
+#endif
+ USBS_TESTING_ENDPOINTS_TERMINATOR
+};
diff --git a/ecos/packages/devs/usb/sa11x0/current/src/usbs_sa11x0_data.cxx b/ecos/packages/devs/usb/sa11x0/current/src/usbs_sa11x0_data.cxx
new file mode 100644
index 0000000..0ce3f3b
--- /dev/null
+++ b/ecos/packages/devs/usb/sa11x0/current/src/usbs_sa11x0_data.cxx
@@ -0,0 +1,173 @@
+//==========================================================================
+//
+// usbs_sa11x0.c
+//
+// Static data for the SA11x0 USB device driver
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors: bartv
+// Date: 2000-10-04
+//
+// This file contains various objects that should go into extras.o
+// rather than libtarget.a, e.g. devtab entries that would normally
+// be eliminated by the selective linking.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/io/devtab.h>
+#include <cyg/io/usb/usbs_sa11x0.h>
+#include <pkgconf/devs_usb_sa11x0.h>
+
+// ----------------------------------------------------------------------------
+// Initialization. The goal here is to call usbs_sa11x0_init()
+// early on during system startup, to take care of things like
+// registering interrupt handlers etc. which are best done
+// during system init.
+//
+// If the endpoint 0 devtab entry is available then its init()
+// function can be used to take care of this. However the devtab
+// entries are optional so an alternative mechanism must be
+// provided. Unfortunately although it is possible to give
+// a C function the constructor attribute, it cannot be given
+// an initpri attribute. Instead it is necessary to define a
+// dummy C++ class.
+
+extern "C" void usbs_sa11x0_init(void);
+
+#ifndef CYGVAR_DEVS_USB_SA11X0_EP0_DEVTAB_ENTRY
+class usbs_sa11x0_initialization {
+ public:
+ usbs_sa11x0_initialization() {
+ usbs_sa11x0_init();
+ }
+};
+
+static usbs_sa11x0_initialization usbs_sa11x0_init_object CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);
+#endif
+
+// ----------------------------------------------------------------------------
+// The devtab entries. Each of these is optional, many applications
+// will want to use the lower-level API rather than go via
+// open/read/write/ioctl.
+
+#ifdef CYGVAR_DEVS_USB_SA11X0_EP0_DEVTAB_ENTRY
+
+// For endpoint 0 the only legal operations are get_config() and
+// set_config(), and these are provided by the common package.
+
+static bool
+usbs_sa11x0_devtab_ep0_init(struct cyg_devtab_entry* tab)
+{
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+ usbs_sa11x0_init();
+ return true;
+}
+
+static CHAR_DEVIO_TABLE(usbs_sa11x0_ep0_devtab_functions,
+ &cyg_devio_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static CHAR_DEVTAB_ENTRY(usbs_sa11x0_ep0_devtab_entry,
+ CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME "0c",
+ 0,
+ &usbs_sa11x0_ep0_devtab_functions,
+ &usbs_sa11x0_devtab_ep0_init,
+ 0,
+ (void*) &usbs_sa11x0_ep0);
+#endif
+
+// ----------------------------------------------------------------------------
+// Common routines for ep1 and ep2.
+#if defined(CYGVAR_DEVS_USB_SA11X0_EP1_DEVTAB_ENTRY) || defined(CYGVAR_DEVS_USB_SA11X0_EP2_DEVTAB_ENTRY)
+static bool
+usbs_sa11x0_devtab_dummy_init(struct cyg_devtab_entry* tab)
+{
+ CYG_UNUSED_PARAM(struct cyg_devtab_entry*, tab);
+ return true;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// ep1 devtab entry. This can only be used for host->slave, so only the
+// cread() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_SA11X0_EP1_DEVTAB_ENTRY
+
+static CHAR_DEVIO_TABLE(usbs_sa11x0_ep1_devtab_functions,
+ &cyg_devio_cwrite,
+ &usbs_devtab_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static CHAR_DEVTAB_ENTRY(usbs_sa11x0_ep1_devtab_entry,
+ CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME "1r",
+ 0,
+ &usbs_sa11x0_ep1_devtab_functions,
+ &usbs_sa11x0_devtab_dummy_init,
+ 0,
+ (void*) &usbs_sa11x0_ep1);
+#endif
+
+// ----------------------------------------------------------------------------
+// ep2 devtab entry. This can only be used for slave->host, so only
+// the cwrite() function makes sense.
+
+#ifdef CYGVAR_DEVS_USB_SA11X0_EP2_DEVTAB_ENTRY
+
+static CHAR_DEVIO_TABLE(usbs_sa11x0_ep2_devtab_functions,
+ &usbs_devtab_cwrite,
+ &cyg_devio_cread,
+ &cyg_devio_select,
+ &usbs_devtab_get_config,
+ &usbs_devtab_set_config);
+
+static DEVTAB_ENTRY(usbs_sa11x0_ep2_devtab_entry,
+ CYGDAT_DEVS_USB_SA11X0_DEVTAB_BASENAME "2w",
+ 0,
+ &usbs_sa11x0_ep2_devtab_functions,
+ &usbs_sa11x0_devtab_dummy_init,
+ 0,
+ (void*) &usbs_sa11x0_ep2);
+
+#endif
+
diff --git a/ecos/packages/devs/wallclock/arm/aim711/current/ChangeLog b/ecos/packages/devs/wallclock/arm/aim711/current/ChangeLog
new file mode 100755
index 0000000..693af73
--- /dev/null
+++ b/ecos/packages/devs/wallclock/arm/aim711/current/ChangeLog
@@ -0,0 +1,29 @@
+2004-04-27 Roland Caßebohm <roland.cassebohm@cisionsystems.de>
+
+ * include/devs_wallclock_arm_aim711.inl:
+ * cdl/aim711_wallclock_drivers.cdl: New package - RTC support for
+ the ARM Industrial Module AIM 711.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+
+
diff --git a/ecos/packages/devs/wallclock/arm/aim711/current/cdl/aim711_wallclock_drivers.cdl b/ecos/packages/devs/wallclock/arm/aim711/current/cdl/aim711_wallclock_drivers.cdl
new file mode 100755
index 0000000..33388a6
--- /dev/null
+++ b/ecos/packages/devs/wallclock/arm/aim711/current/cdl/aim711_wallclock_drivers.cdl
@@ -0,0 +1,68 @@
+# ====================================================================
+#
+# aim711_wallclock_drivers.cdl
+#
+# Wallclock drivers - support for DS1339 RTC on the
+# ARM Industrial Module AIM 711
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): rcassebohm
+# Contributors: rcassebohm
+# Date: 2003-10-05
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_ARM_AIM711 {
+ display "ARM Industrial Module AIM 711 RTC Driver"
+ description "RTC driver for the ARM Industrial Module AIM 711."
+
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_HAL_ARM_AIM711
+ requires CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1307
+
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "/***** AIM 711 RTC driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_WALLCLOCK_DALLAS_1307_INL <cyg/io/devs_wallclock_arm_aim711.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_WALLCLOCK_ARM_AIM711_CFG <pkgconf/devices_wallclock_arm_aim711.h>"
+ puts $::cdl_system_header "/***** AIM 711 RTC driver proc output end *****/"
+ }
+}
diff --git a/ecos/packages/devs/wallclock/arm/aim711/current/include/devs_wallclock_arm_aim711.inl b/ecos/packages/devs/wallclock/arm/aim711/current/include/devs_wallclock_arm_aim711.inl
new file mode 100755
index 0000000..bf60d6b
--- /dev/null
+++ b/ecos/packages/devs/wallclock/arm/aim711/current/include/devs_wallclock_arm_aim711.inl
@@ -0,0 +1,105 @@
+//==========================================================================
+//
+// devs/wallclock/arm/aim711/include/devs_wallclock_arm_aim711.inl
+//
+// ARM Industrial Module AIM 711 RTC IO definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): rcassebohm
+// Contributors:rcassebohm
+// Date: 2003-10-05
+// Purpose: AIM 711 RTC definitions for using DS1339
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/hal/hal_io.h>
+#include <string.h>
+
+#include CYGDAT_DEVS_WALLCLOCK_ARM_AIM711_CFG
+
+static __inline__ void
+DS_GET(cyg_uint8 *regs)
+{
+ hal_ks32c_i2c_msg_t msgs[2];
+ int status;
+ cyg_uint8 offset = 0x00;
+
+ // write message to set the address
+ msgs[0].devaddr = AIM711_RTC_ADDR | KS32C_I2C_WR;
+ msgs[0].pbuf = &offset;
+ msgs[0].bufsize = sizeof(offset);
+
+ // read message
+ msgs[1].devaddr = AIM711_RTC_ADDR | KS32C_I2C_RD;
+ msgs[1].pbuf = regs;
+ msgs[1].bufsize = DS_REGS_SIZE;
+
+ // transfer the messages
+ status = hal_ks32c_i2c_transfer(2, msgs);
+
+ if (status < 0)
+ diag_printf("%s - Can't read RTC\n", __FUNCTION__);
+
+ return;
+}
+
+static __inline__ void
+DS_PUT(cyg_uint8 *regs)
+{
+ hal_ks32c_i2c_msg_t msg;
+ int status;
+ cyg_uint8 offset = 0x00;
+ cyg_uint8 buffer[1 + DS_REGS_SIZE];
+
+ buffer[0]=offset;
+ memcpy(&buffer[1], regs, DS_REGS_SIZE);
+
+ // write message
+ msg.devaddr = AIM711_RTC_ADDR | KS32C_I2C_WR;
+ msg.pbuf = buffer;
+ msg.bufsize = sizeof(buffer);
+
+ // transfer the messages
+ status = hal_ks32c_i2c_transfer(1, &msg);
+
+ if (status < 0)
+ diag_printf("%s - Can't write RTC\n", __FUNCTION__);
+
+ return;
+}
+
+// EOF devs_wallclock_arm_aim711.inl
diff --git a/ecos/packages/devs/wallclock/arm/lpc2xxx/current/ChangeLog b/ecos/packages/devs/wallclock/arm/lpc2xxx/current/ChangeLog
new file mode 100644
index 0000000..1f85431
--- /dev/null
+++ b/ecos/packages/devs/wallclock/arm/lpc2xxx/current/ChangeLog
@@ -0,0 +1,41 @@
+2011-01-15 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/lpc2xxx_wallclock.cdl:
+ * src/lpc2xxx_wallclock.cxx: Added support for LPC17XX CPUs.
+
+2008-11-01 Uwe Kindler <uwe_kindler@web.de>
+
+ * cdl/lpc2xxx_wallclock.cdl: Moved CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT
+ and CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREFRAC to lpc2xxx_wallclock.cxx
+ * src/lpc2xxx_wallclock.cxx: Some small changes to support LPC24xx
+ devices
+
+2007-07-12 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+
+ * lpc2xxx: driver for on-chip RTC unit
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
+
diff --git a/ecos/packages/devs/wallclock/arm/lpc2xxx/current/cdl/lpc2xxx_wallclock.cdl b/ecos/packages/devs/wallclock/arm/lpc2xxx/current/cdl/lpc2xxx_wallclock.cdl
new file mode 100644
index 0000000..4c1f332
--- /dev/null
+++ b/ecos/packages/devs/wallclock/arm/lpc2xxx/current/cdl/lpc2xxx_wallclock.cdl
@@ -0,0 +1,72 @@
+# ====================================================================
+#
+# lpc2xxx_wallclock.cdl
+#
+# eCos configuration data for LPC2xxx, LPC17xx internal RTC
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors: jskov, ilijak
+# Date: 2007-06-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_ARM_LPC2XXX {
+ display "Real-time clock"
+ description "RTC driver for the LPC2XXX, LPC17XX CPUs"
+
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ active_if { CYGPKG_HAL_ARM_LPC2XXX || CYGPKG_HAL_ARM_LPC24XX ||
+ CYGPKG_HAL_CORTEXM_LPC17XX }
+
+ requires { CYGHWR_HAL_ARM_LPC2XXX_IDLE_PWRSAVE == 0 }
+ compile lpc2xxx_wallclock.cxx
+
+ implements CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WALLCLOCK_HARDWARE
+ implements CYGINT_WALLCLOCK_SET_GET_MODE_SUPPORTED
+
+ cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+ parent CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+ display "Hardware wallclock"
+ default_value 1
+ implements CYGINT_WALLCLOCK_IMPLEMENTATIONS
+ }
+}
diff --git a/ecos/packages/devs/wallclock/arm/lpc2xxx/current/src/lpc2xxx_wallclock.cxx b/ecos/packages/devs/wallclock/arm/lpc2xxx/current/src/lpc2xxx_wallclock.cxx
new file mode 100644
index 0000000..8676593
--- /dev/null
+++ b/ecos/packages/devs/wallclock/arm/lpc2xxx/current/src/lpc2xxx_wallclock.cxx
@@ -0,0 +1,194 @@
+//==========================================================================
+//
+// lpc2xxx_wallclock.cxx
+//
+// Wallclock implementation for LPC2xxx and LPC17xx CPUs
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors: Uwe Kindler <uwe_kindler@web.de, ilijak
+// Date: 2007-06-19
+// Purpose: Wallclock driver for LPC2xxx and LPC17xx CPUs
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/wallclock.h>
+#include <pkgconf/devices_wallclock_arm_lpc2xxx.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/io/wallclock.hxx>
+#include <cyg/io/wallclock/wallclock.inl>
+
+//
+// The LPC2xxx variant HAL provides the CPU clock and the peripheral divider
+// VPBDIV. The LPC24xx variant HAL provides the RTC clock directly be means
+// of CYGNUM_HAL_ARM_LPC24XX_RTC_CLK.
+//
+#ifdef CYGNUM_HAL_ARM_LPC2XXX_VPBDIV
+#define LPC2XXX_RTC_CLK (CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / \
+ CYGNUM_HAL_ARM_LPC2XXX_VPBDIV)
+#endif // CYGNUM_HAL_ARM_LPC2XXX_VPBDIV
+
+#ifdef CYGNUM_HAL_ARM_LPC24XX_RTC_CLK
+#define LPC2XXX_RTC_CLK (CYGNUM_HAL_ARM_LPC24XX_RTC_CLK)
+#endif // CYGNUM_HAL_ARM_LPC2XXX_VPBDIV
+
+
+#define CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT \
+ ((LPC2XXX_RTC_CLK / 32768) - 1)
+
+#define CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREFRAC \
+ (LPC2XXX_RTC_CLK - \
+ ((CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT + 1) * 32768))
+
+
+
+/*
+ * I don't like to write LOTS OF CAPITALIZED TEXT.
+ * This code is intended for LPC2xxx processors _only_, so there is nothing
+ * wrong with accessing this device directly without using the HAL macros.
+ */
+
+struct time {
+ volatile cyg_uint32 sec;
+ volatile cyg_uint32 min;
+ volatile cyg_uint32 hour;
+ volatile cyg_uint32 dom;
+ volatile cyg_uint32 dow;
+ volatile cyg_uint32 doy;
+ volatile cyg_uint32 month;
+ volatile cyg_uint32 year;
+};
+
+struct rtcdev {
+ volatile cyg_uint32 ilr;
+ volatile cyg_uint32 ctc;
+ volatile cyg_uint32 ccr;
+ volatile cyg_uint32 ciir;
+ volatile cyg_uint32 amr;
+ volatile cyg_uint32 ctime[3];
+ struct time time;
+ cyg_uint32 dummy[8];
+ struct time alarm;
+#ifndef CYGHWR_HAL_LPC_RTC_32768HZ
+ volatile cyg_uint32 preint;
+ volatile cyg_uint32 prefrac;
+#endif
+};
+
+static struct rtcdev * const rtc =
+ (struct rtcdev *) CYGARC_HAL_LPC2XXX_REG_RTC_BASE;
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+ /* halt clock, disable interrupts, disable alarm */
+ rtc->ccr = 0x2;
+ rtc->ciir = 0x0;
+ rtc->amr = 0xf;
+
+ // initialize prescaler - if the RTC id driven by an external 32.768 crystal
+ // clock then initializing the prescaler is not required but writing the
+ // registers here should not cause any trouble
+#ifndef CYGHWR_HAL_LPC_RTC_32768HZ
+ rtc->preint = CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT;
+ rtc->prefrac = CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREFRAC;
+#endif
+
+#ifndef CYGSEM_WALLCLOCK_SET_GET_MODE
+ /* reset time to the Unix Epoch */
+ rtc->time.year = 1970;
+ rtc->time.month = 1;
+ rtc->time.dom = 1;
+ rtc->time.doy = 1;
+ rtc->time.dow = 4;
+ rtc->time.hour = 0;
+ rtc->time.min = 0;
+ rtc->time.sec = 0;
+#endif
+
+ /* reset alarm */
+ rtc->alarm.year = rtc->alarm.month = rtc->alarm.dom = rtc->alarm.doy =
+ rtc->alarm.dow = rtc->alarm.hour = rtc->alarm.min =
+ rtc->alarm.sec = 0;
+
+ /* start clock */
+ rtc->ccr = 0x1;
+}
+
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+ return _simple_mktime(rtc->time.year,
+ rtc->time.month,
+ rtc->time.dom,
+ rtc->time.hour,
+ rtc->time.min,
+ rtc->time.sec);
+}
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+void
+Cyg_WallClock::set_hw_seconds(cyg_uint32 secs)
+{
+ cyg_uint32 year, month, dom, hour, min, sec;
+
+ /* halt clock, reset counter */
+ rtc->ccr = 0x2;
+
+ /* set time */
+ _simple_mkdate(secs, &year, &month, &dom, &hour, &min, &sec);
+ rtc->time.year = year;
+ rtc->time.month = month;
+ rtc->time.dom = dom;
+ rtc->time.hour = hour;
+ rtc->time.min = min;
+ rtc->time.sec = sec;
+
+ /* restart clock */
+ rtc->ccr = 0x1;
+}
+#endif // CYGSEM_WALLCLOCK_SET_GET_MODE
+
+//==========================================================================
+// EOF lpc2xxx_wallclock.cxx
diff --git a/ecos/packages/devs/wallclock/cortexm/stm32/current/ChangeLog b/ecos/packages/devs/wallclock/cortexm/stm32/current/ChangeLog
new file mode 100644
index 0000000..d35f186
--- /dev/null
+++ b/ecos/packages/devs/wallclock/cortexm/stm32/current/ChangeLog
@@ -0,0 +1,50 @@
+2012-01-19 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/wallclock_stm32.cdl: Ensure this driver is only active for F1
+ parts.
+
+2009-06-29 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/stm32_wallclock.cxx (Cyg_WallClock::init_hw_seconds): Add
+ enables for clocks of devices used by this device.
+
+2008-11-12 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/stm32_wallclock.cxx: Using new CYGHWR_HAL_STM32_BD_PROTECT
+ macro.
+
+2008-11-05 Simon Kallweit <simon.kalweit@intefo.ch>
+
+ * cdl/wallclock_stm32.cdl:
+ * src/stm32_wallclock.cxx:
+ Adapted to ecoscentric cortexm port.
+
+2008-10-27 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * cdl/stm32_wallclock.cdl:
+ * src/stm32_wallclock.cxx:
+ Driver for on-chip RTC unit.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/wallclock/cortexm/stm32/current/cdl/wallclock_stm32.cdl b/ecos/packages/devs/wallclock/cortexm/stm32/current/cdl/wallclock_stm32.cdl
new file mode 100644
index 0000000..be0803f
--- /dev/null
+++ b/ecos/packages/devs/wallclock/cortexm/stm32/current/cdl/wallclock_stm32.cdl
@@ -0,0 +1,81 @@
+# ====================================================================
+#
+# wallclock_stm32.cdl
+#
+# Hardware support for STM32 on-chip RTC.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2008 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Simon Kallweit
+# Contributors:
+# Date: 2008-10-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_WALLCLOCK_STM32 {
+ display "STM32 RTC wallclock support"
+ description "
+ Wallclock support for on-chip RTC on STM32 devices."
+
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_HAL_CORTEXM_STM32
+ active_if { CYGHWR_HAL_CORTEXM_STM32_FAMILY == "F1" }
+
+ compile stm32_wallclock.cxx
+
+ implements CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WALLCLOCK_HARDWARE
+ implements CYGINT_WALLCLOCK_SET_GET_MODE_SUPPORTED
+
+ cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+ parent CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+ display "Hardware wallclock"
+ default_value 1
+ implements CYGINT_WALLCLOCK_IMPLEMENTATIONS
+ }
+
+ cdl_option CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE {
+ display "RTC clock source"
+ flavor data
+ default_value { "LSE" }
+ legal_values { "LSE" "LSI" "HSE_128" }
+ }
+}
+
+# End of wallclock_stm32.cdl
diff --git a/ecos/packages/devs/wallclock/cortexm/stm32/current/src/stm32_wallclock.cxx b/ecos/packages/devs/wallclock/cortexm/stm32/current/src/stm32_wallclock.cxx
new file mode 100644
index 0000000..0484e3e
--- /dev/null
+++ b/ecos/packages/devs/wallclock/cortexm/stm32/current/src/stm32_wallclock.cxx
@@ -0,0 +1,250 @@
+//==========================================================================
+//
+// stm32_wallclock.cxx
+//
+// Wallclock implementation for STM32
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Simon Kallweit
+// Contributors:
+// Date: 2008-10-27
+// Purpose: Wallclock driver for STM32
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_cortexm.h>
+#include <pkgconf/hal_cortexm_stm32.h>
+#include <pkgconf/wallclock.h>
+#include <pkgconf/devs_wallclock_stm32.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/io/wallclock.hxx>
+
+//==========================================================================
+// Clock Initialization values
+
+#if defined(CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE_LSE)
+# define CYGHWR_DEVS_WALLCLOCK_STM32_RTCSEL CYGHWR_HAL_STM32_RCC_BDCR_RTCSEL_LSE
+# define CYGHWR_DEVS_WALLCLOCK_STM32_CLOCK 32768
+#elif defined(CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE_LSI)
+# define CYGHWR_DEVS_WALLCLOCK_STM32_RTCSEL CYGHWR_HAL_STM32_RCC_BDCR_RTCSEL_LSI
+# define CYGHWR_DEVS_WALLCLOCK_STM32_CLOCK 40000
+#elif defined(CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE_HSE_128)
+# define CYGHWR_DEVS_WALLCLOCK_STM32_RTCSEL CYGHWR_HAL_STM32_RCC_BDCR_RTCSEL_HSE
+# define CYGHWR_DEVS_WALLCLOCK_STM32_CLOCK (CYGARC_HAL_CORTEXM_STM32_INPUT_CLOCK / 128)
+#endif
+
+// Wait for registers to be synchronized
+static void
+wait_sync(void)
+{
+ CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+ cyg_uint16 crl;
+
+ do
+ {
+ HAL_READ_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CRL, crl );
+ } while ( !(crl & CYGHWR_HAL_STM32_RTC_CRL_RSF) );
+}
+
+// Wait for last write operation to finish
+static void
+wait_rtoff(void)
+{
+ CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+ cyg_uint16 crl;
+
+ do
+ {
+ HAL_READ_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CRL, crl );
+ } while ( !(crl & CYGHWR_HAL_STM32_RTC_CRL_RTOFF) );
+}
+
+// Enter/leave configuration mode
+static void
+config_mode(int val)
+{
+ CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+ cyg_uint16 crl;
+
+ if (val)
+ wait_rtoff();
+
+ HAL_READ_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CRL, crl );
+ if (val)
+ crl |= CYGHWR_HAL_STM32_RTC_CRL_CNF;
+ else
+ crl &= ~CYGHWR_HAL_STM32_RTC_CRL_CNF;
+ HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CRL, crl );
+
+ if (!val)
+ wait_rtoff();
+}
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+ CYG_ADDRESS rcc = CYGHWR_HAL_STM32_RCC;
+ CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+ cyg_uint32 bdcr, csr;
+ cyg_uint32 prescaler = CYGHWR_DEVS_WALLCLOCK_STM32_CLOCK - 1;
+
+ // Enable backup domain and power control
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( CYGHWR_HAL_STM32_CLOCK_BKP );
+ CYGHWR_HAL_STM32_CLOCK_ENABLE( CYGHWR_HAL_STM32_CLOCK_PWR );
+
+ // Reset the backup domain if clock source does not match as
+ // RTCSEL can only be written to backup domain once
+ HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_BDCR, bdcr );
+ if ((bdcr & CYGHWR_HAL_STM32_RCC_BDCR_RTCSEL_XXX) !=
+ CYGHWR_DEVS_WALLCLOCK_STM32_RTCSEL)
+ {
+ // Reset backup domain
+ CYGHWR_HAL_STM32_BD_RESET();
+ }
+
+ // Disable backup domain protection
+ CYGHWR_HAL_STM32_BD_PROTECT(0);
+
+#if defined(CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE_LSI)
+ // Start up LSI clock
+ HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CSR, csr );
+ csr |= CYGHWR_HAL_STM32_RCC_CSR_LSION;
+ HAL_WRITE_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CSR, csr );
+
+ // Wait for LSI clock to startup
+ do
+ {
+ HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CSR, csr );
+ } while( !(csr & CYGHWR_HAL_STM32_RCC_CSR_LSIRDY) );
+#endif
+
+#if defined(CYGHWR_DEVS_WALLCLOCK_STM32_RTC_SOURCE_LSE)
+ // Start up LSE clock
+ HAL_WRITE_UINT32( rcc+CYGHWR_HAL_STM32_RCC_BDCR, CYGHWR_HAL_STM32_RCC_BDCR_LSEON );
+
+ // Wait for LSE clock to startup
+ do
+ {
+ HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_BDCR, bdcr );
+ } while( !(bdcr & CYGHWR_HAL_STM32_RCC_BDCR_LSERDY) );
+#endif
+
+ // Enable RTC
+ HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_BDCR, bdcr );
+ bdcr |= CYGHWR_DEVS_WALLCLOCK_STM32_RTCSEL;
+ bdcr |= CYGHWR_HAL_STM32_RCC_BDCR_RTCEN;
+ HAL_WRITE_UINT32( rcc+CYGHWR_HAL_STM32_RCC_BDCR, bdcr );
+
+ // Synchronize registers
+ wait_sync();
+
+ // Enter configuration mode
+ config_mode(1);
+
+ // Disable all interrupts
+ HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CRH, 0 );
+
+ // Set prescaler load value
+ HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_PRLL, prescaler & 0xffff);
+ HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_PRLH, prescaler >> 16);
+
+ // Reset alarm value
+ HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_ALRL, 0 );
+ HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_ALRH, 0 );
+
+#ifndef CYGSEM_WALLCLOCK_SET_GET_MODE
+ // Reset counter value
+ HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTL, 0 );
+ HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTH, 0 );
+#endif
+
+ // Leave configuration mode
+ config_mode(0);
+
+ // Restore backup domain protection
+ CYGHWR_HAL_STM32_BD_PROTECT(1);
+}
+
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+ CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+ cyg_uint16 cnt;
+ cyg_uint32 secs;
+
+ // Synchronize registers
+ wait_sync();
+
+ // Read counter value
+ HAL_READ_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTL, cnt );
+ secs = cnt;
+ HAL_READ_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTH, cnt );
+ secs |= (cnt << 16);
+
+ return secs;
+}
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+void
+Cyg_WallClock::set_hw_seconds(cyg_uint32 secs)
+{
+ CYG_ADDRESS rtc = CYGHWR_HAL_STM32_RTC;
+
+ // Disable backup domain protection
+ CYGHWR_HAL_STM32_BD_PROTECT(0);
+
+ // Enter configuration mode
+ config_mode(1);
+
+ // Set counter value
+ HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTL, secs & 0xffff );
+ HAL_WRITE_UINT16( rtc+CYGHWR_HAL_STM32_RTC_CNTH, secs >> 16 );
+
+ // Leave configuration mode
+ config_mode(0);
+
+ // Restore backup domain protection
+ CYGHWR_HAL_STM32_BD_PROTECT(1);
+}
+#endif
diff --git a/ecos/packages/devs/wallclock/dallas/ds12887/current/ChangeLog b/ecos/packages/devs/wallclock/dallas/ds12887/current/ChangeLog
new file mode 100644
index 0000000..cfa995b
--- /dev/null
+++ b/ecos/packages/devs/wallclock/dallas/ds12887/current/ChangeLog
@@ -0,0 +1,41 @@
+2006-11-23 David Fernandez <dfernandez@cct.co.uk>
+
+ * src/ds17887.cxx (defines): Added check for some defines being done
+ in INL file.
+
+2001-07-27 Jesper Skov <jskov@redhat.com>
+
+ * src/ds12887.cxx (init_ds_hwclock): Use BCD mode since Century is
+ NA in binary mode. Force sane settings in registers if they are
+ undefined.
+
+2001-07-06 Jesper Skov <jskov@redhat.com>
+
+ * src/ds12887.cxx (get_ds_hwclock): Instead of locking while
+ reading (which prevents updates if polled), disable interrupts.
+
+ * New package, based on 1742 driver.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+
+
diff --git a/ecos/packages/devs/wallclock/dallas/ds12887/current/cdl/wallclock_ds12887.cdl b/ecos/packages/devs/wallclock/dallas/ds12887/current/cdl/wallclock_ds12887.cdl
new file mode 100644
index 0000000..1e6e315
--- /dev/null
+++ b/ecos/packages/devs/wallclock/dallas/ds12887/current/cdl/wallclock_ds12887.cdl
@@ -0,0 +1,104 @@
+# ====================================================================
+#
+# wallclock_ds12887.cdl
+#
+# eCos configuration data for Dallas 12887
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS12887 {
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ display "Wallclock device driver for Dallas 12887"
+ description "
+ This package provides a file with init, get and set functions
+ for the Dallas 12887 clock part."
+
+ compile ds12887.cxx
+
+ implements CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WALLCLOCK_HARDWARE
+ implements CYGINT_WALLCLOCK_SET_GET_MODE_SUPPORTED
+
+ cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+ parent CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+ display "Hardware wallclock"
+ default_value 1
+ implements CYGINT_WALLCLOCK_IMPLEMENTATIONS
+ }
+
+
+ cdl_component CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS12887_OPTIONS {
+ display "DS12887 wallclock build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS12887_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS12887_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/wallclock/dallas/ds12887/current/src/ds12887.cxx b/ecos/packages/devs/wallclock/dallas/ds12887/current/src/ds12887.cxx
new file mode 100644
index 0000000..2313031
--- /dev/null
+++ b/ecos/packages/devs/wallclock/dallas/ds12887/current/src/ds12887.cxx
@@ -0,0 +1,300 @@
+//==========================================================================
+//
+// devs/wallclock/ds12887.inl
+//
+// Wallclock implementation for Dallas 12887
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-07-06
+// Purpose: Wallclock driver for Dallas 12887
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/wallclock.h> // Wallclock device config
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_intr.h> // interrupt enable/disable
+#include <cyg/infra/cyg_type.h> // Common type definitions and support
+
+#include <cyg/io/wallclock.hxx> // The WallClock API
+#include <cyg/io/wallclock/wallclock.inl> // Helpers
+
+#include <cyg/infra/diag.h>
+
+#define nDEBUG
+
+// Platform details
+#include CYGDAT_DEVS_WALLCLOCK_DALLAS_12887_INL
+
+#ifndef DS_READ_UINT8
+# define DS_READ_UINT8(x,y) HAL_READ_UINT8(x,y)
+# define DS_WRITE_UINT8(x,y) HAL_WRITE_UINT8(x,y)
+#endif
+
+#if !defined(DS_READ) && !defined(DS_WRITE) // Allow for INL to define this
+#ifdef DS_LINEAR
+# ifndef DS_STEP
+# define DS_STEP 0
+# endif
+# ifndef DS_BASE
+# error "Need to know base of DS12887 part"
+# endif
+#define DS_READ( offset, data) \
+ DS_READ_UINT8( DS_BASE + ((offset) << DS_STEP), (data))
+#define DS_WRITE(offset, data) \
+ DS_WRITE_UINT8(DS_BASE + ((offset) << DS_STEP), (data))
+#else // !DS_LINEAR
+# if !defined(DS_ADDR) || !defined(DS_DATA)
+# error "Need to know addr/data locations of DS12887 part"
+# endif
+# define DS_READ(offset, data) \
+ CYG_MACRO_START \
+ DS_WRITE_UINT8(DS_ADDR, (offset)); \
+ DS_READ_UINT8(DS_DATA, (data)); \
+ CYG_MACRO_END
+# define DS_WRITE(offset, data) \
+ CYG_MACRO_START \
+ DS_WRITE_UINT8(DS_ADDR, (offset)); \
+ DS_WRITE_UINT8(DS_DATA, (data)); \
+ CYG_MACRO_END
+#endif
+#endif // ! DS_READ && ! DS_WRITE
+
+// Registers
+#define DS_SECONDS 0x00
+#define DS_SECONDS_ALARM 0x01
+#define DS_MINUTES 0x02
+#define DS_MINUTES_ALARM 0x03
+#define DS_HOURS 0x04
+#define DS_HOURS_ALARM 0x05
+#define DS_DOW 0x06
+#define DS_DOM 0x07
+#define DS_MONTH 0x08
+#define DS_YEAR 0x09
+#define DS_CENTURY 0x32
+
+#define DS_REG_A 0x0a
+#define DS_REG_B 0x0b
+#define DS_REG_C 0x0c
+#define DS_REG_D 0x0d
+
+// Control bits
+#define DS_REG_A_UIP 0x80
+#define DS_REG_A_ENABLE 0x20
+
+#define DS_REG_B_SET 0x80
+#define DS_REG_B_DM 0x04
+#define DS_REG_B_24H 0x02
+
+
+//----------------------------------------------------------------------------
+// Accessor functions
+static inline void
+init_ds_hwclock(void)
+{
+ cyg_uint8 _regb, _tmp;
+
+ // Set 24H mode
+ DS_WRITE(DS_REG_B, DS_REG_B_24H);
+ // Enable clock
+ DS_WRITE(DS_REG_A, DS_REG_A_ENABLE);
+
+ // Verify that there are reasonable default settings - otherwise
+ // set them.
+
+ // Stop counting
+ DS_READ(DS_REG_B, _regb);
+ _regb |= DS_REG_B_SET;
+ DS_WRITE(DS_REG_B, _regb);
+
+ DS_READ(DS_CENTURY, _tmp);
+ if (0xff == _tmp)
+ DS_WRITE(DS_CENTURY, TO_BCD(20));
+
+ DS_READ(DS_MONTH, _tmp);
+ if (0x00 == _tmp)
+ DS_WRITE(DS_MONTH, TO_BCD(1));
+
+ DS_READ(DS_DOM, _tmp);
+ if (0x00 == _tmp)
+ DS_WRITE(DS_DOM, TO_BCD(1));
+
+ DS_READ(DS_DOM, _tmp);
+ if (0x00 == _tmp)
+ DS_WRITE(DS_DOM, TO_BCD(1));
+
+ // Restart counting
+ _regb &= ~DS_REG_B_SET;
+ DS_WRITE(DS_REG_B, _regb);
+}
+
+
+static inline void
+set_ds_hwclock(cyg_uint32 year, cyg_uint32 month, cyg_uint32 mday,
+ cyg_uint32 hour, cyg_uint32 minute, cyg_uint32 second)
+{
+ cyg_uint8 _regb;
+ // Stop counting
+ DS_READ(DS_REG_B, _regb);
+ _regb |= DS_REG_B_SET;
+ DS_WRITE(DS_REG_B, _regb);
+
+ DS_WRITE(DS_CENTURY, TO_BCD((cyg_uint8)(year / 100)));
+ DS_WRITE(DS_YEAR, TO_BCD((cyg_uint8)(year % 100)));
+ DS_WRITE(DS_MONTH, TO_BCD((cyg_uint8)month));
+ DS_WRITE(DS_DOM, TO_BCD((cyg_uint8)mday));
+ DS_WRITE(DS_HOURS, TO_BCD((cyg_uint8)hour));
+ DS_WRITE(DS_MINUTES, TO_BCD((cyg_uint8)minute));
+ DS_WRITE(DS_SECONDS, TO_BCD((cyg_uint8)second));
+
+ // Restart counting
+ _regb &= ~DS_REG_B_SET;
+ DS_WRITE(DS_REG_B, _regb);
+
+#ifdef DEBUG
+ // This will cause the test to eventually fail due to these printouts
+ // causing timer interrupts to be lost...
+ diag_printf("Set -------------\n");
+ diag_printf("year %02d\n", year);
+ diag_printf("month %02d\n", month);
+ diag_printf("mday %02d\n", mday);
+ diag_printf("hour %02d\n", hour);
+ diag_printf("minute %02d\n", minute);
+ diag_printf("second %02d\n", second);
+#endif
+}
+
+static inline void
+get_ds_hwclock(cyg_uint32* year, cyg_uint32* month, cyg_uint32* mday,
+ cyg_uint32* hour, cyg_uint32* minute, cyg_uint32* second)
+{
+ cyg_uint8 _reg, _t1, _t2;
+ cyg_uint32 _old;
+
+ // Wait for update flag clears
+ do {
+ DS_READ(DS_REG_A, _reg);
+ } while (_reg & DS_REG_A_UIP);
+
+ // Disable interrupts while reading to ensure it doesn't take more
+ // than 244us.
+ HAL_DISABLE_INTERRUPTS(_old);
+
+ DS_READ(DS_CENTURY, _t1);
+ DS_READ(DS_YEAR, _t2);
+ *year = (cyg_uint32)TO_DEC(_t1)*100 + (cyg_uint32)TO_DEC(_t2);
+
+ DS_READ(DS_MONTH, _t1);
+ *month = (cyg_uint32)TO_DEC(_t1);
+
+ DS_READ(DS_DOM, _t1);
+ *mday = (cyg_uint32)TO_DEC(_t1);
+
+ DS_READ(DS_HOURS, _t1);
+ *hour = (cyg_uint32)TO_DEC(_t1);
+
+ DS_READ(DS_MINUTES, _t1);
+ *minute = (cyg_uint32)TO_DEC(_t1);
+
+ DS_READ(DS_SECONDS, _t1);
+ *second = (cyg_uint32)TO_DEC(_t1);
+
+ // Reenable interrupts
+ HAL_RESTORE_INTERRUPTS(_old);
+
+#ifdef DEBUG
+ // This will cause the test to eventually fail due to these printouts
+ // causing timer interrupts to be lost...
+ diag_printf("year %02d\n", *year);
+ diag_printf("month %02d\n", *month);
+ diag_printf("mday %02d\n", *mday);
+ diag_printf("hour %02d\n", *hour);
+ diag_printf("minute %02d\n", *minute);
+ diag_printf("second %02d\n", *second);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Functions required for the hardware-driver API.
+
+// Returns the number of seconds elapsed since 1970-01-01 00:00:00.
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+ cyg_uint32 year, month, mday, hour, minute, second;
+
+ get_ds_hwclock(&year, &month, &mday, &hour, &minute, &second);
+
+ cyg_uint32 now = _simple_mktime(year, month, mday, hour, minute, second);
+ return now;
+}
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+
+// Sets the clock. Argument is seconds elapsed since 1970-01-01 00:00:00.
+void
+Cyg_WallClock::set_hw_seconds( cyg_uint32 secs )
+{
+ cyg_uint32 year, month, mday, hour, minute, second;
+
+ _simple_mkdate(secs, &year, &month, &mday, &hour, &minute, &second);
+
+ set_ds_hwclock(year, month, mday, hour, minute, second);
+}
+
+#endif
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+ init_ds_hwclock();
+#else
+ // This is our base: 1970-01-01 00:00:00
+ // Set the HW clock - if for nothing else, just to be sure it's in a
+ // legal range. Any arbitrary base could be used.
+ // After this the hardware clock is only read.
+ set_ds_hwclock(1970,1,1,0,0,0);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// End of devs/wallclock/ds12887.inl
diff --git a/ecos/packages/devs/wallclock/dallas/ds1307/current/ChangeLog b/ecos/packages/devs/wallclock/dallas/ds1307/current/ChangeLog
new file mode 100644
index 0000000..c570068
--- /dev/null
+++ b/ecos/packages/devs/wallclock/dallas/ds1307/current/ChangeLog
@@ -0,0 +1,40 @@
+2008-12-30 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/wallclock_ds1307.cdl: Reference per-package documentation.
+
+2004-10-09 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/ds1307.sgml: add package documentation
+
+ * src/ds1307.cxx, cdl/wallclock_ds1307.cdl: use the generic I2C
+ API rather than ad-hoc macros, if supported.
+
+2003-09-19 Gary Thomas <gary@mlbassoc.com>
+
+ * src/ds1307.cxx:
+ * cdl/wallclock_ds1307.cdl: New package - support for DS1307 device,
+ based on DS12887 package. Note: this is a two-wire device (I2C).
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+
+
diff --git a/ecos/packages/devs/wallclock/dallas/ds1307/current/cdl/wallclock_ds1307.cdl b/ecos/packages/devs/wallclock/dallas/ds1307/current/cdl/wallclock_ds1307.cdl
new file mode 100644
index 0000000..a7c8520
--- /dev/null
+++ b/ecos/packages/devs/wallclock/dallas/ds1307/current/cdl/wallclock_ds1307.cdl
@@ -0,0 +1,113 @@
+# ====================================================================
+#
+# wallclock_ds1307.cdl
+#
+# eCos configuration data for Dallas 1307
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1307 {
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ display "Wallclock device driver for Dallas 1307"
+ description "
+ This package provides a file with init, get and set functions
+ for the Dallas 1307 clock part."
+ doc ref/devs-wallclock-dallas-ds1307-part.html
+
+ compile ds1307.cxx
+
+ implements CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WALLCLOCK_HARDWARE
+ implements CYGINT_WALLCLOCK_SET_GET_MODE_SUPPORTED
+
+ cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+ parent CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+ display "Hardware wallclock"
+ default_value 1
+ implements CYGINT_WALLCLOCK_IMPLEMENTATIONS
+ }
+
+ cdl_interface CYGINT_DEVICES_WALLCLOCK_DALLAS_DS1307_I2C {
+ display "Access DS1307 device via the I2C API"
+ flavor bool
+ description "
+ This interface will be implemented if the platform supports
+ the standard I2C API and the platform HAL exports an I2C
+ device cyg_i2c_wallclock_ds1307."
+ }
+
+ cdl_component CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1307_OPTIONS {
+ display "DS1307 wallclock build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1307_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1307_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/wallclock/dallas/ds1307/current/doc/ds1307.sgml b/ecos/packages/devs/wallclock/dallas/ds1307/current/doc/ds1307.sgml
new file mode 100644
index 0000000..9529a8e
--- /dev/null
+++ b/ecos/packages/devs/wallclock/dallas/ds1307/current/doc/ds1307.sgml
@@ -0,0 +1,124 @@
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- ds1307.sgml -->
+<!-- -->
+<!-- Documentation for the ds1307 wallclock driver -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2004/10/09 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-wallclock-dallas-ds1307-part"><title>Dallas DS1307 Wallclock Device Driver</title>
+
+<refentry id="devs-wallclock-dallas-ds1307">
+ <refmeta>
+ <refentrytitle>Dallas DS1307 Wallclock Device Driver</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname><varname>CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1307</varname></refname>
+ <refpurpose>eCos Support for the Dallas DS1307 Serial Real-Time Clock</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="devs-wallclock-dallas-ds1307-description"><title>Description</title>
+ <para>
+This package
+<varname>CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1307</varname> provides a
+device driver for the wallclock device in the Dallas DS1307 Serial
+Real-Time Clock chips. This combines a real-time clock and 56 bytes of
+battery-backed RAM in a single package. The driver can also be used
+with any other chips that provide the same interface to the clock
+hardware.
+ </para>
+ <para>
+The package will usually be loaded into the configuration
+automatically whenever selecting a target which contains a compatible
+chip. By default it will provide the standard eCos wallclock device,
+although another implementation such as software emulation may be
+selected if desired. The only other configuration options related to
+this package allow users to change the compiler flags. If the
+application does not actually use the wallclock device, directly or
+indirectly, then the code should get removed automatically at
+link-time to ensure that the application does not suffer any
+unnecessary overheads.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-wallclock-dallas-ds1307-functions"><title>Functionality</title>
+ <para>
+This wallclock device driver package implements the standard
+functionality required by the generic wallclock support
+<varname>CYGPKG_IO_WALLCLOCK</varname>. The functionality is not
+normally accessed directly. Instead it is used by the C library time
+package to implement standard calls such as <function>time</function>
+and <function>gmtime</function>. The eCos C library also provides a
+non-standard function <function>cyg_libc_time_settime</function> for
+changing the current wallclock setting. In addition RedBoot provides
+a <command>date</command> command which interacts with the wallclock
+device.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-wallclock-dallas-ds1307-porting"><title>Porting</title>
+ <para>
+DS1307 platform support can be implemented in one of two ways. The
+preferred approach involves the generic I2C API, as defined by the
+package <varname>CYGPKG_IO_I2C</varname>. The platform HAL can just
+provide a <structname>cyg_i2c_device</structname> structure
+<varname>cyg_i2c_wallclock_ds1307</varname> and implement the CDL
+interface
+<varname>CYGINT_DEVICES_WALLCLOCK_DALLAS_DS1307_I2C</varname>. The
+DS1307 driver will now use I2C rx and tx operations to interact with
+the chip.
+ </para>
+ <para>
+Alternatively the DS1307 driver can use macros or functions provided
+by another package to access the chip. This is intended primarily for
+older platforms that predate the <varname>CYGPKG_IO_I2C</varname>
+package. The other package should export a header file containing
+macros <function>DS_GET</function> and <function>DS_PUT</function>
+that transfer the eight bytes corresponding to the chip's clock
+registers. It should also export the name of this header via a
+<literal>#define</literal>
+<varname>CYGDAT_DEVS_WALLCLOCK_DS1307_INL</varname> in the global
+configuration header <filename
+class="headerfile">pkgconf/system.h</filename>. For full details see
+the source code.
+ </para>
+ <para>
+In addition the DS1307 device driver package
+<varname>CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1307</varname> should be
+included in the CDL target entry so that it gets loaded automatically
+whenever eCos is configured for that target.
+ </para>
+ </refsect1>
+
+</refentry>
+
+</part>
diff --git a/ecos/packages/devs/wallclock/dallas/ds1307/current/src/ds1307.cxx b/ecos/packages/devs/wallclock/dallas/ds1307/current/src/ds1307.cxx
new file mode 100644
index 0000000..a8f6382
--- /dev/null
+++ b/ecos/packages/devs/wallclock/dallas/ds1307/current/src/ds1307.cxx
@@ -0,0 +1,335 @@
+//==========================================================================
+//
+// devs/wallclock/ds1307.inl
+//
+// Wallclock implementation for Dallas 1307
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors:
+// Date: 2003-09-19
+// Purpose: Wallclock driver for Dallas 1307
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h> // Platform specific configury
+#include <pkgconf/wallclock.h> // Wallclock device config
+#include <pkgconf/devices_wallclock_dallas_ds1307.h>
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_intr.h> // interrupt enable/disable
+#include <cyg/infra/cyg_type.h> // Common type definitions and support
+#include <string.h> // memcpy()
+
+#include <cyg/io/wallclock.hxx> // The WallClock API
+#include <cyg/io/wallclock/wallclock.inl> // Helpers
+
+#include <cyg/infra/diag.h>
+
+#if 1
+# define DEBUG(_format_, ...)
+#else
+# define DEBUG(_format_, ...) diag_printf(_format_, ## __VA_ARGS__)
+#endif
+
+// Registers.
+// FIXME: there is no need to include the control register here, it
+// controls a square wave output which is independent from the wallclock.
+// However fixing it would require changing any platforms that use the
+// old DS_GET()/DS_PUT() functionality.
+#define DS_SECONDS 0x00
+#define DS_MINUTES 0x01
+#define DS_HOURS 0x02
+#define DS_DOW 0x03
+#define DS_DOM 0x04
+#define DS_MONTH 0x05
+#define DS_YEAR 0x06
+#define DS_CONTROL 0x07
+#define DS_REGS_SIZE 0x08 // Size of register space
+
+#define DS_SECONDS_CH 0x80 // Clock Halt
+#define DS_HOURS_24 0x40 // 24 hour clock mode
+
+// The DS1307 chip is accessed via I2C (2-wire protocol). This can be
+// implemented in one of two ways. If the platform supports the generic
+// I2C API then it should also export a cyg_i2c_device structure
+// cyg_i2c_wallclock_ds1307, and this can be manipulated via the
+// usual cyg_i2c_tx() and cyg_i2c_rx() functions. Alternatively (and
+// primarily for older ports predating the generic I2C package)
+// the platform HAL can provide the following two macros/functions:
+//
+// void DS_GET(cyg_uint8 *regs)
+// Reads the entire set of registers (8 bytes) into *regs
+// void DS_PUT(cyg_uint8 *regs)
+// Updated the entire set of registers (8 bytes) from *regs
+//
+// Using this method, the data in the registers is guaranteed to be
+// stable (if the access function manipulates the registers in an
+// single operation)
+//
+// If the platform HAL implements the CDL interface
+// CYGINT_DEVICES_WALLCLOCK_DALLAS_DS1307_I2C then the I2C API will be used.
+
+#ifdef CYGINT_DEVICES_WALLCLOCK_DALLAS_DS1307_I2C
+# if defined(DS_GET) || defined(DS_PUT)
+# error The macros DS_GET and DS_PUT should not be defined if the generic I2C API is used
+# endif
+
+#include <cyg/io/i2c.h>
+
+static void
+DS_GET(cyg_uint8* regs)
+{
+ cyg_uint8 tx_data[1];
+ cyg_bool ok = true;
+
+ tx_data[0] = 0x00; // Initial register to read
+ cyg_i2c_transaction_begin(&cyg_i2c_wallclock_ds1307);
+ if (1 != cyg_i2c_transaction_tx(&cyg_i2c_wallclock_ds1307, true, tx_data, 1, false)) {
+ // The device has not responded to the address byte.
+ ok = false;
+ } else {
+ // Now fetch the data
+ cyg_i2c_transaction_rx(&cyg_i2c_wallclock_ds1307, true, regs, 8, true, true);
+
+ // Verify that there are reasonable default settings. The
+ // register values can be used as array indices so bogus
+ // values can lead to bus errors or similar problems.
+
+ // Years: 00 - 99, with 70-99 interpreted as 1970 onwards.
+ if ((regs[DS_YEAR] & 0x0F) > 0x09) {
+ ok = false;
+ }
+ // Month: 1 - 12
+ if ((regs[DS_MONTH] == 0x00) ||
+ ((regs[DS_MONTH] > 0x09) && (regs[DS_MONTH] < 0x10)) ||
+ (regs[DS_MONTH] > 0x12)) {
+ ok = false;
+ }
+ // Day: 1 - 31. This check does not allow for 28-30 day months.
+ if ((regs[DS_DOM] == 0x00) ||
+ ((regs[DS_DOM] & 0x0F) > 0x09) ||
+ (regs[DS_DOM] > 0x31)) {
+ ok = false;
+ }
+ // Hours: 0 - 23. Always run in 24-hour mode
+ if ((0 != (regs[DS_HOURS] & DS_HOURS_24)) ||
+ ((regs[DS_HOURS] & 0x0F) > 0x09) ||
+ ((regs[DS_HOURS] & 0x3F) > 0x023)) {
+ ok = false;
+ }
+ // Ignore the DOW field. The wallclock code does not need it, and
+ // it is hard to calculate.
+ // Minutes: 0 - 59
+ if (((regs[DS_MINUTES] & 0x0F) > 0x09) ||
+ (regs[DS_MINUTES] > 0x59)) {
+ ok = false;
+ }
+ // Seconds: 0 - 59
+ if (((regs[DS_SECONDS] & 0x0F) > 0x09) ||
+ (regs[DS_SECONDS] > 0x59)) {
+ ok = false;
+ }
+ }
+ cyg_i2c_transaction_end(&cyg_i2c_wallclock_ds1307);
+ if (! ok) {
+ // Any problems, return Jan 1 1970 but do not update the hardware.
+ // Leave it to the user or other code to set the clock to a sensible
+ // value.
+ regs[DS_SECONDS] = 0x00;
+ regs[DS_MINUTES] = 0x00;
+ regs[DS_HOURS] = 0x00;
+ regs[DS_DOW] = 0x00;
+ regs[DS_DOM] = 0x01;
+ regs[DS_MONTH] = 0x01;
+ regs[DS_YEAR] = 0x70;
+ regs[DS_CONTROL] = 0x00;
+ }
+}
+
+static void
+DS_PUT(cyg_uint8* regs)
+{
+ cyg_uint8 tx_data[9];
+ tx_data[0] = 0;
+ memcpy(&(tx_data[1]), regs, 8);
+ cyg_i2c_tx(&cyg_i2c_wallclock_ds1307, tx_data, 9);
+}
+
+#else
+// Platform details. The platform HAL or some other package should
+// provide this header, containing the required macros
+# include CYGDAT_DEVS_WALLCLOCK_DALLAS_1307_INL
+#endif
+
+//----------------------------------------------------------------------------
+// Accessor functions
+
+static inline void
+init_ds_hwclock(void)
+{
+ cyg_uint8 regs[DS_REGS_SIZE];
+
+ // Fetch the current state
+ DS_GET(regs);
+
+ // If the clock is not currently running or is not in 24-hours mode,
+ // update it. Otherwise skip the update because the clock may have
+ // ticked between DS_GET() and DS_PUT() and we could be losing the
+ // occasional second.
+ if ((0 != (regs[DS_HOURS] & DS_HOURS_24)) ||
+ (0 != (regs[DS_SECONDS] & DS_SECONDS_CH))) {
+ regs[DS_SECONDS] &= ~DS_SECONDS_CH;
+ regs[DS_HOURS] &= ~DS_HOURS_24;
+ DS_PUT(regs);
+ }
+}
+
+static inline void
+set_ds_hwclock(cyg_uint32 year, cyg_uint32 month, cyg_uint32 mday,
+ cyg_uint32 hour, cyg_uint32 minute, cyg_uint32 second)
+{
+ cyg_uint8 regs[DS_REGS_SIZE];
+
+ // Set up the registers
+ regs[DS_CONTROL] = 0x00;
+ regs[DS_YEAR] = TO_BCD((cyg_uint8)(year % 100));
+ regs[DS_MONTH] = TO_BCD((cyg_uint8)month);
+ regs[DS_DOM] = TO_BCD((cyg_uint8)mday);
+ regs[DS_DOW] = TO_BCD(0x01); // Not accurate, but not used by this driver either
+ regs[DS_HOURS] = TO_BCD((cyg_uint8)hour);
+ regs[DS_MINUTES] = TO_BCD((cyg_uint8)minute);
+ // This also starts the clock
+ regs[DS_SECONDS] = TO_BCD((cyg_uint8)second);
+
+ // Send the register set to the hardware
+ DS_PUT(regs);
+
+ // These debugs will cause the test to eventually fail due to
+ // the printouts causing timer interrupts to be lost...
+ DEBUG("DS1307 set -------------\n");
+ DEBUG("regs %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7]);
+ DEBUG("year %02d\n", year);
+ DEBUG("month %02d\n", month);
+ DEBUG("mday %02d\n", mday);
+ DEBUG("hour %02d\n", hour);
+ DEBUG("minute %02d\n", minute);
+ DEBUG("second %02d\n", second);
+}
+
+static inline void
+get_ds_hwclock(cyg_uint32* year, cyg_uint32* month, cyg_uint32* mday,
+ cyg_uint32* hour, cyg_uint32* minute, cyg_uint32* second)
+{
+ cyg_uint8 regs[DS_REGS_SIZE];
+
+ // Fetch the current state
+ DS_GET(regs);
+
+ *year = (cyg_uint32)TO_DEC(regs[DS_YEAR]);
+ // The year field only has the 2 least significant digits :-(
+ if (*year >= 70) {
+ *year += 1900;
+ } else {
+ *year += 2000;
+ }
+ *month = (cyg_uint32)TO_DEC(regs[DS_MONTH]);
+ *mday = (cyg_uint32)TO_DEC(regs[DS_DOM]);
+ *hour = (cyg_uint32)TO_DEC(regs[DS_HOURS] & 0x3F);
+ *minute = (cyg_uint32)TO_DEC(regs[DS_MINUTES]);
+ *second = (cyg_uint32)TO_DEC(regs[DS_SECONDS] & 0x7F);
+
+ // These debugs will cause the test to eventually fail due to
+ // the printouts causing timer interrupts to be lost...
+ DEBUG("DS1307 get -------------\n");
+ DEBUG("regs %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7]);
+ DEBUG("year %02d\n", *year);
+ DEBUG("month %02d\n", *month);
+ DEBUG("mday %02d\n", *mday);
+ DEBUG("hour %02d\n", *hour);
+ DEBUG("minute %02d\n", *minute);
+ DEBUG("second %02d\n", *second);
+}
+
+//-----------------------------------------------------------------------------
+// Functions required for the hardware-driver API.
+
+// Returns the number of seconds elapsed since 1970-01-01 00:00:00.
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+ cyg_uint32 year, month, mday, hour, minute, second;
+
+ get_ds_hwclock(&year, &month, &mday, &hour, &minute, &second);
+ cyg_uint32 now = _simple_mktime(year, month, mday, hour, minute, second);
+ return now;
+}
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+
+// Sets the clock. Argument is seconds elapsed since 1970-01-01 00:00:00.
+void
+Cyg_WallClock::set_hw_seconds( cyg_uint32 secs )
+{
+ cyg_uint32 year, month, mday, hour, minute, second;
+
+ _simple_mkdate(secs, &year, &month, &mday, &hour, &minute, &second);
+ set_ds_hwclock(year, month, mday, hour, minute, second);
+}
+
+#endif
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+ init_ds_hwclock();
+#else
+ // This is our base: 1970-01-01 00:00:00
+ // Set the HW clock - if for nothing else, just to be sure it's in a
+ // legal range. Any arbitrary base could be used.
+ // After this the hardware clock is only read.
+ set_ds_hwclock(1970,1,1,0,0,0);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// End of devs/wallclock/ds1307.inl
diff --git a/ecos/packages/devs/wallclock/dallas/ds1742/current/ChangeLog b/ecos/packages/devs/wallclock/dallas/ds1742/current/ChangeLog
new file mode 100644
index 0000000..16f4dde
--- /dev/null
+++ b/ecos/packages/devs/wallclock/dallas/ds1742/current/ChangeLog
@@ -0,0 +1,27 @@
+2000-05-26 Jesper Skov <jskov@redhat.com>
+ * wallclock_ds1742.cdl:
+ Parent under IO/Wallclock.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+
+
diff --git a/ecos/packages/devs/wallclock/dallas/ds1742/current/ds1742.inl b/ecos/packages/devs/wallclock/dallas/ds1742/current/ds1742.inl
new file mode 100644
index 0000000..6db6d86
--- /dev/null
+++ b/ecos/packages/devs/wallclock/dallas/ds1742/current/ds1742.inl
@@ -0,0 +1,182 @@
+//==========================================================================
+//
+// devs/wallclock/ds1742.inl
+//
+// Wallclock implementation for Dallas 1742
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2000-05-25
+// Purpose: Wallclock driver for Dallas 1742
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#ifndef DS_BASE
+# error "Need to know base of DS1742 RAM"
+#endif
+
+#include <cyg/infra/cyg_type.h> // Common type definitions and support
+#include <cyg/hal/hal_io.h> // IO macros
+
+// Offsets from DS_BASE
+#define DS_SECONDS 0x7f9 // control bit!
+#define DS_SECONDS_MASK 0x7f
+#define DS_MINUTES 0x7fa
+#define DS_HOUR 0x7fb
+#define DS_DAY 0x7fc // control bits
+#define DS_DAY_MASK 0x07
+#define DS_DATE 0x7fd
+#define DS_MONTH 0x7fe
+#define DS_YEAR 0x7ff
+#define DS_CENTURY 0x7f8 // control bits!
+#define DS_CENTURY_MASK 0x3f
+
+// Control bits
+#define DS_SECONDS_OSC 0x80 // set to stop oscillator (power save)
+#define DS_CENTURY_READ 0x40 // set during read
+#define DS_CENTURY_WRITE 0x80 // set during write
+#define DS_DAY_BF 0x80 // battery flag
+#define DS_DAY_FT 0x40 // frequency test
+
+
+// Make sure test modes are disabled and that clock is running.
+static void
+init_ds_hwclock(void)
+{
+ cyg_uint8 _tmp;
+
+ // Enable clock
+ HAL_READ_UINT8(DS_BASE+DS_SECONDS, _tmp);
+ _tmp &= ~DS_SECONDS_OSC;
+ HAL_WRITE_UINT8(DS_BASE+DS_SECONDS, _tmp);
+
+ // clear frequency test
+ HAL_READ_UINT8(DS_BASE+DS_DAY, _tmp);
+ _tmp &= ~DS_DAY_FT;
+ HAL_WRITE_UINT8(DS_BASE+DS_DAY, _tmp);
+}
+
+
+static void
+set_ds_hwclock(cyg_uint32 year, cyg_uint32 month, cyg_uint32 mday,
+ cyg_uint32 hour, cyg_uint32 minute, cyg_uint32 second)
+{
+ cyg_uint8 _tmp;
+ // Init write operation
+ HAL_READ_UINT8(DS_BASE+DS_CENTURY, _tmp);
+ _tmp &= ~(DS_CENTURY_WRITE|DS_CENTURY_READ);
+ _tmp |= DS_CENTURY_WRITE;
+ HAL_WRITE_UINT8(DS_BASE+DS_CENTURY, _tmp);
+
+ // Entries with control bits
+ HAL_READ_UINT8(DS_BASE+DS_CENTURY, _tmp);
+ _tmp &= ~DS_CENTURY_MASK;
+ _tmp |= TO_BCD(year/100) & DS_CENTURY_MASK;
+ HAL_WRITE_UINT8(DS_BASE+DS_CENTURY, _tmp);
+
+ HAL_READ_UINT8(DS_BASE+DS_SECONDS, _tmp);
+ _tmp &= ~DS_SECONDS_MASK;
+ _tmp |= TO_BCD(second) & DS_SECONDS_MASK;
+ HAL_WRITE_UINT8(DS_BASE+DS_SECONDS, _tmp);
+
+ HAL_READ_UINT8(DS_BASE+DS_DAY, _tmp);
+ _tmp &= ~DS_DAY_FT; // clear frequency test
+ HAL_WRITE_UINT8(DS_BASE+DS_DAY, _tmp);
+
+
+ // Dedicated entries
+ HAL_WRITE_UINT8(DS_BASE+DS_YEAR, TO_BCD(year % 100));
+ HAL_WRITE_UINT8(DS_BASE+DS_MONTH, TO_BCD(month));
+ HAL_WRITE_UINT8(DS_BASE+DS_DATE, TO_BCD(mday));
+ HAL_WRITE_UINT8(DS_BASE+DS_HOUR, TO_BCD(hour));
+ HAL_WRITE_UINT8(DS_BASE+DS_MINUTES, TO_BCD(minute));
+
+ // Enable clock
+ HAL_READ_UINT8(DS_BASE+DS_SECONDS, _tmp);
+ _tmp &= ~DS_SECONDS_OSC;
+ HAL_WRITE_UINT8(DS_BASE+DS_SECONDS, _tmp);
+
+ // Finish write operation
+ HAL_READ_UINT8(DS_BASE+DS_CENTURY, _tmp);
+ _tmp &= ~(DS_CENTURY_WRITE|DS_CENTURY_READ);
+ HAL_WRITE_UINT8(DS_BASE+DS_CENTURY, _tmp);
+}
+
+static void
+get_ds_hwclock(cyg_uint32* year, cyg_uint32* month, cyg_uint32* mday,
+ cyg_uint32* hour, cyg_uint32* minute, cyg_uint32* second)
+{
+ cyg_uint8 _tmp;
+
+ // Init read operation
+ HAL_READ_UINT8(DS_BASE+DS_CENTURY, _tmp);
+ _tmp &= ~(DS_CENTURY_WRITE|DS_CENTURY_READ);
+ _tmp |= DS_CENTURY_READ;
+ HAL_WRITE_UINT8(DS_BASE+DS_CENTURY, _tmp);
+
+ // Entries with control bits
+ HAL_READ_UINT8(DS_BASE+DS_CENTURY, _tmp);
+ _tmp &= DS_CENTURY_MASK;
+ *year = 100*TO_DEC(_tmp);
+
+ HAL_READ_UINT8(DS_BASE+DS_SECONDS, _tmp);
+ _tmp &= DS_SECONDS_MASK;
+ *second = TO_DEC(_tmp);
+
+ // Dedicated entries
+ HAL_READ_UINT8(DS_BASE+DS_YEAR, _tmp);
+ *year += TO_DEC(_tmp);
+ HAL_READ_UINT8(DS_BASE+DS_MONTH, _tmp);
+ *month = TO_DEC(_tmp);
+ HAL_READ_UINT8(DS_BASE+DS_DATE, _tmp);
+ *mday = TO_DEC(_tmp);
+ HAL_READ_UINT8(DS_BASE+DS_HOUR, _tmp);
+ *hour = TO_DEC(_tmp);
+ HAL_READ_UINT8(DS_BASE+DS_MINUTES, _tmp);
+ *minute = TO_DEC(_tmp);
+
+ // Finish read operation
+ HAL_READ_UINT8(DS_BASE+DS_CENTURY, _tmp);
+ _tmp &= ~(DS_CENTURY_WRITE|DS_CENTURY_READ);
+ HAL_WRITE_UINT8(DS_BASE+DS_CENTURY, _tmp);
+}
+
+//-----------------------------------------------------------------------------
+// End of devs/wallclock/ds1742.inl
diff --git a/ecos/packages/devs/wallclock/dallas/ds1742/current/wallclock_ds1742.cdl b/ecos/packages/devs/wallclock/dallas/ds1742/current/wallclock_ds1742.cdl
new file mode 100644
index 0000000..6d5ff65
--- /dev/null
+++ b/ecos/packages/devs/wallclock/dallas/ds1742/current/wallclock_ds1742.cdl
@@ -0,0 +1,59 @@
+# ====================================================================
+#
+# wallclock_ds1742.cdl
+#
+# eCos configuration data for Dallas 1742
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2000-05-26
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1742 {
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ display "Wallclock device driver for Dallas 1742"
+ include_dir cyg/io/wallclock
+ include_files ds1742.inl
+ description "
+ This package provides a file with init, get and set functions
+ for the Dallas 1742 clock part."
+}
diff --git a/ecos/packages/devs/wallclock/freescale/kinetis/current/ChangeLog b/ecos/packages/devs/wallclock/freescale/kinetis/current/ChangeLog
new file mode 100644
index 0000000..a657124
--- /dev/null
+++ b/ecos/packages/devs/wallclock/freescale/kinetis/current/ChangeLog
@@ -0,0 +1,29 @@
+2011-04-24 Ilija Kocho <ilijak@siva.com.mk>
+
+ * cdl/wallclock_kinetis_rtc.cdl:
+ * src/wallclock_kinetis_rtc.cxx:
+ New wallclock driver
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/wallclock/freescale/kinetis/current/cdl/wallclock_kinetis_rtc.cdl b/ecos/packages/devs/wallclock/freescale/kinetis/current/cdl/wallclock_kinetis_rtc.cdl
new file mode 100644
index 0000000..4cbc595
--- /dev/null
+++ b/ecos/packages/devs/wallclock/freescale/kinetis/current/cdl/wallclock_kinetis_rtc.cdl
@@ -0,0 +1,70 @@
+# ====================================================================
+#
+# wallclock_kinetis_rtc.cdl
+#
+# eCos configuration data for Kinetis RTC
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ilijak
+# Contributors:
+# Date: 2011-04-23
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_KINETIS_RTC {
+ display "Real-time clock"
+
+ description "Driver for the Kinetis RTC"
+
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+
+ compile wallclock_kinetis_rtc.cxx
+
+ implements CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WALLCLOCK_HARDWARE
+ implements CYGINT_WALLCLOCK_SET_GET_MODE_SUPPORTED
+
+ cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+ parent CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+ display "Hardware wallclock"
+ default_value 1
+ implements CYGINT_WALLCLOCK_IMPLEMENTATIONS
+ }
+}
diff --git a/ecos/packages/devs/wallclock/freescale/kinetis/current/src/wallclock_kinetis_rtc.cxx b/ecos/packages/devs/wallclock/freescale/kinetis/current/src/wallclock_kinetis_rtc.cxx
new file mode 100644
index 0000000..c4c0fb4
--- /dev/null
+++ b/ecos/packages/devs/wallclock/freescale/kinetis/current/src/wallclock_kinetis_rtc.cxx
@@ -0,0 +1,105 @@
+//==========================================================================
+//
+// wallclock_kinetis_rtc.cxx
+//
+// Wallclock implementation for Kinetis RTC module
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Ilija Kocho <ilijak@siva.com.mk>
+// Contributors:
+// Date: 2011-04-23
+// Purpose: Wallclock driver for Kinetis RTC module
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/wallclock.h>
+#include <pkgconf/devices_wallclock_kinetis_rtc.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/io/wallclock.hxx>
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+ volatile cyghwr_hal_kinetis_rtc_t *rtc_p = CYGHWR_HAL_KINETIS_RTC_P;
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+ // if RTC is disabled (e.g. due to power loss) initialize it.
+ if(!(rtc_p->sr &CYGHWR_HAL_KINETIS_RTC_SR_TCE))
+#endif
+ {
+ // halt clock, reset
+ rtc_p->sr &= ~CYGHWR_HAL_KINETIS_RTC_SR_TCE;
+ // set time
+ rtc_p->tpr = 0;
+ rtc_p->tsr = 0;
+ // restart clock
+ rtc_p->sr |= CYGHWR_HAL_KINETIS_RTC_SR_TCE;
+ }
+}
+
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+ volatile cyghwr_hal_kinetis_rtc_t *rtc_p = CYGHWR_HAL_KINETIS_RTC_P;
+
+ return rtc_p->tsr;
+}
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+void
+Cyg_WallClock::set_hw_seconds(cyg_uint32 secs)
+{
+ volatile cyghwr_hal_kinetis_rtc_t *rtc_p = CYGHWR_HAL_KINETIS_RTC_P;
+
+ // halt clock, reset
+ rtc_p->sr &= ~CYGHWR_HAL_KINETIS_RTC_SR_TCE;
+ // set time
+ rtc_p->tpr = 0;
+ rtc_p->tsr = secs;
+ // restart clock
+ rtc_p->sr |= CYGHWR_HAL_KINETIS_RTC_SR_TCE;
+}
+#endif // CYGSEM_WALLCLOCK_SET_GET_MODE
+
+//==========================================================================
+// EOF wallclock_kinetis_rtc.cxx
diff --git a/ecos/packages/devs/wallclock/i386/pc/current/ChangeLog b/ecos/packages/devs/wallclock/i386/pc/current/ChangeLog
new file mode 100644
index 0000000..9829530
--- /dev/null
+++ b/ecos/packages/devs/wallclock/i386/pc/current/ChangeLog
@@ -0,0 +1,36 @@
+2006-11-23 David Fernandez <dfernandez@cct.co.uk>
+
+ * include/devices_wallclock_i386_pc.inl: Added exception for DS_READ
+ DS_WRITE. Take into account that in Intel PC platforms the 8Th bit
+ in DS_ADDR is used to enable or disable NMI gate, and therefore,
+ should be preserved.
+
+2001-09-18 Rajagopalan Thiruvenkatachary <rajt@us.ibm.com>
+
+ * include/devices_wallclock_i386_pc.inl:
+ * cdl/i386_pc_wallclock_drivers.cdl:
+ New package.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+
+
diff --git a/ecos/packages/devs/wallclock/i386/pc/current/cdl/i386_pc_wallclock_drivers.cdl b/ecos/packages/devs/wallclock/i386/pc/current/cdl/i386_pc_wallclock_drivers.cdl
new file mode 100644
index 0000000..3eaa94b
--- /dev/null
+++ b/ecos/packages/devs/wallclock/i386/pc/current/cdl/i386_pc_wallclock_drivers.cdl
@@ -0,0 +1,85 @@
+# ====================================================================
+#
+# i386_pc_wallclock_drivers.cdl
+#
+# Wallclock drivers - support for DS12887 RTC on the PC
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): rajt
+# Contributors: rajt
+# Date: 2001-07-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_I386_PC {
+ display "PC board RTC Driver"
+ description "RTC driver for PC."
+
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_HAL_I386_PC
+ requires CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS12887
+
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "/***** PC RTC driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_WALLCLOCK_DALLAS_12887_INL <cyg/io/devices_wallclock_i386_pc.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_WALLCLOCK_i386_PC_CFG <pkgconf/devices_wallclock_i386_pc.h>"
+ puts $::cdl_system_header "/***** PC RTC driver proc output end *****/"
+ }
+
+ cdl_option CYGDAT_DEVS_WALLCLOCK_I386_PC_RTC_ADDRESS_PORT {
+ display "IO port address of the ADDRESS register"
+ flavor data
+ default_value 0x70
+ description "
+ This option sets the io address of the address port for
+ accessing the PC RTC"
+ }
+
+ cdl_option CYGDAT_DEVS_WALLCLOCK_I386_PC_RTC_DATA_PORT {
+ display "IO port address of the DATA register"
+ flavor data
+ default_value 0x71
+ description "
+ This option sets the io address of the data port for
+ accessing the PC RTC"
+ }
+}
diff --git a/ecos/packages/devs/wallclock/i386/pc/current/include/devices_wallclock_i386_pc.inl b/ecos/packages/devs/wallclock/i386/pc/current/include/devices_wallclock_i386_pc.inl
new file mode 100644
index 0000000..31835ba
--- /dev/null
+++ b/ecos/packages/devs/wallclock/i386/pc/current/include/devices_wallclock_i386_pc.inl
@@ -0,0 +1,72 @@
+//==========================================================================
+//
+// devs/wallclock/i386/pc/include/devs_wallclock_i386_pc.inl
+//
+// PC RTC IO definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): rajt
+// Contributors:rajt
+// Date: 2001-07-19
+// Purpose: PC RTC definitions for using DS12887
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include CYGDAT_DEVS_WALLCLOCK_i386_PC_CFG
+
+#define DS_ADDR CYGDAT_DEVS_WALLCLOCK_I386_PC_RTC_ADDRESS_PORT
+#define DS_DATA CYGDAT_DEVS_WALLCLOCK_I386_PC_RTC_DATA_PORT
+
+#ifndef DS_LINEAR
+#define DS_READ(offset, data) \
+CYG_MACRO_START \
+ register CYG_BYTE btval; \
+ DS_READ_UINT8( DS_ADDR, (btval)); \
+ DS_WRITE_UINT8(DS_ADDR, ((offset)&0x7F)|(btval&0x80)); \
+ DS_READ_UINT8( DS_DATA, (data)); \
+CYG_MACRO_END
+#define DS_WRITE(offset, data) \
+CYG_MACRO_START \
+ register CYG_BYTE btval; \
+ DS_READ_UINT8( DS_ADDR, (btval)); \
+ DS_WRITE_UINT8(DS_ADDR, ((offset)&0x7F)|(btval&0x80)); \
+ DS_WRITE_UINT8(DS_DATA, (data)); \
+CYG_MACRO_END
+#endif
+
+
+// EOF devs_wallclock_i386_pc.inl
diff --git a/ecos/packages/devs/wallclock/mips/ref4955/current/ChangeLog b/ecos/packages/devs/wallclock/mips/ref4955/current/ChangeLog
new file mode 100644
index 0000000..3f91b41
--- /dev/null
+++ b/ecos/packages/devs/wallclock/mips/ref4955/current/ChangeLog
@@ -0,0 +1,42 @@
+2001-07-03 Jesper Skov <jskov@redhat.com>
+
+ * src/wallclock_ref4955.cxx: Don't include kernel config.
+
+2000-05-26 Jesper Skov <jskov@redhat.com>
+
+ * cdl/wallclock_ref4955.cdl:
+ * src/wallclock_ref4955.cxx:
+ * src/ds1742.inl: [deleted]
+ Added set-get mode. Moved Dallas driver to its own package.
+
+2000-05-25 Jesper Skov <jskov@redhat.com>
+
+ * cdl/wallclock_ref4955.cdl:
+ * src/wallclock_ref4955.cxx:
+ * src/ds1742.inl:
+ Added wallclock driver REF4955 (Dallas 1742)
+ (set_ds_hwclock): Clear frequency test bit.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+
+
diff --git a/ecos/packages/devs/wallclock/mips/ref4955/current/cdl/wallclock_ref4955.cdl b/ecos/packages/devs/wallclock/mips/ref4955/current/cdl/wallclock_ref4955.cdl
new file mode 100644
index 0000000..e438f83
--- /dev/null
+++ b/ecos/packages/devs/wallclock/mips/ref4955/current/cdl/wallclock_ref4955.cdl
@@ -0,0 +1,101 @@
+# ====================================================================
+#
+# wallclock_ref4955.cdl
+#
+# eCos wallclock for REF4955 driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2000-05-25
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_MIPS_REF4955 {
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ display "REF4955 wallclock driver"
+ requires CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1742
+ requires CYGPKG_HAL_MIPS_TX49_REF4955
+ hardware
+ compile wallclock_ref4955.cxx
+ implements CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+ implements CYGINT_WALLCLOCK_SET_GET_MODE_SUPPORTED
+ active_if CYGIMP_WALLCLOCK_HARDWARE
+
+ cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+ parent CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+ display "Hardware wallclock"
+ default_value 1
+ implements CYGINT_WALLCLOCK_IMPLEMENTATIONS
+ }
+
+ cdl_component CYGPKG_DEVICES_WALLCLOCK_MIPS_REF4955_OPTIONS {
+ display "REF4955 wallclock build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WALLCLOCK_MIPS_REF4955_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WALLCLOCK_MIPS_REF4955_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/wallclock/mips/ref4955/current/src/wallclock_ref4955.cxx b/ecos/packages/devs/wallclock/mips/ref4955/current/src/wallclock_ref4955.cxx
new file mode 100644
index 0000000..5c2e9d3
--- /dev/null
+++ b/ecos/packages/devs/wallclock/mips/ref4955/current/src/wallclock_ref4955.cxx
@@ -0,0 +1,121 @@
+//==========================================================================
+//
+// devs/wallclock/mips/ref4955/ref4955.cxx
+//
+// Wallclock implementation
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2000-05-25
+// Purpose: Wallclock driver for REF4955
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/wallclock.h> // Wallclock device config
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/infra/cyg_type.h> // Common type definitions and support
+
+#include <cyg/io/wallclock.hxx> // The WallClock API
+#include <cyg/io/wallclock/wallclock.inl> // Helpers
+
+#include <cyg/infra/diag.h> // For debugging
+
+// REF4955 has a Dallas 1742W part.
+#define DS_BASE 0xb5000000
+#include <cyg/io/wallclock/ds1742.inl>
+
+//-----------------------------------------------------------------------------
+// Functions required for the hardware-driver API.
+
+// Returns the number of seconds elapsed since 1970-01-01 00:00:00.
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+ cyg_uint32 year, month, mday, hour, minute, second;
+
+ get_ds_hwclock(&year, &month, &mday, &hour, &minute, &second);
+
+#if 0
+ // This will cause the test to eventually fail due to these printouts
+ // causing timer interrupts to be lost...
+ diag_printf("year %02d\n", year);
+ diag_printf("month %02d\n", month);
+ diag_printf("mday %02d\n", mday);
+ diag_printf("hour %02d\n", hour);
+ diag_printf("minute %02d\n", minute);
+ diag_printf("second %02d\n", second);
+#endif
+
+ cyg_uint32 now = _simple_mktime(year, month, mday, hour, minute, second);
+ return now;
+}
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+
+// Sets the clock. Argument is seconds elapsed since 1970-01-01 00:00:00.
+void
+Cyg_WallClock::set_hw_seconds( cyg_uint32 secs )
+{
+ cyg_uint32 year, month, mday, hour, minute, second;
+
+ _simple_mkdate(secs, &year, &month, &mday, &hour, &minute, &second);
+
+ set_ds_hwclock(year, month, mday, hour, minute, second);
+}
+
+#endif
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+ init_ds_hwclock();
+#else
+ // This is our base: 1970-01-01 00:00:00
+ // Set the HW clock - if for nothing else, just to be sure it's in a
+ // legal range. Any arbitrary base could be used.
+ // After this the hardware clock is only read.
+ set_ds_hwclock(1970,1,1,0,0,0);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// End of devs/wallclock/mips/ref4955/wallclock_ref4955.cxx
diff --git a/ecos/packages/devs/wallclock/powerpc/moab/current/ChangeLog b/ecos/packages/devs/wallclock/powerpc/moab/current/ChangeLog
new file mode 100644
index 0000000..dca0aed
--- /dev/null
+++ b/ecos/packages/devs/wallclock/powerpc/moab/current/ChangeLog
@@ -0,0 +1,29 @@
+2003-09-19 Gary Thomas <gary@mlbassoc.com>
+
+ * include/devices_wallclock_moab.inl:
+ * cdl/moab_wallclock_drivers.cdl: New package - RTC support on
+ TAMS MOAB (PowerPC 405GPr) board.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+
+
diff --git a/ecos/packages/devs/wallclock/powerpc/moab/current/cdl/moab_wallclock_drivers.cdl b/ecos/packages/devs/wallclock/powerpc/moab/current/cdl/moab_wallclock_drivers.cdl
new file mode 100644
index 0000000..337860b
--- /dev/null
+++ b/ecos/packages/devs/wallclock/powerpc/moab/current/cdl/moab_wallclock_drivers.cdl
@@ -0,0 +1,67 @@
+# ====================================================================
+#
+# moab_wallclock_drivers.cdl
+#
+# Wallclock drivers - support for DS1307 RTC on the TAMS MOAB
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): rajt
+# Contributors: rajt
+# Date: 2001-07-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_POWERPC_MOAB {
+ display "TAMS MOAB board RTC Driver"
+ description "RTC driver for TAMS MOAB."
+
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_HAL_POWERPC_MOAB
+ requires CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS1307
+
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "/***** MOAB RTC driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_WALLCLOCK_DALLAS_1307_INL <cyg/io/devices_wallclock_moab.inl>"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_WALLCLOCK_MOAB_CFG <pkgconf/devices_wallclock_powerpc_moab.h>"
+ puts $::cdl_system_header "/***** MOAB RTC driver proc output end *****/"
+ }
+}
diff --git a/ecos/packages/devs/wallclock/powerpc/moab/current/include/devices_wallclock_moab.inl b/ecos/packages/devs/wallclock/powerpc/moab/current/include/devices_wallclock_moab.inl
new file mode 100644
index 0000000..467a991
--- /dev/null
+++ b/ecos/packages/devs/wallclock/powerpc/moab/current/include/devices_wallclock_moab.inl
@@ -0,0 +1,122 @@
+//==========================================================================
+//
+// devs/wallclock/powerpc/moab/include/devs_wallclock_moab.inl
+//
+// TAMS MOAB RTC IO definitions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): rajt
+// Contributors:rajt
+// Date: 2001-07-19
+// Purpose: MOAB RTC definitions for using DS1307
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include CYGDAT_DEVS_WALLCLOCK_MOAB_CFG
+
+static __inline__ void
+DS_GET(cyg_uint8 *regs)
+{
+ cyg_uint8 addr, page;
+
+ // Read RTC
+ addr = 0x00;
+ page = 0xD1;
+ if (!hal_ppc405_i2c_put_bytes(page, &addr, 1)) {
+ diag_printf("%s - Can't select page %x\n", __FUNCTION__, page);
+ return;
+ }
+ if (!hal_ppc405_i2c_get_bytes(page, regs, DS_REGS_SIZE)) {
+ diag_printf("%s - Can't read RTC\n", __FUNCTION__);
+ return;
+ }
+#if 0
+ diag_printf("RTC data - read\n");
+ diag_dump_buf(regs, DS_REGS_SIZE);
+#endif
+
+#ifdef RTC_TEST
+ addr = 0x10;
+ page = 0xD1;
+ if (!hal_ppc405_i2c_put_bytes(page, &addr, 1)) {
+ diag_printf("%s - Can't select page %x\n", __FUNCTION__, page);
+ return;
+ }
+ if (!hal_ppc405_i2c_get_bytes(page, regs, DS_REGS_SIZE)) {
+ diag_printf("%s - Can't read RTC\n", __FUNCTION__);
+ return;
+ }
+ diag_printf("RTC data - test\n");
+ diag_dump_buf(regs, DS_REGS_SIZE);
+#endif
+}
+
+static __inline__ void
+DS_PUT(cyg_uint8 *regs)
+{
+ cyg_uint8 addr_data[DS_REGS_SIZE+1], page;
+ int i;
+
+#if 0
+ diag_printf("RTC data - write\n");
+ diag_dump_buf(regs, DS_REGS_SIZE);
+#endif
+ // Update RTC in one swoop
+ addr_data[0] = 0x00; // Starting register address
+ for (i = 0; i < DS_REGS_SIZE; i++) {
+ addr_data[i+1] = regs[i];
+ }
+ page = 0xD0;
+ if (!hal_ppc405_i2c_put_bytes(page, addr_data, DS_REGS_SIZE+1)) {
+ diag_printf("%s - Can't write registers\n", __FUNCTION__);
+ return;
+ }
+#ifdef RTC_TEST
+ // Test RTC by copying the registers to some of the RAM
+ addr_data[0] = 0x10; // Starting register address
+ for (i = 0; i < DS_REGS_SIZE; i++) {
+ addr_data[i+1] = regs[i];
+ }
+ page = 0xD0;
+ if (!hal_ppc405_i2c_put_bytes(page, addr_data, DS_REGS_SIZE+1)) {
+ diag_printf("%s - Can't write registers\n", __FUNCTION__);
+ return;
+ }
+#endif
+}
+
+// EOF devs_wallclock_moab.inl
diff --git a/ecos/packages/devs/wallclock/powerpc/mpc5xx/current/ChangeLog b/ecos/packages/devs/wallclock/powerpc/mpc5xx/current/ChangeLog
new file mode 100644
index 0000000..8d41a7c
--- /dev/null
+++ b/ecos/packages/devs/wallclock/powerpc/mpc5xx/current/ChangeLog
@@ -0,0 +1,27 @@
+2002-04-24 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * New package.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/wallclock/powerpc/mpc5xx/current/cdl/wallclock_mpc5xx.cdl b/ecos/packages/devs/wallclock/powerpc/mpc5xx/current/cdl/wallclock_mpc5xx.cdl
new file mode 100644
index 0000000..f25544b
--- /dev/null
+++ b/ecos/packages/devs/wallclock/powerpc/mpc5xx/current/cdl/wallclock_mpc5xx.cdl
@@ -0,0 +1,100 @@
+# ====================================================================
+#
+# wallclock_mpc5xx.cdl
+#
+# eCos wallclock motorola MPC555-module driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Bob Koninckx
+# Original data: nickg
+# Contributors:
+# Date: 2002-01-18
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_MPC5xx {
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ display "mpc5xx RTC-module wallclock driver"
+ requires CYGPKG_HAL_POWERPC_MPC5xx
+ hardware
+ compile wallclock_mpc5xx.cxx
+ implements CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WALLCLOCK_HARDWARE
+
+ cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+ parent CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+ display "Hardware wallclock"
+ default_value 1
+ implements CYGINT_WALLCLOCK_IMPLEMENTATIONS
+ }
+
+ cdl_component CYGPKG_DEVICES_WALLCLOCK_MPC5xx_OPTIONS {
+ display "mpc5xx RTC-module wallclock build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WALLCLOCK_MPC5xx_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WALLCLOCK_MPC5xx_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/wallclock/powerpc/mpc5xx/current/src/wallclock_mpc5xx.cxx b/ecos/packages/devs/wallclock/powerpc/mpc5xx/current/src/wallclock_mpc5xx.cxx
new file mode 100644
index 0000000..0c57e81
--- /dev/null
+++ b/ecos/packages/devs/wallclock/powerpc/mpc5xx/current/src/wallclock_mpc5xx.cxx
@@ -0,0 +1,99 @@
+//==========================================================================
+//
+// wallclock_mpc5xx.cxx
+//
+// mpc5xx RTC module driver.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bob Koninckx
+// Contributors: Bob Koninckx
+// Date: 2002-01-18
+// Purpose: Wallclock driver for mpc5xx
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/wallclock.h> // Wallclock device config
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/infra/cyg_type.h> // Common type definitions and support
+
+#include <cyg/io/wallclock.hxx> // The WallClock API
+#include <cyg/io/wallclock/wallclock.inl> // Helpers
+
+#include <cyg/hal/hal_arch.h> // RTC register definitions
+
+#include <cyg/infra/diag.h> // For debugging
+
+//-----------------------------------------------------------------------------
+// Functions required for the hardware-driver API.
+
+// Returns the number of seconds elapsed since 1970-01-01 00:00:00.
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+ cyg_uint32 now;
+ HAL_READ_UINT32(CYGARC_REG_IMM_RTC, now);
+
+ return now;
+}
+
+#ifndef CYGSEM_WALLCLOCK_SET_GET_MODE
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+ cyg_uint32 key = 0x55ccaa33;
+ cyg_uint16 rtcsc;
+
+ // Write zero to the time register
+ // and start up the RTC
+ HAL_WRITE_UINT32(CYGARC_REG_IMM_RTCK, key);
+ HAL_WRITE_UINT32(CYGARC_REG_IMM_RTCSCK, key);
+
+ key = 0;
+ HAL_WRITE_UINT32(CYGARC_REG_IMM_RTC, key);
+ HAL_READ_UINT16(CYGARC_REG_IMM_RTCSC, rtcsc);
+ rtcsc |= 0x0001;
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_RTCSC, rtcsc);
+}
+
+#endif // CYGSEM_WALLCLOCK_SET_GET_MODE
+
+//-----------------------------------------------------------------------------
+// End of wallclock_mpc5xx.cxx
diff --git a/ecos/packages/devs/wallclock/sh/hs7729pci/current/ChangeLog b/ecos/packages/devs/wallclock/sh/hs7729pci/current/ChangeLog
new file mode 100644
index 0000000..963da72
--- /dev/null
+++ b/ecos/packages/devs/wallclock/sh/hs7729pci/current/ChangeLog
@@ -0,0 +1,27 @@
+2001-07-06 Jesper Skov <jskov@redhat.com>
+
+ New package.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+
+
diff --git a/ecos/packages/devs/wallclock/sh/hs7729pci/current/cdl/wallclock_hs7729pci.cdl b/ecos/packages/devs/wallclock/sh/hs7729pci/current/cdl/wallclock_hs7729pci.cdl
new file mode 100644
index 0000000..0855b09
--- /dev/null
+++ b/ecos/packages/devs/wallclock/sh/hs7729pci/current/cdl/wallclock_hs7729pci.cdl
@@ -0,0 +1,64 @@
+# ====================================================================
+#
+# wallclock_hs7729pci.cdl
+#
+# eCos wallclock for HS7729PCI driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2001-07-06
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_SH_HS7729PCI {
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ display "HS7729PCI wallclock driver"
+ requires CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS12887
+ requires CYGPKG_HAL_SH_SH7729_HS7729PCI
+ hardware
+ include_dir cyg/io
+
+ define_proc {
+ puts $::cdl_system_header "/***** wallclock driver proc output start *****/"
+ puts $::cdl_system_header "#define CYGDAT_DEVS_WALLCLOCK_DALLAS_12887_INL <cyg/io/devs_wallclock_sh_hs7729pci.inl>"
+ puts $::cdl_system_header "/***** wallclock driver proc output end *****/"
+ }
+}
diff --git a/ecos/packages/devs/wallclock/sh/hs7729pci/current/include/devs_wallclock_sh_hs7729pci.inl b/ecos/packages/devs/wallclock/sh/hs7729pci/current/include/devs_wallclock_sh_hs7729pci.inl
new file mode 100644
index 0000000..e4ecae0
--- /dev/null
+++ b/ecos/packages/devs/wallclock/sh/hs7729pci/current/include/devs_wallclock_sh_hs7729pci.inl
@@ -0,0 +1,69 @@
+//==========================================================================
+//
+// wallclock_hs7729pci.inl
+//
+// HS7729PCI wallclock details
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-07-06
+// Purpose: Wallclock driver details for HS7729PCI
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#define nDS_LINEAR
+#define DS_ADDR 0xa80000e0
+#define DS_DATA 0xa80000e2
+
+#define DS_READ_UINT8(_a_, _d_) \
+ CYG_MACRO_START \
+ cyg_uint16 t; \
+ HAL_READ_UINT16((_a_), t); \
+ (_d_) = (t >> 8) & 0xff; \
+ CYG_MACRO_END
+
+#define DS_WRITE_UINT8(_a_, _d_) \
+ CYG_MACRO_START \
+ HAL_WRITE_UINT16((_a_), (_d_)<<8); \
+ CYG_MACRO_END
+
+
+//-----------------------------------------------------------------------------
+// End of wallclock_hs7729pci.inl
diff --git a/ecos/packages/devs/wallclock/sh/sh3/current/ChangeLog b/ecos/packages/devs/wallclock/sh/sh3/current/ChangeLog
new file mode 100644
index 0000000..e72a67a
--- /dev/null
+++ b/ecos/packages/devs/wallclock/sh/sh3/current/ChangeLog
@@ -0,0 +1,72 @@
+2001-07-09 Jesper Skov <jskov@redhat.com>
+
+ * src/wallclock_sh3.cxx: fix description.
+
+2001-03-20 Jesper Skov <jskov@redhat.com>
+
+ * src/wallclock_sh3.cxx: Don't include kernel config.
+
+2000-05-26 Jesper Skov <jskov@redhat.com>
+
+ * cdl/wallclock_sh3.cdl: CYGSEM_WALLCLOCK_SET_GET_MODE moved to IO
+ package.
+
+ * src/wallclock_sh3.cxx: Get helpers from new file.
+
+2000-04-06 Jesper Skov <jskov@redhat.com>
+
+ * cdl/wallclock_sh3.cdl: Only active when wallclock is.
+
+2000-04-05 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/wallclock_sh3.cdl:
+
+ Provide hardware wallclock implementation as a radio button.
+
+2000-04-05 Jesper Skov <jskov@redhat.com>
+
+ * src/wallclock_sh3.cxx:
+ Moved from devs/wallclock/current to here.
+ Get API from io/wallclock.
+ Deleted all non-SH3 changelog entries
+
+2000-03-29 Jesper Skov <jskov@redhat.com>
+
+ * tests/wallclock2.cxx:
+ * include/wallclock.hxx:
+ * src/sh3.cxx:
+ * src/wallclock.cxx:
+ * cdl/wallclock.cdl:
+ Reworked WallClock API. It should now be simpler to add new
+ wallclock drivers. Added a simple test to print out the current
+ wallclock value so a human can verify battery backup works.
+
+2000-03-17 Jesper Skov <jskov@redhat.com>
+
+ * cdl/wallclock.cdl:
+ * src/sh3.cxx:
+ Added wallclock driver for SH3 RTC module.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+
+
diff --git a/ecos/packages/devs/wallclock/sh/sh3/current/cdl/wallclock_sh3.cdl b/ecos/packages/devs/wallclock/sh/sh3/current/cdl/wallclock_sh3.cdl
new file mode 100644
index 0000000..ead7da6
--- /dev/null
+++ b/ecos/packages/devs/wallclock/sh/sh3/current/cdl/wallclock_sh3.cdl
@@ -0,0 +1,100 @@
+# ====================================================================
+#
+# wallclock_sh3.cdl
+#
+# eCos wallclock SH3 RTC-module driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: nickg
+# Contributors:
+# Date: 2000-04-05
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_SH3 {
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ display "SH3 RTC-module wallclock driver"
+ requires CYGPKG_HAL_SH
+ hardware
+ compile wallclock_sh3.cxx
+ implements CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WALLCLOCK_HARDWARE
+
+ cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+ parent CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+ display "Hardware wallclock"
+ default_value 1
+ implements CYGINT_WALLCLOCK_IMPLEMENTATIONS
+ }
+
+ cdl_component CYGPKG_DEVICES_WALLCLOCK_SH3_OPTIONS {
+ display "SH3 RTC-module wallclock build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WALLCLOCK_SH3_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WALLCLOCK_SH3_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/wallclock/sh/sh3/current/src/wallclock_sh3.cxx b/ecos/packages/devs/wallclock/sh/sh3/current/src/wallclock_sh3.cxx
new file mode 100644
index 0000000..7155254
--- /dev/null
+++ b/ecos/packages/devs/wallclock/sh/sh3/current/src/wallclock_sh3.cxx
@@ -0,0 +1,174 @@
+//==========================================================================
+//
+// devs/wallclock/sh3.cxx
+//
+// SH3 RTC module driver.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2000-03-17
+// Purpose: Wallclock driver for SH3 CPU RTC module
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/wallclock.h> // Wallclock device config
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/infra/cyg_type.h> // Common type definitions and support
+
+#include <cyg/io/wallclock.hxx> // The WallClock API
+#include <cyg/io/wallclock/wallclock.inl> // Helpers
+
+#include <cyg/hal/sh_regs.h> // RTC register definitions
+
+#include <cyg/infra/diag.h> // For debugging
+
+
+
+//-----------------------------------------------------------------------------
+// Functions for setting and getting the hardware clock counters
+
+// Year must be last two digits of "western calendar year". Leap year when
+// divisible by four.
+static void
+set_sh3_hwclock(cyg_uint32 year, cyg_uint32 month, cyg_uint32 mday,
+ cyg_uint32 hour, cyg_uint32 minute, cyg_uint32 second)
+{
+ // Stop RTC
+ HAL_WRITE_UINT8(CYGARC_REG_RCR2, CYGARC_REG_RCR2_RESET);
+
+ // Program it
+ HAL_WRITE_UINT8(CYGARC_REG_RYRCNT, TO_BCD(year));
+ HAL_WRITE_UINT8(CYGARC_REG_RMONCNT, TO_BCD(month));
+ HAL_WRITE_UINT8(CYGARC_REG_RDAYCNT, TO_BCD(mday));
+ HAL_WRITE_UINT8(CYGARC_REG_RHRCNT, TO_BCD(hour));
+ HAL_WRITE_UINT8(CYGARC_REG_RMINCNT, TO_BCD(minute));
+ HAL_WRITE_UINT8(CYGARC_REG_RSECCNT, TO_BCD(second));
+
+ // Start RTC
+ HAL_WRITE_UINT8(CYGARC_REG_RCR1, CYGARC_REG_RCR1_CIE);
+ HAL_WRITE_UINT8(CYGARC_REG_RCR2,
+ CYGARC_REG_RCR2_RTCEN | CYGARC_REG_RCR2_START);
+
+}
+
+static void
+get_sh3_hwclock(cyg_uint32* year, cyg_uint32* month, cyg_uint32* mday,
+ cyg_uint32* hour, cyg_uint32* minute, cyg_uint32* second)
+{
+ cyg_uint8 tmp;
+
+ do {
+ // Clear carry flag
+ HAL_WRITE_UINT8(CYGARC_REG_RCR1, 0);
+
+ // Read time
+ HAL_READ_UINT8(CYGARC_REG_RYRCNT, tmp);
+ *year = TO_DEC(tmp);
+ HAL_READ_UINT8(CYGARC_REG_RMONCNT, tmp);
+ *month = TO_DEC(tmp);
+ HAL_READ_UINT8(CYGARC_REG_RDAYCNT, tmp);
+ *mday = TO_DEC(tmp);
+ HAL_READ_UINT8(CYGARC_REG_RHRCNT, tmp);
+ *hour = TO_DEC(tmp);
+ HAL_READ_UINT8(CYGARC_REG_RMINCNT, tmp);
+ *minute = TO_DEC(tmp);
+ HAL_READ_UINT8(CYGARC_REG_RSECCNT, tmp);
+ *second = TO_DEC(tmp);
+
+ // Read carry flag
+ HAL_READ_UINT8(CYGARC_REG_RCR1, tmp);
+ } while (CYGARC_REG_RCR1_CF & tmp); // loop if carry set
+}
+
+//-----------------------------------------------------------------------------
+// Functions required for the hardware-driver API.
+
+// Returns the number of seconds elapsed since 1970-01-01 00:00:00.
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+ cyg_uint32 year, month, mday, hour, minute, second;
+
+ get_sh3_hwclock(&year, &month, &mday, &hour, &minute, &second);
+
+#if 0
+ // This will cause the test to eventually fail due to these printouts
+ // causing timer interrupts to be lost...
+ diag_printf("year %02d\n", year);
+ diag_printf("month %02d\n", month);
+ diag_printf("mday %02d\n", mday);
+ diag_printf("hour %02d\n", hour);
+ diag_printf("minute %02d\n", minute);
+ diag_printf("second %02d\n", second);
+#endif
+
+#ifndef CYGSEM_WALLCLOCK_SET_GET_MODE
+ // We know what we initialized the hardware for : 1970, so by doing this
+ // the returned time should be OK for 30 years uptime.
+ year += 1900;
+#else
+ // Need to use sliding window or similar to figure out what the
+ // century should be... Patent issue is unclear, and since there's
+ // no battery backup of the clock, there's little point in
+ // investigating.
+# error "Need some magic here to figure out century counter"
+#endif
+
+ cyg_uint32 now = _simple_mktime(year, month, mday, hour, minute, second);
+ return now;
+}
+
+#ifndef CYGSEM_WALLCLOCK_SET_GET_MODE
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+ // This is our base: 1970-01-01 00:00:00
+ // Set the HW clock - if for nothing else, just to be sure it's in a
+ // legal range. Any arbitrary base could be used.
+ // After this the hardware clock is only read.
+ set_sh3_hwclock(70,1,1,0,0,0);
+}
+
+#endif // CYGSEM_WALLCLOCK_SET_GET_MODE
+
+//-----------------------------------------------------------------------------
+// End of devs/wallclock/sh3.cxx
diff --git a/ecos/packages/devs/wallclock/synth/current/ChangeLog b/ecos/packages/devs/wallclock/synth/current/ChangeLog
new file mode 100644
index 0000000..801aba6
--- /dev/null
+++ b/ecos/packages/devs/wallclock/synth/current/ChangeLog
@@ -0,0 +1,35 @@
+2003-10-06 Savin Zlobec <savin@elatec.si>
+
+ * cdl/wallclock_synth.cdl:
+ * src/wallclock_synth.cxx:
+ Implemented set_get mode.
+
+2003-10-02 Savin Zlobec <savin@elatec.si>
+
+ * cdl/wallclock_synth.cdl:
+ * src/wallclock_synth.cxx:
+ Created wallclock driver for synthetic target.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/devs/wallclock/synth/current/cdl/wallclock_synth.cdl b/ecos/packages/devs/wallclock/synth/current/cdl/wallclock_synth.cdl
new file mode 100644
index 0000000..0cf3966
--- /dev/null
+++ b/ecos/packages/devs/wallclock/synth/current/cdl/wallclock_synth.cdl
@@ -0,0 +1,112 @@
+# ====================================================================
+#
+# wallclock_synth.cdl
+#
+# eCos synthetic wallclock
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Savin Zlobec <savin@elatec.si>
+# Original data: nickg, jskov
+# Contributors:
+# Date: 2003-10-02
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_WALLCLOCK_SYNTH {
+ parent CYGPKG_IO_WALLCLOCK
+ active_if CYGPKG_IO_WALLCLOCK
+ display "Synthetic wallclock driver"
+ requires CYGPKG_HAL_SYNTH
+ hardware
+ compile wallclock_synth.cxx
+ implements CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+ implements CYGINT_WALLCLOCK_SET_GET_MODE_SUPPORTED
+ active_if CYGIMP_WALLCLOCK_HARDWARE
+
+ cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+ parent CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+ display "Hardware wallclock"
+ default_value 0
+ implements CYGINT_WALLCLOCK_IMPLEMENTATIONS
+ }
+
+ cdl_option CYGDAT_DEVS_WALLCLOCK_SYNTH_FILENAME {
+ display "Name of file wich holds system-eCos wallclock offset"
+ flavor data
+ default_value { "\"synth.wallclock\"" }
+ active_if CYGSEM_WALLCLOCK_SET_GET_MODE
+ description "
+ This is the name of the file which holds the difference
+ between system and eCos wallclock. It is read at initialization
+ and written to each time the wallclock it set."
+ }
+
+ cdl_component CYGPKG_DEVS_WALLCLOCK_SYNTH_OPTIONS {
+ display "Synthetic wallclock build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_DEVS_WALLCLOCK_SYNTH_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVS_WALLCLOCK_SYNTH_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the wallclock device. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF wallclock_synth.cdl
diff --git a/ecos/packages/devs/wallclock/synth/current/src/wallclock_synth.cxx b/ecos/packages/devs/wallclock/synth/current/src/wallclock_synth.cxx
new file mode 100644
index 0000000..48095cd
--- /dev/null
+++ b/ecos/packages/devs/wallclock/synth/current/src/wallclock_synth.cxx
@@ -0,0 +1,145 @@
+//==========================================================================
+//
+// wallclock_synth.cxx
+//
+// eCos synthetic wallclock driver.
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Savin Zlobec <savin@elatec.si>
+// Contributors:
+// Date: 2003-10-02
+// Purpose:
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/wallclock.h>
+#include <pkgconf/devs_wallclock_synth.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_arch.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/wallclock.hxx>
+
+//-----------------------------------------------------------------------------
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+// Difference between system and eCos wallclock
+static cyg_uint32 epoch_ticks;
+static cyg_uint32 epoch_time_stamp;
+#endif
+
+//-----------------------------------------------------------------------------
+// Functions required for the hardware-driver API.
+
+// Initializes the clock
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+ int fd;
+
+ // Read difference between system and eCos wallclock from file
+ fd = cyg_hal_sys_open(CYGDAT_DEVS_WALLCLOCK_SYNTH_FILENAME,
+ CYG_HAL_SYS_O_RDONLY, 0);
+
+ if (fd > 0)
+ {
+ cyg_hal_sys_read(fd, &epoch_time_stamp, sizeof(epoch_time_stamp));
+ cyg_hal_sys_read(fd, &epoch_ticks, sizeof(epoch_ticks));
+ cyg_hal_sys_close(fd);
+ }
+#endif
+}
+
+// Returns the number of seconds elapsed since 1970-01-01 00:00:00
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+ cyg_uint32 res;
+ struct cyg_hal_sys_timeval ctv;
+ struct cyg_hal_sys_timezone ctz;
+
+ cyg_hal_sys_gettimeofday(&ctv, &ctz);
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+ res = epoch_time_stamp + ctv.hal_tv_sec - epoch_ticks;
+#else
+ res = ctv.hal_tv_sec;
+#endif
+
+ return res;
+}
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+
+// Sets the clock. Argument is seconds elapsed since 1970-01-01 00:00:00
+void
+Cyg_WallClock::set_hw_seconds(cyg_uint32 secs)
+{
+ int fd;
+ struct cyg_hal_sys_timeval ctv;
+ struct cyg_hal_sys_timezone ctz;
+
+ // System wallclock time
+ cyg_hal_sys_gettimeofday(&ctv, &ctz);
+
+ // Set the difference between the system and eCos wallclock
+ epoch_time_stamp = secs;
+ epoch_ticks = ctv.hal_tv_sec;
+
+ // Write difference to file
+ fd = cyg_hal_sys_open(CYGDAT_DEVS_WALLCLOCK_SYNTH_FILENAME,
+ CYG_HAL_SYS_O_WRONLY | CYG_HAL_SYS_O_CREAT,
+ CYG_HAL_SYS_S_IRWXU | CYG_HAL_SYS_S_IRWXG | CYG_HAL_SYS_S_IRWXO);
+
+ if (fd > 0)
+ {
+ cyg_hal_sys_write(fd, &epoch_time_stamp, sizeof(epoch_time_stamp));
+ cyg_hal_sys_write(fd, &epoch_ticks, sizeof(epoch_ticks));
+ cyg_hal_sys_close(fd);
+ }
+}
+
+#endif // CYGSEM_WALLCLOCK_SET_GET_MODE
+
+//-----------------------------------------------------------------------------
+// EOF wallclock_synth.cxx
diff --git a/ecos/packages/devs/watchdog/arm/aeb/current/ChangeLog b/ecos/packages/devs/watchdog/arm/aeb/current/ChangeLog
new file mode 100644
index 0000000..d14ecd5
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/aeb/current/ChangeLog
@@ -0,0 +1,33 @@
+2000-05-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/watchdog_aeb.cdl:
+ * src/watchdog_aeb.cxx:
+ Driver moved to devs/watchdog/arm/aeb. Stripped out
+ unrelated ChangeLog entries.
+
+1999-09-07 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/aeb1.cxx: [added]
+ Added watchdog driver for AEB-1 board.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/devs/watchdog/arm/aeb/current/cdl/watchdog_aeb.cdl b/ecos/packages/devs/watchdog/arm/aeb/current/cdl/watchdog_aeb.cdl
new file mode 100644
index 0000000..eeaa385
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/aeb/current/cdl/watchdog_aeb.cdl
@@ -0,0 +1,101 @@
+# ====================================================================
+#
+# watchdog_aeb.cdl
+#
+# eCos watchdog for ARM/AEB driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2000-05-31
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_ARM_AEB {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "AEB watchdog driver"
+ requires CYGPKG_HAL_ARM_AEB
+ requires CYGPKG_KERNEL
+ hardware
+ compile watchdog_aeb.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+ active_if CYGIMP_WATCHDOG_HARDWARE
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_ARM_AEB_OPTIONS {
+ display "AEB watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_AEB_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_AEB_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/watchdog/arm/aeb/current/src/watchdog_aeb.cxx b/ecos/packages/devs/watchdog/arm/aeb/current/src/watchdog_aeb.cxx
new file mode 100644
index 0000000..80fc7c7
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/aeb/current/src/watchdog_aeb.cxx
@@ -0,0 +1,160 @@
+//==========================================================================
+//
+// devs/watchdog/arm/aeb/watchdog_aeb.cxx
+//
+// Watchdog implementation for ARM AEB1 board (SHARP LH77790 CPU)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 1999-09-01
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the SHARP LH77790 watchdog timer.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h> // system configuration file
+#include <pkgconf/watchdog.h> // configuration for this package
+#include <pkgconf/kernel.h> // kernel config
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/kernel/instrmnt.h> // instrumentation
+
+#include <cyg/hal/hal_io.h> // IO register access
+
+#include <cyg/io/watchdog.hxx> // watchdog API
+
+// -------------------------------------------------------------------------
+// Register definitions
+#define CYGARC_REG_WATCHDOG_BASE 0xFFFFAC00
+#define CYGARC_REG_WATCHDOG_WDCTLR (CYGARC_REG_WATCHDOG_BASE+0x30)
+#define CYGARC_REG_WATCHDOG_WDCNTR (CYGARC_REG_WATCHDOG_BASE+0x34)
+
+// Control register bits
+#define CYGARC_REG_WATCHDOG_WDCTLR_EN 0x01 // enable
+#define CYGARC_REG_WATCHDOG_WDCTLR_RSP_NMF 0x00 // non-maskable fiq
+#define CYGARC_REG_WATCHDOG_WDCTLR_RSP_ER 0x04 // external reset
+#define CYGARC_REG_WATCHDOG_WDCTLR_RSP_SR 0x06 // system reset
+#define CYGARC_REG_WATCHDOG_WDCTLR_FRZ 0x08 // lock enable bit
+#define CYGARC_REG_WATCHDOG_WDCTLR_TOP_MASK 0x70 // time out period
+
+#define CYGARC_REG_WATCHDOG_WDCTLR_TOP_17 0x00 // 2^17
+#define CYGARC_REG_WATCHDOG_WDCTLR_TOP_17_P 5242880 // = 5.2ms
+
+#define CYGARC_REG_WATCHDOG_WDCTLR_TOP_25 0x40 // 2^25
+#define CYGARC_REG_WATCHDOG_WDCTLR_TOP_25_P 1342177300 // = 1.3421773s
+
+
+// -------------------------------------------------------------------------
+// Constructor
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ // No HW init.
+
+ resolution = CYGARC_REG_WATCHDOG_WDCTLR_TOP_25_P;
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Start the watchdog running.
+
+void
+Cyg_Watchdog::start()
+{
+ CYG_REPORT_FUNCTION();
+
+ // Clear the watchdog counter.
+ HAL_WRITE_UINT32(CYGARC_REG_WATCHDOG_WDCNTR, 0);
+
+ // Enable the watchdog (and lock/FRZ it).
+ HAL_WRITE_UINT8(CYGARC_REG_WATCHDOG_WDCTLR,
+ (CYGARC_REG_WATCHDOG_WDCTLR_TOP_25
+ | CYGARC_REG_WATCHDOG_WDCTLR_FRZ
+ | CYGARC_REG_WATCHDOG_WDCTLR_RSP_SR
+ | CYGARC_REG_WATCHDOG_WDCTLR_EN));
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Reset watchdog timer. This needs to be called regularly to prevent
+// the watchdog firing.
+
+void
+Cyg_Watchdog::reset()
+{
+ CYG_REPORT_FUNCTION();
+
+ HAL_WRITE_UINT32(CYGARC_REG_WATCHDOG_WDCNTR, 0);
+
+ CYG_REPORT_RETURN();
+}
+
+#if 0
+// -------------------------------------------------------------------------
+// Action which will do a board reset. Application can register this
+// action to get a board reset on watchdog timeout.
+
+void
+Cyg_Watchdog::reset_action(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ // Clear the watchdog counter.
+ HAL_WRITE_UINT32(CYGARC_REG_WATCHDOG_WDCNTR, 0);
+
+ // Enable the watchdog with the smallest timeout.
+ HAL_WRITE_UINT8(CYGARC_REG_WATCHDOG_WDCTLR,
+ (CYGARC_REG_WATCHDOG_WDCTLR_TOP_17
+ | CYGARC_REG_WATCHDOG_WDCTLR_FRZ
+ | CYGARC_REG_WATCHDOG_WDCTLR_RSP_SR
+ | CYGARC_REG_WATCHDOG_WDCTLR_EN));
+
+ CYG_REPORT_RETURN();
+}
+#endif
+
+// -------------------------------------------------------------------------
+// EOF watchdog_aeb.cxx
diff --git a/ecos/packages/devs/watchdog/arm/at91/current/ChangeLog b/ecos/packages/devs/watchdog/arm/at91/current/ChangeLog
new file mode 100644
index 0000000..1580453
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/at91/current/ChangeLog
@@ -0,0 +1,42 @@
+2009-04-28 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/watchdog_at91.cdl: Give CYGIMP_WATCHDOG_HARDWARE a default
+ value rather than a calculated value to accommodate other
+ implementations of CYGINT_WATCHDOG_IMPLEMENTATIONS.
+
+2004-10-4 Andrea Michelotti <amichelotti@atmel.com>
+
+ * src/watchdog_at91.cxx:
+ * cdl/watchdog_at91.cdl: added JTST support
+
+2003-05-12 Nick Garnett <nickg@balti.calivar.com>
+
+ * src/watchdog_at91.cxx:
+ * cdl/watchdog_at91.cdl: Modified driver to work for EB40, EB40A
+ and EB55 boards. Generally tidied up a little.
+
+2002-08-06 Thomas Koeller <thomas@koeller.dyndns.org>
+
+ * Added watchdog driver for ARM AT91 board.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/devs/watchdog/arm/at91/current/cdl/watchdog_at91.cdl b/ecos/packages/devs/watchdog/arm/at91/current/cdl/watchdog_at91.cdl
new file mode 100644
index 0000000..7e5b737
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/at91/current/cdl/watchdog_at91.cdl
@@ -0,0 +1,136 @@
+# ====================================================================
+#
+# watchdog_at91.cdl
+#
+# eCos watchdog for ARM AT91 driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): tkoeller
+# Contributors: tkoeller, nickg
+# Date: 2000-05-05
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_ARM_AT91 {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "ARM AT91 watchdog driver"
+ requires CYGPKG_HAL_ARM_AT91
+ requires CYGPKG_KERNEL
+ hardware
+ define_header devs_watchdog_arm_at91.h
+ compile watchdog_at91.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WATCHDOG_HARDWARE
+ description "
+ This package uses the watchdog device integrated
+ in the AT91 to execute a predefined action if the
+ application fails to call the reset function for
+ longer than a given timeout interval. This package
+ currently only supports the AT91x408xx, AT91M55800A and Diopsis
+ devices found on the Atmel EB40, EB40A, EB55 and JTST evaluation
+ boards. The AT91M42800 found on the EB42 is not supported
+ since it uses a totally different watchdog device."
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_option CYGNUM_DEVS_WATCHDOG_ARM_AT91_DESIRED_TIMEOUT_MS {
+ display "Desired timeout value"
+ flavor data
+ legal_values 1 to 2047
+ default_value 100
+ description "
+ This parameter controls the watchdog timeout interval.
+ Note that you may not get the exact value requested
+ here, the timeout interval may have to be adjusted
+ because of hardware limitations. The actual timeout
+ used will be the smallest possible value that is not
+ less than this parameter."
+ }
+
+ cdl_option CYGSEM_DEVS_WATCHDOG_ARM_AT91_RESET {
+ display "Generate reset on watchdog expiration"
+ flavor bool
+ default_value 1
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+ description "
+ Enabling this option changes the watchdog operation mode
+ to generate a system reset upon expiration instead of
+ invoking an application-defined action."
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_ARM_AT91_OPTIONS {
+ display "AT91 watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_AT91_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_AT91_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
+
+# EOF watchdog_at91.cdl
diff --git a/ecos/packages/devs/watchdog/arm/at91/current/src/watchdog_at91.cxx b/ecos/packages/devs/watchdog/arm/at91/current/src/watchdog_at91.cxx
new file mode 100644
index 0000000..e5830d3
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/at91/current/src/watchdog_at91.cxx
@@ -0,0 +1,245 @@
+//==========================================================================
+//
+// devs/watchdog/arm/at91/watchdog_at91.cxx
+//
+// Watchdog implementation for ARM AT91 CPU
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): tkoeller
+// Contributors: tkoeller, nickg
+// Date: 2002-05-05
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the ATMEL AT91 watchdog timer.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/infra.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/watchdog.h>
+#include <pkgconf/devs_watchdog_arm_at91.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/io/watchdog.hxx>
+
+#if !defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
+#include <cyg/hal/hal_platform_ints.h>
+#include <cyg/kernel/intr.hxx>
+#endif
+
+//==========================================================================
+
+#define MCLK_FREQUENCY_KHZ (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED/1000)
+#define MAX_TICKS 0x0000ffff
+#define BASE_TICKS (MCLK_FREQUENCY_KHZ * CYGNUM_DEVS_WATCHDOG_ARM_AT91_DESIRED_TIMEOUT_MS)
+
+#if defined(CYGHWR_HAL_ARM_AT91_R40008) || \
+ defined(CYGHWR_HAL_ARM_AT91_R40807)
+
+#if BASE_TICKS / 8 <= MAX_TICKS
+#define DIVIDER 0
+#define DIV_FACTOR 8
+#elif BASE_TICKS / 32 <= MAX_TICKS
+#define DIVIDER 1
+#define DIV_FACTOR 32
+#elif BASE_TICKS / 128 <= MAX_TICKS
+#define DIVIDER 2
+#define DIV_FACTOR 128
+#elif BASE_TICKS / 1024 <= MAX_TICKS
+#define DIVIDER 3
+#define DIV_FACTOR 1024
+#else
+#error Desired resolution beyond hardware capabilities
+#endif
+
+#elif defined(CYGHWR_HAL_ARM_AT91_M55800A)
+
+#if BASE_TICKS / 32 <= MAX_TICKS
+#define DIVIDER 0
+#define DIV_FACTOR 32
+#elif BASE_TICKS / 128 <= MAX_TICKS
+#define DIVIDER 1
+#define DIV_FACTOR 128
+#elif BASE_TICKS / 1024 <= MAX_TICKS
+#define DIVIDER 2
+#define DIV_FACTOR 1024
+#elif BASE_TICKS / 4096 <= MAX_TICKS
+#define DIVIDER 3
+#define DIV_FACTOR 4096
+#else
+#error Desired resolution beyond hardware capabilities
+#endif
+#elif defined(CYGHWR_HAL_ARM_AT91_JTST)
+#if BASE_TICKS / 32 <= MAX_TICKS
+#define DIVIDER 0
+#define DIV_FACTOR 32
+#elif BASE_TICKS / 128 <= MAX_TICKS
+#define DIVIDER 1
+#define DIV_FACTOR 128
+#elif BASE_TICKS / 1024 <= MAX_TICKS
+#define DIVIDER 2
+#define DIV_FACTOR 1024
+#elif BASE_TICKS / 2046 <= MAX_TICKS
+#define DIVIDER 3
+#define DIV_FACTOR 2046
+#else
+#error Desired resolution beyond hardware capabilities
+#endif
+
+#endif
+
+#define TICKS ((BASE_TICKS / DIV_FACTOR) | 0xfff)
+#define RESOLUTION ((cyg_uint64) (TICKS * DIV_FACTOR ) * 1000000 / MCLK_FREQUENCY_KHZ)
+
+//==========================================================================
+
+#if defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
+
+#define OMRVAL (AT91_WD_OMR_OKEY | AT91_WD_OMR_RSTEN | AT91_WD_OMR_WDEN)
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+ resolution = RESOLUTION;
+ CYG_REPORT_RETURN();
+}
+
+#else /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
+
+//==========================================================================
+
+#define OMRVAL (AT91_WD_OMR_OKEY | AT91_WD_OMR_IRQEN | AT91_WD_OMR_WDEN)
+#define INT_PRIO 7
+
+//==========================================================================
+
+static Cyg_Watchdog *wd;
+
+//==========================================================================
+
+static cyg_uint32
+isr(cyg_vector vector, CYG_ADDRWORD data)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG2XV(vector, data);
+
+ wd->trigger();
+ Cyg_Interrupt::acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
+ CYG_REPORT_RETVAL(Cyg_Interrupt::HANDLED);
+ return Cyg_Interrupt::HANDLED;
+}
+
+//==========================================================================
+
+static Cyg_Interrupt wdint(
+ CYGNUM_HAL_INTERRUPT_WATCHDOG,
+ INT_PRIO,
+ 0,
+ isr,
+ NULL
+ );
+
+//==========================================================================
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ wd = this;
+ resolution = RESOLUTION;
+ wdint.configure_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG, false, true);
+ wdint.attach();
+ wdint.acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
+ wdint.unmask_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
+ CYG_REPORT_RETURN();
+}
+
+#endif /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
+
+//==========================================================================
+/*
+ * Reset watchdog timer. This needs to be called regularly to prevent
+ * the watchdog from firing.
+ */
+
+void
+Cyg_Watchdog::reset(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ /* Write magic code to reset the watchdog. */
+ HAL_WRITE_UINT32(AT91_WD + AT91_WD_CR, AT91_WD_CR_RSTKEY);
+ CYG_REPORT_RETURN();
+}
+
+//==========================================================================
+/*
+ * Start watchdog to generate a hardware reset
+ * or interrupt when expiring.
+ */
+
+void
+Cyg_Watchdog::start(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, AT91_WD_OMR_OKEY);
+ HAL_WRITE_UINT32(
+ AT91_WD + AT91_WD_CMR,
+ AT91_WD_CMR_CKEY | ((TICKS >> 10) & AT91_WD_CMR_HPCV) | DIVIDER
+ );
+ HAL_WRITE_UINT32(AT91_WD + AT91_WD_CR, AT91_WD_CR_RSTKEY);
+ HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, OMRVAL);
+ CYG_REPORT_RETURN();
+}
+
+//==========================================================================
+// End of watchdog_at91.cxx
diff --git a/ecos/packages/devs/watchdog/arm/at91wdtc/current/ChangeLog b/ecos/packages/devs/watchdog/arm/at91wdtc/current/ChangeLog
new file mode 100644
index 0000000..faa208d
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/at91wdtc/current/ChangeLog
@@ -0,0 +1,38 @@
+2009-04-28 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/watchdog_at91wdtc.cdl: Give CYGIMP_WATCHDOG_HARDWARE a default
+ value rather than a calculated value to accommodate other
+ implementations of CYGINT_WATCHDOG_IMPLEMENTATIONS.
+
+2009-02-04 Bart Veer <bartv@ecoscentric.com>
+
+ * src/watchdog_at91wdtc.cxx: switch init priority to
+ CYG_INIT_INTERRUPTS.
+
+2006-02-18 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * Added watchdog driver for ARM AT91 devices which have the
+ Watchdog Timer Controller as opposed to the older devices which
+ have the Watchdog Timer Interface.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/devs/watchdog/arm/at91wdtc/current/cdl/watchdog_at91wdtc.cdl b/ecos/packages/devs/watchdog/arm/at91wdtc/current/cdl/watchdog_at91wdtc.cdl
new file mode 100644
index 0000000..7a113ce
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/at91wdtc/current/cdl/watchdog_at91wdtc.cdl
@@ -0,0 +1,146 @@
+# ====================================================================
+#
+# watchdog_at91wdtc.cdl
+#
+# eCos watchdog for ARM AT91 WDTC driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): tkoeller
+# Contributors: tkoeller, nickg, asl
+# Date: 2006-02-18
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "ARM AT91 WDTC watchdog driver"
+ requires CYGPKG_HAL_ARM_AT91
+ requires CYGPKG_KERNEL
+ hardware
+ define_header devs_watchdog_arm_at91wdtc.h
+ compile watchdog_at91wdtc.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WATCHDOG_HARDWARE
+ description "
+ This package uses the watchdog device integrated
+ in the AT91 to execute a predefined action if the
+ application fails to call the reset function for
+ longer than a given timeout interval. This package
+ currently only supports the AT91SAM7S device which
+ use the Watchdog Timer Controller."
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_option CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_DESIRED_TIMEOUT_MS {
+ display "Desired timeout value"
+ flavor data
+ default_value 1000
+ description "
+ This parameter controls the watchdog timeout interval.
+ Note that you may not get the exact value requested
+ here, the timeout interval may have to be adjusted
+ because of hardware limitations. The actual timeout
+ used will be the smallest possible value that is not
+ less than this parameter. Since the timeout is derived
+ from the LC based slow clock don't expect great accuracy.
+ On my board a 1000ms timeout actually goes off after 550ms!"
+ }
+
+ cdl_option CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_TIMEOUT_VALUE {
+ display "Calculated timeout value"
+ flavor data
+ calculated { (CYGNUM_HAL_ARM_AT91_SLOW_CLOCK / 128) *
+ (CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_DESIRED_TIMEOUT_MS / 1000)
+ }
+ legal_values { 0 to 4096 }
+ description "
+ This is the calculated value that will be placed into
+ watchdog counter timer."
+ }
+
+ cdl_option CYGSEM_DEVS_WATCHDOG_ARM_AT91WDTC_RESET {
+ display "Generate reset on watchdog expiration"
+ flavor bool
+ default_value 1
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+ description "
+ Enabling this option changes the watchdog operation mode
+ to generate a system reset upon expiration instead of
+ invoking an application-defined action."
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC_OPTIONS {
+ display "AT91 watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_AT91WDTC_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
+# EOF watchdog_at91WDTC.cdl
diff --git a/ecos/packages/devs/watchdog/arm/at91wdtc/current/src/watchdog_at91wdtc.cxx b/ecos/packages/devs/watchdog/arm/at91wdtc/current/src/watchdog_at91wdtc.cxx
new file mode 100644
index 0000000..34bc10b
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/at91wdtc/current/src/watchdog_at91wdtc.cxx
@@ -0,0 +1,198 @@
+//==========================================================================
+//
+// devs/watchdog/arm/at91/watchdog_at91wdtc.cxx
+//
+// Watchdog implementation for ARM AT91 CPUs using the WDTC
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): tkoeller
+// Contributors: tkoeller, nickg, asl
+// Date: 2006-02-18
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the ATMEL AT91 watchdog timer controller.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/infra.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/watchdog.h>
+#include <pkgconf/devs_watchdog_arm_at91wdtc.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/io/watchdog.hxx>
+
+#include <cyg/infra/diag.h>
+
+#if !defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
+#include <cyg/hal/hal_platform_ints.h>
+#include <cyg/kernel/intr.hxx>
+#endif
+
+//==========================================================================
+
+#if defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
+
+#define MRVAL (AT91_WDTC_WDMR_RSTEN | AT91_WDTC_WDMR_DBGHLT)
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+ resolution = CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_DESIRED_TIMEOUT_MS * 1000000;
+ CYG_REPORT_RETURN();
+}
+
+#else /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
+
+//==========================================================================
+
+#define MRVAL (AT91_WDTC_WDMR_FIEN | AT91_WDTC_WDMR_DBGHLT)
+#define INT_PRIO 7
+
+//==========================================================================
+
+static Cyg_Watchdog *wd;
+
+//==========================================================================
+
+static cyg_uint32
+isr(cyg_vector vector, CYG_ADDRWORD data)
+{
+ cyg_uint32 sr;
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG2XV(vector, data);
+
+ // Read the status register to clear the interrupt
+ HAL_READ_UINT32(AT91_WDTC + AT91_WDTC_WDSR, sr);
+
+ wd->trigger();
+ Cyg_Interrupt::acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WDTC);
+ CYG_REPORT_RETVAL(Cyg_Interrupt::HANDLED);
+ return Cyg_Interrupt::HANDLED;
+}
+
+//==========================================================================
+
+static CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_INTERRUPTS)
+ Cyg_Interrupt wdint(
+ CYGNUM_HAL_INTERRUPT_WDTC,
+ INT_PRIO,
+ 0,
+ isr,
+ NULL
+ );
+
+//==========================================================================
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ wd = this;
+
+ wdint.attach();
+ wdint.acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WDTC);
+ wdint.unmask_interrupt(CYGNUM_HAL_INTERRUPT_WDTC);
+ resolution = CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_DESIRED_TIMEOUT_MS * 1000000;
+ CYG_REPORT_RETURN();
+}
+
+#endif /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
+
+//==========================================================================
+/*
+ * Reset watchdog timer. This needs to be called regularly to prevent
+ * the watchdog from firing.
+ */
+
+void
+Cyg_Watchdog::reset(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ /* Write magic code to reset the watchdog. */
+ HAL_WRITE_UINT32(AT91_WDTC + AT91_WDTC_WDCR,
+ AT91_WDTC_WDCR_RELOAD | AT91_WDTC_WDCR_KEY);
+
+ CYG_REPORT_RETURN();
+}
+
+//==========================================================================
+/*
+ * Start watchdog to generate a hardware reset
+ * or interrupt when expiring.
+ */
+
+void
+Cyg_Watchdog::start(void)
+{
+ cyg_uint32 val, val1;
+
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ val = (MRVAL | CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_TIMEOUT_VALUE |
+ (CYGNUM_DEVS_WATCHDOG_ARM_AT91WDTC_TIMEOUT_VALUE <<
+ AT91_WDTC_WDMR_WDD_SHIFT));
+
+ HAL_WRITE_UINT32(AT91_WDTC + AT91_WDTC_WDMR, val);
+ HAL_READ_UINT32(AT91_WDTC + AT91_WDTC_WDMR, val1);
+
+ // If this assert goes if it probably means something else has
+ // already programmed the watchdog. The mode register is only
+ // writeable once and once it is set it can only be reset by a
+ // processor reset.
+ CYG_ASSERT(val == val1, "Unable to configure watchdog");
+
+ CYG_REPORT_RETURN();
+}
+
+//==========================================================================
+// End of watchdog_at91.cxx
diff --git a/ecos/packages/devs/watchdog/arm/ebsa285/current/ChangeLog b/ecos/packages/devs/watchdog/arm/ebsa285/current/ChangeLog
new file mode 100644
index 0000000..ae4179a
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/ebsa285/current/ChangeLog
@@ -0,0 +1,33 @@
+2000-05-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/watchdog_ebsa285.cdl:
+ * src/watchdog_ebsa285.cxx:
+ Driver moved to devs/watchdog/arm/ebsa285. Stripped out
+ unrelated ChangeLog entries.
+
+1999-08-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/ebsa285.cxx:
+ Added watchdog device for 21285.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/devs/watchdog/arm/ebsa285/current/cdl/watchdog_ebsa285.cdl b/ecos/packages/devs/watchdog/arm/ebsa285/current/cdl/watchdog_ebsa285.cdl
new file mode 100644
index 0000000..632e48f
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/ebsa285/current/cdl/watchdog_ebsa285.cdl
@@ -0,0 +1,101 @@
+# ====================================================================
+#
+# watchdog_ebsa285.cdl
+#
+# eCos watchdog for ARM/EBSA285 driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2000-05-31
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_ARM_EBSA285 {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "EBSA285 watchdog driver"
+ requires CYGPKG_HAL_ARM_EBSA285
+ requires CYGPKG_KERNEL
+ hardware
+ compile watchdog_ebsa285.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+ active_if CYGIMP_WATCHDOG_HARDWARE
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_ARM_EBSA285_OPTIONS {
+ display "EBSA285 watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_EBSA285_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_EBSA285_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/watchdog/arm/ebsa285/current/src/watchdog_ebsa285.cxx b/ecos/packages/devs/watchdog/arm/ebsa285/current/src/watchdog_ebsa285.cxx
new file mode 100644
index 0000000..06f5527
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/ebsa285/current/src/watchdog_ebsa285.cxx
@@ -0,0 +1,150 @@
+//==========================================================================
+//
+// watchdog/ebsa285.cxx
+//
+// Watchdog implementation for Intel EBSA-285 StronARM board
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov (based on the MN10300 watchdog code by nickg)
+// Contributors: jskov, nickg
+// Date: 1999-08-26
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the EBSA285/21285 hardware watchdog timer.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h> // system configuration file
+#include <pkgconf/watchdog.h> // configuration for this package
+#include <pkgconf/kernel.h> // kernel config
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/kernel/instrmnt.h> // instrumentation
+
+#include <cyg/hal/hal_io.h> // IO register access
+
+#include <cyg/io/watchdog.hxx> // watchdog API
+
+// -------------------------------------------------------------------------
+// 21285 watchdog works by letting timer4 run; if it ever underflows,
+// it resets the system.
+// Timer 4 is set to run at fclk_in/16 = 50MHz/16 = 3.125MHz
+// The timer register is 24 bits, so it can easily hold a value that
+// gives a 1s timeout.
+#define WATCHDOG_TIMER_TICKS 3125000
+#define WATCHDOG_RESOLUTION (1000000000)
+
+// -------------------------------------------------------------------------
+// Constructor
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ // HW doesn't need init
+
+ resolution = WATCHDOG_RESOLUTION;
+
+ CYG_REPORT_RETURN();
+}
+
+
+
+// -------------------------------------------------------------------------
+// Start the watchdog running.
+
+void
+Cyg_Watchdog::start(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ // Init the watchdog timer.
+ HAL_WRITE_UINT32(SA110_TIMER4_LOAD, WATCHDOG_TIMER_TICKS);
+ HAL_WRITE_UINT32(SA110_TIMER4_CLEAR, 0);
+ HAL_WRITE_UINT32(SA110_TIMER4_CONTROL,
+ SA110_TIMER_CONTROL_ENABLE|SA110_TIMER_CONTROL_SCALE_16);
+ // Enable the watchdog.
+ cyg_uint32 ctrl;
+ HAL_READ_UINT32(SA110_CONTROL, ctrl);
+ ctrl |= SA110_CONTROL_WATCHDOG;
+ HAL_WRITE_UINT32(SA110_CONTROL, ctrl);
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Reset watchdog timer. This needs to be called regularly to prevent
+// the watchdog firing.
+
+void
+Cyg_Watchdog::reset()
+{
+ CYG_REPORT_FUNCTION();
+
+ HAL_WRITE_UINT32(SA110_TIMER4_LOAD, WATCHDOG_TIMER_TICKS);
+
+ CYG_REPORT_RETURN();
+}
+
+#if 0
+// -------------------------------------------------------------------------
+// Trigger the watchdog as if the timer had expired.
+
+void
+Cyg_Watchdog::reset_action(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ // Init the watchdog timer.
+ HAL_WRITE_UINT32(SA110_TIMER4_LOAD, 1);
+ HAL_WRITE_UINT32(SA110_TIMER4_CONTROL, SA110_TIMER_CONTROL_ENABLE);
+ // Enable the watchdog.
+ cyg_uint32 ctrl;
+ HAL_READ_UINT32(SA110_CONTROL, ctrl);
+ ctrl |= SA110_CONTROL_WATCHDOG;
+ HAL_WRITE_UINT32(SA110_CONTROL, ctrl);
+
+ CYG_REPORT_RETURN();
+}
+#endif
+
+
+// -------------------------------------------------------------------------
+// EOF watchdog_ebsa285.cxx
diff --git a/ecos/packages/devs/watchdog/arm/lpc2xxx/current/ChangeLog b/ecos/packages/devs/watchdog/arm/lpc2xxx/current/ChangeLog
new file mode 100644
index 0000000..cabbe95
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/lpc2xxx/current/ChangeLog
@@ -0,0 +1,52 @@
+2009-04-28 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/watchdog_lpc2xxx.cdl: Give CYGIMP_WATCHDOG_HARDWARE a default
+ value rather than a calculated value to accommodate other
+ implementations of CYGINT_WATCHDOG_IMPLEMENTATIONS.
+
+2009-02-09 Bart Veer <bartv@ecoscentric.com>
+
+ * src/watchdog_lpc2xxx.cxx: switch init priority to
+ CYG_INIT_INTERRUPTS.
+
+2008-11-23 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+ Andrew Lunn <andrew@lunn.ch>
+
+ * src/watchdog_lpc2xxx.cxx: Since CYG_HAL_ARM_LPC2XXX_PCLK()
+ macro has been removed from lpc2xxx_misc.h, insert a definition here.
+
+2008-09-03 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * src/watchdog_lpc2xxx.cxx: Since CYG_HAL_ARM_LPC2XXX_PCLK()
+ macro had been gone away from lpc2xxx_misc.h, it is replaced by
+ an equal CYGNUM_HAL_ARM_LPC2XXX_PCLK constant.
+
+2007-08-19 Sergei Gavrikov <sg@sgs.gomel.by>
+
+ * src/watchdog_lpc2xxx.cxx: Fixed to work properly in WDINT mode.
+
+2004-10-04 Jani Monoses <jani@iv.ro>
+
+ * Added watchdog driver for ARM LPC2XXX based on the AT91 code.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/devs/watchdog/arm/lpc2xxx/current/cdl/watchdog_lpc2xxx.cdl b/ecos/packages/devs/watchdog/arm/lpc2xxx/current/cdl/watchdog_lpc2xxx.cdl
new file mode 100644
index 0000000..a2c50a1
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/lpc2xxx/current/cdl/watchdog_lpc2xxx.cdl
@@ -0,0 +1,132 @@
+# ====================================================================
+#
+# watchdog_lpc2xxx.cdl
+#
+# eCos watchdog for ARM LPC2XXX driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): tkoeller
+# Contributors: tkoeller, nickg
+# Date: 2000-05-05
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_ARM_LPC2XXX {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "ARM LPC2XXX watchdog driver"
+ requires CYGPKG_HAL_ARM_LPC2XXX
+ requires CYGPKG_KERNEL
+ hardware
+ define_header devs_watchdog_arm_lpc2xxx.h
+ compile watchdog_lpc2xxx.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WATCHDOG_HARDWARE
+ description "
+ This package uses the watchdog device integrated
+ in the LPC2XXX to execute a predefined action if the
+ application fails to call the reset function for
+ longer than a given timeout interval."
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_option CYGNUM_DEVS_WATCHDOG_ARM_LPC2XXX_DESIRED_TIMEOUT_MS {
+ display "Desired timeout value"
+ flavor data
+ legal_values 1 to 2047
+ default_value 100
+ description "
+ This parameter controls the watchdog timeout interval.
+ Note that you may not get the exact value requested
+ here, the timeout interval may have to be adjusted
+ because of hardware limitations. The actual timeout
+ used will be the smallest possible value that is not
+ less than this parameter."
+ }
+
+ cdl_option CYGSEM_DEVS_WATCHDOG_ARM_LPC2XXX_RESET {
+ display "Generate reset on watchdog expiration"
+ flavor bool
+ default_value 1
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+ description "
+ Enabling this option changes the watchdog operation mode
+ to generate a system reset upon expiration instead of
+ invoking an application-defined action."
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_ARM_LPC2XXX_OPTIONS {
+ display "LPC2XXX watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_LPC2XXX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_LPC2XXX_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
+
+# EOF watchdog_lpc2xxx.cdl
diff --git a/ecos/packages/devs/watchdog/arm/lpc2xxx/current/src/watchdog_lpc2xxx.cxx b/ecos/packages/devs/watchdog/arm/lpc2xxx/current/src/watchdog_lpc2xxx.cxx
new file mode 100644
index 0000000..a1240fa
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/lpc2xxx/current/src/watchdog_lpc2xxx.cxx
@@ -0,0 +1,199 @@
+//==========================================================================
+//
+// devs/watchdog/arm/lpc2xxx/watchdog_lpc2xxx.cxx
+//
+// Watchdog implementation for ARM LPC2XXX CPU
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jani
+// Contributors: tkoeller, nickg
+// Date: 2004-10-05
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the Philips LPC2XXX watchdog timer.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/infra.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/watchdog.h>
+#include <pkgconf/devs_watchdog_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/io/watchdog.hxx>
+
+#include <cyg/hal/hal_var_ints.h>
+#if !defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
+#include <cyg/kernel/intr.hxx>
+#endif
+
+//==========================================================================
+
+#define TICKS (CYGNUM_HAL_ARM_LPC2XXX_PCLK/4000 * \
+ CYGNUM_DEVS_WATCHDOG_ARM_LPC2XXX_DESIRED_TIMEOUT_MS)
+
+#define RESOLUTION CYGNUM_DEVS_WATCHDOG_ARM_LPC2XXX_DESIRED_TIMEOUT_MS*1000000
+
+//==========================================================================
+
+#if defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
+
+#define MODVAL (CYGARC_HAL_LPC2XXX_REG_WDMOD_WDEN | \
+ CYGARC_HAL_LPC2XXX_REG_WDMOD_WDRESET)
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+ resolution = RESOLUTION;
+ CYG_REPORT_RETURN();
+}
+
+#else /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
+
+//==========================================================================
+
+#define MODVAL (CYGARC_HAL_LPC2XXX_REG_WDMOD_WDEN | \
+ CYGARC_HAL_LPC2XXX_REG_WDMOD_WDINT)
+#define INT_PRIO 7
+
+//==========================================================================
+
+static Cyg_Watchdog *wd;
+
+//==========================================================================
+
+static cyg_uint32
+isr(cyg_vector vector, CYG_ADDRWORD data)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG2XV(vector, data);
+
+ wd->trigger();
+ Cyg_Interrupt::acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WD);
+ CYG_REPORT_RETVAL(Cyg_Interrupt::HANDLED);
+ return Cyg_Interrupt::HANDLED;
+}
+
+//==========================================================================
+
+static CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_INTERRUPTS)
+ Cyg_Interrupt wdint(
+ CYGNUM_HAL_INTERRUPT_WD,
+ INT_PRIO,
+ 0,
+ isr,
+ NULL
+ );
+
+//==========================================================================
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ wd = this;
+ resolution = RESOLUTION;
+ wdint.attach();
+ wdint.acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WD);
+ wdint.unmask_interrupt(CYGNUM_HAL_INTERRUPT_WD);
+ CYG_REPORT_RETURN();
+}
+
+#endif /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
+
+//==========================================================================
+/*
+ * Reset watchdog timer. This needs to be called regularly to prevent
+ * the watchdog from firing.
+ */
+
+void
+Cyg_Watchdog::reset(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ /* Feed magic values to reset the watchdog. */
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE +
+ CYGARC_HAL_LPC2XXX_REG_WDFEED,
+ CYGARC_HAL_LPC2XXX_REG_WDFEED_MAGIC1);
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE +
+ CYGARC_HAL_LPC2XXX_REG_WDFEED,
+ CYGARC_HAL_LPC2XXX_REG_WDFEED_MAGIC2);
+ CYG_REPORT_RETURN();
+}
+
+//==========================================================================
+/*
+ * Start watchdog to generate a hardware reset
+ * or interrupt when expiring.
+ */
+
+void
+Cyg_Watchdog::start(void)
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE +
+ CYGARC_HAL_LPC2XXX_REG_WDTC, TICKS);
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE +
+ CYGARC_HAL_LPC2XXX_REG_WDMOD, MODVAL);
+ /* Feed magic values to reset the watchdog. */
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE +
+ CYGARC_HAL_LPC2XXX_REG_WDFEED,
+ CYGARC_HAL_LPC2XXX_REG_WDFEED_MAGIC1);
+ HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE +
+ CYGARC_HAL_LPC2XXX_REG_WDFEED,
+ CYGARC_HAL_LPC2XXX_REG_WDFEED_MAGIC2);
+ CYG_REPORT_RETURN();
+}
+
+//==========================================================================
+// End of watchdog_lpc2xxx.cxx
diff --git a/ecos/packages/devs/watchdog/arm/sa11x0/current/ChangeLog b/ecos/packages/devs/watchdog/arm/sa11x0/current/ChangeLog
new file mode 100644
index 0000000..7159705
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/sa11x0/current/ChangeLog
@@ -0,0 +1,39 @@
+2001-02-28 Hugo Tyson <hmt@redhat.com>
+
+ * src/watchdog_sa11x0.cxx: New file.
+ * cdl/watchdog_sa11x0.cdl: New file.
+ Copied from those referred to below.
+
+2000-05-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/watchdog_ebsa285.cdl:
+ * src/watchdog_ebsa285.cxx:
+ Driver moved to devs/watchdog/arm/ebsa285. Stripped out
+ unrelated ChangeLog entries.
+
+1999-08-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/ebsa285.cxx:
+ Added watchdog device for 21285.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/devs/watchdog/arm/sa11x0/current/cdl/watchdog_sa11x0.cdl b/ecos/packages/devs/watchdog/arm/sa11x0/current/cdl/watchdog_sa11x0.cdl
new file mode 100644
index 0000000..e375964
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/sa11x0/current/cdl/watchdog_sa11x0.cdl
@@ -0,0 +1,101 @@
+# ====================================================================
+#
+# watchdog_sa11x0.cdl
+#
+# eCos watchdog for ARM/SA11X0 driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: hmt, jskov
+# Date: 2001-02-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_ARM_SA11X0 {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "SA11X0 watchdog driver"
+ requires CYGPKG_HAL_ARM_SA11X0
+ requires CYGPKG_KERNEL
+ hardware
+ compile watchdog_sa11x0.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+ active_if CYGIMP_WATCHDOG_HARDWARE
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_ARM_SA11X0_OPTIONS {
+ display "SA11X0 watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_SA11X0_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_ARM_SA11X0_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/watchdog/arm/sa11x0/current/src/watchdog_sa11x0.cxx b/ecos/packages/devs/watchdog/arm/sa11x0/current/src/watchdog_sa11x0.cxx
new file mode 100644
index 0000000..1652676
--- /dev/null
+++ b/ecos/packages/devs/watchdog/arm/sa11x0/current/src/watchdog_sa11x0.cxx
@@ -0,0 +1,146 @@
+//==========================================================================
+//
+// watchdog/sa11x0.cxx
+//
+// Watchdog implementation for StrongARM SA11x0s
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt, jskov (based on the MN10300 watchdog code by nickg)
+// Contributors: jskov, nickg
+// Date: 2001-02-27
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the SA11X0 hardware watchdog timer.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h> // system configuration file
+#include <pkgconf/watchdog.h> // configuration for this package
+#include <pkgconf/kernel.h> // kernel config
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/kernel/instrmnt.h> // instrumentation
+
+#include <cyg/hal/hal_io.h> // IO register access
+#include <cyg/hal/hal_intr.h> // Interrupts
+#include <cyg/hal/hal_sa11x0.h> // IO registers per se
+
+#include <cyg/io/watchdog.hxx> // watchdog API
+
+// -------------------------------------------------------------------------
+// SA11x0 watchdog works by enabling the watchdog (duh!) which means that
+// when OS Timer Match Register #3 "OSMR3" compares equal to the 3.6864MHz
+// clock in OSCR, then the system resets.
+//
+// To stay ahead of this, we must repeatedly set OSMR3 to OSCR + K where K
+// is the watchdog timeout. This REQUIRES that the OSCR be freerunning.
+//
+// OSCR runs at 3.6864MHz, so one second is 3686400 ticks.
+//
+// The match register is 32 bits, and wraps as an int32 does (the
+// comparison is exact, so you don't need to take special care.) So we can
+// literally do the addition in the obvious way.
+
+#define WATCHDOG_TIMER_TICKS 3686400
+#define WATCHDOG_RESOLUTION (1000000000)
+
+// -------------------------------------------------------------------------
+// Constructor
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ // HW doesn't need init
+
+ resolution = WATCHDOG_RESOLUTION;
+
+ CYG_REPORT_RETURN();
+}
+
+
+
+// -------------------------------------------------------------------------
+// Start the watchdog running.
+
+void
+Cyg_Watchdog::start(void)
+{
+ int old;
+ CYG_REPORT_FUNCTION();
+
+ HAL_DISABLE_INTERRUPTS( old );
+
+ // Init the watchdog timer.
+ *SA11X0_OSMR3 = *SA11X0_OSCR + WATCHDOG_TIMER_TICKS;
+ *SA11X0_OSSR = SA11X0_OSSR_TIMER3; // Ack any pending intr
+ *SA11X0_OIER |= SA11X0_OIER_TIMER3; // Enable interrupt is necessary
+
+ CYG_ASSERT( *SA11X0_OSCR < *SA11X0_OSMR3 ||
+ *SA11X0_OSMR3 <= WATCHDOG_TIMER_TICKS, "Watchdog wierdness" );
+
+ // Enable the watchdog.
+ *SA11X0_OWER = SA11X0_OWER_ENABLE;
+
+ HAL_RESTORE_INTERRUPTS( old );
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Reset watchdog timer. This needs to be called regularly to prevent
+// the watchdog firing.
+
+void
+Cyg_Watchdog::reset()
+{
+ CYG_REPORT_FUNCTION();
+
+ *SA11X0_OSMR3 = *SA11X0_OSCR + WATCHDOG_TIMER_TICKS;
+
+ CYG_ASSERT( *SA11X0_OSCR < *SA11X0_OSMR3 ||
+ *SA11X0_OSMR3 <= WATCHDOG_TIMER_TICKS, "Watchdog wierdness" );
+
+ CYG_REPORT_RETURN();
+}
+
+
+// -------------------------------------------------------------------------
+// EOF watchdog_sa11x0.cxx
diff --git a/ecos/packages/devs/watchdog/h8300/h8300h/current/ChangeLog b/ecos/packages/devs/watchdog/h8300/h8300h/current/ChangeLog
new file mode 100644
index 0000000..29f6be6
--- /dev/null
+++ b/ecos/packages/devs/watchdog/h8300/h8300h/current/ChangeLog
@@ -0,0 +1,29 @@
+2005-01-27 Yoshinori Sato <ysato@users.sourceforge.jp>
+
+ * src/watchdog_h8300.cxx: add include header
+
+2002-08-14 Yoshinori Sato <qzb04471@nifty.ne.jp>
+
+ * New package.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/devs/watchdog/h8300/h8300h/current/cdl/watchdog_h8300h.cdl b/ecos/packages/devs/watchdog/h8300/h8300h/current/cdl/watchdog_h8300h.cdl
new file mode 100644
index 0000000..a8767b6
--- /dev/null
+++ b/ecos/packages/devs/watchdog/h8300/h8300h/current/cdl/watchdog_h8300h.cdl
@@ -0,0 +1,102 @@
+# ====================================================================
+#
+# watchdog_h8300h.cdl
+#
+# eCos watchdog for the Hitachi H8/300H driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): ysato
+# Contributors: ysato
+# Date: 2002-04-29
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_H8300_H8300H {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "H8/300H watchdog driver"
+ requires CYGPKG_HAL_H8300_H8300H
+ hardware
+ compile watchdog_h8300h.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+ active_if CYGIMP_WATCHDOG_HARDWARE
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_H8300_H8300H_OPTIONS {
+ display "H8/300H watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_H8300_H8300H_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_H8300_H8300H_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
+
+# EOF watchdog_h8300h.cdl
diff --git a/ecos/packages/devs/watchdog/h8300/h8300h/current/src/watchdog_h8300h.cxx b/ecos/packages/devs/watchdog/h8300/h8300h/current/src/watchdog_h8300h.cxx
new file mode 100644
index 0000000..51d2f43
--- /dev/null
+++ b/ecos/packages/devs/watchdog/h8300/h8300h/current/src/watchdog_h8300h.cxx
@@ -0,0 +1,112 @@
+//==========================================================================
+//
+// devs/watchdog/h8300/h83000/watchdog_h8300.cxx
+//
+// Watchdog implementation for Hitachi H8/300H CPUs
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): yoshinori sato
+// Contributors: yoshinori sato
+// Date: 2002-04-29
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the Hitachi H8/300H watchdog timer.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h> // system configuration file
+#include <pkgconf/watchdog.h> // configuration for this package
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h> // IO register access
+#include <cyg/hal/mod_regs_wdt.h> // watchdog register definitions
+
+#include <cyg/io/watchdog.hxx> // watchdog API
+
+// -------------------------------------------------------------------------
+// Constructor
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ // No hardware init needed.
+
+ resolution = CYGARC_WDT_PERIOD;
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Start the watchdog running.
+
+void
+Cyg_Watchdog::start()
+{
+ CYG_REPORT_FUNCTION();
+
+ //Stop WDT
+ HAL_WRITE_UINT16(CYGARC_TCSR,CYGARC_TCSR_MAGIC);
+ //Clear WDT Count
+ HAL_WRITE_UINT16(CYGARC_TCSR,CYGARC_TCNT_MAGIC);
+ //Start WDT
+ HAL_WRITE_UINT16(CYGARC_TCSR,CYGARC_TCSR_MAGIC|
+ CYGARC_WDT_WT|CYGARC_WDT_TME|CYGARC_WDT_CKS);
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Reset watchdog timer. This needs to be called regularly to prevent
+// the watchdog firing.
+
+void
+Cyg_Watchdog::reset()
+{
+ CYG_REPORT_FUNCTION();
+
+ HAL_WRITE_UINT16(CYGARC_TCSR,CYGARC_TCNT_MAGIC);
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// EOF watchdog_h8300.cxx
diff --git a/ecos/packages/devs/watchdog/mn10300/mn10300/current/ChangeLog b/ecos/packages/devs/watchdog/mn10300/mn10300/current/ChangeLog
new file mode 100644
index 0000000..90c8bbc
--- /dev/null
+++ b/ecos/packages/devs/watchdog/mn10300/mn10300/current/ChangeLog
@@ -0,0 +1,79 @@
+2000-05-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/watchdog_mn10300.cdl:
+ * src/watchdog_mn10300.cxx:
+ Driver moved to devs/watchdog/mn10300/mn10300. Stripped out
+ unrelated ChangeLog entries.
+
+1999-08-24 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300.cxx: Turn watchdog off in Cyg_Watchdog::trigger() to
+ prevent it repeating.
+
+1999-08-18 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300.cxx:
+ Added support for AM33 variant. Since the AM33 can only provide a
+ maximum watchdog cycle time of 621ms, this has motiviated the
+ addition of the get_resolution() call described above.
+
+1999-07-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/mn10300.cxx:
+ Include pkgconf/kernel.h.
+
+1999-02-20 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300.cxx:
+ Change CYG_VECTOR_WATCHDOG to CYGNUM_HAL_INTERRUPT_WATCHDOG in line
+ with HAL changes.
+ General QA improvements
+
+Tue Oct 20 15:52:46 1998 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/mn10300.cxx:
+ Include <pkgconf/watchdog.h> so that we get CYGIMP_WATCHDOG_EMULATE
+ defined appropriately
+
+1998-09-01 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/mn10300.cxx:
+ Added include for <cyg/kernel/sched.inl>, for scheduler lock and
+ unlock functions.
+
+1998-07-31 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ Added mn10300.cxx to COMPILE list.
+
+ * src/mn10300.cxx:
+ Completed implementation using MN10300 watchdog timer.
+
+ * include/watchdog.hxx:
+ Renamed 'register' functions to 'install'. Added install() and
+ uninstall() to Cyg_Watchdog_Action class.
+
+ * include/pkgconf/watchdog.h:
+ Added this file to contain watchdog config options.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/devs/watchdog/mn10300/mn10300/current/cdl/watchdog_mn10300.cdl b/ecos/packages/devs/watchdog/mn10300/mn10300/current/cdl/watchdog_mn10300.cdl
new file mode 100644
index 0000000..f819170
--- /dev/null
+++ b/ecos/packages/devs/watchdog/mn10300/mn10300/current/cdl/watchdog_mn10300.cdl
@@ -0,0 +1,100 @@
+# ====================================================================
+#
+# watchdog_mn10300.cdl
+#
+# eCos watchdog for VR4300/Mn10300 driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2000-05-31
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_MN10300_MN10300 {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "MN10300 watchdog driver"
+ requires CYGPKG_HAL_MN10300
+ requires CYGPKG_KERNEL
+ hardware
+ compile watchdog_mn10300.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ active_if CYGIMP_WATCHDOG_HARDWARE
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_MN10300_MN10300_OPTIONS {
+ display "MN10300 watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_MN10300_MN10300_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_MN10300_MN10300_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/watchdog/mn10300/mn10300/current/src/watchdog_mn10300.cxx b/ecos/packages/devs/watchdog/mn10300/mn10300/current/src/watchdog_mn10300.cxx
new file mode 100644
index 0000000..031155a
--- /dev/null
+++ b/ecos/packages/devs/watchdog/mn10300/mn10300/current/src/watchdog_mn10300.cxx
@@ -0,0 +1,198 @@
+//==========================================================================
+//
+// devs/watchdog/mn10300/mn10300/watchdog_mn10300.cxx
+//
+// Watchdog implementation for MN10300
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1999-02-18
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the MN10300 hardware watchdog timer.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h> // system configuration file
+#include <pkgconf/watchdog.h> // configuration for this package
+#include <pkgconf/kernel.h> // Kernel config
+
+#include <cyg/kernel/ktypes.h> // base kernel types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/kernel/instrmnt.h> // instrumentation
+
+#include <cyg/hal/hal_io.h> // IO register access
+
+#include <cyg/kernel/intr.hxx> // interrupts
+
+#include <cyg/io/watchdog.hxx> // watchdog API
+
+// -------------------------------------------------------------------------
+// MN10300 watchdog timer registers
+
+#if defined(CYGPKG_HAL_MN10300_AM31)
+
+#define WATCHDOG_BASE 0x34004000
+#define WATCHDOG_COUNTER (WATCHDOG_BASE)
+#define WATCHDOG_CONTROL (WATCHDOG_BASE+2)
+#define WATCHDOG_RESET (WATCHDOG_BASE+4)
+
+#define WATCHDOG_WDCK0 0x07
+#define WATCHDOG_WDCK0_DEFAULT 0x04 // 1016.801ms cycle
+#define WATCHDOG_WDRST 0x40
+#define WATCHDOG_WDCNE 0x80
+
+#define WATCHDOG_RESOLUTION 1016801000 // cycle time in nanoseconds
+
+#elif defined(CYGPKG_HAL_MN10300_AM33)
+
+#define WATCHDOG_BASE 0xC0001000
+#define WATCHDOG_COUNTER (WATCHDOG_BASE)
+#define WATCHDOG_CONTROL (WATCHDOG_BASE+2)
+#define WATCHDOG_RESET (WATCHDOG_BASE+4)
+
+#define WATCHDOG_WDCK0 0x07
+#define WATCHDOG_WDCK0_DEFAULT 0x04 // 621.387ms cycle
+#define WATCHDOG_WDRST 0x40
+#define WATCHDOG_WDCNE 0x80
+
+#define WATCHDOG_RESOLUTION 621387000 // cycle time in nanoseconds
+
+#else
+
+#error Unsupported MN10300 variant
+
+#endif
+
+// -------------------------------------------------------------------------
+// Forward definitions
+
+static cyg_ISR watchdog_isr;
+
+// -------------------------------------------------------------------------
+// Statics
+
+// Interrupt object
+static Cyg_Interrupt interrupt(
+ CYGNUM_HAL_INTERRUPT_WATCHDOG,
+ 0,
+ 0,
+ watchdog_isr,
+ NULL // no DSR
+ );
+
+// -------------------------------------------------------------------------
+// Constructor
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ // HW doesn't need init.
+
+ resolution = WATCHDOG_RESOLUTION;
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Start the watchdog running.
+
+void
+Cyg_Watchdog::start(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ interrupt.attach();
+
+ HAL_WRITE_UINT8( WATCHDOG_COUNTER, 0 );
+
+ // Set overflow cycle
+ // Enable and reset counter
+ HAL_WRITE_UINT8( WATCHDOG_CONTROL,
+ WATCHDOG_WDCK0_DEFAULT|WATCHDOG_WDCNE|WATCHDOG_WDRST);
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Reset watchdog timer. This needs to be called regularly to prevent
+// the watchdog firing.
+
+void
+Cyg_Watchdog::reset()
+{
+ CYG_REPORT_FUNCTION();
+
+ cyg_uint8 ctrl;
+
+ HAL_READ_UINT8( WATCHDOG_CONTROL, ctrl );
+
+ ctrl |= WATCHDOG_WDRST;
+
+ HAL_WRITE_UINT8( WATCHDOG_CONTROL, ctrl );
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// ISR
+
+cyg_uint32
+watchdog_isr( cyg_vector vector, CYG_ADDRWORD data)
+{
+ CYG_REPORT_FUNCTION();
+
+ // Disable interrupt just in case
+ interrupt.detach();
+
+ // Turn watchdog off to prevent it re-triggering.
+ HAL_WRITE_UINT8( WATCHDOG_CONTROL, 0 );
+
+ Cyg_Watchdog::watchdog.trigger();
+
+ CYG_REPORT_RETURN();
+
+ return Cyg_Interrupt::HANDLED;
+}
+
+// -------------------------------------------------------------------------
+// EOF watchdog_mn10300.cxx
diff --git a/ecos/packages/devs/watchdog/powerpc/mpc5xx/current/ChangeLog b/ecos/packages/devs/watchdog/powerpc/mpc5xx/current/ChangeLog
new file mode 100644
index 0000000..bff60f2
--- /dev/null
+++ b/ecos/packages/devs/watchdog/powerpc/mpc5xx/current/ChangeLog
@@ -0,0 +1,26 @@
+
+2003-05-25 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * new package
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/devs/watchdog/powerpc/mpc5xx/current/cdl/watchdog_mpc5xx.cdl b/ecos/packages/devs/watchdog/powerpc/mpc5xx/current/cdl/watchdog_mpc5xx.cdl
new file mode 100644
index 0000000..c5bc325
--- /dev/null
+++ b/ecos/packages/devs/watchdog/powerpc/mpc5xx/current/cdl/watchdog_mpc5xx.cdl
@@ -0,0 +1,121 @@
+# ====================================================================
+#
+# watchdog_mpc5xx.cdl
+#
+# eCos watchdog for powerpc/mpc5xx driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): Bob Koninckx
+# Contributors: Bob Koninckx
+# Date: 2003-05-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_MPC5xx {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "mpc5xx watchdog driver"
+ requires CYGPKG_HAL_POWERPC_MPC5xx
+ hardware
+ compile watchdog_mpc5xx.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+ active_if CYGIMP_WATCHDOG_HARDWARE
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_option CYGNUM_DEVICES_WATCHDOG_POWERPC_MPC5XX_RELOAD {
+ display "mpc5xx watchog reload value"
+ flavor data
+ default_value 0xffff
+ legal_values 0 to 0xffff
+ description "
+ This option determines the number of ticks before the watchdog
+ times out and resets the board. The watchdog is timed from the
+ same clock source as the Periodic interrupt timer (PIT), but
+ can be additionaly prescaled by a factor 2048."
+ }
+
+ cdl_option CYGDAT_DEVICES_WATCHDOG_POWERPC_MPC5XX_PRESCALE {
+ display "mpc5xx watchdog prescaler"
+ flavor bool
+ default_value 1
+ description "
+ This option determines wether to prescale the watchdog timer with
+ a factor 2048 or not."
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_POWERPC_MPC5XX_OPTIONS {
+ display "mpc5xx watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_POWERPC_MPC5XX_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_POWERPC_MPC5XXX_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/watchdog/powerpc/mpc5xx/current/src/watchdog_mpc5xx.cxx b/ecos/packages/devs/watchdog/powerpc/mpc5xx/current/src/watchdog_mpc5xx.cxx
new file mode 100644
index 0000000..4d8b2ac
--- /dev/null
+++ b/ecos/packages/devs/watchdog/powerpc/mpc5xx/current/src/watchdog_mpc5xx.cxx
@@ -0,0 +1,126 @@
+//==========================================================================
+//
+// devs/watchdog/powerpc/mpc5xx/watchdog_mpc5xx.cxx
+//
+// Watchdog implementation for MPC5XX
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Bob Koninckx
+// Contributors: Bob Koninckx
+// Date: 2003-05-18
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the mpc5xx watchdog timer.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h> // system configuration file
+#include <pkgconf/watchdog.h> // configuration for this package
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+
+#include <cyg/hal/hal_io.h> // IO register access
+#include <cyg/hal/hal_arch.h> // Register definitions
+
+#include <cyg/io/watchdog.hxx> // watchdog API
+
+// -------------------------------------------------------------------------
+// MPC5xx SYPCR register bit definitions
+#define MPC5XX_SYPCR_SWTC 0xffff0000
+#define MPC5XX_SYPCR_SWP 0x00000001
+#define MPC5XX_SYPCR_SWRI 0x00000002
+#define MPC5XX_SYPCR_SWE 0x00000004
+#define MPC5XX_SYPCR_SWF 0x00000008
+
+// -------------------------------------------------------------------------
+// Constructor
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ cyg_uint32 sypcr;
+ HAL_READ_UINT32(CYGARC_REG_IMM_SYPCR, sypcr);
+
+ resolution = (sypcr & MPC5XX_SYPCR_SWTC) >> 16;
+ if(sypcr & MPC5XX_SYPCR_SWP)
+ resolution *= 2048;
+
+ // Now we have it in ticks, convert to nanoseconds
+ // This holds for a system clock of 40 Mhz (25 nanosecond ticks) which is normal
+ // for the MPC5xx
+ resolution *= 25;
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Start the watchdog running.
+// On powerpc, the watchdog is enabled by default. If the watchdog package
+// is present, board setup does not disable it, so, nothing special to be
+// done here.
+void
+Cyg_Watchdog::start(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Reset watchdog timer. This needs to be called regularly to prevent
+// the watchdog firing.
+
+void
+Cyg_Watchdog::reset()
+{
+ CYG_REPORT_FUNCTION();
+
+ cyg_uint16 swsr;
+ swsr = 0x556c;
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_SWSR, swsr);
+ swsr = 0xaa39;
+ HAL_WRITE_UINT16(CYGARC_REG_IMM_SWSR, swsr);
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// EOF watchdog_mpc5xx.cxx
diff --git a/ecos/packages/devs/watchdog/sh/sh3/current/ChangeLog b/ecos/packages/devs/watchdog/sh/sh3/current/ChangeLog
new file mode 100644
index 0000000..5da49ca
--- /dev/null
+++ b/ecos/packages/devs/watchdog/sh/sh3/current/ChangeLog
@@ -0,0 +1,33 @@
+2000-05-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/watchdog_sh3.cdl:
+ * src/watchdog_sh3.cxx:
+ Driver moved to devs/watchdog/sh/sh3. Stripped out
+ unrelated ChangeLog entries.
+
+1999-09-01 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/sh.cxx:
+ Added watchdog driver for SH.
+
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
diff --git a/ecos/packages/devs/watchdog/sh/sh3/current/cdl/watchdog_sh3.cdl b/ecos/packages/devs/watchdog/sh/sh3/current/cdl/watchdog_sh3.cdl
new file mode 100644
index 0000000..6f316a1
--- /dev/null
+++ b/ecos/packages/devs/watchdog/sh/sh3/current/cdl/watchdog_sh3.cdl
@@ -0,0 +1,101 @@
+# ====================================================================
+#
+# watchdog_sh3.cdl
+#
+# eCos watchdog for the Hitachi SH3 driver configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Contributors: jskov
+# Date: 2000-05-31
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WATCHDOG_SH_SH3 {
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ display "SH3 watchdog driver"
+ requires CYGPKG_HAL_SH
+ requires CYGPKG_KERNEL
+ hardware
+ compile watchdog_sh3.cxx
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+ active_if CYGIMP_WATCHDOG_HARDWARE
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "Hardware watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ }
+
+ cdl_component CYGPKG_DEVICES_WATCHDOG_SH_SH3_OPTIONS {
+ display "SH3 watchdog build options"
+ flavor none
+ description "
+ Package specific build options including control over
+ compiler flags used only in building this package,
+ and details of which tests are built."
+
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_SH_SH3_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_DEVICES_WATCHDOG_SH_SH3_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building the watchdog device. These flags are removed from
+ the set of global flags if present."
+ }
+
+ }
+}
diff --git a/ecos/packages/devs/watchdog/sh/sh3/current/src/watchdog_sh3.cxx b/ecos/packages/devs/watchdog/sh/sh3/current/src/watchdog_sh3.cxx
new file mode 100644
index 0000000..d469743
--- /dev/null
+++ b/ecos/packages/devs/watchdog/sh/sh3/current/src/watchdog_sh3.cxx
@@ -0,0 +1,140 @@
+//==========================================================================
+//
+// devs/watchdog/sh/sh3/watchdog_sh3.cxx
+//
+// Watchdog implementation for Hitachi SH CPUs
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 1999-09-01
+// Purpose: Watchdog class implementation
+// Description: Contains an implementation of the Watchdog class for use
+// with the Hitachi SH watchdog timer.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h> // system configuration file
+#include <pkgconf/watchdog.h> // configuration for this package
+#include <pkgconf/kernel.h> // kernel config
+
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/kernel/instrmnt.h> // instrumentation
+
+#include <cyg/hal/hal_io.h> // IO register access
+#include <cyg/hal/sh_regs.h> // watchdog register definitions
+
+#include <cyg/io/watchdog.hxx> // watchdog API
+
+// -------------------------------------------------------------------------
+// Constructor
+
+void
+Cyg_Watchdog::init_hw(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ // No hardware init needed.
+
+ resolution = CYGARC_REG_WTCSR_PERIOD;
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Start the watchdog running.
+
+void
+Cyg_Watchdog::start()
+{
+ CYG_REPORT_FUNCTION();
+
+ // Init the watchdog timer (note: 8 bit reads, 16 bit writes)
+ cyg_uint16 csr;
+ // First disable without changing other bits.
+ HAL_READ_UINT8(CYGARC_REG_WTCSR, csr);
+ csr |= CYGARC_REG_WTCSR_WRITE;
+ csr &= ~CYGARC_REG_WTCSR_TME;
+ HAL_WRITE_UINT16(CYGARC_REG_WTCSR, csr);
+ // Then set control bits and clear counter.
+ csr = (CYGARC_REG_WTCSR_WRITE
+ |CYGARC_REG_WTCSR_WT_IT
+ |CYGARC_REG_WTCSR_CKSx_SETTING);
+ HAL_WRITE_UINT16(CYGARC_REG_WTCSR, csr);
+ HAL_WRITE_UINT16(CYGARC_REG_WTCNT, CYGARC_REG_WTCNT_WRITE);
+ // Finally enable timer.
+ csr |= CYGARC_REG_WTCSR_TME;
+ HAL_WRITE_UINT16(CYGARC_REG_WTCSR, csr);
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Reset watchdog timer. This needs to be called regularly to prevent
+// the watchdog firing.
+
+void
+Cyg_Watchdog::reset()
+{
+ CYG_REPORT_FUNCTION();
+
+ HAL_WRITE_UINT16(CYGARC_REG_WTCNT, CYGARC_REG_WTCNT_WRITE);
+
+ CYG_REPORT_RETURN();
+}
+
+#if 0
+// -------------------------------------------------------------------------
+// Trigger the watchdog as if the timer had expired.
+
+void
+Cyg_Watchdog::action_reset(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ start();
+
+ HAL_WRITE_UINT16(CYGARC_REG_WTCNT, CYGARC_REG_WTCNT_WRITE|0xfe);
+
+ CYG_REPORT_RETURN();
+}
+#endif
+
+// -------------------------------------------------------------------------
+// EOF watchdog_sh3.cxx
diff --git a/ecos/packages/devs/watchdog/synth/current/ChangeLog b/ecos/packages/devs/watchdog/synth/current/ChangeLog
new file mode 100644
index 0000000..7fe3eb6
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/ChangeLog
@@ -0,0 +1,77 @@
+2009-07-14 Bart Veer <bartv@ecoscentric.com>
+
+ * host/configure.in: allow builds on x86_64 machines.
+
+ * host/configure, host/Makefile.in, host/aclocal.m4: regenerate.
+
+2009-02-04 Bart Veer <bartv@ecoscentric.com>
+
+ * src/synth_watchdog.cxx: use the generic watchdog package's
+ prioritized constructor.
+
+2008-08-18 Bart Veer <bartv@ecoscentric.com>
+
+ * host/Makefile.am: update host-side configury
+ * host/Makefile.in, host/aclocal.m4, host/configure: regenerate.
+
+2003-03-23 Iztok Zupet<iz@vsr.si>
+
+ * doc/synth_watchdog.sgml: Replaced .gif with .png to allow for
+ PDF build.
+
+ * doc/asleep.gif, doc/awake.gif: Converted to *.png and deleted.
+ * doc/asleep.png, doc/awake.png: New files.
+
+2003-02-25 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * doc/synth_watchdog.sgml: Declare as <part> not <reference> to get
+ correct TOC numbering.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/synth_watchdog.cdl: Add doc link.
+
+ * doc/synth_watchdog.sgml: Comment out DOCTYPE for now to allow
+ building with standard doc build.
+ Add an enclosing <reference> so it's structured better with standard
+ doc build.
+
+2003-02-12 Bart Veer <bartv@ecoscentric.com>
+
+ * host/Makefile.in:
+ Regenerate after toplevel acinclude.m4 update
+
+2002-09-16 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/synth_watchdog.cdl:
+ Synthetic watchdog device should only be active if the
+ generic watchdog support is present
+
+2002-09-04 Bart Veer <bartv@ecoscentric.com>
+
+ * Synthetic target watchdog package created
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
+
diff --git a/ecos/packages/devs/watchdog/synth/current/cdl/synth_watchdog.cdl b/ecos/packages/devs/watchdog/synth/current/cdl/synth_watchdog.cdl
new file mode 100644
index 0000000..6e47dd7
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/cdl/synth_watchdog.cdl
@@ -0,0 +1,109 @@
+# ====================================================================
+#
+# synth_watchdog.cdl
+#
+# Synthetic target watchdog package.
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Original data: bartv
+# Contributors:
+# Date: 2002-08-07
+#
+#####DESCRIPTIONEND####
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_WATCHDOG_SYNTH {
+ display "Synthetic target watchdog support"
+ description "
+ The watchdog driver for the eCos synthetic target provides
+ emulation of a watchdog device: if the eCos application starts
+ the watchdog and fails to reset it regularly then the host-side
+ support will detect this and kill the eCos application with a
+ SIGPWR signal."
+ doc ref/devs-watchdog-synth.html
+
+ parent CYGPKG_IO_WATCHDOG
+ active_if CYGPKG_IO_WATCHDOG
+ implements CYGINT_WATCHDOG_HW_IMPLEMENTATIONS
+ implements CYGINT_WATCHDOG_RESETS_ON_TIMEOUT
+
+ cdl_option CYGIMP_WATCHDOG_HARDWARE {
+ parent CYGPKG_IO_WATCHDOG_IMPLEMENTATION
+ display "use \"hardware\" watchdog"
+ default_value 1
+ implements CYGINT_WATCHDOG_IMPLEMENTATIONS
+ compile synth_watchdog.cxx
+ description "
+ eCos provides several implementations of a watchdog device.
+ The default is to use the \"hardware\" implementation, which
+ for the synthetic target involves interacting with a
+ watchdog.tcl script running inside the I/O auxiliary."
+ }
+
+ cdl_component CYGPKG_DEVS_WATCHDOG_SYNTH_OPTIONS {
+ display "Build options"
+ active_if CYGIMP_WATCHDOG_HARDWARE
+ flavor none
+
+ description "
+ Package-specific build options including control over compiler
+ flags used only in building this package."
+
+ cdl_option CYGPKG_DEVS_WATCHDOG_SYNTH_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building this package. These flags are used in addition
+ to the set of global flags."
+ }
+ cdl_option CYGPKG_DEVS_WATCHDOG_SYNTH_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for
+ building this package. These flags are removed from
+ the set of global flags if present."
+ }
+ }
+}
+
diff --git a/ecos/packages/devs/watchdog/synth/current/doc/asleep.png b/ecos/packages/devs/watchdog/synth/current/doc/asleep.png
new file mode 100644
index 0000000..c127379
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/doc/asleep.png
Binary files differ
diff --git a/ecos/packages/devs/watchdog/synth/current/doc/awake.png b/ecos/packages/devs/watchdog/synth/current/doc/awake.png
new file mode 100644
index 0000000..c3504dc
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/doc/awake.png
Binary files differ
diff --git a/ecos/packages/devs/watchdog/synth/current/doc/devs-watchdog-synth.html b/ecos/packages/devs/watchdog/synth/current/doc/devs-watchdog-synth.html
new file mode 100644
index 0000000..572f6f4
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/doc/devs-watchdog-synth.html
@@ -0,0 +1,526 @@
+<!-- Copyright (C) 2002 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/). -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission is obtained from the copyright holder. -->
+<HTML
+><HEAD
+><TITLE
+>Synthetic Target Watchdog Device</TITLE
+><meta name="MSSmartTagsPreventParsing" content="TRUE">
+<META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="DEVS-WATCHDOG-SYNTH">Synthetic Target Watchdog Device</H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN4"
+></A
+><H2
+>Name</H2
+>Synthetic Target Watchdog Device&nbsp;--&nbsp;Emulate watchdog hardware in the synthetic target</DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN7"
+></A
+><H2
+>Overview</H2
+><P
+>Some target hardware comes equipped with a watchdog timer. Application
+code can start this timer and after a certain period of time,
+typically a second, the watchdog will trigger. Usually this causes the
+hardware to reboot. The application can prevent this by regularly
+resetting the watchdog. An automatic reboot can be very useful when
+deploying hardware in the field: a hardware glitch could cause the
+unit to hang; or the software could receive an unexpected sequence of
+inputs, never seen in the laboratory, causing the system to lock up.
+Often the hardware is still functional, and a reboot sorts out the
+problem with only a brief interruption in service.
+ </P
+><P
+>The synthetic target watchdog package emulates watchdog hardware.
+During system initialization watchdog device will be instantiated,
+and the <TT
+CLASS="FILENAME"
+>watchdog.tcl</TT
+> script will be loaded by the
+I/O auxiliary. When the eCos application starts the watchdog device,
+the <TT
+CLASS="FILENAME"
+>watchdog.tcl</TT
+> script will start checking the
+state of the eCos application at one second intervals. A watchdog
+reset call simply involves a message to the I/O auxiliary. If the
+<TT
+CLASS="FILENAME"
+>watchdog.tcl</TT
+> script detects that a second has
+<A
+HREF="devs-watchdog-synth.html#SYNTH-WATCHDOG-WALLCLOCK-ELAPSED"
+>elapsed</A
+>
+without a reset then it will send a <TT
+CLASS="LITERAL"
+>SIGPWR</TT
+> signal
+to the eCos application, causing the latter to terminate. If gdb is
+being used to run the application, the user will get a chance to
+investigate what is happening. This behaviour is different from real
+hardware in that there is no automatic reboot, but the synthetic
+target is used only for development purposes, not deployment in the
+field: if a reboot is desired then this can be achieved very easily
+by using gdb commands to run another instance of the application.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-WATCHDOG-SYNTH-INSTALL"
+></A
+><H2
+>Installation</H2
+><P
+>Before a synthetic target eCos application can use a watchdog device
+it is necessary to build and install host-side support. The relevant
+code resides in the <TT
+CLASS="FILENAME"
+>host</TT
+>
+subdirectory of the synthetic target watchdog package, and building it
+involves the standard <B
+CLASS="COMMAND"
+>configure</B
+>,
+<B
+CLASS="COMMAND"
+>make</B
+> and <B
+CLASS="COMMAND"
+>make install</B
+> steps. The
+implementation of the watchdog support does not require any
+executables, just a Tcl script <TT
+CLASS="FILENAME"
+>watchdog.tcl</TT
+> and
+some support files, so the <B
+CLASS="COMMAND"
+>make</B
+> step is a no-op.
+ </P
+><P
+>There are two main ways of building the host-side software. It is
+possible to build both the generic host-side software and all
+package-specific host-side software, including the watchdog support,
+in a single build tree. This involves using the
+<B
+CLASS="COMMAND"
+>configure</B
+> script at the toplevel of the eCos
+repository. For more information on this, see the
+<TT
+CLASS="FILENAME"
+>README.host</TT
+> file at the top of the repository.
+Note that if you have an existing build tree which does not include
+the synthetic target watchdog support then it will be necessary to
+rerun the toplevel configure script: the search for appropriate
+packages happens at configure time.
+ </P
+><P
+>The alternative is to build just the host-side for this package.
+This requires a separate build directory, building directly in the
+source tree is disallowed. The <B
+CLASS="COMMAND"
+>configure</B
+> options
+are much the same as for a build from the toplevel, and the
+<TT
+CLASS="FILENAME"
+>README.host</TT
+> file can be consulted for more
+details. It is essential that the watchdog support be configured with
+the same <TT
+CLASS="OPTION"
+>--prefix</TT
+> option as other eCos host-side
+software, especially the I/O auxiliary provided by the architectural
+synthetic target HAL package, otherwise the I/O auxiliary will be
+unable to locate the watchdog support.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="SYNTH-WATCHDOG-TARGET-CONFIG"
+></A
+><H2
+>Target-side
+Configuration</H2
+><P
+>The watchdog device depends on the generic watchdog support,
+<TT
+CLASS="VARNAME"
+>CYGPKG_IO_WATCHDOG</TT
+>: if the generic support is
+absent then the watchdog device will be inactive. Some templates
+include this generic package by default, but not all. If the
+configuration does not include the generic package then it can be
+added using the eCos configuration tools, for example:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="SCREEN"
+>$ ecosconfig add CYGPKG_IO_WATCHDOG</PRE
+></TD
+></TR
+></TABLE
+><P
+>By default the configuration will use the hardware-specific support,
+i.e. this package. However the generic watchdog package contains an
+alternative implementation using the kernel alarm facility, and that
+implementation can be selected if desired. However usually it will be
+better to rely on an external watchdog facility as provided by the I/O
+auxiliary and the <TT
+CLASS="FILENAME"
+>watchdog.tcl</TT
+> script: if there
+are serious problems within the application, for example memory
+corruption, then an internal software-only implementation will not be
+reliable.
+ </P
+><P
+>The watchdog resolution is currently fixed to one second: if the
+device does not receive a reset signal at least once a second then
+the watchdog will trigger and the eCos application will be terminated
+with a <TT
+CLASS="LITERAL"
+>SIGPWR</TT
+> signal. The current implementation
+does not allow this resolution to be changed.
+ </P
+><P
+>On some targets the watchdog device does not perform a hard reset.
+Instead the device works more or less via the interrupt subsystem,
+allowing application code to install action routines that will be
+called when the watchdog triggers. The synthetic target watchdog
+support effectively does perform a hard reset, by sending a
+<TT
+CLASS="LITERAL"
+>SIGPWR</TT
+> signal to the eCos application, and there is
+no support for action routines.
+ </P
+><P
+>The synthetic target watchdog package provides some configuration
+options for manipulating the compiler flags used for building the
+target-side code. That code is fairly simple, so for nearly all
+applications the default flags will suffice.
+ </P
+><P
+>It should be noted that the watchdog device is subject to selective
+linking. Unless some code explicitly references the device, for
+example by calling the start and reset functions, the watchdog support
+will not appear in the final executable. This is desirable because a
+watchdog device has no effect until started.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="SYNTH-WATCHDOG-WALLCLOCK-ELAPSED"
+></A
+><H2
+>Wallclock versus Elapsed Time</H2
+><P
+>On real hardware the watchdog device uses wallclock time: if the
+device does not receive a reset signal within a set period of time
+then the watchdog will trigger. When developing for the synthetic
+target this is not always appropriate. There may be other processes
+running, using up some or most of the cpu time. For example, the
+application may be written such that it will issue a reset after some
+calculations which are known to complete within half a second, well
+within the one-second resolution of the watchdog device. However if
+other Linux processes are running then the synthetic target
+application may get timesliced, and half a second of computation may
+take several seconds of wallclock time.
+ </P
+><P
+>Another problem with using wallclock time is that it interferes with
+debugging: if the application hits a breakpoint then it is unlikely
+that the user will manage to restart it in less than a second, and the
+watchdog will not get reset in time.
+ </P
+><P
+>To avoid these problems the synthetic target watchdog normally uses
+consumed cpu time rather than wallclock time. If the application is
+timesliced or if it is halted inside gdb then it does not consume any
+cpu time. The application actually has to spend a whole second's worth
+of cpu cycles without issuing a reset before the watchdog triggers.
+ </P
+><P
+>However using consumed cpu time is not a perfect solution either. If
+the application makes blocking system calls then it is not using cpu
+time. Interaction with the I/O auxiliary involves system calls, but
+these should take only a short amount of time so their effects can be
+ignored. If the application makes direct system calls such as
+<TT
+CLASS="FUNCTION"
+>cyg_hal_sys_read</TT
+> then the system behaviour
+becomes undefined. In addition by default the idle thread will make
+blocking <TT
+CLASS="FUNCTION"
+>select</TT
+> system calls, effectively waiting
+until an interrupt occurs. If an application spends much of its time
+idle then the watchdog device may take much longer to trigger than
+expected. It may be desirable to enable the synthetic target HAL
+configuration option <TT
+CLASS="VARNAME"
+>CYGIMP_HAL_IDLE_THREAD_SPIN</TT
+>,
+causing the idle thread to spin rather than block, at the cost of
+wasted cpu cycles.
+ </P
+><P
+>The default is to use consumed cpu time, but this can be changed in
+the target definition file:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device watchdog {
+ use wallclock_time
+ &#8230;
+}</PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="SYNTH-WATCHDOG-GUI"
+></A
+><H2
+>User Interface</H2
+><P
+>When the synthetic target is run in graphical mode the watchdog device
+extends the user interface in two ways. The <SPAN
+CLASS="GUIMENU"
+>Help</SPAN
+>
+menu is extended with an entry for the watchdog-specific
+documentation. There is also a graphical display of the current state
+of the watchdog. Initially the watchdog is asleep:
+ </P
+><DIV
+CLASS="INFORMALFIGURE"
+><A
+NAME="AEN60"><P
+></P
+><DIV
+CLASS="MEDIAOBJECT"
+><P
+><IMG
+SRC="asleep.gif"
+ALIGN="CENTER"></P
+></DIV
+><P
+></P
+></DIV
+><P
+>When application code starts the device the watchdog will begin to
+keep an eye on things (or occasionally both eyes).
+ </P
+><DIV
+CLASS="INFORMALFIGURE"
+><A
+NAME="AEN65"><P
+></P
+><DIV
+CLASS="MEDIAOBJECT"
+><P
+><IMG
+SRC="awake.gif"
+ALIGN="CENTER"></P
+></DIV
+><P
+></P
+></DIV
+><P
+>If the watchdog triggers the display will change again, and optionally
+the user can receive an audible alert. The location of the watchdog
+display within the I/O auxiliary's window can be controlled via
+a <B
+CLASS="COMMAND"
+>watchdog_pack</B
+> entry in the target definition
+file. For example the following can be used to put the watchdog
+display to the right of the central text window:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device watchdog {
+ watchdog_pack -in .main.e -side top
+ &#8230;
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>The user interface section of the generic synthetic target HAL
+documentation can be consulted for more information on window packing.
+ </P
+><P
+>By default the watchdog support will not generate an audible alert
+when the watchdog triggers, to avoid annoying colleagues. Sound can be
+enabled in the target definition file, and two suitable files
+<TT
+CLASS="FILENAME"
+>sound1.au</TT
+> and <TT
+CLASS="FILENAME"
+>sound2.au</TT
+> are
+supplied as standard:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device watchdog {
+ sound sound1.au
+ &#8230;
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>An absolute path can be specified if desired:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device watchdog {
+ sound /usr/share/emacs/site-lisp/emacspeak/sounds/default-8k/alarm.au
+ &#8230;
+}</PRE
+></TD
+></TR
+></TABLE
+><P
+>Sound facilities are not built into the I/O auxiliary itself, instead
+an external program is used. The default player is
+<B
+CLASS="COMMAND"
+>play</B
+>, a front-end to the
+<SPAN
+CLASS="APPLICATION"
+>sox</SPAN
+> application shipped with some Linux
+distributions. If another player should be used then this can be
+specified in the target definition file:
+ </P
+><TABLE
+BORDER="5"
+BGCOLOR="#E0E0F0"
+WIDTH="70%"
+><TR
+><TD
+><PRE
+CLASS="PROGRAMLISTING"
+>synth_device watchdog {
+ &#8230;
+ sound_player my_sound_player</PRE
+></TD
+></TR
+></TABLE
+><P
+>The specified program will be run in the background with a single
+argument, the sound file.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-WATCHDOG-SYNTH-ARGS"
+></A
+><H2
+>Command Line Arguments</H2
+><P
+>The watchdog support does not use any command line arguments. All
+configuration is handled through the target definition file.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-WATCHDOG-SYNTH-HOOKS"
+></A
+><H2
+>Hooks</H2
+><P
+>The watchdog support does not provide any hooks for use by other
+scripts. There is rarely any need for customizing the system's
+behaviour when a watchdog triggers because those should be rare
+events, even during application development.
+ </P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="DEVS-WATCHDOG-SYNTH-TCL"
+></A
+><H2
+>Additional Tcl Procedures</H2
+><P
+>The watchdog support does not provide any additional Tcl procedures or
+variables for use by other scripts.
+ </P
+></DIV
+></BODY
+></HTML
+>
diff --git a/ecos/packages/devs/watchdog/synth/current/doc/makefile b/ecos/packages/devs/watchdog/synth/current/doc/makefile
new file mode 100644
index 0000000..1f195d0
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/doc/makefile
@@ -0,0 +1,54 @@
+#=============================================================================
+#
+# makefile
+#
+# For building the synthetic target watchdog package documentation
+#
+#=============================================================================
+# ####ECOSGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2002 Free Software Foundation, Inc.
+#
+# eCos is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 or (at your option) any later
+# version.
+#
+# eCos is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with eCos; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception, if other files instantiate templates or use
+# macros or inline functions from this file, or you compile this file
+# and link it with other works to produce a work based on this file,
+# this file does not by itself cause the resulting work to be covered by
+# the GNU General Public License. However the source code for this file
+# must still be made available in accordance with section (3) of the GNU
+# General Public License v2.
+#
+# This exception does not invalidate any other reasons why a work based
+# on this file might be covered by the GNU General Public License.
+# -------------------------------------------
+# ####ECOSGPLCOPYRIGHTEND####
+#=============================================================================
+#####DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Date: 2002-09-09
+#####DESCRIPTIONEND####
+#=============================================================================
+
+TOPLEVEL := ../../../../..
+MAIN_SGML := synth_watchdog.sgml
+MAIN_HTML := devs-watchdog-synth.html
+MAIN_PDF := devs-watchdog-synth.pdf
+OTHER_SGML :=
+PICTURES :=
+
+include $(TOPLEVEL)/pkgconf/rules.doc
diff --git a/ecos/packages/devs/watchdog/synth/current/doc/synth_watchdog.sgml b/ecos/packages/devs/watchdog/synth/current/doc/synth_watchdog.sgml
new file mode 100644
index 0000000..6085aa4
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/doc/synth_watchdog.sgml
@@ -0,0 +1,343 @@
+<!-- DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- synth_watchdog.sgml -->
+<!-- -->
+<!-- Synthetic target watchdog device -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2002 Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2002/09/09 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="devs-watchdog-synth-ref">
+<!-- reference id="devs-watchdog-synth-ref" -->
+ <title>Synthetic Target Watchdog Device</title>
+
+<refentry id="devs-watchdog-synth">
+ <refmeta>
+ <refentrytitle>Synthetic Target Watchdog Device</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Synthetic Target Watchdog Device</refname>
+ <refpurpose>Emulate watchdog hardware in the synthetic target</refpurpose>
+ </refnamediv>
+
+ <refsect1><title>Overview</title>
+ <para>
+Some target hardware comes equipped with a watchdog timer. Application
+code can start this timer and after a certain period of time,
+typically a second, the watchdog will trigger. Usually this causes the
+hardware to reboot. The application can prevent this by regularly
+resetting the watchdog. An automatic reboot can be very useful when
+deploying hardware in the field: a hardware glitch could cause the
+unit to hang; or the software could receive an unexpected sequence of
+inputs, never seen in the laboratory, causing the system to lock up.
+Often the hardware is still functional, and a reboot sorts out the
+problem with only a brief interruption in service.
+ </para>
+ <para>
+The synthetic target watchdog package emulates watchdog hardware.
+During system initialization watchdog device will be instantiated,
+and the <filename>watchdog.tcl</filename> script will be loaded by the
+I/O auxiliary. When the eCos application starts the watchdog device,
+the <filename>watchdog.tcl</filename> script will start checking the
+state of the eCos application at one second intervals. A watchdog
+reset call simply involves a message to the I/O auxiliary. If the
+<filename>watchdog.tcl</filename> script detects that a second has
+<link linkend="synth-watchdog-wallclock-elapsed">elapsed</link>
+without a reset then it will send a <literal>SIGPWR</literal> signal
+to the eCos application, causing the latter to terminate. If gdb is
+being used to run the application, the user will get a chance to
+investigate what is happening. This behaviour is different from real
+hardware in that there is no automatic reboot, but the synthetic
+target is used only for development purposes, not deployment in the
+field: if a reboot is desired then this can be achieved very easily
+by using gdb commands to run another instance of the application.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-watchdog-synth-install"><title>Installation</title>
+ <para>
+Before a synthetic target eCos application can use a watchdog device
+it is necessary to build and install host-side support. The relevant
+code resides in the <filename class="directory">host</filename>
+subdirectory of the synthetic target watchdog package, and building it
+involves the standard <command>configure</command>,
+<command>make</command> and <command>make install</command> steps. The
+implementation of the watchdog support does not require any
+executables, just a Tcl script <filename>watchdog.tcl</filename> and
+some support files, so the <command>make</command> step is a no-op.
+ </para>
+ <para>
+There are two main ways of building the host-side software. It is
+possible to build both the generic host-side software and all
+package-specific host-side software, including the watchdog support,
+in a single build tree. This involves using the
+<command>configure</command> script at the toplevel of the eCos
+repository. For more information on this, see the
+<filename>README.host</filename> file at the top of the repository.
+Note that if you have an existing build tree which does not include
+the synthetic target watchdog support then it will be necessary to
+rerun the toplevel configure script: the search for appropriate
+packages happens at configure time.
+ </para>
+ <para>
+The alternative is to build just the host-side for this package.
+This requires a separate build directory, building directly in the
+source tree is disallowed. The <command>configure</command> options
+are much the same as for a build from the toplevel, and the
+<filename>README.host</filename> file can be consulted for more
+details. It is essential that the watchdog support be configured with
+the same <option>--prefix</option> option as other eCos host-side
+software, especially the I/O auxiliary provided by the architectural
+synthetic target HAL package, otherwise the I/O auxiliary will be
+unable to locate the watchdog support.
+ </para>
+ </refsect1>
+
+ <refsect1 id="synth-watchdog-target-config"><title>Target-side
+Configuration</title>
+ <para>
+The watchdog device depends on the generic watchdog support,
+<varname>CYGPKG_IO_WATCHDOG</varname>: if the generic support is
+absent then the watchdog device will be inactive. Some templates
+include this generic package by default, but not all. If the
+configuration does not include the generic package then it can be
+added using the eCos configuration tools, for example:
+ </para>
+ <screen>
+$ ecosconfig add CYGPKG_IO_WATCHDOG
+</screen>
+ <para>
+By default the configuration will use the hardware-specific support,
+i.e. this package. However the generic watchdog package contains an
+alternative implementation using the kernel alarm facility, and that
+implementation can be selected if desired. However usually it will be
+better to rely on an external watchdog facility as provided by the I/O
+auxiliary and the <filename>watchdog.tcl</filename> script: if there
+are serious problems within the application, for example memory
+corruption, then an internal software-only implementation will not be
+reliable.
+ </para>
+ <para>
+The watchdog resolution is currently fixed to one second: if the
+device does not receive a reset signal at least once a second then
+the watchdog will trigger and the eCos application will be terminated
+with a <literal>SIGPWR</literal> signal. The current implementation
+does not allow this resolution to be changed.
+ </para>
+ <para>
+On some targets the watchdog device does not perform a hard reset.
+Instead the device works more or less via the interrupt subsystem,
+allowing application code to install action routines that will be
+called when the watchdog triggers. The synthetic target watchdog
+support effectively does perform a hard reset, by sending a
+<literal>SIGPWR</literal> signal to the eCos application, and there is
+no support for action routines.
+ </para>
+ <para>
+The synthetic target watchdog package provides some configuration
+options for manipulating the compiler flags used for building the
+target-side code. That code is fairly simple, so for nearly all
+applications the default flags will suffice.
+ </para>
+ <para>
+It should be noted that the watchdog device is subject to selective
+linking. Unless some code explicitly references the device, for
+example by calling the start and reset functions, the watchdog support
+will not appear in the final executable. This is desirable because a
+watchdog device has no effect until started.
+ </para>
+ </refsect1>
+
+ <refsect1 id="synth-watchdog-wallclock-elapsed"><title>Wallclock versus Elapsed Time</title>
+ <para>
+On real hardware the watchdog device uses wallclock time: if the
+device does not receive a reset signal within a set period of time
+then the watchdog will trigger. When developing for the synthetic
+target this is not always appropriate. There may be other processes
+running, using up some or most of the cpu time. For example, the
+application may be written such that it will issue a reset after some
+calculations which are known to complete within half a second, well
+within the one-second resolution of the watchdog device. However if
+other Linux processes are running then the synthetic target
+application may get timesliced, and half a second of computation may
+take several seconds of wallclock time.
+ </para>
+ <para>
+Another problem with using wallclock time is that it interferes with
+debugging: if the application hits a breakpoint then it is unlikely
+that the user will manage to restart it in less than a second, and the
+watchdog will not get reset in time.
+ </para>
+ <para>
+To avoid these problems the synthetic target watchdog normally uses
+consumed cpu time rather than wallclock time. If the application is
+timesliced or if it is halted inside gdb then it does not consume any
+cpu time. The application actually has to spend a whole second's worth
+of cpu cycles without issuing a reset before the watchdog triggers.
+ </para>
+ <para>
+However using consumed cpu time is not a perfect solution either. If
+the application makes blocking system calls then it is not using cpu
+time. Interaction with the I/O auxiliary involves system calls, but
+these should take only a short amount of time so their effects can be
+ignored. If the application makes direct system calls such as
+<function>cyg_hal_sys_read</function> then the system behaviour
+becomes undefined. In addition by default the idle thread will make
+blocking <function>select</function> system calls, effectively waiting
+until an interrupt occurs. If an application spends much of its time
+idle then the watchdog device may take much longer to trigger than
+expected. It may be desirable to enable the synthetic target HAL
+configuration option <varname>CYGIMP_HAL_IDLE_THREAD_SPIN</varname>,
+causing the idle thread to spin rather than block, at the cost of
+wasted cpu cycles.
+ </para>
+ <para>
+The default is to use consumed cpu time, but this can be changed in
+the target definition file:
+ </para>
+ <programlisting>
+synth_device watchdog {
+ use wallclock_time
+ &hellip;
+}
+</programlisting>
+ </refsect1>
+
+ <refsect1 id="synth-watchdog-gui"><title>User Interface</title>
+ <para>
+When the synthetic target is run in graphical mode the watchdog device
+extends the user interface in two ways. The <guimenu>Help</guimenu>
+menu is extended with an entry for the watchdog-specific
+documentation. There is also a graphical display of the current state
+of the watchdog. Initially the watchdog is asleep:
+ </para>
+ <informalfigure PgWide=1>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="asleep.png" Scalefit=1 Align="Center">
+ </imageobject>
+ </mediaobject>
+ </informalfigure>
+ <para>
+When application code starts the device the watchdog will begin to
+keep an eye on things (or occasionally both eyes).
+ </para>
+ <informalfigure PgWide=1>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="awake.png" Scalefit=1 Align="Center">
+ </imageobject>
+ </mediaobject>
+ </informalfigure>
+ <para>
+If the watchdog triggers the display will change again, and optionally
+the user can receive an audible alert. The location of the watchdog
+display within the I/O auxiliary's window can be controlled via
+a <command>watchdog_pack</command> entry in the target definition
+file. For example the following can be used to put the watchdog
+display to the right of the central text window:
+ </para>
+ <programlisting>
+synth_device watchdog {
+ watchdog_pack -in .main.e -side top
+ &hellip;
+}
+</programlisting>
+ <para>
+The user interface section of the generic synthetic target HAL
+documentation can be consulted for more information on window packing.
+ </para>
+ <para>
+By default the watchdog support will not generate an audible alert
+when the watchdog triggers, to avoid annoying colleagues. Sound can be
+enabled in the target definition file, and two suitable files
+<filename>sound1.au</filename> and <filename>sound2.au</filename> are
+supplied as standard:
+ </para>
+ <programlisting>
+synth_device watchdog {
+ sound sound1.au
+ &hellip;
+}
+</programlisting>
+ <para>
+An absolute path can be specified if desired:
+ </para>
+ <programlisting>
+synth_device watchdog {
+ sound /usr/share/emacs/site-lisp/emacspeak/sounds/default-8k/alarm.au
+ &hellip;
+}
+</programlisting>
+ <para>
+Sound facilities are not built into the I/O auxiliary itself, instead
+an external program is used. The default player is
+<command>play</command>, a front-end to the
+<application>sox</application> application shipped with some Linux
+distributions. If another player should be used then this can be
+specified in the target definition file:
+ </para>
+ <programlisting>
+synth_device watchdog {
+ &hellip;
+ sound_player my_sound_player
+</programlisting>
+ <para>
+The specified program will be run in the background with a single
+argument, the sound file.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-watchdog-synth-args"><title>Command Line Arguments</title>
+ <para>
+The watchdog support does not use any command line arguments. All
+configuration is handled through the target definition file.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-watchdog-synth-hooks"><title>Hooks</title>
+ <para>
+The watchdog support does not provide any hooks for use by other
+scripts. There is rarely any need for customizing the system's
+behaviour when a watchdog triggers because those should be rare
+events, even during application development.
+ </para>
+ </refsect1>
+
+ <refsect1 id="devs-watchdog-synth-tcl"><title>Additional Tcl Procedures</title>
+ <para>
+The watchdog support does not provide any additional Tcl procedures or
+variables for use by other scripts.
+ </para>
+ </refsect1>
+
+</refentry>
+</part>
+<!-- /reference -->
diff --git a/ecos/packages/devs/watchdog/synth/current/host/Makefile.am b/ecos/packages/devs/watchdog/synth/current/host/Makefile.am
new file mode 100644
index 0000000..0ecc5a2
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/Makefile.am
@@ -0,0 +1,59 @@
+## Process this file with automake to produce Makefile.in
+## =====================================================================
+##
+## Makefile.am
+##
+## Build support for the host-side synthetic target support,
+## the watchdog package
+##
+## =====================================================================
+# ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of the eCos host tools.
+# Copyright (C) 2002 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street,
+# Fifth Floor, Boston, MA 02110-1301, USA.
+# -------------------------------------------
+# ####ECOSHOSTGPLCOPYRIGHTEND####
+## =====================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): bartv
+## Contact(s): bartv
+## Date: 2002/09/04
+## Version: 0.01
+##
+######DESCRIPTIONEND####
+## =====================================================================
+
+AUTOMAKE_OPTIONS = 1.10 foreign
+
+## Only some platforms are supported. Having the configure script throw
+## an error when attempting to configure on an unsupported platform
+## would be a mistake, since that would prevent any configury from
+## the toplevel on unsupported platforms. Instead an automake conditional
+## is used, leading to null makefiles on unsupported platforms.
+
+if SUPPORTED
+
+## The only thing that needs to be installed is a Tcl script and some
+## data files.
+watchdogdir = $(libexecdir)/ecos/@PACKAGE_INSTALL@
+watchdog_DATA = watchdog.tcl \
+ watchdog.tdf \
+ alarm.gif doghouse.gif eye.gif asleep.gif \
+ sound1.au sound2.au
+endif
diff --git a/ecos/packages/devs/watchdog/synth/current/host/Makefile.in b/ecos/packages/devs/watchdog/synth/current/host/Makefile.in
new file mode 100644
index 0000000..2f4d25d
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/Makefile.in
@@ -0,0 +1,545 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of the eCos host tools.
+# Copyright (C) 2002 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street,
+# Fifth Floor, Boston, MA 02110-1301, USA.
+# -------------------------------------------
+# ####ECOSHOSTGPLCOPYRIGHTEND####
+#######DESCRIPTIONBEGIN####
+######DESCRIPTIONEND####
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = .
+DIST_COMMON = $(am__configure_deps) \
+ $(srcdir)/../../../../../../acsupport/config.guess \
+ $(srcdir)/../../../../../../acsupport/config.sub \
+ $(srcdir)/../../../../../../acsupport/install-sh \
+ $(srcdir)/../../../../../../acsupport/missing \
+ $(srcdir)/../../../../../../acsupport/mkinstalldirs \
+ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/configure ../../../../../../acsupport/ChangeLog \
+ ../../../../../../acsupport/config.guess \
+ ../../../../../../acsupport/config.sub \
+ ../../../../../../acsupport/depcomp \
+ ../../../../../../acsupport/install-sh \
+ ../../../../../../acsupport/ltconfig \
+ ../../../../../../acsupport/ltmain.sh \
+ ../../../../../../acsupport/missing \
+ ../../../../../../acsupport/mkinstalldirs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/../../../../../../acsupport/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(SHELL) \
+ $(top_srcdir)/../../../../../../acsupport/mkinstalldirs
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(watchdogdir)"
+DATA = $(watchdog_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d "$(distdir)" \
+ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr "$(distdir)"; }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECOS_REPOSITORY = @ECOS_REPOSITORY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_DIR = @PACKAGE_DIR@
+PACKAGE_INSTALL = @PACKAGE_INSTALL@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = 1.10 foreign
+@SUPPORTED_TRUE@watchdogdir = $(libexecdir)/ecos/@PACKAGE_INSTALL@
+@SUPPORTED_TRUE@watchdog_DATA = watchdog.tcl \
+@SUPPORTED_TRUE@ watchdog.tdf \
+@SUPPORTED_TRUE@ alarm.gif doghouse.gif eye.gif asleep.gif \
+@SUPPORTED_TRUE@ sound1.au sound2.au
+
+all: all-am
+
+.SUFFIXES:
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+install-watchdogDATA: $(watchdog_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(watchdogdir)" || $(MKDIR_P) "$(DESTDIR)$(watchdogdir)"
+ @list='$(watchdog_DATA)'; test -n "$(watchdogdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(watchdogdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(watchdogdir)" || exit $$?; \
+ done
+
+uninstall-watchdogDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(watchdog_DATA)'; test -n "$(watchdogdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(watchdogdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(watchdogdir)" && rm -f $$files
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @$(am__cd) '$(distuninstallcheck_dir)' \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(watchdogdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-watchdogDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-watchdogDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am am--refresh check check-am clean clean-generic dist \
+ dist-all dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ \
+ dist-xz dist-zip distcheck distclean distclean-generic \
+ distcleancheck distdir distuninstallcheck dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip install-watchdogDATA \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+ pdf-am ps ps-am uninstall uninstall-am uninstall-watchdogDATA
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ecos/packages/devs/watchdog/synth/current/host/acinclude.m4 b/ecos/packages/devs/watchdog/synth/current/host/acinclude.m4
new file mode 100644
index 0000000..a2d3000
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/acinclude.m4
@@ -0,0 +1,43 @@
+dnl Process this file with aclocal to get an aclocal.m4 file. Then
+dnl process that with autoconf.
+dnl ====================================================================
+dnl
+dnl acinclude.m4
+dnl
+dnl ====================================================================
+dnl ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+dnl -------------------------------------------
+dnl This file is part of the eCos host tools.
+dnl Copyright (C) 2002 Free Software Foundation, Inc.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 or (at your option) any
+dnl later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the
+dnl Free Software Foundation, Inc., 51 Franklin Street,
+dnl Fifth Floor, Boston, MA 02110-1301, USA.
+dnl -------------------------------------------
+dnl ####ECOSHOSTGPLCOPYRIGHTEND####
+dnl ====================================================================
+dnl#####DESCRIPTIONBEGIN####
+dnl
+dnl Author(s): bartv
+dnl Contact(s): bartv
+dnl Date: 2002/09/04
+dnl Version: 0.01
+dnl
+dnl####DESCRIPTIONEND####
+dnl ====================================================================
+
+dnl Access shared macros.
+dnl AM_CONDITIONAL needs to be mentioned here or else aclocal does not
+dnl incorporate the macro into aclocal.m4
+sinclude(../../../../../../acsupport/acinclude.m4)
diff --git a/ecos/packages/devs/watchdog/synth/current/host/aclocal.m4 b/ecos/packages/devs/watchdog/synth/current/host/aclocal.m4
new file mode 100644
index 0000000..95d65f1
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/aclocal.m4
@@ -0,0 +1,678 @@
+# generated automatically by aclocal 1.11 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.63],,
+[m4_warning([this file was generated for autoconf 2.63.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/ecos/packages/devs/watchdog/synth/current/host/alarm.gif b/ecos/packages/devs/watchdog/synth/current/host/alarm.gif
new file mode 100644
index 0000000..2c8c318
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/alarm.gif
Binary files differ
diff --git a/ecos/packages/devs/watchdog/synth/current/host/asleep.gif b/ecos/packages/devs/watchdog/synth/current/host/asleep.gif
new file mode 100644
index 0000000..24f4382
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/asleep.gif
Binary files differ
diff --git a/ecos/packages/devs/watchdog/synth/current/host/configure b/ecos/packages/devs/watchdog/synth/current/host/configure
new file mode 100755
index 0000000..55e1ba0
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/configure
@@ -0,0 +1,3587 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.63.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+ if (eval ":") 2>/dev/null; then
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+
+ if test $as_have_required = yes && (eval ":
+(as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=\$LINENO
+ as_lineno_2=\$LINENO
+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+ :
+else
+ as_candidate_shells=
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ case $as_dir in
+ /*)
+ for as_base in sh bash ksh sh5; do
+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+ done;;
+ esac
+done
+IFS=$as_save_IFS
+
+
+ for as_shell in $as_candidate_shells $SHELL; do
+ # Try only shells that exist, to save several forks.
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+ CONFIG_SHELL=$as_shell
+ as_have_required=yes
+ if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+ (exit $1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+ break
+fi
+
+fi
+
+ done
+
+ if test "x$CONFIG_SHELL" != x; then
+ for as_var in BASH_ENV ENV
+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ done
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+ if test $as_have_required = no; then
+ echo This script requires a shell more modern than all the
+ echo shells that I found on your system. Please install a
+ echo modern shell, or manually run the script under such a
+ echo shell if you do have one.
+ { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+ echo No shell found that supports shell functions.
+ echo Please tell bug-autoconf@gnu.org about your system,
+ echo including any error possibly output before this message.
+ echo This can help us improve future autoconf versions.
+ echo Configuration will now proceed without shell functions.
+}
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="watchdog.tcl"
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+PACKAGE_INSTALL
+PACKAGE_DIR
+ECOS_REPOSITORY
+SUPPORTED_FALSE
+SUPPORTED_TRUE
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { $as_echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { $as_echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2
+ { (exit 1); exit 1; }; } ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ { $as_echo "$as_me: error: working directory cannot be determined" >&2
+ { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ { $as_echo "$as_me: error: pwd does not report name of working directory" >&2
+ { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2
+ { (exit 1); exit 1; }; }
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.63
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.63. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args '$ac_arg'"
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_aux_dir=
+for ac_dir in ../../../../../../acsupport "$srcdir"/../../../../../../acsupport; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in ../../../../../../acsupport \"$srcdir\"/../../../../../../acsupport" >&5
+$as_echo "$as_me: error: cannot find install-sh or install.sh in ../../../../../../acsupport \"$srcdir\"/../../../../../../acsupport" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+
+ { $as_echo "$as_me:$LINENO: checking that a separate build tree is being used" >&5
+$as_echo_n "checking that a separate build tree is being used... " >&6; }
+ ecos_cwd=`/bin/pwd`
+ if test "${srcdir}" = "." ; then
+ srcdir=${ecos_cwd}
+ fi
+ if test "${ecos_cwd}" = "${srcdir}" ; then
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:$LINENO: error: This configure script should not be run inside the source tree. Instead please use a separate build tree" >&5
+$as_echo "$as_me: error: This configure script should not be run inside the source tree. Instead please use a separate build tree" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ { { $as_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
+$as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
+ { (exit 1); exit 1; }; }
+
+{ $as_echo "$as_me:$LINENO: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ { { $as_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+$as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+ { (exit 1); exit 1; }; }
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
+$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
+$as_echo "$as_me: error: invalid value of canonical build" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:$LINENO: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+$as_echo "$as_me: error: invalid value of canonical host" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+am__api_version='1.11'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ { { $as_echo "$as_me:$LINENO: error: unsafe absolute working directory name" >&5
+$as_echo "$as_me: error: unsafe absolute working directory name" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ { { $as_echo "$as_me:$LINENO: error: unsafe srcdir value: \`$srcdir'" >&5
+$as_echo "$as_me: error: unsafe srcdir value: \`$srcdir'" >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&5
+$as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+$as_echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+{ $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:$LINENO: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+done
+IFS=$as_save_IFS
+
+fi
+
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ test -d ./--version && rmdir ./--version
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:$LINENO: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+$as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=eCos_synthetic_target_watchdog
+ VERSION=0.1
+
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+{ $as_echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+case "${host}" in
+ i[34567]86-*-linux-gnu* ) SUPPORTED="yes";;
+ x86_64-*-linux-gnu* ) SUPPORTED="yes";;
+ * ) SUPPORTED="no"
+esac
+ if test "${SUPPORTED}" = "yes"; then
+ SUPPORTED_TRUE=
+ SUPPORTED_FALSE='#'
+else
+ SUPPORTED_TRUE='#'
+ SUPPORTED_FALSE=
+fi
+
+
+if test "${SUPPORTED}" = "yes" ; then
+
+
+ package_dir=`cd ${srcdir} && /bin/pwd`
+ PACKAGE_VERSION=`dirname ${package_dir}`
+ PACKAGE_VERSION=`basename ${PACKAGE_VERSION}`
+
+ package_dir=`dirname ${package_dir}`
+ package_dir=`dirname ${package_dir}`
+
+ possibles="${package_dir}/.. ${package_dir}/../.. ${package_dir}/../../.. ${package_dir}/../../../.."
+ possibles="${possibles} ${package_dir}/../../../../.. ${package_dir}/../../../../../.."
+
+ repository_root=""
+ for i in ${possibles}; do
+ if test -d "$i/"acsupport""; then
+ repository_root=$i
+ break
+ fi
+ done
+
+ if test "${repository_root}" = "" ; then
+ { { $as_echo "$as_me:$LINENO: error: Failed to identify this package's position within the eCos repository" >&5
+$as_echo "$as_me: error: Failed to identify this package's position within the eCos repository" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ ECOS_REPOSITORY=`cd "${repository_root}/packages/pkgconf/.." && /bin/pwd`
+
+ PACKAGE_DIR=`echo ${package_dir} | sed -e "s:${ECOS_REPOSITORY}/::"`
+
+ PACKAGE_INSTALL="${PACKAGE_DIR}/${PACKAGE_VERSION}"
+
+
+
+
+
+
+fi
+
+ac_config_files="$ac_config_files Makefile:Makefile.in"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${SUPPORTED_TRUE}" && test -z "${SUPPORTED_FALSE}"; then
+ { { $as_echo "$as_me:$LINENO: error: conditional \"SUPPORTED\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"SUPPORTED\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.63. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTION]... [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.63,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_FILES="$CONFIG_FILES '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { $as_echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile:Makefile.in" ;;
+
+ *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ $as_echo "$as_me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=' '
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5
+$as_echo "$as_me: error: could not setup config files machinery" >&2;}
+ { (exit 1); exit 1; }; }
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X " :F $CONFIG_FILES "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5
+$as_echo "$as_me: error: invalid tag $ac_tag" >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ ac_file_inputs="$ac_file_inputs '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:$LINENO: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+
+
+
+ esac
+
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/ecos/packages/devs/watchdog/synth/current/host/configure.in b/ecos/packages/devs/watchdog/synth/current/host/configure.in
new file mode 100644
index 0000000..90e4dca
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/configure.in
@@ -0,0 +1,72 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl ====================================================================
+dnl
+dnl configure.in
+dnl
+dnl configure script for eCos synthetic target watchdog
+dnl host-side support
+dnl
+dnl ====================================================================
+dnl ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+dnl -------------------------------------------
+dnl This file is part of the eCos host tools.
+dnl Copyright (C) 2002 Free Software Foundation, Inc.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 or (at your option) any
+dnl later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the
+dnl Free Software Foundation, Inc., 51 Franklin Street,
+dnl Fifth Floor, Boston, MA 02110-1301, USA.
+dnl -------------------------------------------
+dnl ####ECOSHOSTGPLCOPYRIGHTEND####
+dnl ====================================================================
+dnl#####DESCRIPTIONBEGIN####
+dnl
+dnl Author(s): bartv
+dnl Contact(s): bartv
+dnl Date: 2002/09/04
+dnl Version: 0.01
+dnl
+dnl####DESCRIPTIONEND####
+dnl ====================================================================
+
+
+AC_INIT(watchdog.tcl)
+
+dnl Pick up the support files from the top-level acsupport directory.
+AC_CONFIG_AUX_DIR(../../../../../../acsupport)
+
+ECOS_CHECK_BUILD_ne_SRC
+AC_CANONICAL_HOST
+AM_INIT_AUTOMAKE(eCos_synthetic_target_watchdog,0.1,0)
+AM_MAINTAINER_MODE
+
+dnl The current version of the synthetic target is implemented only for
+dnl x86 Linux platforms, so a test is appropriate here. However
+dnl it is not a good idea for the configure script to report an error:
+dnl that would prevent any top-level configury working for other
+dnl platforms. Instead an automake conditional is used to suppress adding
+dnl targets to the build.
+case "${host}" in
+ i[[34567]]86-*-linux-gnu* ) SUPPORTED="yes";;
+ x86_64-*-linux-gnu* ) SUPPORTED="yes";;
+ * ) SUPPORTED="no"
+esac
+AM_CONDITIONAL(SUPPORTED, test "${SUPPORTED}" = "yes")
+
+dnl The watchdog host-side support only involves a Tcl
+dnl script and data files, so nothing needs to be compiled
+if test "${SUPPORTED}" = "yes" ; then
+ ECOS_PACKAGE_DIRS
+fi
+
+AC_OUTPUT(Makefile:Makefile.in)
diff --git a/ecos/packages/devs/watchdog/synth/current/host/doghouse.gif b/ecos/packages/devs/watchdog/synth/current/host/doghouse.gif
new file mode 100644
index 0000000..a9ba8a6
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/doghouse.gif
Binary files differ
diff --git a/ecos/packages/devs/watchdog/synth/current/host/doghouse.pov b/ecos/packages/devs/watchdog/synth/current/host/doghouse.pov
new file mode 100644
index 0000000..e353a6f
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/doghouse.pov
@@ -0,0 +1,161 @@
+// A simple "doghouse" picture, used for the synthetic target
+// watchdog device host-side.
+//
+// This file is normally built using the following command line:
+//
+// x-povray +Idoghouse.pov +W128 +H128 +D +Q9 +AM2 +A0.9 +FP
+
+#include "consts.inc"
+#include "colors.inc"
+#include "shapes.inc"
+#include "textures.inc"
+#include "skies.inc"
+#include "woods.inc"
+
+camera {
+ location <4.5, 2.2, -5>
+ look_at <2, 2, 2>
+}
+
+light_source {
+ <7, 4, -1.5>
+ color White
+}
+
+sky_sphere { S_Cloud2 scale 2 }
+background { colour LightBlue }
+
+plane {
+ y 0
+ texture {
+ pigment { color red 0.5 green 0.98 blue 0 turbulence 0.5}
+ normal { bumps 0.4 scale 0.1 }
+ }
+}
+
+fog {
+ distance 40
+ fog_type Ground_Fog
+ fog_offset 1
+ fog_alt 1
+ colour rgbf<0, 0.2, 0.2, 0.3>
+ turbulence 0.2
+}
+
+// A plank is a 1x1x0.1 block with a corner at the origin. The edges are
+// slightly rounded, to make sure that the plank boundaries are just
+// about visible.
+#declare Plank =
+ superellipsoid { <0.03,0.03> scale <0.5,0.5,0.05> translate <0.5,0.5,0.05> texture { T_Wood10 } }
+
+// A variant, for the roof
+#declare RoofPlank =
+ superellipsoid { <0.05,0.05> scale <0.5,0.5,0.05> translate <0.5,0.5,0.05> texture { T_Wood14 } }
+
+// The front and back, a rectangle with a triangle on top.
+// Going clockwise from the bottom left, the coordinates are:
+// <0,0> <0,3.2>, <2.4.5>, <4,3.2>, <4.0>
+// Each is made from five horizontal planks.
+//
+// Note: this doghouse is not intended to be an example of good
+// woodworking. For example, butt joints for the walls are a bad idea.
+// Most importantly the roof should involve lapped joints with a
+// sensible ridge, the current construction is not going to keep the
+// rain out.
+#declare RoofAngle = degrees(atan2(1.3,2));
+#declare RoofAngleR = atan2(1.3,2);
+
+#declare FrontBack =
+ difference {
+ union {
+ object { Plank scale <4,1,1> translate <0,0,0> }
+ object { Plank scale <4,1,1> translate <0,1,0> }
+ object { Plank scale <4,1,1> translate <0,2,0> }
+ object { Plank scale <4,1,1> translate <0,3,0> }
+ object { Plank scale <4,1,1> translate <0,4,0> }
+ }
+ union {
+ box { <0,0,0> <4,4,1> rotate <0,0,RoofAngle> translate <0,3.2,-0.5> }
+ box { <0,0,0> <4,4,1> rotate <0,0, -1 * RoofAngle> translate <2,4.5,-0.5> }
+ pigment { Black }
+ }
+ }
+
+// The front also has some text to name the dog, and a
+// cutout for the opening.
+object {
+ difference {
+ object { FrontBack }
+ union {
+ text {
+ ttf "cyrvetic.ttf" "FIFI" 0.1 0
+ translate <1.2, 2.8, -0.05>
+ }
+ box { <1,0,-0.5> <3,2.2,0.5> }
+ object {
+ cylinder { <0,0,0> <0,0,1> 1 }
+ scale <1,0.33,1>
+ translate <2,2.2,-0.5>
+ }
+ pigment { Black }
+ }
+ }
+}
+
+// The back, nothing fancy needed here. The doghouse is twice
+// as deep as it is wide.
+object { FrontBack translate <0,0,8> }
+
+// A floor, to prevent any bright grass showing inside
+box { <0.05,0,0.05> <3.95,0.05,7.95> texture { T_Wood3 } }
+
+// LHS
+object { Plank scale <8,1,1> rotate <0,-90,0> translate <0,0,0.1> }
+object { Plank scale <8,1,1> rotate <0,-90,0> translate <0,1,0.1> }
+object { Plank scale <8,1,1> rotate <0,-90,0> translate <0,2,0.1> }
+
+// RHS
+object { Plank scale <8,1,1> rotate <0,-90,0> translate <4,0,0.1> }
+object { Plank scale <8,1,1> rotate <0,-90,0> translate <4,1,0.1> }
+object { Plank scale <8,1,1> rotate <0,-90,0> translate <4,2,0.1> }
+
+// Now for the roof. The top of the roof is at <2,4.5,0>, and the
+// corners are at <0,3.2,0> and <4,3.2,0>. The planks are 0.1 units
+// thick.
+
+#declare RoofPlank =
+ superellipsoid { <0.05,0.05> scale <0.5,0.5,0.05> translate <0.5,0.5,0.05> texture { T_Wood14 } }
+
+#declare RoofPlank_L = object {
+ RoofPlank
+ rotate <0, -90, RoofAngle - 90>
+ scale<1,1,8.5>
+}
+
+#declare RoofPlank_R = object {
+ RoofPlank
+ rotate <0, -90, -90 - RoofAngle>
+ scale<1,1,8.5>
+}
+
+object { RoofPlank_L translate<2 - (1 * cos(RoofAngleR)), 4.5 - (1 * sin(RoofAngleR)), -0.25> }
+object { RoofPlank_L translate<2 - (2 * cos(RoofAngleR)), 4.5 - (2 * sin(RoofAngleR)), -0.25> }
+object { RoofPlank_L translate<2 - (3 * cos(RoofAngleR)), 4.5 - (3 * sin(RoofAngleR)), -0.25> }
+
+object { RoofPlank_R translate<2 + (-0.1 * cos(RoofAngleR)), 4.5 - (-0.1 * sin(RoofAngleR)), -0.25> }
+object { RoofPlank_R translate<2 + (0.9 * cos(RoofAngleR)), 4.5 - (0.9 * sin(RoofAngleR)), -0.25> }
+object { RoofPlank_R translate<2 + (1.9 * cos(RoofAngleR)), 4.5 - (1.9 * sin(RoofAngleR)), -0.25> }
+
+// And just for fun, a dog bowl.
+object {
+ merge {
+ difference {
+ torus { 1.0 0.5 }
+ box { <-1,-1,-1> <1,0,1> pigment { Black } }
+ }
+ cylinder { <0,0,0> <0,0.2,0> 0.9 }
+ }
+ scale <0.5,0.5,0.5>
+ translate <-0.5,0,-0.7>
+ pigment { Yellow }
+}
diff --git a/ecos/packages/devs/watchdog/synth/current/host/eye.gif b/ecos/packages/devs/watchdog/synth/current/host/eye.gif
new file mode 100644
index 0000000..520f5ea
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/eye.gif
Binary files differ
diff --git a/ecos/packages/devs/watchdog/synth/current/host/sound1.au b/ecos/packages/devs/watchdog/synth/current/host/sound1.au
new file mode 100644
index 0000000..156af9a
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/sound1.au
Binary files differ
diff --git a/ecos/packages/devs/watchdog/synth/current/host/sound2.au b/ecos/packages/devs/watchdog/synth/current/host/sound2.au
new file mode 100644
index 0000000..f188581
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/sound2.au
Binary files differ
diff --git a/ecos/packages/devs/watchdog/synth/current/host/watchdog.tcl b/ecos/packages/devs/watchdog/synth/current/host/watchdog.tcl
new file mode 100644
index 0000000..9e1a021
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/watchdog.tcl
@@ -0,0 +1,422 @@
+# {{{ Banner
+
+# ============================================================================
+#
+# watchdog.tcl
+#
+# Watchdog support for the eCos synthetic target I/O auxiliary
+#
+# ============================================================================
+# ####ECOSHOSTGPLCOPYRIGHTBEGIN####
+# -------------------------------------------
+# This file is part of the eCos host tools.
+# Copyright (C) 2002 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street,
+# Fifth Floor, Boston, MA 02110-1301, USA.
+# -------------------------------------------
+# ####ECOSHOSTGPLCOPYRIGHTEND####
+# ============================================================================
+# #####DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Contact(s): bartv
+# Date: 2002/09/04
+# Version: 0.01
+# Description:
+# Implementation of the watchdog device. This script should only ever
+# be run from inside the ecosynth auxiliary.
+#
+# ####DESCRIPTIONEND####
+# ============================================================================
+
+# }}}
+
+namespace eval watchdog {
+
+ # Was initialization successful?
+ variable init_ok 1
+
+ # Has the alarm triggered?
+ variable alarm_triggered 0
+
+ # The eCos application process id. This is needed to send a SIGPWR signal
+ # if the watchdog triggers, and to access /proc/<pid>/stat to obtain
+ # timing information. Strictly speaking _ppid is not exported by
+ # the I/O auxiliary.
+ if { ! [info exists synth::_ppid] } {
+ synth::report_error "Watchdog initialization failed, _ppid variable required"
+ return ""
+ }
+ variable ecos_pid $synth::_ppid
+
+ # Resolution, i.e. how long to go between checks. Currently this is hard-wired
+ # to one second, or 1000 ms. This may become configurable, either on the
+ # target-side via CDL or on the host-side via the target definition file.
+ # Note that currently the watchdog device and the GUI get updated via the
+ # same timer. If the resolution is changed to e.g. 10 seconds then it might
+ # be a good idea to update the GUI more frequently, although there are
+ # arguments for keeping the animation in step with the real work.
+ variable resolution 1000
+
+ # Options from the target definition file
+ variable use_wallclock 0
+ variable window_pack "-in .main.n -side right"
+ variable sound_file ""
+ variable sound_player "play"
+
+ if { [synth::tdf_has_device "watchdog"] } {
+ if { [synth::tdf_has_option "watchdog" "use"] } {
+ set _use [synth::tdf_get_option "watchdog" "use"]
+ if { "wallclock_time" == $_use } {
+ set watchdog::use_wallclock 1
+ } elseif { "consumed_cpu_time" == $_use } {
+ set watchdog::use_wallclock 0
+ } else {
+ synth::report_error "Invalid entry in target definition file $synth::target_definition\n\
+ \ Device watchdog, option \"use\" should be \"wallclock_time\" or \"consumed_cpu_time\"\n"
+ }
+ unset _use
+ }
+ if { [synth::tdf_has_option "watchdog" "watchdog_pack"] } {
+ set watchdog::window_pack [synth::tdf_get_option "watchdog" "watchdog_pack"]
+ # Too complicated to validate here, instead leave it to a catch statement
+ # when the window actually gets packed
+ }
+ if { [synth::tdf_has_option "watchdog" "sound"] } {
+ set _sound_file [synth::tdf_get_option "watchdog" "sound"]
+ # Look for this sound file in the install tree first, then absolute or relative
+ if { [file exists [file join $synth::device_install_dir $_sound_file] ] } {
+ set _sound_file [file join $synth::device_install_dir $_sound_file]
+ }
+ if { ![file exists $_sound_file] } {
+ synth::report_error "Invalid entry in target definition file $synth::target_definition\n\
+ \ Device watchdog, option \"sound\", failed to find $_sound_file\n"
+ } elseif { ! [file readable $_sound_file] } {
+ synth::report_error "Invalid entry in target definition file $synth::target_definition\n\
+ \ Device watchdog, option \"sound\", no read access to file $_sound_file\n"
+ } else {
+ set watchdog::sound_file $_sound_file
+ }
+ unset _sound_file
+ }
+ if { [synth::tdf_has_option "watchdog" "sound_player"] } {
+ set watchdog::sound_player [synth::tdf_get_option "watchdog" "sound_player"]
+ }
+ }
+
+ # There is no point in creating the watchdog window if any of the image files are missing
+ if { $synth::flag_gui } {
+ foreach _image [list "doghouse.gif" "alarm.gif" "eye.gif" "asleep.gif"] {
+ variable image_[file rootname $_image]
+ if { ! [synth::load_image "watchdog::image_[file rootname $_image]" [file join $synth::device_install_dir $_image]] } {
+ synth::report_error "Watchdog device, unable to load image $_image\n\
+ \ This file should have been installed in $synth::device_install_dir\n"
+ set watchdog::init_ok 0
+ }
+ }
+ }
+ if { $synth::flag_gui && $watchdog::init_ok } {
+ canvas .watchdog -width [image width $image_doghouse] -height [image height $image_doghouse] \
+ -borderwidth 0
+ variable background [.watchdog create image 0 0 -anchor nw -image $image_doghouse]
+
+ # Eye positions inside the doghouse. The eye is an 8x10 gif,
+ # mostly white but transparent around the corners
+ variable left_eye_x 48
+ variable left_eye_y 70
+ variable right_eye_x 58
+ variable right_eye_y 70
+
+ # Pupil positions relative to the eye. The pupils are 3x3 rectangles.
+ # The dog can look in one of nine different directions, with both eyes
+ # looking in the same direction (if visible)
+ variable pupil_positions { { 1 6 } { 1 5 } { 1 3 } { 3 1 } { 3 4 } { 3 6 } { 4 3 } { 4 5 } { 4 6 } }
+
+ # Which eyes are currently visible: none, left, right or both
+ variable eyes "none"
+ # What is the current pupil position?
+ variable pupils 4
+
+ variable left_eye [.watchdog create image $left_eye_x $left_eye_y -anchor nw -image $image_eye]
+ variable right_eye [.watchdog create image $right_eye_x $right_eye_y -anchor nw -image $image_eye]
+
+ variable left_pupil \
+ [.watchdog create rectangle \
+ [expr $left_eye_x + [lindex [lindex $pupil_positions $pupils] 0]] \
+ [expr $left_eye_y + [lindex [lindex $pupil_positions $pupils] 1]] \
+ [expr $left_eye_x + [lindex [lindex $pupil_positions $pupils] 0] + 2] \
+ [expr $left_eye_y + [lindex [lindex $pupil_positions $pupils] 1] + 2] \
+ -fill black]
+ variable right_pupil \
+ [.watchdog create rectangle \
+ [expr $right_eye_x + [lindex [lindex $pupil_positions $pupils] 0]] \
+ [expr $right_eye_y + [lindex [lindex $pupil_positions $pupils] 1]] \
+ [expr $right_eye_x + [lindex [lindex $pupil_positions $pupils] 0] + 2] \
+ [expr $right_eye_y + [lindex [lindex $pupil_positions $pupils] 1] + 2] \
+ -fill black]
+
+
+ # The dog is asleep until the eCos application activates the watchdog device
+ .watchdog lower $left_eye $background
+ .watchdog lower $right_eye $background
+ .watchdog lower $left_pupil $background
+ .watchdog lower $right_pupil $background
+
+ # Prepare for an alarm, but obviously the alarm picture should be hidden for now.
+ variable alarm [.watchdog create image 30 56 -anchor nw -image $image_alarm]
+ .watchdog lower $alarm $background
+
+ # Start asleep
+ variable asleep [.watchdog create image 48 70 -anchor nw -image $image_asleep]
+
+ # Now try to pack the watchdog window using the option provided by the
+ # user. If that fails, report the error and pack in a default window.
+ if { [catch { eval pack .watchdog $watchdog::window_pack } message] } {
+ synth::report_error "Watchdog device, failed to pack window in $watchdog::window_pack\n $message"
+ pack .watchdog -in .main.n -side right
+ }
+
+ # Updating the display. This happens once a second.
+ # If neither eye is visible, choose randomly between
+ # left-only, right-only or both. Otherwise there is
+ # a one in eight chance of blinking, probably switching
+ # to one of the other eye modes
+ #
+ # Also, the visible pupil(s) will move every second, to one
+ # of nine positions
+ proc gui_update { } {
+
+ if { "none" == $watchdog::eyes} {
+ set rand [expr int(3 * rand())]
+ if { 0 == $rand } {
+ set watchdog::eyes "left"
+ .watchdog raise $watchdog::left_eye $watchdog::background
+ .watchdog raise $watchdog::left_pupil $watchdog::left_eye
+ } elseif { 1 == $rand } {
+ set watchdog::eyes "right"
+ .watchdog raise $watchdog::right_eye $watchdog::background
+ .watchdog raise $watchdog::right_pupil $watchdog::right_eye
+ } else {
+ set watchdog::eyes "both"
+ .watchdog raise $watchdog::left_eye $watchdog::background
+ .watchdog raise $watchdog::left_pupil $watchdog::left_eye
+ .watchdog raise $watchdog::right_eye $watchdog::background
+ .watchdog raise $watchdog::right_pupil $watchdog::right_eye
+ }
+ } else {
+ if { 0 == [expr int(8 * rand())] } {
+ set watchdog::eyes "none"
+ .watchdog lower $watchdog::left_eye $watchdog::background
+ .watchdog lower $watchdog::right_eye $watchdog::background
+ .watchdog lower $watchdog::left_pupil $watchdog::background
+ .watchdog lower $watchdog::right_pupil $watchdog::background
+
+ # There is no point in moving the pupils if both eyes are shut
+ return
+ }
+ }
+
+ set watchdog::pupils [expr int(9 * rand())]
+ set new_pupil_x [lindex [lindex $watchdog::pupil_positions $watchdog::pupils] 0]
+ set new_pupil_y [lindex [lindex $watchdog::pupil_positions $watchdog::pupils] 1]
+
+ if { ("left" == $watchdog::eyes) || ("both" == $watchdog::eyes) } {
+ .watchdog coords $watchdog::left_pupil \
+ [expr $watchdog::left_eye_x + $new_pupil_x] \
+ [expr $watchdog::left_eye_y + $new_pupil_y] \
+ [expr $watchdog::left_eye_x + $new_pupil_x + 2] \
+ [expr $watchdog::left_eye_y + $new_pupil_y + 2]
+ }
+ if { ("right" == $watchdog::eyes) || ("both" == $watchdog::eyes) } {
+ .watchdog coords $watchdog::right_pupil \
+ [expr $watchdog::right_eye_x + $new_pupil_x] \
+ [expr $watchdog::right_eye_y + $new_pupil_y] \
+ [expr $watchdog::right_eye_x + $new_pupil_x + 2] \
+ [expr $watchdog::right_eye_y + $new_pupil_y + 2]
+ }
+ }
+
+ # Cancel the gui display when the eCos application has exited.
+ # The watchdog is allowed to go back to sleep. If the application
+ # exited because of the watchdog then of course the alarm picture
+ # should remain visible, otherwise it would be just a flash.
+ proc gui_cancel { } {
+ .watchdog lower $watchdog::left_eye $watchdog::background
+ .watchdog lower $watchdog::right_eye $watchdog::background
+ .watchdog lower $watchdog::left_pupil $watchdog::background
+ .watchdog lower $watchdog::right_pupil $watchdog::background
+ if { ! $watchdog::alarm_triggered } {
+ .watchdog raise $watchdog::asleep $watchdog::background
+ }
+ }
+
+ # Raise the alarm. This involves hiding the eyes and raising
+ # the alarm picture. If sound is enabled, the sound player
+ # should be invoked
+ proc gui_alarm { } {
+ .watchdog lower $watchdog::asleep $watchdog::background
+ .watchdog lower $watchdog::left_eye $watchdog::background
+ .watchdog lower $watchdog::right_eye $watchdog::background
+ .watchdog lower $watchdog::left_pupil $watchdog::background
+ .watchdog lower $watchdog::right_pupil $watchdog::background
+ .watchdog raise $watchdog::alarm $watchdog::background
+
+ if { "" != $watchdog::sound_file } {
+ # Catch errors on the actual exec, e.g. if the sound player is
+ # invalid, but play the sound in the background. If there are
+ # problems actually playing the sound then the user should
+ # still see a message on stderr. Blocking the entire auxiliary
+ # for a few seconds is not acceptable.
+ if { [catch { eval exec -- $watchdog::sound_player $watchdog::sound_file & } message] } {
+ synth::report_warning "Watchdog device, failed to play alarm sound file\n $message\n"
+ }
+ }
+ }
+
+ set _watchdog_help [file join $synth::device_src_dir "doc" "devs-watchdog-synth.html"]
+ if { ![file readable $_watchdog_help] } {
+ synth::report_warning "Failed to locate synthetic watchdog documentation $_watchdog_help\n\
+ \ Help->Watchdog target menu option disabled.\n"
+ set _watchdog_help ""
+ }
+ if { "" == $_watchdog_help } {
+ .menubar.help add command -label "Watchdog" -state disabled
+ } else {
+ .menubar.help add command -label "Watchdog" -command [list synth::handle_help "file://$_watchdog_help"]
+ }
+ }
+
+ # Now for the real work. By default the watchdog is asleep. The eCos
+ # application can activate it with a start message, which results
+ # in an "after" timer. That runs once a second to check whether or not
+ # the watchdog should trigger, and also updates the GUI.
+ #
+ # The target-side code should perform a watchdog reset at least once
+ # a second, which involves another message to this script and the
+ # setting of the reset_received flag.
+ #
+ # The update handler gets information about the eCos application using
+ # /proc/<pid>/stat (see man 5 proc). The "state" field is important:
+ # a state of T indicates that the application is stopped, probably
+ # inside gdb, so cannot reset the watchdog. The other important field
+ # is utime, the total number of jiffies (0.01 seconds) executed in
+ # user space. The code maintains an open file handle to the /proc file.
+
+ variable reset_received 0
+ variable after_id ""
+ variable proc_stat ""
+ variable last_jiffies 0
+
+ set _filename "/proc/[set watchdog::ecos_pid]/stat"
+ if { [catch { open $_filename "r" } proc_stat ] } {
+ synth::report_error "Watchdog device, failed to open $_filename\n $proc_stat\n"
+ set watchdog::init_ok 0
+ }
+ unset _filename
+
+ proc update { } {
+ set watchdog::after_id [after $watchdog::resolution watchdog::update]
+ if { $synth::flag_gui } {
+ watchdog::gui_update
+ }
+ seek $watchdog::proc_stat 0 "start"
+ set line [gets $watchdog::proc_stat]
+ scan $line "%*d %*s %s %*d %*d %*d %*d %*d %*lu %*lu %*lu %*lu %*lu %lu" state jiffies
+
+ # In theory it is possible to examine the state field (the third argument).
+ # If set to T then that indicates the eCos application is traced or
+ # stopped, probably inside gdb, and it would make sense to act as if
+ # the application had sent a reset. Unfortunately the state also appears
+ # to be set to T if the application is blocked in a system call while
+ # being debugged - including the idle select(), making the test useless.
+ # FIXME: figure out how to distinguish between being blocked inside gdb
+ # and being in a system call.
+ #if { "T" == $state } {
+ # set watchdog::reset_received 1
+ # return
+ #}
+
+ # If there has been a recent reset the eCos application can continue to run for a bit longer.
+ if { $watchdog::reset_received } {
+ set watchdog::last_jiffies $jiffies
+ set watchdog::reset_received 0
+ return
+ }
+
+ # We have not received a reset. If the watchdog is using wallclock time then
+ # that is serious. If the watchdog is using elapsed cpu time then the eCos
+ # application may not actually have consumed a whole second of cpu time yet.
+ if { $watchdog::use_wallclock || (($jiffies - $watchdog::last_jiffies) > ($watchdog::resolution / 10)) } {
+ set watchdog::alarm_triggered 1
+ # Report the situation via the main text window
+ synth::report "Watchdog device: the eCos application has not sent a recent reset\n Raising SIGPWR signal.\n"
+ # Then kill off the eCos application
+ exec kill -PWR $watchdog::ecos_pid
+ # There is no point in another run of the timer
+ after cancel $watchdog::after_id
+ # And if the GUI is running, raise the alarm visually
+ if { $synth::flag_gui } {
+ watchdog::gui_alarm
+ }
+ }
+ }
+
+ # When the eCos application has exited, cancel the timer and
+ # clean-up the GUI. Also get rid of the open file since the
+ # /proc/<pid>/stat file is no longer meaningful
+ proc exit_hook { arg_list } {
+ if { "" != $watchdog::after_id } {
+ after cancel $watchdog::after_id
+ }
+ if { $synth::flag_gui } {
+ watchdog::gui_cancel
+ }
+ close $watchdog::proc_stat
+ }
+ synth::hook_add "ecos_exit" watchdog::exit_hook
+
+ proc handle_request { id reqcode arg1 arg2 reqdata reqlen reply_len } {
+ if { 0x01 == $reqcode } {
+ # A "start" request. If the watchdog has already started,
+ # this request is a no-op. Otherwise a timer is enabled.
+ # This is made to run almost immediately, so that the
+ # GUI gets a quick update. Setting the reset_received flag
+ # ensures that the watchdog will not trigger immediately
+ set watchdog::reset_received 1
+ if { "" == $watchdog::after_id } {
+ set watchdog::after_id [after 1 watchdog::update]
+ }
+ if { $synth::flag_gui } {
+ .watchdog lower $watchdog::asleep $watchdog::background
+ }
+ } elseif { 0x02 == $reqcode } {
+ # A "reset" request. Just set a flag, the update handler
+ # will detect this next time it runs.
+ set watchdog::reset_received 1
+ }
+ }
+
+ proc instantiate { id name data } {
+ return watchdog::handle_request
+ }
+}
+
+if { $watchdog::init_ok } {
+ return watchdog::instantiate
+} else {
+ synth::report "Watchdog cannot be instantiated, initialization failed.\n"
+ return ""
+}
diff --git a/ecos/packages/devs/watchdog/synth/current/host/watchdog.tdf b/ecos/packages/devs/watchdog/synth/current/host/watchdog.tdf
new file mode 100644
index 0000000..6a1677d
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/host/watchdog.tdf
@@ -0,0 +1,63 @@
+synth_device watchdog {
+
+ ## How should the watchdog device decide that the watchdog has
+ ## triggered, assuming the eCos application has failed to
+ ## reset the device in time. There are two options: wallclock
+ ## time, where the watchdog will trigger after a second
+ ## irrespective of what the eCos application has been doing;
+ ## or consumed cpu time, where the watchdog will only trigger
+ ## if the eCos application has actually run for a whole second.
+ ##
+ ## Using wallclock time matches most real hardware,
+ ## but can give spurious results if there are other processes
+ ## running and consuming cpu cycles. Also, if the user has
+ ## halted the application in gdb then the watchdog will trigger
+ ## even though the application has no chance to reset the
+ ## watchdog.
+ ##
+ ## Using consumed cpu cycles avoids these problems.
+ ## However the default implementation of the idle thread action
+ ## is to block in a select() system call, so if the eCos
+ ## application spends most of its time idling but not resetting
+ ## the watchdog then the device will not trigger. The
+ ## configuration option CYGIMP_HAL_IDLE_THREAD_SPIN can be used
+ ## to change the synthetic target HAL's implementation of the
+ ## idle thread action.
+ ##
+ ## The default is to use consumed_cpu_time. Wallclock time can
+ ## be selected by uncommenting the next line.
+ # use wallclock_time
+ # use consumed_cpu_time
+
+ ## When running in GUI mode there will be a small window showing
+ ## the current state of the watchdog: asleep, watching, or giving
+ ## the alarm. This window can be packed as desired, using one
+ ## of the container frames .main.nw .main.n .main.ne .main.w
+ ## .main.e .main.sw .main.s or .main.se, and with a position of
+ ## left, right, top or bottom. The default is to pack inside the
+ ## .main.n frame, on the right, thus causing the watchdog to
+ ## appear above the central text window.
+ # watchdog_pack -in .main.n -side right
+
+ ## If running in GUI mode, when the watchdog triggers and resets
+ ## the eCos application this will be shown in the display.
+ ## Optionally the watchdog device can also give an audible alert
+ ## when this happens. This is disabled by default to avoid
+ ## annoying co-workers, but can be enabled by specifying a suitable
+ ## sound file. Two such files, sound1.au and sound2.au, are supplied
+ ## with the watchdog device itself. Alternatively the user can
+ ## specify a different sound file using a suitable path
+ # sound sound1.au
+ # sound sound2.au
+ # sound ~/sounds/my_watchdog_alert.au
+
+ ## If sound is enabled then the watchdog device needs some way to
+ ## access the host's sound hardware. Rather than accessing
+ ## /dev/audio or /dev/dsp directly the watchdog.tcl script will
+ ## run an external program. This can avoid complications with
+ ## different sound file formats etc. The default program is
+ ## "play", a front-end to the sox utility, but a different
+ ## program or script can be specified if desired. It will be run
+ ## simply as "<program> <sound file> &"
+ # sound_player play
+}
diff --git a/ecos/packages/devs/watchdog/synth/current/src/synth_watchdog.cxx b/ecos/packages/devs/watchdog/synth/current/src/synth_watchdog.cxx
new file mode 100644
index 0000000..b098654
--- /dev/null
+++ b/ecos/packages/devs/watchdog/synth/current/src/synth_watchdog.cxx
@@ -0,0 +1,132 @@
+//==========================================================================
+//
+// synth_watchdog.cxx
+//
+// Watchdog driver for the synthetic target
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2002, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors: bartv
+// Date: 2002-09-04
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_watchdog_synth.h>
+
+#ifdef CYGIMP_WATCHDOG_HARDWARE
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_io.h>
+
+// FIXME: right now the generic watchdog header depends on the
+// kernel. That should be fixed in the watchdog code, but will
+// affect some device drivers as well
+#include <pkgconf/kernel.h>
+#include <cyg/io/watchdog.hxx>
+
+// Protocol between host and target
+#define SYNTH_WATCHDOG_START 0x01
+#define SYNTH_WATCHDOG_RESET 0x02
+
+// The synthetic target's watchdog implementation involves interaction
+// with a watchdog.tcl script running in the I/O auxiliary. The device
+// is instantiated during system initialization via the generic
+// watchdog package's prioritized constructor. The main
+// Cyg_Watchdog::start() and reset() functions involve passing a
+// message to the host-side.
+//
+// There is an open issue re. resolution. Usually the hardware imposes
+// limits on what resolutions are valid, in fact there may be only one.
+// With the synthetic target it would be possible to configure the
+// desired resolution either on the target-side using a CDL option, or
+// on the host-side using the target definition file. The resolution
+// would have to be fairly coarse, probably at least 0.1 seconds,
+// to allow for communication overheads. It is not clear whether
+// target-side or host-side configuration is more appropriate, so for
+// now a fixed resolution of one second is used.
+
+// Id for communicating with the watchdog instance in the auxiliary
+static int aux_id = -1;
+
+// Hardware initialization.
+void
+Cyg_Watchdog::init_hw(void)
+{
+ // SIGPWR is disabled by default. It has to be reenabled.
+ struct cyg_hal_sys_sigset_t blocked;
+ CYG_HAL_SYS_SIGEMPTYSET(&blocked);
+ CYG_HAL_SYS_SIGADDSET(&blocked, CYG_HAL_SYS_SIGPWR);
+ cyg_hal_sys_sigprocmask(CYG_HAL_SYS_SIG_UNBLOCK, &blocked, (cyg_hal_sys_sigset_t*) 0);
+
+ resolution = 1000000000LL;
+ if (synth_auxiliary_running) {
+ aux_id = synth_auxiliary_instantiate("devs/watchdog/synth",
+ SYNTH_MAKESTRING(CYGPKG_DEVS_WATCHDOG_SYNTH),
+ "watchdog",
+ (const char*) 0,
+ (const char*) 0);
+ }
+}
+
+void
+Cyg_Watchdog::start(void)
+{
+ if (synth_auxiliary_running && (-1 != aux_id)) {
+ synth_auxiliary_xchgmsg(aux_id, SYNTH_WATCHDOG_START, 0, 0,
+ (const unsigned char*)0, 0,
+ (int *) 0,
+ (unsigned char*) 0, (int*) 0, 0);
+ }
+}
+
+void
+Cyg_Watchdog::reset()
+{
+ if (synth_auxiliary_running && (-1 != aux_id)) {
+ synth_auxiliary_xchgmsg(aux_id, SYNTH_WATCHDOG_RESET, 0, 0,
+ (const unsigned char*)0, 0,
+ (int *) 0,
+ (unsigned char*) 0, (int*) 0, 0);
+ }
+}
+
+#endif // CYGIMP_WATCHDOG_HARDWARE